log4cplus — Short User Manual
log4cplus is a C++ logging library modeled on log4j, providing thread-safe,
configurable logging with levels, appenders (output destinations), and
layouts (formatting).
1. How to Use It
1.1 Install / Link
Ubuntu / Debian
sudo apt-get install liblog4cplus-dev
Link against the library in your build:
g++ myapp.cpp -llog4cplus -o myapp
From Source
git clone https://github.com/log4cplus/log4cplus.git
cd log4cplus
mkdir build && cd build
cmake ..
make -j$(nproc)
sudo make install
Link against the library in your build:
g++ myapp.cpp -llog4cplus -o myapp
For cross-compilation (e.g. embedded ARM/MIPS targets), build with your
toolchain's cmake toolchain file and point CMAKE_INSTALL_PREFIX to
your sysroot, the same way you would for any other cross-compiled
C/C++ library.
Compiler requirements: the 2.x series (including the 2.1.2 Conan
release above) requires C++11. The 3.x series (current master)
requires C++23 — check your toolchain before building from the latest
source.
Conan
ConanCenter has an up-to-date recipe:
# conanfile.txt
[requires]
log4cplus/2.1.2
[generators]
CMakeDeps
CMakeToolchain
conan install . --output-folder=build --build=missing
Then find_package(log4cplus REQUIRED) and link log4cplus::log4cplus
in your CMakeLists.txt as usual.
1.2 Quick Reference (minimal working example)
#include <log4cplus/logger.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/configurator.h>
int main() {
log4cplus::initialize();
log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("log4cplus.properties"));
log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("main"));
LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("Hello from log4cplus"));
log4cplus::Logger::shutdown();
}
1.3 Basic Initialization
#include <log4cplus/logger.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/configurator.h>
int main()
{
// Simple default setup: logs to console at DEBUG level
log4cplus::BasicConfigurator config;
config.configure();
log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("main"));
LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("Application started"));
LOG4CPLUS_DEBUG(logger, LOG4CPLUS_TEXT("Debug value: ") << 42);
LOG4CPLUS_ERROR(logger, LOG4CPLUS_TEXT("Something failed"));
return 0;
}
Key pieces:
-
Logger — named handle you log through (hierarchical, e.g.
"main.video.decoder"). -
Configurator — sets up appenders/levels either in code
(
BasicConfigurator) or from a properties file (PropertyConfigurator). -
Macros (
LOG4CPLUS_INFO,LOG4CPLUS_DEBUG, etc.) — stream-style logging, only evaluate arguments if the level is enabled.
1.4 Configure via Properties File (recommended for real projects)
log4cplus.properties:
log4cplus.rootLogger=DEBUG, STDOUT, FILE
log4cplus.appender.STDOUT=log4cplus::ConsoleAppender
log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout
log4cplus.appender.STDOUT.layout.ConversionPattern=%d{%H:%M:%S} [%t] %-5p %c - %m%n
log4cplus.appender.FILE=log4cplus::RollingFileAppender
log4cplus.appender.FILE.File=app.log
log4cplus.appender.FILE.MaxFileSize=5MB
log4cplus.appender.FILE.MaxBackupIndex=3
log4cplus.appender.FILE.layout=log4cplus::PatternLayout
log4cplus.appender.FILE.layout.ConversionPattern=%d %-5p %c [%t] - %m%n
Load it in code:
#include <log4cplus/configurator.h>
log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("log4cplus.properties"));
This lets you change log levels/destinations without recompiling — useful
for field debugging on embedded targets.
1.5 Log Levels (lowest → highest severity)
TRACE < DEBUG < INFO < WARN < ERROR < FATAL
Plus two special pseudo-levels used only for filtering (not real events):
ALL (enables everything) and OFF (disables everything).
Set per-logger level to control verbosity:
logger.setLogLevel(log4cplus::WARN_LOG_LEVEL);
Is there a built-in MILESTONE level? No — there's no such level shipped
with log4cplus. It does support registering custom log levels (via
LogLevelManager::pushToStringMethod/pushFromStringMethod), so you could
in theory define a MILESTONE level between INFO and WARN. In practice
this is a fragile corner of the library — there are known issues where
custom levels set via a property file crash configuration, and levels set
at runtime can show up as UNKNOWN in log output. Most projects avoid this
by just using INFO with a distinct logger name or message prefix (e.g. a
dedicated "milestone" logger) instead of a real custom level.
1.6 Common Appenders
| Appender | Purpose |
|---|---|
ConsoleAppender |
stdout/stderr |
FileAppender |
plain file |
RollingFileAppender |
size-based log rotation |
DailyRollingFileAppender |
date-based rotation |
SocketAppender |
send logs over TCP |
SysLogAppender |
forward to syslog (handy on embedded Linux) |
CallbackAppender |
invoke your own C-style function per log event |
Routing logs into your own function: CallbackAppender
If you want log events delivered straight into your own code (e.g. push to
a UI, telemetry pipe, ring buffer) rather than to a file/console/socket,
use CallbackAppender (log4cplus/callbackappender.h). It takes a plain
function pointer plus a void* "cookie" for your own context — no
subclassing required.
#include <log4cplus/callbackappender.h>
#include <log4cplus/loggingmacros.h>
void myLogCallback(void* cookie,
const log4cplus::tchar* message,
const log4cplus::tchar* loggerName,
int loglevel,
const log4cplus::tchar* thread,
const log4cplus::tchar* thread2,
unsigned long long timestampSec,
unsigned long timestampUsec,
const log4cplus::tchar* file,
const log4cplus::tchar* function,
int line)
{
// Route into your own function — e.g. push to a UI, telemetry, etc.
MyOwnSink(message, loglevel);
}
int main()
{
log4cplus::SharedAppenderPtr appender(
new log4cplus::CallbackAppender(myLogCallback, /*cookie=*/nullptr));
appender->setName(LOG4CPLUS_TEXT("myCallback"));
log4cplus::Logger::getRoot().addAppender(appender);
log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("main"));
LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("This goes through my function"));
}
Threading note: appenders run synchronously by default
By default, an appender's I/O runs on whichever thread called the log
macro — there's no dedicated logging thread. ConsoleAppender in
particular locks a single, process-wide mutex before writing (shared by
all ConsoleAppender instances), so heavy or frequent console logging
from a latency-sensitive thread can become a real serialization point.
If an appender's I/O cost is showing up as jitter on a thread you're
analyzing, set async=true on that appender (in code, or via
log4cplus.appender.X.async=true in the properties file). This offloads
the actual write to log4cplus's internal thread pool (size configurable
via log4cplus.threadPoolSize) instead of blocking the calling thread.
If you need more control (internal state, filtering logic, batching),
subclass log4cplus::Appender directly and implement append() and
close() instead.
1.7 Shutdown
Call at program exit to flush/close appenders cleanly:
log4cplus::Logger::shutdown();
References
Ordered roughly by relevance/usefulness for day-to-day use:
docs/examples.md — canonical minimal usage walkthrough
https://github.com/log4cplus/log4cplus/blob/master/docs/examples.mdlog4cplus GitHub repository — README, build options, source
https://github.com/log4cplus/log4cplusDoxygen API reference (v2.0.8) — full class docs
https://log4cplus.github.io/log4cplus/docs/log4cplus-2.0.8/doxygen/classlog4cplus_1_1Appender.htmlcallbackappender.cxx — CallbackAppender source
https://github.com/log4cplus/log4cplus/blob/master/src/callbackappender.cxxappender.h — base Appender class header
https://github.com/log4cplus/log4cplus/blob/master/include/log4cplus/appender.hconfigurator.h — PropertyConfigurator, root logger syntax, additivity rule
https://github.com/log4cplus/log4cplus/blob/master/include/log4cplus/configurator.hSourceForge wiki — Code Examples (older, supplementary snippets)
https://sourceforge.net/p/log4cplus/wiki/CodeExamples/GitHub Issue #308 — discussion on custom loggers/log level control
https://github.com/log4cplus/log4cplus/issues/308SourceForge Bug #268 — custom log level property-file crash issue
https://sourceforge.net/p/log4cplus/bugs/268/
Top comments (0)