Convenient Development Tool - Log4CPP Quick User Guide
content:
Advantages Manually manually use steps configuration file driver mode Use steps Related considerations About the author
In the Linux area:
Tutorial Tools & Product Codes & Component Articles
Li Qun@nsfocus.com www.ihere.org) Green Alliance Technology September 2003
Log4cpp is a LGPL-based open source project, which is based on a good log processing tracking project Java language log4j transplant. Log4j introduces a lot of documents, and it is also relatively wide in the Java area, and this powerful library is not used in the domestic C language developers in China. This library is introduced here from the perspective of developers to enable developers to master this technology as soon as possible. Let's briefly introduce the advantages of this project (also the advantage of log4j), then the principle, manual use steps, configuration file driver use steps, other considerations, etc. to discuss. The following discussion is based on LOG4CPP0.3.4B.
0. Advantages
Provide application run context to facilitate tracking debugging;
Scalable, multiple ways log logs, including command line, file, back file, memory, syslog server, Win event log, etc.
You can dynamically control the logging level, adjust the efficiency and function;
All configurations can be dynamically adjusted by configuration files;
Multi-language support, including Java (Log4J), C (Log4cpp, Log4cplus), C (Log4c), Python (Log4P), etc .;
...
1. Principle LOG4CPP has 3 main components: Categories, Appenders, and Layouts (layout). (In order to facilitate everyone to understand, try to use English principles in the text) Layout class control output log messages display style (what is like what is like). LOG4CPP currently offers the following layout format:
Log4cpp :: BasicLayout // Take "Timestamp Priority (Priority, Introduction below)
// Category (Category, introduction below)
// NDC tag (NESTED DIAGNOSTIC Contexts Introduction): Log Information.
/ / RESULE: 1056638652 Info Main: this is some info
Log4cpp :: patternlayout / / Let the user specify the output format based on the conversion mode similar to the C language Printf function. Format Definition See the code with a document.
Log4cpp :: SimpleLayout // Displayed in "priority - log information" format.
The Appender class is used to output a log (after being formatted by Layout) to some devices. Such as files, syslog services, some sockets, etc. You can define your own appender class output log information to other devices, such as applying itself day handling process, database, etc. The relationship between Appender and Layout is Layout attached to the appender, and the Appender class calls the Layout to process the log message, record it on a device. Log4CPP currently available below:
Log4cpp :: idsaAppender // Send to IDS or Logger, see http://jade.cs.uct.ac.za/idsa/log4cpp::LileAppender // Output to File
Log4cpp :: rollingfileAppender // Output to the back file, ie when the file reaches a certain size
Log4cpp :: OstreamAppender // Output to an Ostream class
Log4cpp :: transosyslogappender // Output to Remote Syslog Server
Log4cpp :: StringqueueAppender // Memory queue
Log4cpp :: Syslogappender / / Local Syslog
Log4cpp :: Win32Debugappender // Send to the default system debugger
Log4cpp :: NteventLogaPnder // Send to Win event log
The Category class really completes the logging log function, and the two main components are appenders and priority (priority). Priority control which type of log information can be recorded by this Category, current priority is: Notset, Debug, Info, Notice, Warn, Error, crit, Alert or Fatal / Emerg. Each log information has a priority, each Category has a priority, and this message will be recorded by the category when the priority of the message is greater than the priority of Category, otherwise it is ignored. The relationship between the priority is as follows. The Category class and appender are, multiple Appenders are attached to Category, such a log message can be output to multiple devices at the same time. NOTSET Instantiate a Layout object; initialize an Appender object; attach the Layout object on the appender object; call log4cpp :: category :: getInstance ("name"). Instantiate a category object; attach the Appender object to Category (according to Additive) The value replaces other appenders or attached to other appenders). Set the priority of Category; // filename: Test_log4cpp1.cpp // Test log4cpp by manual operation. // announce: USE as your owmb. // compile: g -otest1 -ll 4cpp test_log4cpp1.cpp1.cpp1 // Run: ./test1 // Tested: redhat 7.2 log4cpp0.3.4b // author: liqun (liqun@nsfocus.com) // Data: 2003-6-27 #include "log4cpp / category.hh" #include "log4cpp / fileapplander.hh" #include "log4cpp / BasicLayout.hh" Int main (int Argc, char * argv []) { // 1 instantiate a Layout object LOG4CPP :: Layout * Layout = New log4cpp :: BasicLayout (); // 2. Initialize an Appender object Log4cpp :: appender * appender = new Log4cpp :: FileAppender ("FileAppender", "./TEST_LOG4CPP1.LOG"); // 3. Attach the Layout object on the Appender object Appender-> setLayout (layout); // 4. Instantiate a category object Log4cpp :: Category & Warn_log = Log4cpp :: Category :: GetInstance ("mywarn"); // 5. Set Additive to False, replace existing Appender WARN_LOG.SETADDITIVITY (FALSE); // 5. Attach the appender object on Category WARN_LOG.SETAPPENDER (APPENDER); // 6. Set the priority of Category, lower than this priority log is not recorded WARN_LOG.SETPRIORITY (log4cpp :: priority :: warn); // Record some logs WARN_LOG.INFO ("Program Info Which Cannot Be Wire"); WARN_LOG.DEBUG ("This Debug Message Will Fail To Write"); WARN_LOG.Alert ("Alert Info"); // Other record log WARN_LOG.LOG (log4cpp :: priority :: warn, "this will be a logged warning"); Log4cpp :: priority :: prioritylevel priority; Bool this_is_critical = true; IF (this_is_critical) Priority = log4cpp :: priority :: crit; Else PRIORITY = log4cpp :: priority :: debug; WARN_LOG.LOG (Priority, "Importance Depends on Context"); WARN_LOG.critstream () << "this will show up << as" << 1 << "critical message" << log4cpp :: CategoryStream :: endline; // Clean Up and flush all appenders Log4cpp :: Category :: Shutdown (); Return 0; } 3. Profile driver mode Use the other very good feature is to determine objects such as Category, Appender, Layout by reading the configuration file. It is also our very recommended way to flexibly define all the objects and their properties, without re-coding, dynamically change the policies. Log4CPP mainly provides log4cpp :: PropertyConfigurator and log4cpp :: SimpleConfigurator two mechanisms (file format), but log4cpp :: SimpleConfigurator will no longer support, and the format is very simple, here is not much, you will see the source code. The format of the configuration file is the same as the Log4j configuration file, is a standard Java property file format. The following is an example of an example profile: # a Simple Test Config # Define 3 category sub1, sub2, sub1.sub2 Log4j.rootcategory = Debug, rootappender Log4j.category.sub1 =, A1 Log4j.category.sub2 = info Log4j.category.sub1.sub2 = Error, A2 # Set the Additive property attribute of Sub1.Sub2 Log4j.additivity.sub1.sub2 = false # Define the rootappender type and layout attribute Log4j.rapnder.rootappender = org.apache.log4j.consoleAppender Log4j.rapnder.rootappender.Layout = org.apache.log4j.basiclayout # Define the properties of the A1 Log4j.Appender.a1 = org.apache.log4j.fileappender Log4j.Appender.a1.filename = a1.log Log4j.Appender.a1.Layout = org.apache.log4j.simpleLayout # Defines the properties of A2 Log4j.Appender.a2 = org.apache.log4j.consoleappender Log4j.Appender.a2.Layout = Org.apache.log4j.patternlayout Log4j.Appender.a2.Layout.ConversionPattern = the message '% m' at time% D% N The configuration file syntax is as follows, not very standard, combined with the above example, you should be able to understand. Log4j / log4cpp. [category / appender]. [category or appender 's protety] = [Appender / layout / property's value / prior, appender name1 [appender name2 ...]] [appender] {ConsoleAppender} {FileAppender} // When the type of appender is FileAppender, it can be defined below the properties below. [filename] String Foobar // Format is: Type of property names default [Append] BOOL TRUE {Rollingfileappender} [filename] String Foobar [MAXFILESIZE] NUM 10 * 1024 * 1024 [MaxBackupIndex] Num 1 [Append] BOOL TRUE {Syslogappender} [syslogname] String syslog [sysloghost] string localhost [Facility] NUM -1 // * 8 to get log_kern, etc. Compatible Values. [portnumber] NUM -1 {IDSAAPPENDER} [IDSANAME] String Foobar {Win32Debugappender} {NTeventLogappender} [Source] String Foobar [Threshold] String "" // all // If this type of appender needs Layout, you must define the following properties of this apnder. [layout] {BasicLayout} {SimpleLayout} {PatternLayout} // When the value of Layout is BasicLayout, the following properties are required. [Conversionpattern] [rootcategory] [additive] [category name] BOOL TRUE Basic use steps are: Read the parsing configuration file; instantiate the Category object; use these Category objects normally to perform log processing; the following is a simple usage code, which is very convenient: // filename: Test_log4cpp2.cpp // Test log4cpp by config file. // announce: USE as your owmb. // compile: g -ll4cpp test_log4cpp2.cpp // Run: ./a.out // Tested: redhat 7.2 log4cpp0.3.4b // author: liqun (liqun@nsfocus.com) // Data: 2003-6-27 #include "log4cpp / category.hh" #include "log4cpp / protyconfigurator.hh" Int main (int Argc, char * argv []) { // 1 read the parsing profile // Read the error, it can be ignored, you can define a default policy or use the system default policy. // BasicLayout outputs all priority logs to ConsoleAppender Try { Log4cpp :: PropertyConfigurator :: Configure ("./ log4cpp.conf"); } catch (log4cpp :: configurefailure & f) { Std :: cout << "configure problem" << f.What () << std :: end1 Return -1; } // 2 instantiate the category object // These objects can be used even if the configuration file is not defined, but its attribute inherits its parent category. // Usually use references may not be too convenient, you can use a pointer, you can use the pointer to use // log4cpp :: category * root = & log4cpp :: category :: getroot (); Log4cpp :: category & root = log4cpp :: category :: getroot (); Log4cpp :: Category & Sub1 = Log4cpp :: Category :: getInstance (std :: string ("sub1"))); log4cpp :: category & sub3 = Log4cpp :: Category :: getInstance (std :: string ("sub1.sub2")); // 3 Normally use these Category objects to log processing. // Sub1 Has Appender A1 and Rootappender. Sub1.info ("this is some info"); Sub1.alert ("A Warning"); // Sub3 Only Have A2 Appender. Sub3.debug ("This Debug Message Will Fail To Write"); Sub3.alert ("All Hands Abandon Ship"); Sub3.critStream () << "" this will show up << as "<< 1 <<" critical message " << log4cpp :: CategoryStream :: endline; SUB3 << log4cpp :: priority :: Error << "And this will be an error" << log4cpp :: CategoryStream :: endline; Sub3.log (Log4cpp :: Priority :: Warn, "this will be a logged warning"); Return 0; } 4. Relevant considerations, performance issues, there may be a lot of problems that you want to use LOG4CPP. There is a description in Reference 2. The conclusion is that log4j and log4cpp is based on performance as primary goals; if the log record is turned off, the performance impact can ignore; open logging, main consumption is recorded, not the management process of the library; so you can use it with confidence . It is really necessary to deepen performance. It can be improved from the following aspects: Output log messages do not use complex conversion or processing, such as: sub1.debug (String ("Current Num IS") i getCurStat ()); this situation even does not perform log processing, parentheses The statement is still executed. Workaround is: IF (Sub1.IndebugeNabled ()) { Sub1.debug (String ("Current Num IS") i getCurStat ()); }