部分参考了博客。

http://www.cppblog.com/tx7do/articles/11719.html

基于脚本配置来过滤log信息
除了通过程序实现对log环境的配置之外,log4cplus通过PropertyConfigurator类实现了基于脚本配置的功能。通过
脚本可以完成对logger、appender和layout的配置,因此可以解决怎样输出,输出到哪里的问题,我将在全文的最后
一部分中提到多线程环境中如何利用脚本配置来配合实现性能测试,本节将重点介绍基脚本实现过滤log信息的功能。

首先简单介绍一下脚本的语法规则:
包括Appender的配置语法和logger的配置语法,其中:

1.Appender 的配置语法:
1.1 设置名称:
/*设置方法*/log4cplus.appender.appenderName=fully.qualified.name.of.appender.class
例如(列举了所有可能的Appender,其中SocketAppender这里没有使用):
log4cplus.appender.append_1=log4cplus::ConsoleAppender
log4cplus.appender.append_2=log4cplus::FileAppender
log4cplus.appender.append_3=log4cplus::RollingFileAppender
log4cplus.appender.append_4=log4cplus::DailyRollingFileAppender
log4cplus.appender.append_4=log4cplus::SocketAppender

1.2. 设置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::LogLevelMatchFilterlog4cplus.appender.append_1.filters.1.LogLevelToMatch=TRACElog4cplus.appender.append_1.filters.1.AcceptOnMatch=true#log4cplus.appender.append_1.filters.2=log4cplus::spi::DenyAllFilter
会首先执行filters.2的过滤条件,关闭所有过滤器,然后执行filters.1,仅匹配TRACE信息。

1.3. 设置Layout
可以选择不设置、TTCCLayout、或PatternLayout
如果不设置,会输出简单格式的log信息。
设置TTCCLayout如下所示:log4cplus.appender.ALL_MSGS.layout=log4cplus::TTCCLayout
设置PatternLayout如下所示:log4cplus.appender.append_1.layout=log4cplus::PatternLayoutlog4cplus.appender.append_1.layout.ConversionPattern=%d{%m/%d/%y %H:%M:%S,%Q} [%t] %-5p - %m%n

2.logger的配置语法
同一个 logger 下的 Appender 会输出内容到该logger 下的所有文件,可以通过 LogLevel 等措施拉过滤。
下面演示了建立不同logger,隔离输出内容的方法。
包括rootLogger和non-root logger。
对于rootLogger来说:log4cplus.rootLogger=[LogLevel], appenderName, appenderName, ...
对于non-root logger来说:log4cplus.logger.logger_name=[LogLevel|INHERITED], appenderName, appenderName, ...
    脚本方式使用起来非常简单,只要首先加载配置即可(urconfig.properties是自行定义的配置文件):
PropertyConfigurator::doConfigure("urconfig.properties");下面我们通过例子体会一下log4cplus强大的基于脚本过滤log信息的功能。

下面建立的是 VS2012 的WIN32控制台工程 log4cplus_test,用来演示日志输出,
工程需要注意两点:
1. 使用的是最新的 log4cplus-1.1.1 版本,链接的是其中的静态库 log4cplusSD.lib
2. 工程需要设置 字符集为 "使用多字节字符集",设置方法是VS2012 菜单:
项目->log4cplus_test属性->配置属性->字符集

下面是配置文件 urconfig.properties 的内容,使用配置来控制log4cplus 的log 输出.

#全局默认根 logger,这里忽略
#log4cplus.rootLogger=TRACE, ALL_MSGS, TRACE_MSGS, DEBUG_INFO_MSGS, FATAL_MSGS

#log4cplus.rootLogger=TRACE,ALL_MSGS
#log4cplus.appender.ALL_MSGS=log4cplus::RollingFileAppender
#log4cplus.appender.ALL_MSGS.File=./logout/all_msgs.log
#log4cplus.appender.ALL_MSGS.layout=log4cplus::TTCCLayout

#独立的 logger 的配置语法,支持两个 appender
log4cplus.logger.APPfilelogger = TRACE,APP,APP_DAILY
og4cplus.additivity.APPfilelogger = false

