log4cpp是一个开源的C++日志库。它提供了灵活的日志记录功能,可以帮助开发者在C++应用程序中记录、管理和格式化日志信息。
主要特点
提供应用程序运行上下文,方便跟踪调试
可扩展的、多种方式记录日志,包括命令行、文件、回卷文件、内存、syslog服务器、Win事件日志等
可以动态控制日志记录级别,在效率和功能中进行调整
所有配置可以通过配置文件进行动态调整
多语言支持,包括Java(log4j),C++(log4cpp、log4cplus),C(log4c),python(log4p)等
log4cpp有三个主要的组件:
日志类别用于控制日志的优先级。如果配置文件中设置的级别是DEBUG,则任意的log都能打印出来;但如果配置的级别是ERROR,则只有高于ERROR优先级的日志才可以打印出来。
日志的常用优先级(从低到高):
xxxxxxxxxx
11DEBUG < INFO < NOTICE < WARN < ERROR < CRIT < ALERT < FATAL = EMERG
输出源用来输出日志(被layout格式化后)到一些设备上,比如文件、命令行、内存等。也可以定义自己的appender输出日志信息到别的设备上。
log4cpp提供的常用appender:
FileAppender:输出到文件
RollingFileAppender:输出到回卷文件,即当文件到达某个大小后回卷
ConsoleAppender:输出到控制台
布局决定了日志信息的格式。PatternLayout表示让用户根据类似于C语言printf函数的转换模式来指定输出格式。
xxxxxxxxxx
91# 下载log4cpp源码
2wget http://sourceforge.net/projects/log4cpp/files/log4cpp-1.1.3.tar.gz
3tar -xvzf log4cpp-1.1.3.tar.gz
4
5# 编译和安装
6cd log4cpp
7./configure # 或指定安装路径:./configure --prefix=/path/to/file
8make
9make install
默认配置安装的log4cpp,其头文件位于/usr/local/include/log4cpp/
,库文件位于/usr/local/lib/
。
在Windows系统中,可以下载预编译的二进制文件或者使用Visual Studio从源码编译。
xxxxxxxxxx
421
2
3
4
5
6
7int main() {
8 // 创建一个输出到控制台的Appender
9 log4cpp::Appender *consoleAppender = new log4cpp::OstreamAppender("console", &std::cout);
10
11 // 设置输出格式
12 log4cpp::PatternLayout *consoleLayout = new log4cpp::PatternLayout();
13 consoleLayout->setConversionPattern("%d [%p] - %m%n");
14 consoleAppender->setLayout(consoleLayout);
15
16 // 创建一个输出到文件的Appender
17 log4cpp::Appender *fileAppender = new log4cpp::FileAppender("file", "application.log");
18
19 // 设置文件输出格式
20 log4cpp::PatternLayout *fileLayout = new log4cpp::PatternLayout();
21 fileLayout->setConversionPattern("%d [%p] %c: %m%n");
22 fileAppender->setLayout(fileLayout);
23
24 // 获取根类别并设置优先级
25 log4cpp::Category &root = log4cpp::Category::getRoot();
26 root.setPriority(log4cpp::Priority::INFO);
27
28 // 添加Appender到根类别
29 root.addAppender(consoleAppender);
30 root.addAppender(fileAppender);
31
32 // 记录不同级别的日志
33 root.debug("这是一条调试信息"); // 不会显示,因为优先级设置为INFO
34 root.info("这是一条信息");
35 root.warn("这是一条警告");
36 root.error("这是一条错误");
37
38 // 清理资源
39 log4cpp::Category::shutdown();
40
41 return 0;
42}
配置文件示例(log4cfg):
xxxxxxxxxx
161
2log4cpp.rootCategory=INFO,console,file
3
4
5log4cpp.appender.file=RollingFileAppender #滚动文件
6log4cpp.appender.file.fileName=./log/data.log #文件名称
7log4cpp.appender.file.maxFileSize=524288000 #单个文件大小
8log4cpp.appender.file.maxBackupIndex=10 #文件保存数量
9log4cpp.appender.file.backupPattern=%Y-%m-%d
10log4cpp.appender.file.layout=PatternLayout #layout格式
11log4cpp.appender.file.layout.ConversionPattern=[%d{%Y-%m-%d %H:%M:%S,%l}](%p)<%t>%c %x: %m%n #输出格式
12
13
14log4cpp.appender.console=ConsoleAppender
15log4cpp.appender.console.layout=PatternLayout
16log4cpp.appender.console.layout.ConversionPattern=[%d{%Y-%m-%d %H:%M:%S,%l}](%p)<%t>%c %x: %m%n
使用配置文件的代码示例:
xxxxxxxxxx
331
2
3
4
5
6int main() {
7 try {
8 // 加载配置文件
9 log4cpp::PropertyConfigurator::configure("./cfg/log4cfg");
10 } catch (log4cpp::ConfigureFailure& f) {
11 std::cerr << "配置问题: " << f.what() << std::endl;
12 return 1;
13 }
14
15 // 获取根类别
16 log4cpp::Category& log = log4cpp::Category::getRoot();
17
18 // 构建日志消息
19 std::string s = __FILE__;
20 s += " : ";
21 std::ostringstream line;
22 line << std::setw(4) << std::setfill('0') << __LINE__;
23 s += line.str();
24 s += " : ";
25 std::ostringstream buf;
26 buf << "测试消息";
27 s += buf.str();
28
29 // 记录日志
30 log.info(s);
31
32 return 0;
33}
PatternLayout的格式化字符串支持以下占位符:
%% - 单个百分号
%c - 类别名称
%d - 日期时间,可以指定格式,如 %d{%Y-%m-%d %H:%M:%S,%l}
%m - 日志消息
%n - 平台特定的行分隔符
%p - 优先级
%r - 自创建此布局以来的毫秒数
%R - 自1970年1月1日以来的秒数
%u - 进程启动以来的时钟滴答数
%x - NDC(嵌套诊断上下文)
%t - 线程名称
编译使用log4cpp的程序时,需要链接log4cpp库:
xxxxxxxxxx
11g++ your_program.cpp -llog4cpp -lpthread
如果运行时提示找不到log4cpp库,需要确保系统能找到动态库:
编辑 /etc/ld.so.conf
添加log4cpp库的路径(通常是 /usr/local/lib
)
运行 ldconfig
使设置生效
Tip
使用配置文件:将日志配置放在配置文件中,便于动态调整日志级别和输出方式
合理设置日志级别:开发环境可以使用DEBUG级别,生产环境使用INFO或更高级别
使用滚动文件:避免日志文件过大,使用RollingFileAppender自动管理日志文件
包含上下文信息:在日志中包含文件名、行号、函数名等信息,便于定位问题
使用NDC:在多线程环境中使用嵌套诊断上下文,便于跟踪特定线程的日志