《C++、Java、JavaScript中的日志(log)》中讲了日志的概念和应用场景,本文将进一步讲讲C++中日志记录的具体用法。C++中有很多记录log的库,比较常用的有log4cpp(log4cxx)、Google Glog 。下面主要讲一个log4cpp(log4cxx)的用法。
log4cxx是apache软件基金会的一个开源库,是由log4j移植过来的跨平台的日志处理跟踪项目。从官网下载的log4cxx只有源码,需要自己编译。
log4cxx的编译
1.下载apache-log4cxx-0.10.0.zip、apr-1.2.11-win32-src.zip、apr-util-1.2.10-win32-src.zip。
2.解压apache-log4cxx-0.10.0.zip、apr-1.2.11-win32-src.zip、apr-util-1.2.10-win32-src.zip。
3.重命名apr-1.2.11为apr,重命名apr-util-1.2.10为apr-util;并将apr和apr-util拷贝apache-log4cxx-0.10.0根目录下。
4.以管理员的身份运行cmd.exe,并定位到log4cxx的当前apache-log4cxx-0.10.0目录下,执行以下命令:
configure configure-aprutil |
当执行configure-aprutil时,提示:“ ‘sed‘ 不是内部或外部命令,也不是可运行的程序或批处理文件”。这是因为 configure-aprutil.bat 文件中使用了 Linux 下的 sed 命令,windows下找不到sed命令。解决的方法有以下几种:1.下载一个sed for windows的工具;2.使用Cygwin(windows平台上运行的类UNIX模拟环境 ),再运行 configure-aprutil.bat;3.手动修改。
还是手动改来的方便,将.\apr-util\include\apu.hw下的#define APU_HAVE_APR_ICONV 1改为#define APU_HAVE_APR_ICONV 0 将.\apr-util\include\apr_ldap.hw下的#define APR_HAS_LDAP 1改为#define APR_HAS_LDAP 0。
5.用VC6或更高版本的Visual Studio工具打开 projects/log4cxx.dsw,在打开的时候会依次要求你选择apr、aprutil、xml工程的工作目录,在apache-log4cxx-0.10.0的子目录中找到对应的apr.dsp、aprutil.dsp、xml.dsp文件打开即可。
6.选择log4cxx为Active工程并编译。
7.在编译过程中可能报错:无法打开包括文件:“apr.h”和“apu.h”,找到对应的apr.hw重命名为apr.h,apu.h重命名为apu.h即可。
log4cxx的使用
<1>简单样例:
创建一个工程,设置log4cxx的头文件路径和lib库的路径,并加载log4cxx.lib文件。测试代码如下,日志信息会在命令行中输出。
[cpp] view plaincopyprint?
- #include "stdafx.h"
- #include "log4cxx/logger.h"
- #include "log4cxx/basicconfigurator.h"
- #include "log4cxx/helpers/exception.h"
- using namespace std;
- using namespace log4cxx;
- using namespace log4cxx::helpers;
- int main()
- {
- //@todo 重定向到文件
- LoggerPtr logger(Logger::getLogger("LogTest"));
- //初始化配制
- BasicConfigurator::configure();
- //输出DEBUG级别的日志
- LOG4CXX_DEBUG(logger, "debug log");
- //输出TRACE级别的日志
- LOG4CXX_TRACE(logger, "debug log");
- //输出INFO级别的日志
- LOG4CXX_INFO(logger, "info log");
- //输出WARN级别的日志
- LOG4CXX_WARN(logger, "debug log");
- //输出ERROR级别的日志
- LOG4CXX_ERROR(logger, "debug log");
- //输出FATAL级别的日志
- LOG4CXX_FATAL(logger, "debug log");
- //ASSERT判断条件是否正确, 条件为false时,输出信息
- LOG4CXX_ASSERT(logger, 1 == 2, "1 == 2");
- return 0;
- }
注:我用VC6.0编译log4cxx的源码,然后在VS2010中使用log4cxx库时,编译会报错:unresolved external symbol "__declspec(dllimport) public: void __thiscall log4cxx::Logger::forcedLog
这是因为不同版本的编译器编译的库可能会有不同,要在VS2010上使用,需要在VS2010上重新编译源码。
<2>.设置配制文件:
如果要将日志信息输出到文件,或同时输出到命令行和文件,则要修改配制文件。
log4cxx.properties:
[plain] view plaincopyprint?
- # 设置root logger为DEBUG级别,使用了ca和fa两个Appender
- log4j.rootLogger=DEBUG, consoleAppender, fileAppender
- #对Appender fileAppender(输出到文件)进行设置:
- # 这是一个文件类型的Appender,
- log4j.appender.fileAppender=org.apache.log4j.FileAppender
- # 将日志信息输出到./log4cxxTest.log,
- log4j.appender.fileAppender.File=./log4cxxTest.log
- # 输出方式为文件末尾追加
- log4j.appender.fileAppender.Append=true
- # 设置输出格式(layout)为PatternLayout
- log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout
- #log4j.appender.fileAppender.layout.ConversionPattern=%d [%t] %-5p %.16c - %m%n
- #对Appender consoleAppender(输出到控制台)进行设置
- log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender
- # 这是一个控制台类型的Appender
- log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout
- # 输出格式(layout)为PatternLayout
- log4j.appender.consoleAppender.layout.ConversionPattern=%d [%t] %-5p %.16c - %m%n
代码:
[cpp] view plaincopyprint?
- #include "stdafx.h"
- #include "log4cxx/logger.h"
- #include "log4cxx/PropertyConfigurator.h"
- using namespace std;
- using namespace log4cxx;
- using namespace log4cxx::helpers;
- int main()
- {
- //用指定的文件加载配制
- log4cxx::PropertyConfigurator::configure("E:/Test/log4cxx.properties");
- //创建logger
- LoggerPtr logger = Logger::getLogger("test");
- //输出DEBUG级别的日志
- LOG4CXX_DEBUG(logger, "debug log");
- //输出TRACE级别的日志
- LOG4CXX_TRACE(logger, "debug log");
- //输出INFO级别的日志
- LOG4CXX_INFO(logger, "info log");
- //输出WARN级别的日志
- LOG4CXX_WARN(logger, "debug log");
- //输出ERROR级别的日志
- LOG4CXX_ERROR(logger, "debug log");
- //输出FATAL级别的日志
- LOG4CXX_FATAL(logger, "debug log");
- //ASSERT判断条件是否正确, 条件为false时,输出信息
- LOG4CXX_ASSERT(logger, 1 == 2, "1 == 2");
- return 0;
- }
如果您有什么疑惑和想法,请在评论处给予反馈,您的反馈就是最好的测评师!由于本人技术和能力有限,如果本博文有错误或不足之处,敬请谅解并给出您宝贵的建议!
========================编程思想系列文章回顾========================