0

Can someone please tell me if this is correct way of using SysLogAppender of log4cplus ? I did not find a proper example for log4cplus. I need to send numerous logs to remote syslog server.

main.cpp
int main()
{
SysLogHelper syslogHelper;
int errCode = syslogHelper.initialize("172.16.72.239");
    errCode = syslogHelper.sendLogstoSyslog("send testing log");
    // I need to send numerous logs to syslog
}

syslog.cpp

#include <log4cplus/syslogappender.h>
#include <log4cplus/spi/loggingevent.h>
#include <log4cplus/logger.h>

class SysLogHelper 
{
    string hostname;
    log4cplus::SysLogAppender *syslogAppender;
        // is it necessary to create a pointer? I am not able to use log4cplus in a class without creating a pointer? Is there any other way?
    log4cplus::spi::InternalLoggingEvent syslogLoggingEvent;

        public:
    SysLogHelper();
    int initialize(string hostname);
    int sendLogstoSyslog(string message);
};

SysLogHelper::SysLogHelper()
{
    hostname = "";
    syslogAppender = NULL;
}

int SysLogHelper::initialize(string hostname)
{
    syslogAppender = new log4cplus::SysLogAppender("ident", hostname);
        //I am not getting what is "ident" here? what input is expected?
    return 0;
}

int SysLogHelper::sendLogstoSyslog(string message)
{
    syslogLoggingEvent.setLoggingEvent( 
    log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("test")).getName(),    
    log4cplus::FATAL_LOG_LEVEL, LOG4CPLUS_TEXT(message),__FILE__, 
    __LINE__, "main");
syslogAppender->doAppend(syslogLoggingEvent);
    //Is this correct method of sending logs to syslog?
return 0;
}

questions:

  1. I am able to send logs to remote syslog using above code. But is this correct way to use log4cplus APIs? Questions are given in the form of comments in above code example.

  2. Why do we need to use log4cplus::initializer? I am not able to import log4cplus/initializer.h in my code.

aromahola
  • 190
  • 1
  • 12

1 Answers1

0

In my opinion the phylosophy at the base of Log4cplus library is that you can have in your application one or more logger and for each logger you can have one or more output, called "appender". Inside your application you have to manage with logger and you don't have care which appender are linked to the logger. This is clear, for example, if you use a property file to config and to tune your logger. By the way here in the following I show what I have done to configure syslog inside my application in both cases:

configuring syslog appender inside the code:

#include <log4cplus/logger.h>
#include <log4cplus/fileappender.h>
#include <log4cplus/syslogappender.h>
#include <log4cplus/layout.h>
#include <log4cplus/ndc.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/property.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/configurator.h>
#include <log4cplus/helpers/stringhelper.h>
#include <log4cplus/helpers/fileinfo.h>
#include <TCHAR.h>

using namespace std;
using namespace log4cplus;
using namespace log4cplus::helpers;
using namespace log4cplus;

int main()
{
    log4cplus::initialize ();

    Logger root = Logger::getRoot();
    // log level INFO: you don't see TRACE and DEBUG on your syslogserver
    root.setLogLevel(log4cplus::INFO_LOG_LEVEL);
    SharedObjectPtr<Appender>  ptrSys(
                                       new SysLogAppender( 
                                      _T("mysyslog"), 
                                      _T("localhost"), 
                                      514,
                                      _T("user"))) ;
    root.addAppender(ptrSys);
    for(int i=0; i<100; ++i) 
    {

        LOG4CPLUS_TRACE(root, LOG4CPLUS_TEXT("Error log test"));  //not visible
        LOG4CPLUS_DEBUG(root, LOG4CPLUS_TEXT("Debug log test"));  //not visible
        LOG4CPLUS_INFO(root, LOG4CPLUS_TEXT("Info log test"));
        LOG4CPLUS_WARN(root, LOG4CPLUS_TEXT("Warning log test"));
        LOG4CPLUS_ERROR(root, LOG4CPLUS_TEXT("Error log test"));
    }
    log4cplus::Logger::shutdown();
    return 0;
}

As I said the way, that I prefer, is by configuration file, called here configlog.properties

#include <log4cplus/logger.h>
#include <log4cplus/fileappender.h>
#include <log4cplus/syslogappender.h>
#include <log4cplus/layout.h>
#include <log4cplus/ndc.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/property.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/configurator.h> 
#include <log4cplus/helpers/stringhelper.h>
#include <log4cplus/helpers/fileinfo.h>
#include <TCHAR.h>

using namespace std;
using namespace log4cplus;
using namespace log4cplus::helpers;
using namespace log4cplus;

log4cplus::tstring getPropertiesFileArgument (std::wstring argv)
{   
    log4cplus::tstring file = LOG4CPLUS_C_STR_TO_TSTRING (argv);
    log4cplus::helpers::FileInfo fi;
    if (getFileInfo (&fi, file) == 0)
        return file;

    return LOG4CPLUS_TEXT ("log4cplus.properties");
}

int main()
{
    log4cplus::initialize ();
 PropertyConfigurator::doConfigure(  getPropertiesFileArgument(_T("c:\\ConfigLog.properties")));

Logger root = Logger::getRoot();
for(int i=0; i<100; ++i) {

    LOG4CPLUS_TRACE(root, LOG4CPLUS_TEXT("Error log test"));
    LOG4CPLUS_DEBUG(root, LOG4CPLUS_TEXT("Debug log test"));
    LOG4CPLUS_INFO(root, LOG4CPLUS_TEXT("Info log test"));
    LOG4CPLUS_WARN(root, LOG4CPLUS_TEXT("Warning log test"));
    LOG4CPLUS_ERROR(root, LOG4CPLUS_TEXT("Error log test"));

}
log4cplus::Logger::shutdown();

return 0;

}

the configlog.properties file is something like this

log4cplus.rootLogger=INFO, syslog

log4cplus.appender.syslog=log4cplus::SysLogAppender
log4cplus.appender.syslog.ident=syslog
log4cplus.appender.syslog.layout=log4cplus::PatternLayout 
log4cplus.appender.syslog.layout.ConversionPattern=[%T] %-5p %b %x - %m%n
log4cplus.appender.syslog.host=localhost
log4cplus.appender.syslog.udp=true
log4cplus.appender.syslog.port=514
log4cplus.appender.syslog.facility=user

I hope to be not too in late and I hope this can be helpful for you

Alessandro Ciurlo
  • 102
  • 1
  • 2
  • 11