9.9 KiB
Code Examples
Hello World
Here is a minimal log4cplus example for log4cplus version 2.0 and later:
#include <log4cplus/logger.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/configurator.h>
#include <log4cplus/initializer.h>
int
main()
{
// Initialization and deinitialization.
log4cplus::Initializer initializer;
log4cplus::BasicConfigurator config;
config.configure();
log4cplus::Logger logger = log4cplus::Logger::getInstance(
LOG4CPLUS_TEXT("main"));
LOG4CPLUS_WARN(logger, LOG4CPLUS_TEXT("Hello, World!"));
return 0;
}
The above code prints WARN - Hello, World!
on console. Let's dissect it:
#include <log4cplus/logger.h>
We need this header to get Logger
class which represents a handle to named
logger.
#include <log4cplus/loggingmacros.h>
This header declares LOG4CPLUS_WARN()
logging macro. Beside this one, it also
declares one for each standard logging level: FATAL, ERROR, WARN, INFO, DEBUG,
TRACE.
#include <log4cplus/configurator.h>
This header declares BasicConfigurator
class.
#include <log4cplus/initializer.h>
This header declares Initializer
class.
log4cplus::Initializer initializer;
Instantiating the Initializer
class internally initializes log4cplus.
The Initializer
class also maintains a reference count. The class can be
instantiated multiple times. When this reference count reaches zero, after the
last instance of Initializer
is destroyed, it shuts down log4cplus
internals. Currently, after log4cplus is deinitialized, it cannot be
re-initialized.
log4cplus tries to use some other methods of shutting down its
internals. However, that means that it cannot be used after main()
exits.
log4cplus::BasicConfigurator config;
config.configure();
These two lines configure root logger with ConsoleAppender
and simple
layout.
log4cplus::Logger logger = log4cplus::Logger::getInstance(
LOG4CPLUS_TEXT("main"));
Here we obtain logger handle to logger named main.
The LOG4CPLUS_TEXT()
macro used above has the same function as the TEXT()
or _T()
macros do on Windows: In case UNICODE
preprocessor symbol is
defined, it prefixes the string literal that is passed as its parameter with
the L
to make it wide character string literal.
LOG4CPLUS_WARN(logger, LOG4CPLUS_TEXT("Hello, World!"));
Here we invoke the LOG4CPLUS_WARN()
macro to log the Hello, World! message
into the main logger. The logged message will be propagated from the main
logger towards the root logger which has a ConsoleAppender
attached to it
to print it on console.
Internally, this macro uses C++ string stream to format the Hello, World! message. The consequence of this is that you can use all of the standard C++ streams manipulators.
(De-)Initialization
Initialization
In most cases, log4cplus is initialized before main()
is executed. However,
depending on compiler, platform, run time libraries and how log4cplus is linked
to, it is possible it will not be initialized automatically. This is why
initializing log4cplus on top of main()
is a good rule of thumb.
As the previous code example shows, initialization of log4cplus is done by
instantiation of log4cplus::Initializer
class. This is true for log4cplus
versions 2.0 and later. In previous versions, instead of instantiating this
class (the header log4cplus/initializer.h
and the class do not exist there),
call to function log4cplus::initialize()
is used.
Deinitialization
log4cplus tries to deinitialize itself and free all of its allocated
resources after main()
exits. However, again, depending on compiler, platform
and run time libraries, it might not be possible. This is why proper
deinitialization is necessary.
In version 2.0 and later, it is done by the last instance of
log4cplus::Initializer
class and its destructor. In previous versions,
calling Logger::shutdown()
was the proper shutdown method.
Logging macros
As we have mentioned earlier, LOG4CPLUS_WARN()
, LOG4CPLUS_ERROR()
, etc.,
macros use C++ string stream under the hood. The following example demonstrates
how is it possible to use it with the macros.
Beside these macros, there are two more groups of logging macros.
LOG4CPLUS_*_STR()
can be used for logging messages that are just plain
strings that do not need any kind of formatting. There is also group of
LOG4CPLUS_*_FMT()
macros which format logged message using printf()
formatting string.
#include <log4cplus/logger.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/configurator.h>
#include <log4cplus/initializer.h>
#include <iomanip>
int
main()
{
log4cplus::Initializer initializer;
log4cplus::BasicConfigurator config;
config.configure();
log4cplus::Logger logger = log4cplus::Logger::getInstance(
LOG4CPLUS_TEXT("main"));
LOG4CPLUS_INFO(logger,
LOG4CPLUS_TEXT("This is")
<< LOG4CPLUS_TEXT(" a reall")
<< LOG4CPLUS_TEXT("y long message.") << std::endl
<< LOG4CPLUS_TEXT("Just testing it out") << std::endl
<< LOG4CPLUS_TEXT("What do you think?"));
LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("This is a bool: ") << true);
LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("This is a char: ")
<< LOG4CPLUS_TEXT('x'));
LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("This is a short: ")
<< static_cast<short>(-100));
LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("This is a unsigned short: ")
<< static_cast<unsigned short>(100));
LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("This is a int: ") << 1000);
LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("This is a unsigned int: ") << 1000U);
LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("This is a long(hex): ")
<< std::hex << 100000000L);
LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("This is a unsigned long: ")
<< static_cast<unsigned long>(100000000U));
LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("This is a float: ") << 1.2345f);
LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("This is a double: ")
<< std::setprecision(15)
<< 1.2345234234);
LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("This is a long double: ")
<< std::setprecision(15)
<< 123452342342.342L);
return 0;
}
The code above should just print the expected:
INFO - This is a really long message.
Just testing it out
What do you think?
INFO - This is a bool: 1
INFO - This is a char: x
INFO - This is a short: -100
INFO - This is a unsigned short: 100
INFO - This is a int: 1000
INFO - This is a unsigned int: 1000
INFO - This is a long(hex): 5f5e100
INFO - This is a unsigned long: 100000000
INFO - This is a float: 1.2345
INFO - This is a double: 1.2345234234
INFO - This is a long double: 123452342342.342
Beside these macros, there are two more groups of logging macros.
LOG4CPLUS_*_STR()
can be used for logging messages that are just plain
strings that do not need any kind of formatting. There is also group of
LOG4CPLUS_*_FMT()
macros which format logged message using printf()
formatting string.
Log level
This example shows how log messages can be filtered at run time by adjusting
the log level threshold on Logger
instance.
#include <log4cplus/logger.h>
#include <log4cplus/loglevel.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/configurator.h>
#include <log4cplus/initializer.h>
#include <iomanip>
void
printMessages(log4cplus::Logger const & logger)
{
// Print messages using all common log levels.
LOG4CPLUS_TRACE (logger, "printMessages()");
LOG4CPLUS_DEBUG (logger, "This is a DEBUG message");
LOG4CPLUS_INFO (logger, "This is a INFO message");
LOG4CPLUS_WARN (logger, "This is a WARN message");
LOG4CPLUS_ERROR (logger, "This is a ERROR message");
LOG4CPLUS_FATAL (logger, "This is a FATAL message");
}
void
thresholdTest(log4cplus::LogLevel ll)
{
log4cplus::Logger logger
= log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("main"));
// Set log level threshold on logger.
logger.setLogLevel(ll);
// Print messages.
log4cplus::tcout
<< LOG4CPLUS_TEXT("*** calling printMessages() with ")
<< log4cplus::getLogLevelManager().toString(ll)
<< LOG4CPLUS_TEXT(" set: ***")
<< std::endl;
printMessages(logger);
log4cplus::tcout << std::endl;
}
int
main()
{
log4cplus::Initializer initializer;
log4cplus::BasicConfigurator config;
config.configure();
thresholdTest(log4cplus::TRACE_LOG_LEVEL);
thresholdTest(log4cplus::DEBUG_LOG_LEVEL);
thresholdTest(log4cplus::INFO_LOG_LEVEL);
thresholdTest(log4cplus::WARN_LOG_LEVEL);
thresholdTest(log4cplus::ERROR_LOG_LEVEL);
thresholdTest(log4cplus::FATAL_LOG_LEVEL);
return 0;
}
The code prints fewer and fewer messages as the log level threshold is being risen.
*** calling printMessages() with TRACE set: ***
TRACE - printMessages()
DEBUG - This is a DEBUG message
INFO - This is a INFO message
WARN - This is a WARN message
ERROR - This is a ERROR message
FATAL - This is a FATAL message
*** calling printMessages() with DEBUG set: ***
DEBUG - This is a DEBUG message
INFO - This is a INFO message
WARN - This is a WARN message
ERROR - This is a ERROR message
FATAL - This is a FATAL message
*** calling printMessages() with INFO set: ***
INFO - This is a INFO message
WARN - This is a WARN message
ERROR - This is a ERROR message
FATAL - This is a FATAL message
*** calling printMessages() with WARN set: ***
WARN - This is a WARN message
ERROR - This is a ERROR message
FATAL - This is a FATAL message
*** calling printMessages() with ERROR set: ***
ERROR - This is a ERROR message
FATAL - This is a FATAL message
*** calling printMessages() with FATAL set: ***
FATAL - This is a FATAL message
More examples
See sources in tests/
directory in log4cplus source distribution for more
examples of log4cplus usage.