Configuration and use of log4cpp

Posted by penguinboy on Tue, 09 Jul 2019 21:46:48 +0200

1. Basic concepts

  • Hierarchical System of categories Logs
  • Where can the appenders log be printed, either as a file or as a terminal
  • The layouts log output format, which defines an output mode similar to that in printf. There are three kinds, followed by examples, the three are: basic, simple, pattern.
  • The level of priority log is EMERG, FATAL, ALERT, CRIT, ERROR, WARN, NOTICE, INFO, DEBUG, NOTSET, of which NOTSET < DEBUG < INFO < NOTICE < WARN < ERROR < CRIT < ALERT < FATAL = EMERG. The meaning of this priority is that if the level is debug in the configuration file, any log can be typed out; if the level is fatal, only the log with a higher priority can be printed out.
  • additivity limits whether Appenders will be inherited (with additional instructions later)

2. Examples of procedures

#include <stdio.h>
#include <log4cpp/Category.hh>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/SimpleLayout.hh>

#define LOGFILE "./test.log"

int main() {
    /*Setting up Appender, layout and Category*/
    log4cpp::Appender *appender = new log4cpp::FileAppender("FileAppender",LOGFILE);//The first parameter is the name of appender, and the second is the name of the log file.
    log4cpp::Layout *layout = new log4cpp::SimpleLayout();
    //log4cpp::Layout *layout = new log4cpp::BasicLayout();
    log4cpp::Category& category = log4cpp::Category::getInstance("abc");

    appender->setLayout(layout);
    category.setAppender(appender);
    category.setPriority(log4cpp::Priority::INFO);

    /*The actual logging*/
    category.info("This is for tracing the flow");
    category.notice("This is to notify certain events");
    category.warn("This is to generate certain warnings");

The above program will get the following log output:

INFO    : This is for tracing the flow
NOTICE  : This is to notify certain events 

WARN    : This is to generate certain warnings 

In this program, log4cpp::Layout * layout = new log4cpp:: Basic Layout (); can be cancelled and the statement above can be commented out. The following log output will be obtained:

1308806376 INFO abc : This is for tracing the flow

1308806376 NOTICE abc : This is to notify certain events

1308806376 WARN abc : This is to generate certain warnings 

The difference between them is that they use different layout s, one is simple and the other is basic.

To achieve the output of complex format, we need to use the third method: PatternLayout, which is illustrated by the configuration file below.

3. Configuration file description

Configuration file log4cpp.conf:

# Three categories sub1, sub2 and sub3 are defined.
# sub2 and sub3 set the additivity attribute to false; the additivity attribute of sub1 defaults to true.
rootCategory=DEBUG, rootAppender

category.sub1=,A1

category.sub2=INFO, A2
additivity.sub2=false

category.sub3=ERROR, A3
additivity.sub3=false


# Define the rootAppender type and layout attribute, using BasicLayout
appender.rootAppender=org.apache.log4cpp.ConsoleAppender
appender.rootAppender.layout=org.apache.log4cpp.BasicLayout

#Define the attributes of A1, using SimpleLayout
appender.A1=org.apache.log4cpp.FileAppender
appender.A1.fileName=./log/A1.log
appender.A1.layout=org.apache.log4cpp.SimpleLayout

#Define the attributes of A2, where PatternLayout is used
appender.A2=org.apache.log4cpp.ConsoleAppender
appender.A2.layout=org.apache.log4cpp.PatternLayout
appender.A2.layout.ConversionPattern=The message '%m' at time %d%n

#Define the attributes of A3
appender.A3=org.apache.log4cpp.RollingFileAppender
appender.A3.fileName=./log/A3.log
appender.A3.maxFileSize=50
appender.A3.maxBackupIndex=3
appender.A3.backupPattern=%Y-%m-%d
appender.A3.layout=org.apache.log4cpp.PatternLayout
appender.A3.layout.ConversionPattern=%d{%Y-%m-%d %H:%M:%S} [%p]: [%c] %m%n

4. Examples of programs with configuration files

Source code:

#include "log4cpp/Category.hh"
#include "log4cpp/PropertyConfigurator.hh"
int main(int argc, char* argv[]) {
    // 1 Read parse configuration file
    // Reading errors are completely negligible, and you can define a default policy or use a system default policy
    // Basic Layout outputs all priority logs to Console Appender
    try
    {
        log4cpp::PropertyConfigurator::configure("./log4cpp.conf");
    }
    catch (log4cpp::ConfigureFailure& f)
    {
        std::cout << "Configure Problem " << f.what() << std::endl;
        return -1;
    }

    //2 Instantiate category objects
    //    These objects can be used even if the configuration file is not defined, but their properties inherit their parent category
    //    Usually it may be inconvenient to use references. You can use pointers and use them later.
    log4cpp::Category& root = log4cpp::Category::getRoot();
    log4cpp::Category& sub1 = log4cpp::Category::getInstance(std::string("sub1"));
    log4cpp::Category& sub2 = log4cpp::Category::getInstance(std::string("sub2"));
    log4cpp::Category& sub3 = log4cpp::Category::getInstance(std::string("sub3"));
    log4cpp::Category& sub4 = log4cpp::Category::getInstance(std::string("sub4"));

    //    These category objects are normally used for log processing.
    root.fatal("root's log");

    //    sub1 has appender A1 and rootappender. since the additivity property is set true by default
    sub1.info("sub1's log");

    //    sub2 has appender A2 appender. since the additivity property is set to false
    sub2.alert("sub2's log");

    //    sub3 only has A3 appender. since the additivity property is set to false
    sub3.debug("sub3's log");
    sub3.alert("sub3's log");

    //    sub4 can not be found in the config file, so the root category's appender and layout are used
    sub4.warn("sub4's log");

    return 0;
}

log printed by terminal:

1308828470 FATAL  : root's log

1308828470 INFO sub1 : sub1's log

The message 'sub2's log' at time 2011-06-23 19:27:50,624 

1308829427 WARN sub4 : sub4's log  

Contents of log/A1.log:

INFO    : sub1's log

Contents of log/A3.log:

2011-06-23 19:27:50 [ALERT]: [sub3] sub3's log 

5. Configuration Reference

Appender Additivity

The output of a log statement of logger C will go to all the appenders in C and its ancestors. This is the meaning of the term "appender additivity".

However, if an ancestor of logger C, say P, has the additivity flag set to false, then C's output will be directed to all the appenders in C and its ancestors upto and including P but not the appenders in any of the ancestors of P.

 

Loggers have their additivity flag set to true by default. 

References are from: http://logging.apache.org/log4j/1.2/manual.html 

 

 

Sets the format of log lines handled by this PatternLayout.

By default, set to "%m%n".
Format characters are as follows:

  • %%%% - a single percent sign
  • %c - the category
  • %d - the date
    Date format: The date format character may be followed by a date format specifier enclosed between braces. For example, %d{%H:%M:%S,%l} or %d{%d %m %Y %H:%M:%S,%l}. If no date format specifier is given then the following format is used: "Wed Jan 02 02:03:55 1980". The date format specifier admits the same syntax as the ANSI C function strftime, with 1 addition. The addition is the specifier %l for milliseconds, padded with zeros to make 3 digits.
  • %m - the message
  • %n - the platform specific line separator
  • %p - the priority
  • %r - milliseconds since this layout was created.
  • %R - seconds since Jan 1, 1970
  • %u - clock ticks since process start
  • %x - the NDC

 

 

References are from: http://log4cpp.sourceforge.net/api/classlog4cpp_1_1PatternLayout.html

 

This is also a good reference article:

http://joysofprogramming.com/log4cpp-tutorial/ 

Topics: Apache Attribute log4j