log4cplus在项目中的使用

Posted liyubo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了log4cplus在项目中的使用相关的知识,希望对你有一定的参考价值。

log4cplus是C++编写的开源的日志系统,宣称具有线程安全、灵活、以及多粒度控制的特点,通过将日志划分优先级使其可以面向程序调试、运行、测试、和维护等全生命周期。你可以选择将日志输出到屏幕、文件、甚至是远程服务器;通过指定策略对日志进行定期备份等等(该段为引用其他文章)。

1.编译log4cplus库

在网上下载log4cplus库(我下载了 log4cplus-1.2.1.zip) ,解压后在 msvc10 目录下由vs的工程 .sln文件,使用VS打开(我用vs2013),

技术图片

打开和工程包含内容如上,其中log4cplus为动态库工程,log4cplusS为动态库工程,可以根据需要进行编译(我测试了静态库动态库都可以正常使用)。编译完成后如下目录会产生.lib、.dll文件(只有编译动态库时产生.dll)。

技术图片

头文件在 log4cplus_1.2.1include 目录下 

接下来就可以在自己的工程中引用该库了(关于引用动态库静态库的方法此处不赘述,《dll、lib编译与加载》中有描述)

 2.log4cplus的初级应用

配置文件 logconfig.property

配置文件说明

#RootLogger配置格式:log4cplus.rootLogger=[LogLevel],appenderName1,appenderName2,...,如此处LogLevel为DEBUG,appenderName1为APPNDER_FILE。
log4cplus.rootLogger=DEBUG,APPNDER_FILE

#设置日志追加到文件尾
log4cplus.appender.APPNDER_FILE=log4cplus::RollingFileAppender  
 
#设置日志文件大小
log4cplus.appender.APPNDER_FILE.MaxFileSize=100MB
 
#设置生成日志最大个数
log4cplus.appender.APPNDER_FILE.MaxBackupIndex=2
 
#设置输出日志路径
log4cplus.appender.APPNDER_FILE.File=E:VS_test hreads hreads2PlateER.log
log4cplus.appender.APPNDER_FILE.layout=log4cplus::PatternLayout
 
#设置日志打印格式
log4cplus.appender.APPNDER_FILE.layout.ConversionPattern=%D:%d{%Q}|%p|%t|%l|%m|%n
 
#设置日志级别范围
log4cplus.appender.APPNDER_FILE.filters.1=log4cplus::spi::LogLevelRangeFilter
log4cplus.appender.APPNDER_FILE.filters.1.LogLevelMin=TRACE
log4cplus.appender.APPNDER_FILE.filters.1.LogLevelMax=FATAL
log4cplus.appender.APPNDER_FILE.filters.1.AcceptOnMatch=true
log4cplus.appender.APPNDER_FILE.filters.2=log4cplus::spi::DenyAllFilter
 

test

#include <log4cplus/logger.h>
#include <log4cplus/configurator.h> 
#include <log4cplus/layout.h> 
#include <log4cplus/loggingmacros.h> 
#include <log4cplus/helpers/stringhelper.h> 
#pragma comment(lib, "..\\..\\log4cplus_1.2.1\\msvc10\\Win32\\bin.Debug\\log4cplusSD.lib")

#define MY_LOG_FILE_PATH "E:\\VS_test\\threads\\threads2\\logconfig.property"    //配置文件路径

int main(int argc, char *argv[])
{
    log4cplus::initialize();    //初始化日志
    log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT(MY_LOG_FILE_PATH));    //读取配置文件
    log4cplus::Logger logger = log4cplus::Logger::getRoot();    //根记录器始终被实例化并可用。它的名字是"root"

    LOG4CPLUS_FATAL(logger, "DeleteService failed,errCode=[" << 1 << "]");    //打印级别为FATAL的日志
    LOG4CPLUS_DEBUG(logger, " Service is removed");    //打印级别为DEBUG的日志

    system("pause");
    return 0;
}

结果

2019-03-05 23:27:49:841.235|FATAL|19336|e:vs_test	hreads	hreads2main.cpp:18|DeleteService failed,errCode=[1]|
2019-03-05 23:27:49:852.238|DEBUG|19336|e:vs_test	hreads	hreads2main.cpp:19| Service is removed|

3.PatternLayout格式有以下选项

(1)"%%",转义为% 。

(2)"%c",输出logger名称,如test.subtest 。也可以控制logger名称的显示层次,比如"%c{1}"时输出"test",其中数字表示层次。

(3)"%D",显示本地时间,比如:"2004-10-16 18:55:45",%d显示标准时间。   

可以通过%d{...}定义更详细的显示格式,比如%d{%H:%M:%s}表示要显示小时:分钟:秒。大括号中可显示的预定义标识符如下:

   %a -- 表示礼拜几,英文缩写形式,比如"Fri"

    %A -- 表示礼拜几,比如"Friday"

   %b -- 表示几月份,英文缩写形式,比如"Oct"

   %B -- 表示几月份,"October"

   %c -- 标准的日期+时间格式,如"Sat Oct 16 18:56:19 2004"

   %d -- 表示今天是这个月的几号(1-31)"16"

   %H -- 表示当前时刻是几时(0-23),如"18"

   %I -- 表示当前时刻是几时(1-12),如"6"

   %j -- 表示今天是哪一天(1-366),如"290"

   %m -- 表示本月是哪一月(1-12),如"10"

   %M -- 表示当前时刻是哪一分钟(0-59),如"59"

   %p -- 表示现在是上午还是下午,AM or PM

   %q -- 表示当前时刻中毫秒部分(0-999),如"237"

   %Q -- 表示当前时刻中带小数的毫秒部分(0-999.999),如 "430.732"

   %S -- 表示当前时刻的多少秒(0-59),如"32"

   %U -- 表示本周是今年的第几个礼拜,以周日为第一天开始计算(0-53),如 "41"

   %w -- 表示礼拜几,(0-6, 礼拜天为0),如"6"

   %W -- 表示本周是今年的第几个礼拜,以周一为第一天开始计算(0-53),如 "41"

   %x -- 标准的日期格式,如"10/16/04"

   %X -- 标准的时间格式,如"19:02:34"

   %y -- 两位数的年份(0-99),如"04"

   %Y -- 四位数的年份,如"2004"

   %Z -- 时区名,比如"GMT"