#独立的 logger 的配置语法,同一个 logger 下会发送到所有文件,
#是否写入到所有文件,通过 LogLevel 来控制
log4cplus.logger.SYSfilelogger = TRACE,SYS
#log4cplus.additivity.SYSfilelogger = TRUE

#独立的 logger 的配置语法
log4cplus.logger.ACCfilelogger = TRACE,ACC
#log4cplus.additivity.ACCfilelogger = TRUE

#支持只写入同一个 logger 下的指定文件
log4cplus.appender.APP=log4cplus::RollingFileAppender
log4cplus.appender.APP.File=./logout/app_msgs.log
log4cplus.appender.APP.ImmediateFlush=false
log4cplus.appender.APP.MaxFileSize=1MB
#log4cplus.appender.APP.MinFileSize=1M
log4cplus.appender.APP.MaxBackupIndex=3
log4cplus.appender.APP.layout=log4cplus::PatternLayout
log4cplus.appender.APP.layout.ConversionPattern=%D{%Y-%m-%d %H:%M:%S.%Q}|%-5p|%c[2]|%t|%F:%L|%m%n
log4cplus.appender.APP.filters.1=log4cplus::spi::LogLevelRangeFilter
log4cplus.appender.APP.filters.1.LogLevelMin=TRACE
log4cplus.appender.APP.filters.1.LogLevelMax=FATAL

#支持只写入同一个 logger 下的指定文件
log4cplus.appender.APP_DAILY=log4cplus::DailyRollingFileAppender
log4cplus.appender.APP_DAILY.File=./logout/app_msgs_d.log
#MONTHLY,WEEKLY,DAILY,TWICE_DAILY,HOURLY,MINUTELY
log4cplus.appender.APP_DAILY.Schedule=MINUTELY
log4cplus.appender.APP_DAILY.DatePattern='.'yyyy-MM-dd
log4cplus.appender.APP_DAILY.ImmediateFlush=false
log4cplus.appender.APP_DAILY.MaxBackupIndex=3
log4cplus.appender.APP_DAILY.layout=log4cplus::PatternLayout
log4cplus.appender.APP_DAILY.layout.ConversionPattern=%D{%Y-%m-%d %H:%M:%S.%Q}|%-5p|%c[2]|%t|%F:%L|%m%n
log4cplus.appender.APP_DAILY.filters.1=log4cplus::spi::LogLevelRangeFilter
log4cplus.appender.APP_DAILY.filters.1.LogLevelMin=TARCE
log4cplus.appender.APP_DAILY.filters.1.LogLevelMax=FATAL

#支持只写入同一个 logger 下的指定文件
log4cplus.appender.SYS=log4cplus::RollingFileAppender
log4cplus.appender.SYS.File=./logout/sys_msgs.log
log4cplus.appender.SYS.MaxFileSize=1MB
log4cplus.appender.SYS.MaxBackupIndex=3
log4cplus.appender.SYS.ImmediateFlush=false
log4cplus.appender.SYS.layout=log4cplus::PatternLayout
log4cplus.appender.SYS.layout.ConversionPattern=%D{%Y-%m-%d %H:%M:%S.%Q}|%-5p|%c[2]|%t|%F:%L|%m%n
log4cplus.appender.SYS.filters.1=log4cplus::spi::LogLevelRangeFilter
log4cplus.appender.SYS.filters.1.LogLevelMin=TRACE
log4cplus.appender.SYS.filters.1.LogLevelMax=FATAL

#支持只写入同一个 logger 下的指定文件
log4cplus.appender.ACC=log4cplus::RollingFileAppender
log4cplus.appender.ACC.File=./logout/acc_msgs.log
log4cplus.appender.ACC.MaxFileSize=1MB
log4cplus.appender.ACC.MaxBackupIndex=3
log4cplus.appender.ACC.ImmediateFlush=false
log4cplus.appender.ACC.layout=log4cplus::PatternLayout
log4cplus.appender.ACC.layout.ConversionPattern=%D{%Y-%m-%d %H:%M:%S.%Q}|%-5p|%c[2]|%t|%F:%L|%m%n
log4cplus.appender.ACC.filters.1=log4cplus::spi::LogLevelRangeFilter
log4cplus.appender.ACC.filters.1.LogLevelMin=TRACE
log4cplus.appender.ACC.filters.1.LogLevelMax=FATAL

