C/C++ 开源日志库log4cplus的编译和使用

开源项目在github上面,目前最新release版本是2.0.7

https://github.com/log4cplus/log4cplus

官网上一句话描述log4cplus:log4cplus是一个易于使用的C++17日志API,它提供了线程安全、灵活、以及多粒度控制日志管理和配置控制,是仿造Java log4j API编写的。

下载源码后解压,就可以进行编译了,编译前,有几个脚本选项需要说明下:

--enable-threads

开启线程功能,默认这个选项是开启的。所以,如果编译代码不加上线程库,就会报一对的线程函数不能找到的错误。关掉就使用脚本:

$ ../configure --enable-threads=no

如果开启线程支持就需要在编译的时候加上:

-l pthread

还有个选项在官网主页没有说明:

--enable-static

这个参数是编译静态库的选项,默认是没打开的,在linux下如果引用so库和a库各有优缺点,我更喜欢用静态库,因为我是用来开发服务器程序的日志,部署的时候就不需要再去安装和运行脚本和复制动态库了。

其他选项在configure文件下可以找到:

Optional Features:
  --disable-option-checking  ignore unrecognized --enable/--with options
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
  --enable-silent-rules   less verbose build output (undo: "make V=1")
  --disable-silent-rules  verbose build output (undo: "make V=0")
  --disable-maintainer-mode
                          disable make rules and dependencies not useful (and
                          sometimes confusing) to the casual installer
  --enable-dependency-tracking
                          do not reject slow dependency extractors
  --disable-dependency-tracking
                          speeds up one-time build
  --enable-debugging      Turns off optimization and adds switches that
                          generate debugging information. [default=no]
  --enable-warnings       Use compiler warnings option, e.g. -Wall.
                          [default=yes]
  --enable-so-version     Use libtool -version-info option. [default=yes]
  --enable-implicit-initialization
                          Initialize log4cplus implicitly. [default=yes]
  --enable-thread-pool    Instantiate internal thread pool for when
                          AsyncAppend=true. [default=yes]
  --enable-release-version
                          Use libtool -release option. [default=yes]
  --enable-symbols-visibility-options
                          Use platform and compiler specific symbols
                          visibility options, where they are available.
                          [default=yes]
  --enable-unit-tests     Enable unit tests [default=no]
  --enable-lto            Enable LTO build [default=no]
  --enable-profiling      Compile with profiling compiler options.
                          [default=no]
  --enable-threads        Create multi-threaded variant [default=yes]
  --enable-static[=PKGS]  build static libraries [default=no]
  --enable-shared[=PKGS]  build shared libraries [default=yes]
  --enable-fast-install[=PKGS]
                          optimize for fast installation [default=yes]
  --disable-libtool-lock  avoid locking (might break parallel builds)

配置结束后再使用 

$ make
$ make install

编译出库文件在makefile中添加:

-L./lib -llog4cplus

就能把库文件链接到工程里面了。

log4cplus提供了一些test工程,方便理解和使用,就几个比较好用的示例,比如:

patternlayout_test

log4cplus::tstring pattern = LOG4CPLUS_TEXT("%d{%m/%d/%y %H:%M:%S,%Q} [%t] %-5p %c{2} %%%x%% - %X{key} - %m [%l]%n");
        
append_1->setLayout( std::unique_ptr(new PatternLayout(pattern)) );
Logger::getRoot().addAppender(append_1);

这段演示了怎么让打印的格式带时间戳,还有很多其他的pantern格式,可以在文档里面查询。

fileappender_test

    SharedFileAppenderPtr append_1(
        new RollingFileAppender(LOG4CPLUS_TEXT("ab/c/d/Test.log"), 5*1024, 5,
            false, true));//最大5M,最多生成5个文件

RollingFileAppender类的原型如下:

RollingFileAppender::RollingFileAppender(const tstring& filename_,
    long maxFileSize_, int maxBackupIndex_, bool immediateFlush_,
    bool createDirs_)
    : FileAppender(filename_, std::ios_base::app, immediateFlush_, createDirs_)
{
    init(maxFileSize_, maxBackupIndex_);
}

在test代码中,第一行可以看到这代码:

log4cplus::Initializer initializer;

官网是这样解释的:

log4cplus uses C++11 thread and synchronization facilities. The synchronization facilities are implemented in Visual Studio C++ standard library in a way that utilizes global variables. Therefore it is impossible (due to "static initialization order fiasco") to use them outside main(). This issue manifests as a deadlock on exit during destruction of log4cplus' thread pool.

To overcome this limitation,

  • always use log4cplus::Initializer initializer; as the first thing in main();

  • never try to log from static/global objects constructors;

  • never try to log from static/global object destructors.

 意思就是log4cplus使用C++11的线程和同步机制,使用了Visual Studio C++标准库中的全局变量来实现同步的,因此在main函数之外就不能使用了,在线程池中会导致无法修复的死锁问题。

给出3点建议:

1.在main函数的开头使用: log4cplus::Initializer initializer

2.不使用静态或者全局的对象constructors

3.不使用静态或者全局的对象destructors

你可能感兴趣的:(c++,p2p,开发语言)