(4)"%F",输出当前记录器所在的文件名称,比如"main.cpp"

(5)"%L",输出当前记录器所在的文件行号,比如"51"

(6)"%l",输出当前记录器所在的文件名称和行号,比如"main.cpp:51"

(7)"%m",输出原始信息。

(8)"%n",换行符。

(9)"%p",输出LogLevel,比如"DEBUG"

(10)"%t",输出记录器所在的线程ID,比如 "1075298944"

(11)"%x",嵌套诊断上下文NDC (nested diagnostic context) 输出,从堆栈中弹出上下文信息,NDC可以用对不同源的log信息(同时地)交叉输出进行区分。

(12)格式对齐,比如"%-10m"时表示左对齐,宽度是10,当然其它的控制字符也可以相同的方式来使用,比如"%-12d","%-5p"等等。

4.设置Filter

包括选择过滤器和设置过滤条件,可选择的过滤器包括:LogLevelMatchFilter、LogLevelRangeFilter、和StringMatchFilter:

对LogLevelMatchFilter来说,过滤条件包括LogLevelToMatch和AcceptOnMatch(true|false), 只有当log信息的LogLevel值与LogLevelToMatch相同,且AcceptOnMatch为true时才会匹配。

LogLevelRangeFilter来说,过滤条件包括LogLevelMin、LogLevelMax和AcceptOnMatch,只有当log信息的LogLevel在LogLevelMin、LogLevelMax之间同时AcceptOnMatch为true时才会匹配。

对StringMatchFilter来说,过滤条件包括StringToMatch和AcceptOnMatch,只有当log信息的LogLevel值与StringToMatch对应的LogLevel值与相同, 且AcceptOnMatch为true时会匹配。

过滤条件处理机制类似于IPTABLE的Responsibility chain,(即先deny、再allow)不过执行顺序刚好相反,后写的条件会被先执行,比如:

log4cplus.appender.append_1.filters.1=log4cplus::spi::LogLevelMatchFilter

log4cplus.appender.append_1.filters.1.LogLevelToMatch=TRACE

log4cplus.appender.append_1.filters.1.AcceptOnMatch=true

#log4cplus.appender.append_1.filters.2=log4cplus::spi::DenyAllFilter

会首先执行filters.2的过滤条件,关闭所有过滤器,然后执行filters.1,仅匹配TRACE信息。

 5.封装一个简单的类(以下忘记在哪里复制的,如有侵权敬请联系删除)

 MyLogger.h

#pragma once

#include <iostream>
#include <string>
#include <log4cplus/logger.h>
#include <log4cplus/configurator.h> 
#include <log4cplus/layout.h> 
#include <log4cplus/loggingmacros.h> 
#include <log4cplus/helpers/stringhelper.h> 
#pragma comment(lib, "..\\..\\log4cplus_1.2.1\\msvc10\\Win32\\bin.Debug\\log4cplusSD.lib")

#define MY_LOG_FILE_PATH "E:\\VS_test\\threads\\threads2\\logconfig.property"

using namespace std;
using namespace log4cplus;
using namespace log4cplus::helpers;

class MyLogger
{
public:
    static MyLogger * getInstance();
    Logger logger;
private:
    MyLogger();
    ~MyLogger();
    static MyLogger * my_logger;
};

MyLogger.cpp

#include "MyLogger.h"

MyLogger *MyLogger::my_logger = NULL;

MyLogger::MyLogger()
{
    log4cplus::initialize();
    PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT(MY_LOG_FILE_PATH));
    logger = Logger::getRoot();
}


MyLogger * MyLogger::getInstance()
{
    if (my_logger == NULL)
    {
        my_logger = new MyLogger();
    }
    return my_logger;
}

MyLogger::~MyLogger()
{
    if (my_logger)
    {
        delete my_logger;
    }
}

main.cpp

#include <windows.h>
#include "MyLogger.h"

int main(int argc, char *argv[])
{
    MyLogger * myLoger = NULL;
    myLoger = MyLogger::getInstance();

    LOG4CPLUS_FATAL(myLoger->logger, "DeleteService failed,errCode=[" << GetLastError() << "]");
    LOG4CPLUS_DEBUG(myLoger->logger, " Service is removed");

    system("pause");
    return 0;
}

 

 

 

 

 

以上是关于log4cplus在项目中的使用的主要内容,如果未能解决你的问题,请参考以下文章

log4cplus使用

链接器错误 - 未定义的符号

180325-log4cplus

如何将 log4cplus appender 输出发送到内存缓冲区?

log4cplus:DailyRollingFileAppender 配置/MaxBackupIndex 不起作用

如何将 log4cplus 日志文件更改为 utf8