主要代码文件是 log4cplus_test.cpp,代码如下:

// log4cplus_test.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <conio.h>
#include <iostream>
#include <xmemory>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/appender.h>
#include <log4cplus/logger.h>
#include <log4cplus/fileappender.h>
#include <log4cplus/consoleappender.h>
#include <log4cplus/configurator.h>
#include <log4cplus/helpers/property.h>

using namespace std;
using namespace log4cplus;

//APP 和 APP_DAILY 共用了一个 logger配置
static Logger APP = Logger::getInstance(LOG4CPLUS_TEXT("APPfilelogger.APP"));
static Logger APP_DAILY = Logger::getInstance(LOG4CPLUS_TEXT("APPfilelogger.APP_DAILY"));

//SYS,ACC 是独立的 logger 配置,这样 SYS,ACC,APP(APP_DAILY) 分别属于不同的logger
//它们可以独立的输出文件,相互不干扰
static Logger SYS = Logger::getInstance(LOG4CPLUS_TEXT("SYSfilelogger.SYS"));
static Logger ACC = Logger::getInstance(LOG4CPLUS_TEXT("ACCfilelogger.ACC"));

void printDebug()
{   
    LOG4CPLUS_TRACE(APP, "::printDebug()");   
    LOG4CPLUS_DEBUG(APP, "This is a DEBUG message");
    LOG4CPLUS_DEBUG(APP_DAILY, "This is a DEBUG message");

LOG4CPLUS_INFO(ACC, "This is a INFO message");
    LOG4CPLUS_INFO(ACC, "This is a INFO message");   
    LOG4CPLUS_WARN(ACC, "This is a WARN message");

LOG4CPLUS_ERROR(SYS, "This is a ERROR message");   
    LOG4CPLUS_FATAL(SYS, "This is a FATAL message");
    LOG4CPLUS_TRACE(SYS, "::printDebug()");
}

