log4cxx的使用(2)

前面已经说完了怎样使用log4cxx进行日志记录,今天发现问题稍有点复杂。原因是系统中用到的一个dll已经使用了log4cxx。我们在开发的过程中也想使用log4cxx,但不想与DLL中的日志写到同一个文件中,问题就来了,怎样区别打印到不同的文件中呢,DLL中采用的为应该为getRootLogger的方式。

这个网址中的文章很好,解决方案主要参考此文:http://www.open-open.com/doc/view/4bf2bd4f517c4044b1f7d4e2d22eccaf

log4cxx主要是由三部分组成:loggers, appenders和layouts.这三个主要组成部分,协同协作能够使我们根据实际的需要进行日志的输出,它们规定了日志信息的类型和级别,控制应用程序运行时的日志信息组成方式以及日志记录的输出方式。

Logger是Log4cxx的核心,Logger具有继承关系的层次结构,最顶层为RootLogger,每个Logger都有一个级别(Level),每个Logger可以附加多个Appender.Appender代表了日志输出的目标,对于每一个Appender可以通过Layout进行格式配置。

Logger命名:保持Logger与其所在的类的名称一致的方法是目前所知的最好的命名策略。

一个关于Logger继承的例子:

#设置root logger 为DEBUG级别,使用了ca, fa两个Appender

log4j.rootLogger = DEBUG, ca, fa

#设置list logger

log4j.logger.list = DEBUG, listApp

#设置list.voice logger

log4j.logger.list.voice= INFO, listVoice, listVoiceBak

list是list.voice的父亲Logger, list.voice是list的儿子Logger. rootLogger是根Logger, 在此例中list和list.voice两个Logger又都继承了rootLogger,不过只是继承了Appenders,Level并没有继。(此解有待验证)

 

还是看配置文件:log4cxx.properties

# 设置root logger为DEBUG级别,使用了ca和fa两个Appender
log4j.rootLogger=DEBUG, fa, ca
# 设置.listApp logger,屏蔽logger-list的LEVEL继承
log4j.logger.listApp=DEBUG, listApp

# 设置.listApp2 logger,屏蔽logger-list的LEVEL继承
log4j.logger.listApp2=DEBUG, listApp2

#屏蔽listApp的Appender继承
log4j.additivity.listApp=false

#屏蔽listApp2的Appender继承
log4j.additivity.listApp2=false

 

#对Appender fa进行设置:# 这是一个文件类型的Appender,
log4j.appender.fa=org.apache.log4j.FileAppender
log4j.appender.fa.ImmediateFlush=true

# 其输出文件(File)为 Runlog.log,
log4j.appender.fa.File=Runlog.log
log4j.appender.fa.layout=org.apache.log4j.PatternLayout

# 输出方式(Append)为覆盖方式,
log4j.appender.fa.Append=false

# 输出格式(layout)为PatternLayout
log4j.appender.fa.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %.16c - %m%n

 

 

#对Appender ca进行设置:

# 这是一个控制台类型的Appender
log4j.appender.ca=org.apache.log4j.ConsoleAppender

# 输出格式(layout)为PatternLayout
log4j.appender.ca.layout=org.apache.log4j.PatternLayout
log4j.appender.ca.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %.16c - %m%n

 

#对Appender listApp进行设置# 这是一个文件类型的Appender,
log4j.appender.listApp=org.apache.log4j.FileAppender

#立即写入日志文件
log4j.appender.listApp.ImmediateFlush=true

# 其输出文件(File)为 listApp.log
log4j.appender.listApp.File=listApp.log

# 输出方式(Append)为覆盖方式,
log4j.appender.listApp.Append=false
log4j.appender.listApp.layout=org.apache.log4j.PatternLayout
log4j.appender.listApp.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %.16c - %m%n

 

#对Appender listApp2进行设置
log4j.appender.listApp2=org.apache.log4j.FileAppender
log4j.appender.listApp2.ImmediateFlush=true
log4j.appender.listApp2.File=listApp2.log
log4j.appender.listApp2.Append=false
log4j.appender.listApp2.layout=org.apache.log4j.PatternLayout
log4j.appender.listApp2.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %.16c - %m%n

 

 

以下为实现代码:

// testlog4cxx.cpp : 定义控制台应用程序的入口点。
//
 
#include "stdafx.h"
#include <iostream>
using namespace std;
#include <log4cxx/logger.h>
#include <log4cxx/propertyconfigurator.h>
 
using namespace log4cxx;
using namespace log4cxx::helpers;
 
int _tmain(int argc, _TCHAR* argv[])
{
 
    PropertyConfigurator::configure("log4cxx.properties");
 
    LOG4CXX_INFO(log4cxx::Logger::getLogger("list5"), "list,log4cxx!");
    LOG4CXX_INFO(log4cxx::Logger::getLogger("list5"), "list,mylog4cxx!");
 
    LOG4CXX_INFO(log4cxx::Logger::getLogger("listApp"), "listApp,log4cxx!");
 
    LOG4CXX_INFO(log4cxx::Logger::getLogger("listApp2"), "listApp2, hello world!");
 
    return 0;
}

 

将log4cxx.properties与生成后的testlog4cxx.exe放置同一目录,运行后发现目录下生成三个文件,分别为:他们的文件名及内容分别为

Runlog.log:

2012-04-06 21:13:56 INFO  list5 - list,log4cxx!
2012-04-06 21:13:56 INFO  list5 - list,mylog4cxx!

 

listApp.log:

2012-04-06 21:13:56 INFO  listApp - listApp,log4cxx!
2012-04-06 21:13:56 INFO  listApp - listApp TimeRsp.nErrno: 123

 

listApp2.log:

2012-04-06 21:13:56 INFO  listApp2 - listApp2, hello world!

 

由此可以看出,所有Logger默认继承于rootLogger的Appender,一般情况下(Level级别允许)总会在Runlog.log中打出,若想有所例外,需用配置log4j.additivity.AppenderName = false将默认继承去除。

posted @ 2012-04-06 23:20  绿色的麦田  阅读(2015)  评论(0编辑  收藏  举报