void ta()
{
    log4cplus::DailyRollingFileAppender *_append;
    _append = new DailyRollingFileAppender("./logout/dd.log",MINUTELY,false,5);
    _append->setName("file test");
    _append->setLayout(std::auto_ptr<TTCCLayout>(new TTCCLayout()));
    Logger::getRoot().addAppender(log4cplus::SharedAppenderPtr(_append));
    Logger test = Logger::getInstance("test");
    for(int i = 0 ;i < 10000000 ;++i)
    {
        LOG4CPLUS_TRACE(test, "::printDebug()");
        LOG4CPLUS_FATAL(test, "This is a FATAL message");
        LOG4CPLUS_FATAL(test, "This is a FATAL message");
        LOG4CPLUS_FATAL(test, "This is a FATAL message");
        LOG4CPLUS_FATAL(test, "This is a FATAL message");
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    PropertyConfigurator config(LOG4CPLUS_TEXT("./urconfig.properties"));
    config.configure();

for(int i = 0; i< 1000000;++i)
    {
        printDebug();
    }

::system("pause");

return 0;
}

使用最新的log4cplus(1.1.1)隔离不同的 log 文件输出的更多相关文章

  1. Webstorm官方最新版本for Mac版本 不用注册码/破坏原文件

    首先,说明下我自己安装的时候看到网上无外乎两种方法: 下载别人封装好的安装包,把JetbrainsCrack.jar复制到/Applications/WebStorm.app/Contents/bin ...

  2. clearcase常用命令

    版本控制工具学习 http://www.itpxpj.com/course.do?method=getAllCourseInFront&classTypeId=21 1.[ClearCase] ...

  3. Redis详解(一)冰叔带你了解Redis

       Redis 是一种基于 键值对 的 NoSQL 数据库.与很多键值对数据库不同,Redis 提供了丰富的 值数据存储结构,包括 string(字符串).hash(哈希).list(列表).set ...

  4. 搭建开源入侵检测系统Snort并实现与防火墙联动

    Snort作为一款优秀的开源主机入侵检测系统,在windows和Linux平台上均可安装运行.BT5作为曾经的一款经典的渗透神器,基于 Ubuntu,里面已经预装很多的应用,比如Mysql.Apach ...

  5. Redis(1.10)Redis主从复制下的哨兵模式

    [0]哨兵 sentinel 的作用 其概念参考:Redis高可用(理论篇) 中的[2] [0.1]监控:监控主从是否正常 [0.2]通知:出现问题时,可以通知相关人员 [0.3]故障转移:自动主从切 ...

  6. Redis(1.7)Redis高可用架构(理论篇)

    [0]常用架构种类 (0.1)单机Redis (0.2)单纯的Redis主从复制 (0.3)哨兵Sentinel+Redis主从复制集群(实现高可用自动故障转移) (0.4)Redis Cluster ...

  7. 01 . Redis简介及部署主从复制

    简介 Remote Dictionary Server, 翻译为远程字典服务, Redis是一个完全开源的基于Key-Value的NoSQL存储系统,他是一个使用ANSIC语言编写的,遵守BSD协议, ...

  8. Python记录日志模块推荐-loguru!

      作者:小张学Python 本文链接: https://mp.weixin.qq.com/s/dkNkEohPl6H2VopUrpxxZg 转载请注明来源!! 前言 在做项目的时候一直在用Pytho ...

  9. Python 中更优雅的日志记录方案

    在 Python 中,一般情况下我们可能直接用自带的 logging 模块来记录日志,包括我之前的时候也是一样.在使用时我们需要配置一些 Handler.Formatter 来进行一些处理,比如把日志 ...

随机推荐

  1. C# List 转Datatable

    最近在做Excel导出,看到了这个方法,虽不是自己写的,但值得收藏,但是忘记从那摘抄的,没写原文作者看到望见谅! #region 导出Excel /// <summary> /// lis ...

  2. js中的一元运算符

    一元运算符只有一个参数,即要操作的对象或值.它们是 ECMAScript 中最简单的运算符. delete delete 运算符删除对以前定义的对象属性或方法的引用.例如: var o = new O ...

  3. slf4j 和 log4j合用的(Maven)配置(转)

    简述:添加logger的日志输出,下面是配置信息供备忘 步骤:1. 在Maven的porn.xml 文件中添加dependency如下 <dependency> <groupId&g ...

  4. ios7状态栏属性的设置

    /* 状态栏的管理: 1> iOS7之前:UIApplication进行管理 2> iOS7开始:交给对应的控制器去管理 */ // 设置状态栏的样式 - (UIStatusBarStyl ...

  5. 小猪猪C++笔记基础篇(四)数组、指针、vector、迭代器

    小猪猪C++笔记基础篇(四) 关键词:数组,Vector. 一.数组与指针 数组相信大家学过C语言或者其他的语言都不陌生,简单的就是同一个变量类型的一组数据.例如:int a[10],意思就是从a开始 ...

  6. gcc支持c99验证

    gcc3.0以上的版本都是支持C99标准的, 但是编译程序的时候需要加上    -std=c9  才可以: 一下程序是验证gcc是否支持c99标准的: #include <stdio.h> ...

  7. BZOJ 1036: [ZJOI2008]树的统计Count( 树链剖分 )

    树链剖分... 不知道为什么跑这么慢 = = 调了一节课啊跪.. ------------------------------------------------------------------- ...

  8. xadmin集成ueditor

    from DjangoUeditor.models import UEditorField content = UEditorField(u"内容", imagePath=&quo ...

  9. 笔记之Cyclone IV 第一卷第一章FPGA 器件系列概述

    因为本人用的黑金四代开发板,中央芯片采用ALTERA的cycloneIV E,所以就此器件阅读altera官网资料,并做相应的笔记,以便于以后查阅 Cyclone IV 器件系列具有以下特性:■ 低成 ...

  10. ASP.NET MVC 5 学习教程:创建连接字符串

    原文 ASP.NET MVC 5 学习教程:创建连接字符串 起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 添加模型 创建连接字符串 ...