Log4Cplus 学习笔记 - 配置文件的使用

说明

最近由于项目开始接触这个类,用起来很方便,看了很多帖子,将针对自己比较常用的配置文件部分归纳出来。

主要参考帖子:Log4cplus使用指南

测试版本 1.2.2

测试软件 VS2010

1 概要

配置文件中总共包含4部分内容:Logger、Appender、layout、filter,逻辑关系如下。

举个例子

#声明一个Logger
#SetverLog = Logger名称
#ALL = 日志输出的级别
#ALL_MSGS = Appender对象,可以有多个对象
log4cplus.logger.SetverLog = ALL, ALL_MSGS, ALL_MSGS_1

#实例化Appender对象,即输出方式:输出到控制台还是文件
log4cplus.appender.ALL_MSGS=log4cplus::RollingFileAppender  
log4cplus.appender.ALL_MSGS.MaxFileSize=100MB
log4cplus.appender.ALL_MSGS.MaxBackupIndex=10
log4cplus.appender.ALL_MSGS.CreateDirs = true
log4cplus.appender.ALL_MSGS.ImmediateFlush = true
log4cplus.appender.ALL_MSGS.File=ServerLog/test.log

#日志文件的打印格式
log4cplus.appender.ALL_MSGS.layout=log4cplus::PatternLayout
log4cplus.appender.ALL_MSGS.layout.ConversionPattern=[%-5p %d{%y-%m-%d %H:%M:%S}] [%l]

#日志输出的过滤器
log4cplus.appender.ALL_MSGS.filters.1=log4cplus::spi::LogLevelMatchFilter
log4cplus.appender.DEBUG_MSGS.filters.1.LogLevelToMatch=DEBUG
log4cplus.appender.DEBUG_MSGS.filters.1.AcceptOnMatch=true
log4cplus.appender.DEBUG_MSGS.filters.2=log4cplus::spi::DenyAllFilter

2 Logger的定义和调用

2.1 rootLogger

配置

log4cplus.rootLogger=ALL, RemoteServer, STDOUT, ALL_MSGS

调用

log4cplus::initialize();	
log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("配置文件名称"));
log4cplus::Logger logger = log4cplus::Logger::getRoot(); 

2.2 logger

配置

log4cplus.logger.ClientLog = ALL, RemoteServer, STDOUT, ALL_MSGS

调用

log4cplus::initialize();	
log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("配置文件名称"));
log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("ClientLog"));

 3 日志的级别和输出

3.1 日志级别

级别合法字符说明
NOT_SET_LOG_LEVEL ( -1) 接受缺省的LogLevel,如果有父logger则继承它的LogLevel
ALL_LOG_LEVEL (0)ALL开放所有log信息输出
TRACE_LOG_LEVEL (0)TRACE开放trace信息输出(即ALL_LOG_LEVEL)
DEBUG_LOG_LEVEL(10000)DEBUG开放debug信息输出
INFO_LOG_LEVEL (20000)INFO开放info信息输出
WARN_LOG_LEVEL (30000)WARN开放warning信息输出
ERROR_LOG_LEVEL(40000)ERROR开放error信息输出
FATAL_LOG_LEVEL (50000)FATAL开放fatal信息输出
OFF_LOG_LEVEL (60000)OFF关闭所有log信息输出

3.2 输出函数

级别函数说明
TRACELOG4CPLUS_TRACE

1. 直接输出。将日志转导 ostringstream 流,再转字符串输出。

2. *_STR。直接字符串输出。

3. *_FMT。先格式化字符串,再转字符串输出。

4. *_METHOD。会在函数的入口和出口处输出 ENTER 和 EXIT。

LOG4CPLUS_TRACE_STR
LOG4CPLUS_TRACE_FMT
LOG4CPLUS_TRACE_METHOD
DEBUGLOG4CPLUS_DEBUG
LOG4CPLUS_DEBUG_STR
LOG4CPLUS_DEBUG_FMT
INFOLOG4CPLUS_INFO
LOG4CPLUS_INFO_STR
LOG4CPLUS_INFO_FMT
WARNLOG4CPLUS_WARN
LOG4CPLUS_WARN_STR
LOG4CPLUS_WARN_FMT
ERRORLOG4CPLUS_ERROR
LOG4CPLUS_ERROR_STR
LOG4CPLUS_ERROR_FMT
FATALLOG4CPLUS_FATAL
LOG4CPLUS_FATAL_STR
LOG4CPLUS_FATAL_FMT
ASSERTLOG4CPLUS_ASSERT

 代码

#include <log4cplus/consoleappender.h>
#include <log4cplus/layout.h>
#include <log4cplus/logger.h>
#include <log4cplus/ndc.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/thread/threads.h>
#include <log4cplus/helpers/sleep.h>
#include <log4cplus/streams.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/tracelogger.h>
#include <exception>
#include <iostream>
#include <string>
#include <log4cplus/configurator.h>

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

int
main()
{
	log4cplus::initialize();
	log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("config.txt"));
	Logger logger = Logger::getInstance(LOG4CPLUS_TEXT("TestOutputMethod"));
	
	LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("111"));
	LOG4CPLUS_TRACE_STR(logger, LOG4CPLUS_TEXT("222"));
	LOG4CPLUS_TRACE_FMT(logger, LOG4CPLUS_TEXT("%d%d%d"), 3, 3, 3);
	{
		LOG4CPLUS_TRACE_METHOD(logger, LOG4CPLUS_TEXT("TestFunc"));
		LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("444"));
		LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("555"));
		LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("666"));
	}	
	LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("777"));

	log4cplus::Logger::shutdown();
	return 0;
}

配置文件

log4cplus.logger.TestOutputMethod = ALL, Test

# 创建Appender对象
log4cplus.appender.Test = log4cplus::FileAppender

# FileAppender 类属性
log4cplus.appender.Test.Threshold = ALL
log4cplus.appender.Test.File = Test/FileAppenderLog.txt
log4cplus.appender.Test.ImmediateFlush = false
log4cplus.appender.Test.BufferSize = 1024
log4cplus.appender.Test.CreateDirs = true
log4cplus.appender.Test.Append = false

结果

TRACE - 111
TRACE - 222
TRACE - 333
TRACE - ENTER: TestFunc
TRACE - 444
TRACE - 555
TRACE - 666
TRACE - EXIT:  TestFunc
TRACE - 777

4 Appender

4.1 Appender 家族

Appender基础Appender类
ConsoleAppender输出到控制台
FileAppenderBase输出到文件的基础类,不可以被实例化
FileAppender输出到文件
RollingFileAppender输出到文件-可以按照文件大小或者数量滚动
DailyRollingFileAppender输出到文件-可以按照日期时间滚动
TimeBasedRollingFileAppender可以按照用户定义的时间滚动日志
AsyncAppender一个异步写入的Appender
SocketAppender网络日志

它们的继承关系:

4.2 Appender 类

属性标签描述
layout

说明:日志打印格式

类型:Layout

默认值:SimpleLayout

可选值:SimpleLayout  TTCCLayout  PatternLayout

filters说明:日志过滤器

类型:Filter

默认值:默认接收所有输出

可选值:DenyAllFilter  LogLevelMatchFilter  LogLevelRangeFilter  StringMatchFilter

Threshold

说明:日志打印的最低级别

类型:LogLevel

默认值:NOT_SET_LOG_LEVEL

可选值:ALL TRACE  DEBUG  INFO  WARN  ERROR  FATAL OFF

4.3 ConsoleAppender 类

属性标签描述
logToStdErr

说明:输出方式

类型:bool

默认值:false

可选值:true=std::cerr false=std::cout

ImmediateFlush

说明:立即输出

类型:bool

默认值:false

可选值:true=std::cerr false=std::cout

 代码

#include <iostream>
#include <log4cplus/ndc.h>
#include <log4cplus/logger.h>
#include <log4cplus/helpers/sleep.h>
#include <log4cplus/helpers/pointer.h>
#include <log4cplus/configurator.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>

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

int main()
{
	log4cplus::initialize();
	log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("config.txt"));
	log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("TestConsoleAppender"));
	
	LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("TRACE-LOG-TEST"));
	LOG4CPLUS_DEBUG(logger, LOG4CPLUS_TEXT("DEBUG-LOG-TEST"));
	LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("INFO-LOG-TEST"));
	LOG4CPLUS_WARN(logger, LOG4CPLUS_TEXT("WARN-LOG-TEST"));
	LOG4CPLUS_ERROR(logger, LOG4CPLUS_TEXT("ERROR-LOG-TEST"));
	LOG4CPLUS_FATAL(logger, LOG4CPLUS_TEXT("FATAL-LOG-TEST"));
    
        log4cplus::Logger::shutdown();
	return 0;
}

配置文件

log4cplus.logger.TestConsoleAppender = ALL, Test

# 创建Appender对象
log4cplus.appender.Test = log4cplus::ConsoleAppender

# Appender类属性
log4cplus.appender.Test.Threshold = INFO

输出结果 

INFO - INFO-LOG-TEST
WARN - WARN-LOG-TEST
ERROR - ERROR-LOG-TEST
FATAL - FATAL-LOG-TEST

4.4 FileAppenderBase

属性标签描述
File

说明:文件路径\文件名

类型:String

默认值:无

可选值:文件路径\文件名

ImmediateFlush

说明:立即刷新

类型:bool

默认值:true

可选值:true false

Append

说明:追加到文件末尾继续写入

类型:bool

默认值:false

可选值:true false

ReopenDelay

说明:当上一次日志写入失败后延长多久后再次打开日志文件继续写入

类型:int

默认值:1(秒)

可选值:int 有效值

BufferSize

说明:缓存大小

类型:unsigned long

默认值:0

可选值:unsigned long 有效值

UseLockFile

说明:使用锁文件,多进程对同一文件同时写入的优化机制

类型:bool

默认值:false

可选值:true false

LockFile

说明:锁文件的文件名尾缀,只有在 UseLockFile 为 true 时有效

类型:String

默认值:.lock

可选值:非空即可

Locale

说明:字符集

类型:String

默认值:DEFAULT

可选值:en_US.UTF-8  GLOBAL  DEFAULT  USER  Chinese_China.936  Chinese_China.65001 chs

CreateDirs

说明:如果目录及文件不存在就创建

类型:bool

默认值:false

可选值:true false

4.5 FileAppender

没有额外的附加属性。

 代码

#include <iostream>
#include <log4cplus/ndc.h>
#include <log4cplus/logger.h>
#include <log4cplus/helpers/sleep.h>
#include <log4cplus/helpers/pointer.h>
#include <log4cplus/configurator.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>

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

int main()
{
	log4cplus::initialize();
	log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("config.txt"));
	log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("TestFileAppender"));
	
	LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("TRACE-LOG-TEST"));
	LOG4CPLUS_DEBUG(logger, LOG4CPLUS_TEXT("DEBUG-LOG-TEST"));
	LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("INFO-LOG-TEST"));
	LOG4CPLUS_WARN(logger, LOG4CPLUS_TEXT("WARN-LOG-TEST"));
	LOG4CPLUS_ERROR(logger, LOG4CPLUS_TEXT("ERROR-LOG-TEST"));
	LOG4CPLUS_FATAL(logger, LOG4CPLUS_TEXT("FATAL-LOG-TEST"));

        log4cplus::Logger::shutdown();
	return 0;
}

配置文件

log4cplus.logger.TestFileAppender = ALL, Test

# 创建Appender对象
log4cplus.appender.Test = log4cplus::FileAppender

# Appender 类属性
log4cplus.appender.Test.Threshold = ALL

# FileAppenderBase 类属性
log4cplus.appender.Test.File = Test/FileAppenderLog.txt
log4cplus.appender.Test.ImmediateFlush = true
log4cplus.appender.Test.Append = true
log4cplus.appender.Test.ImmediateFlush = false
log4cplus.appender.Test.CreateDirs = true

# FileAppender 类属性
# 空

结果

TRACE - TRACE-LOG-TEST
DEBUG - DEBUG-LOG-TEST
INFO - INFO-LOG-TEST
WARN - WARN-LOG-TEST
ERROR - ERROR-LOG-TEST
FATAL - FATAL-LOG-TEST

 4.6 RollingFileAppender

通过控制每个文件大小以及总文件数量控制日志的量

属性标签描述
MaxFileSize

说明:最大文件大小

类型:long

默认值:10 MB

可选值:不能小于200kb,如果小于200kb会自动调整为200kb。在配置文件中可以带上单位 10KB 10MB,代码中 10*1024  10*1024*1024 。

MaxBackupIndex

说明:最大文件数量

类型:int

默认值:1

可选值:大于零即可

代码

#include <iostream>
#include <log4cplus/ndc.h>
#include <log4cplus/logger.h>
#include <log4cplus/helpers/sleep.h>
#include <log4cplus/helpers/pointer.h>
#include <log4cplus/configurator.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>

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

int main()
{
	log4cplus::initialize();
	log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("config.txt"));
	log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("TestRollingFileAppender"));
	
	for (int i = 0; i < 5000; i++)
	{
		LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("TRACE-LOG-TEST"));
		LOG4CPLUS_DEBUG(logger, LOG4CPLUS_TEXT("DEBUG-LOG-TEST"));
		LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("INFO-LOG-TEST"));
		LOG4CPLUS_WARN(logger, LOG4CPLUS_TEXT("WARN-LOG-TEST"));
		LOG4CPLUS_ERROR(logger, LOG4CPLUS_TEXT("ERROR-LOG-TEST"));
		LOG4CPLUS_FATAL(logger, LOG4CPLUS_TEXT("FATAL-LOG-TEST"));
	}
        log4cplus::Logger::shutdown();
	return 0;
}

配置文件

log4cplus.logger.TestRollingFileAppender = ALL, Test

# 创建Appender对象
log4cplus.appender.Test = log4cplus::RollingFileAppender

# Appender 类属性
log4cplus.appender.Test.Threshold = ALL

# FileAppenderBase 类属性
log4cplus.appender.Test.File = Test/RollingFileAppenderLog.txt
log4cplus.appender.Test.ImmediateFlush = true
log4cplus.appender.Test.Append = true
log4cplus.appender.Test.ImmediateFlush = false
log4cplus.appender.Test.CreateDirs = true

# RollingFileAppender 类属性
log4cplus.appender.Test.MaxFileSize = 1kb
log4cplus.appender.Test.MaxBackupIndex = 3

结果

结果说明

MaxBackupIndex 是指最大的滚动备份数量,备份文件会以“文件名.n”的格式存在。举例MaxBackupIndex=3,则有三个备份文件。注意此处 RollingFileAppenderLog.txt 大小不为0, 备份文件大小最小是200kb。

 4.7 DailyRollingFileAppender

属性标签描述
Schedule

说明:滚动的时间计划以及滚动的日期格式(当DatePattern为空时日期格式有效)

类型:DailyRollingFileSchedule

默认值:DAILY

可选值:MONTHLY  WEEKLY  DAILY   TWICE_DAILY  HOURLY  MINUTELY

MaxBackupIndex

说明:最大文件数量

类型:int

默认值:10

可选值:大于零即可

RollOnClose

说明:在关闭时是否滚动日志文件

类型:bool

默认值:true

可选值:true false

DatePattern

说明:滚动的日期格式,如果该属性不为空,则 Schedule 的日期格式无效,但滚动计划有效。

类型:String

默认值:无

可选值:参考下表“日期时间输出格式转换符”中的内容。例如:%Y-%m-%d

 代码

#include <iostream>
#include <log4cplus/ndc.h>
#include <log4cplus/logger.h>
#include <log4cplus/helpers/sleep.h>
#include <log4cplus/helpers/pointer.h>
#include <log4cplus/configurator.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>

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

int main()
{
	log4cplus::initialize();
	log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("config.txt"));
	log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("TestDailyRollingFileAppender"));
	
	//for (int i = 0; i < 5000; i++)
	{
		LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("TRACE-LOG-TEST"));
		LOG4CPLUS_DEBUG(logger, LOG4CPLUS_TEXT("DEBUG-LOG-TEST"));
		LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("INFO-LOG-TEST"));
		LOG4CPLUS_WARN(logger, LOG4CPLUS_TEXT("WARN-LOG-TEST"));
		LOG4CPLUS_ERROR(logger, LOG4CPLUS_TEXT("ERROR-LOG-TEST"));
		LOG4CPLUS_FATAL(logger, LOG4CPLUS_TEXT("FATAL-LOG-TEST"));
	}
        log4cplus::Logger::shutdown();
	return 0;
}

配置文件

log4cplus.logger.TestDailyRollingFileAppender = ALL, Test

# 创建Appender对象
log4cplus.appender.Test = log4cplus::DailyRollingFileAppender

# Appender 类属性
log4cplus.appender.Test.Threshold = ALL

# FileAppenderBase 类属性
log4cplus.appender.Test.File = Test/DailyRollingFileAppenderLog.txt
log4cplus.appender.Test.ImmediateFlush = true
log4cplus.appender.Test.Append = true
log4cplus.appender.Test.ImmediateFlush = false
log4cplus.appender.Test.CreateDirs = true

# DailyRollingFileAppender 类属性
log4cplus.appender.Test.Schedule = DAILY
log4cplus.appender.Test.MaxBackupIndex = 3
log4cplus.appender.Test.RollOnClose = true
#log4cplus.appender.Test.DatePattern = 3

结果

 结果说明

Schedule 是说明按天生成文件,新文件会以文件名.Schedule 的形式存在。

MaxBackupIndex 同 RollingFileAppender 的 MaxBackupIndex,只不过是按天刷新统计数量。

RollOnClose = true 则在每次关闭程序时 DailyRollingFileAppenderLog.txt 大小为0,区别于 RollingFileAppender 的滚动文件。

DatePattern 自定义滚动文件的日期格式,如果在上面配置文件最后增加 DatePattern  属性,输出文件名会改变。

log4cplus.logger.TestDailyRollingFileAppender = ALL, Test

# 创建Appender对象
log4cplus.appender.Test = log4cplus::DailyRollingFileAppender

# Appender 类属性
log4cplus.appender.Test.Threshold = ALL

# FileAppenderBase 类属性
log4cplus.appender.Test.File = Test/DailyRollingFileAppenderLog.txt
log4cplus.appender.Test.ImmediateFlush = true
log4cplus.appender.Test.Append = true
log4cplus.appender.Test.ImmediateFlush = false
log4cplus.appender.Test.CreateDirs = true

# DailyRollingFileAppender 类属性
log4cplus.appender.Test.Schedule = DAILY
log4cplus.appender.Test.MaxBackupIndex = 3
log4cplus.appender.Test.RollOnClose = true
log4cplus.appender.Test.DatePattern = %Y k %m kk %d.TestDatePattern

注意:需要改变系统时间做测试~

 4.8 TimeBasedRollingFileAppender

属性标签描述
FilenamePattern

说明:自定义文件名

类型:String

默认值:无

可选值:适用格式 %d{...},例如Test/%d{yyyy-MM}/%d{yyyy-MM-dd.log}

MaxHistory

说明:最大历史文件数量

类型:int

默认值:10

可选值:大于零即可

CleanHistoryOnStart

说明:每次运行清空历史文件

类型:bool

默认值:false

可选值:true false

RollOnClose

说明:每次停止程序滚动日志

类型:bool

默认值:true

可选值:true false

源代码调用方式,例如输入MMM,则调用时会识别 char=M,len=3,,然后将MM转换成%b继续格式输出。

...
case LOG4CPLUS_TEXT('M'): // Month in year
    if (len == 2)
        result << LOG4CPLUS_TEXT("%m");
    else if (len == 3)
        result << LOG4CPLUS_TEXT("%b");
    else if (len > 3)
        result << LOG4CPLUS_TEXT("%B");
break;
...

 转换标识符整理,测试时间 2020-04-22  23:40:14。

输出含义格式字符输出结果
yy20
yyyy2020
Week yearYY报错,无此格式
YYYY报错,无此格式
MM04
MMMApr
MMMMApril
今年的第几周ww16
今年的第几天DDD113
这个月的第几天dd22
今天周几EEEWed
EEEEWednesday
Day number of weeku报错,无此格式
AM/PMaaPM
小时(24小时制)HH23
小时(12小时制)hh11
分钟mm40
ss14
Time zone namez报错,无此格式
Time zone offsetZ报错,无此格式

代码

#include <iostream>
#include <log4cplus/ndc.h>
#include <log4cplus/logger.h>
#include <log4cplus/helpers/sleep.h>
#include <log4cplus/helpers/pointer.h>
#include <log4cplus/configurator.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>

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

int main()
{
	log4cplus::initialize();
	log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("config.txt"));
	log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("TestTimeBasedRollingFileAppender"));
	
	//for (int i = 0; i < 5000; i++)
	{
		LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("TRACE-LOG-TEST"));
		LOG4CPLUS_DEBUG(logger, LOG4CPLUS_TEXT("DEBUG-LOG-TEST"));
		LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("INFO-LOG-TEST"));
		LOG4CPLUS_WARN(logger, LOG4CPLUS_TEXT("WARN-LOG-TEST"));
		LOG4CPLUS_ERROR(logger, LOG4CPLUS_TEXT("ERROR-LOG-TEST"));
		LOG4CPLUS_FATAL(logger, LOG4CPLUS_TEXT("FATAL-LOG-TEST"));
	}
        log4cplus::Logger::shutdown();
	return 0;
}

配置文件

log4cplus.logger.TestTimeBasedRollingFileAppender = ALL, Test

# 创建Appender对象
log4cplus.appender.Test = log4cplus::TimeBasedRollingFileAppender

# Appender 类属性
log4cplus.appender.Test.Threshold = ALL

# FileAppenderBase 类属性
log4cplus.appender.Test.File = Test/TimeBasedRollingFileAppenderLog.txt
log4cplus.appender.Test.ImmediateFlush = true
log4cplus.appender.Test.Append = true
log4cplus.appender.Test.ImmediateFlush = false
log4cplus.appender.Test.CreateDirs = true

# TimeBasedRollingFileAppender 类属性
log4cplus.appender.Test.FilenamePattern = Test/%d{yyyy-MM-dd-ss.log}
log4cplus.appender.Test.MaxHistory = 3
log4cplus.appender.Test.CleanHistoryOnStart = false
log4cplus.appender.Test.RollOnClose = true

结果

说明

1. FilenamePattern 这里的格式是套用 %d{yyyy-MM-dd} 的形式,和其他的地方不一样。

2. MaxHistory 配置文件最大的历史数量。需要注意这里的操作逻辑

1)历史文件的检查是在每次程序退出时 void TimeBasedRollingFileAppender::clean(Time time) 函数里进行的

2)历史文件的检查有个时间跨度,默认是天,时间跨度是根据设定的 FilenamePattern 来统计的

3)计算时间跨度的起止时间是程序刚开始运行的时间和退出的时间。也就是说,如果每天将程序运行一次(一次10秒钟),则生成一个年-月-日.log的日志文件,连续运行一个月,也不会清理历史文件,即使文件数量超过了设定值3个。因为每次程序运行的时间跨度是10秒钟,小于一天,程序认为没到清理的时候是不会清理历史文件的,只有在程序连续运行超过一天推出时才会清理历史文件

4)RollOnClose 默认为true。程序运行时会将所有的日志文件写到 File 属性定义的文件里,在程序关闭时再将所有文件复制到 FilenamePattern 属性定义的文件里。注意,如果此时已经有个同名的 FilenamePattern 文件,会覆盖旧文件,并不是像通常理解的 追加写入,也就是说 Append 追加写入属性是在  File 属性定义的文件中完成的,在 FilenamePattern 文件的处理上是单纯的覆盖,而不是追加写入。这里可以可以将 FilenamePattern 属性定义到秒,规避同名文件来实现不覆盖历史日志。

 4.9 SocketAppender

属性标签描述
host

说明:主机IP

类型:String

默认值:无

可选值:localhost IP地址

port

说明:端口号

类型:unsigned int

默认值:9998

可选值:端口号合法值即可

ServerName

说明:服务端名称

类型:String

默认值:无

可选值:字符串即可

客户端

代码

#include <iostream>
#include <log4cplus/ndc.h>
#include <log4cplus/logger.h>
#include <log4cplus/helpers/sleep.h>
#include <log4cplus/helpers/pointer.h>
#include <log4cplus/configurator.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>

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

int main()
{
	log4cplus::initialize();
	log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("client_config"));
	log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("ClientLog"));
	for (int i = 0; i < 10; i++)
	{
		LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("TRACE-LOG-TEST ") << i);
	}
	log4cplus::Logger::shutdown();
	return 0;
}

配置文件

log4cplus.logger.ClientLog = ALL, RemoteServer

log4cplus.appender.RemoteServer=log4cplus::SocketAppender
log4cplus.appender.RemoteServer.host=localhost
log4cplus.appender.RemoteServer.port=9000
log4cplus.appender.RemoteServer.ServerName=ThisIsServerName

服务端

代码

#include <cstdlib>
#include <iostream>
#include <log4cplus/configurator.h>
#include <log4cplus/socketappender.h>
#include <log4cplus/helpers/socket.h>
#include <log4cplus/thread/threads.h>
#include <log4cplus/spi/loggingevent.h>
#include <log4cplus\helpers\pointer.h>

namespace loggingserver
{

	class ClientThread : public log4cplus::thread::AbstractThread
	{
	public:
		ClientThread(log4cplus::helpers::Socket clientsock)
			: clientsock(clientsock)
		{
			std::cout << "Received a client connection!!!!" << std::endl;
		}

		~ClientThread()
		{
			std::cout << "Client connection closed." << std::endl;
		}

		virtual void run();

	private:
		log4cplus::helpers::Socket clientsock;
	};


	void
	ClientThread::run()
	{
			while (1) {
				if (!clientsock.isOpen()) {
					return;
				}
				log4cplus::helpers::SocketBuffer msgSizeBuffer(sizeof(unsigned int));
				if (!clientsock.read(msgSizeBuffer)) {
					return;
				}

				unsigned int msgSize = msgSizeBuffer.readInt();

				log4cplus::helpers::SocketBuffer buffer(msgSize);
				if (!clientsock.read(buffer)) {
					return;
				}

				log4cplus::spi::InternalLoggingEvent event
					= log4cplus::helpers::readFromBuffer(buffer);
				
				log4cplus::tstring strLoggerName = event.getLoggerName();// strLoggerName = ClientLog
				log4cplus::tstring strLoggerNDC = event.getNDC();// strLoggerNDC = ThisIsServerName

				log4cplus::Logger logger
					= log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("SetverLog"));
				logger.callAppenders(event);
			}
		}

}



int
main(int argc, char** argv)
{
	int port = 9000;
	log4cplus::PropertyConfigurator config(LOG4CPLUS_C_STR_TO_TSTRING("server_config"));
	config.configure();

	log4cplus::helpers::ServerSocket serverSocket(port);
	if (!serverSocket.isOpen()) {
		std::cout << "Could not open server socket, maybe port "
			<< port << " is already in use." << std::endl;
		return 2;
	}

	while (1) {
		loggingserver::ClientThread *thr =
			new loggingserver::ClientThread(serverSocket.accept());
		thr->start();
	}

	return 0;
}

配置文件

log4cplus.logger.SetverLog = ALL, FileOut

log4cplus.appender.FileOut = log4cplus::FileAppender
log4cplus.appender.FileOut.File = D:\\FileAppenderLog.txt
log4cplus.appender.FileOut.ImmediateFlush = true
log4cplus.appender.FileOut.Append = true
log4cplus.appender.FileOut.ImmediateFlush = true
log4cplus.appender.FileOut.CreateDirs = true

输出

TRACE - TRACE-LOG-TEST 0
TRACE - TRACE-LOG-TEST 1
TRACE - TRACE-LOG-TEST 2
TRACE - TRACE-LOG-TEST 3
TRACE - TRACE-LOG-TEST 4
TRACE - TRACE-LOG-TEST 5
TRACE - TRACE-LOG-TEST 6
TRACE - TRACE-LOG-TEST 7
TRACE - TRACE-LOG-TEST 8
TRACE - TRACE-LOG-TEST 9

4.10 AsyncAppender

官方介绍它不是一个可以作为流输出的具体类,而是一个用于多线程时控制日志有序输出的一个类。

属性标签描述
Appender

说明:输出对象

类型:Appender

默认值:无

可选值:ConsoleAppender  FileAppender  RollingFileAppender  

              DailyRollingFileAppender  TimeBasedRollingFileAppender  SocketAppender

QueueLimit

说明:队列大小

类型:unsigned int

默认值:100

可选值:0 ~ Max Unsign Int

 代码

#include <log4cplus/consoleappender.h>
#include <log4cplus/layout.h>
#include <log4cplus/logger.h>
#include <log4cplus/ndc.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/thread/threads.h>
#include <log4cplus/helpers/sleep.h>
#include <log4cplus/streams.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/tracelogger.h>
#include <exception>
#include <iostream>
#include <string>
#include <log4cplus/configurator.h>

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


#define MILLIS_TO_NANOS 1000
#define NUM_THREADS 4
#define NUM_LOOPS 10

class SlowObject {
public:
	SlowObject()
		: logger(Logger::getInstance(LOG4CPLUS_TEXT("TestAsyncAppender")))
	{
		LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("Init SlowObject"));
	}

	void doSomething()
	{
		LOG4CPLUS_TRACE_METHOD(logger, LOG4CPLUS_TEXT("In SlowObject::doSomething()"));

		{
			// 并没有测试出这个互斥有什么作用
			log4cplus::thread::MutexGuard guard(mutex);

			sleep(0, 75 * MILLIS_TO_NANOS);
			LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("Actually doing 111111111..."));
			LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("Actually doing 222222222..."));
			LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("Actually doing 333333333..."));
			LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("Actually doing 444444444..."));
		}
		log4cplus::thread::yield();
	}

	~SlowObject()
	{
		LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("Out SlowObject"));
	}

private:
	log4cplus::thread::Mutex mutex;
	Logger logger;
};


class TestThread : public AbstractThread {
public:
	TestThread(tstring const & n, SlowObject * so)
		: name(n)
		, slow(so)
		, logger(Logger::getInstance(LOG4CPLUS_TEXT("TestAsyncAppender")))
	{ }

	virtual void run();

private:
	tstring name;
	SlowObject * slow;
	Logger logger;
};


int
main()
{
	log4cplus::initialize();
	log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("config.txt"));
	try
	{
		auto_ptr<SlowObject> slowObject(new SlowObject());
		Logger logger = Logger::getInstance(LOG4CPLUS_TEXT("TestAsyncAppender"));

		log4cplus::helpers::SharedObjectPtr<TestThread> threads[NUM_THREADS];
		int i = 0;
		for (i = 0; i<NUM_THREADS; ++i) {
			tostringstream s;
			s << "Thread-" << i;
			threads[i] = new TestThread(s.str(), slowObject.get());
		}

		for (i = 0; i<NUM_THREADS; ++i) {
			threads[i]->start();
		}
		LOG4CPLUS_DEBUG(logger, "All Threads started...");

		for (i = 0; i<NUM_THREADS; ++i) {
			while (threads[i]->isRunning()) {
				sleep(0, 200 * MILLIS_TO_NANOS);
			}
		}
		LOG4CPLUS_INFO(logger, "Exiting main()...");
	}
	catch (std::exception &e) {
		LOG4CPLUS_FATAL(Logger::getRoot(), "main()- Exception occured: " << e.what());
	}
	catch (...) {
		LOG4CPLUS_FATAL(Logger::getRoot(), "main()- Exception occured");
	}


	log4cplus::Logger::shutdown();
	return 0;
}


void
TestThread::run()
{
	try {
		LOG4CPLUS_WARN(logger, name + LOG4CPLUS_TEXT(" TestThread.run()- Starting..."));

		NDC& ndc = getNDC();
		NDCContextCreator _first_ndc(name);

		LOG4CPLUS_DEBUG(logger, "Entering Run()...");
		for (int i = 0; i<NUM_LOOPS; ++i) {
			NDCContextCreator _ndc(LOG4CPLUS_TEXT("loop"));
			slow->doSomething();
		}

		LOG4CPLUS_DEBUG(logger, "Exiting run()...");

		ndc.remove();
	}
	catch (std::exception const & e) {
		LOG4CPLUS_FATAL(logger, "TestThread.run()- Exception occurred: " << e.what());
	}
	catch (...) {
		LOG4CPLUS_FATAL(logger, "TestThread.run()- Exception occurred!!");
	}
	LOG4CPLUS_WARN(logger, name << " TestThread.run()- Finished");
} // end "run"

配置文件

log4cplus.logger.TestAsyncAppender = ALL, Test

# 创建Appender对象
log4cplus.appender.Test = log4cplus::AsyncAppender

# AsyncAppender 类属性
log4cplus.appender.Test.QueueLimit = 1000
log4cplus.appender.Test.Appender = log4cplus::FileAppender

# FileAppender 类属性
log4cplus.appender.Test.Appender.Threshold = ALL
log4cplus.appender.Test.Appender.File = Test/FileAppenderLog.txt
log4cplus.appender.Test.Appender.ImmediateFlush = false
log4cplus.appender.Test.Appender.BufferSize = 1024
log4cplus.appender.Test.Appender.CreateDirs = true
log4cplus.appender.Test.Appender.Append = false
log4cplus.appender.Test.Appender.layout = log4cplus::TTCCLayout

结果

71 [6608] INFO TestAsyncAppender <> - Init SlowObject
73 [10984] WARN TestAsyncAppender <> - Thread-0 TestThread.run()- Starting...
73 [6608] DEBUG TestAsyncAppender <> - All Threads started...
74 [3936] WARN TestAsyncAppender <> - Thread-1 TestThread.run()- Starting...
75 [10984] DEBUG TestAsyncAppender <Thread-0> - Entering Run()...
75 [3928] WARN TestAsyncAppender <> - Thread-3 TestThread.run()- Starting...
74 [4160] WARN TestAsyncAppender <> - Thread-2 TestThread.run()- Starting...
75 [3936] DEBUG TestAsyncAppender <Thread-1> - Entering Run()...
75 [10984] TRACE TestAsyncAppender <Thread-0 loop> - ENTER: In SlowObject::doSomething()
76 [3928] DEBUG TestAsyncAppender <Thread-3> - Entering Run()...
76 [4160] DEBUG TestAsyncAppender <Thread-2> - Entering Run()...
76 [3936] TRACE TestAsyncAppender <Thread-1 loop> - ENTER: In SlowObject::doSomething()
76 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 111111111...
76 [3928] TRACE TestAsyncAppender <Thread-3 loop> - ENTER: In SlowObject::doSomething()
76 [4160] TRACE TestAsyncAppender <Thread-2 loop> - ENTER: In SlowObject::doSomething()
76 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 222222222...
77 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 333333333...
77 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 444444444...
77 [10984] TRACE TestAsyncAppender <Thread-0 loop> - EXIT:  In SlowObject::doSomething()
77 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 111111111...
77 [10984] TRACE TestAsyncAppender <Thread-0 loop> - ENTER: In SlowObject::doSomething()
77 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 222222222...
78 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 333333333...
78 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 444444444...
78 [3936] TRACE TestAsyncAppender <Thread-1 loop> - EXIT:  In SlowObject::doSomething()
78 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 111111111...
78 [3936] TRACE TestAsyncAppender <Thread-1 loop> - ENTER: In SlowObject::doSomething()
78 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 222222222...
78 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 333333333...
79 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 444444444...
79 [3928] TRACE TestAsyncAppender <Thread-3 loop> - EXIT:  In SlowObject::doSomething()
79 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 111111111...
79 [3928] TRACE TestAsyncAppender <Thread-3 loop> - ENTER: In SlowObject::doSomething()
79 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 222222222...
79 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 333333333...
79 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 444444444...
80 [4160] TRACE TestAsyncAppender <Thread-2 loop> - EXIT:  In SlowObject::doSomething()
80 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 111111111...
80 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 222222222...
80 [4160] TRACE TestAsyncAppender <Thread-2 loop> - ENTER: In SlowObject::doSomething()
80 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 333333333...
80 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 444444444...
80 [10984] TRACE TestAsyncAppender <Thread-0 loop> - EXIT:  In SlowObject::doSomething()
80 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 111111111...
81 [10984] TRACE TestAsyncAppender <Thread-0 loop> - ENTER: In SlowObject::doSomething()
81 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 222222222...
81 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 333333333...
81 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 444444444...
81 [3936] TRACE TestAsyncAppender <Thread-1 loop> - EXIT:  In SlowObject::doSomething()
81 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 111111111...
82 [3936] TRACE TestAsyncAppender <Thread-1 loop> - ENTER: In SlowObject::doSomething()
82 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 222222222...
82 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 333333333...
82 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 444444444...
82 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 111111111...
82 [3928] TRACE TestAsyncAppender <Thread-3 loop> - EXIT:  In SlowObject::doSomething()
82 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 222222222...
83 [3928] TRACE TestAsyncAppender <Thread-3 loop> - ENTER: In SlowObject::doSomething()
83 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 333333333...
83 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 444444444...
83 [4160] TRACE TestAsyncAppender <Thread-2 loop> - EXIT:  In SlowObject::doSomething()
83 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 111111111...
83 [4160] TRACE TestAsyncAppender <Thread-2 loop> - ENTER: In SlowObject::doSomething()
83 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 222222222...
84 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 333333333...
84 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 444444444...
84 [10984] TRACE TestAsyncAppender <Thread-0 loop> - EXIT:  In SlowObject::doSomething()
84 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 111111111...
84 [10984] TRACE TestAsyncAppender <Thread-0 loop> - ENTER: In SlowObject::doSomething()
84 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 222222222...
85 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 333333333...
85 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 444444444...
85 [3936] TRACE TestAsyncAppender <Thread-1 loop> - EXIT:  In SlowObject::doSomething()
85 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 111111111...
85 [3936] TRACE TestAsyncAppender <Thread-1 loop> - ENTER: In SlowObject::doSomething()
85 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 222222222...
85 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 333333333...
86 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 444444444...
86 [3928] TRACE TestAsyncAppender <Thread-3 loop> - EXIT:  In SlowObject::doSomething()
86 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 111111111...
86 [3928] TRACE TestAsyncAppender <Thread-3 loop> - ENTER: In SlowObject::doSomething()
86 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 222222222...
86 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 333333333...
87 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 444444444...
87 [4160] TRACE TestAsyncAppender <Thread-2 loop> - EXIT:  In SlowObject::doSomething()
87 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 111111111...
87 [4160] TRACE TestAsyncAppender <Thread-2 loop> - ENTER: In SlowObject::doSomething()
87 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 222222222...
87 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 333333333...
87 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 444444444...
88 [10984] TRACE TestAsyncAppender <Thread-0 loop> - EXIT:  In SlowObject::doSomething()
88 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 111111111...
88 [10984] TRACE TestAsyncAppender <Thread-0 loop> - ENTER: In SlowObject::doSomething()
88 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 222222222...
88 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 333333333...
88 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 444444444...
88 [3936] TRACE TestAsyncAppender <Thread-1 loop> - EXIT:  In SlowObject::doSomething()
88 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 111111111...
89 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 222222222...
89 [3936] TRACE TestAsyncAppender <Thread-1 loop> - ENTER: In SlowObject::doSomething()
89 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 333333333...
89 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 444444444...
89 [3928] TRACE TestAsyncAppender <Thread-3 loop> - EXIT:  In SlowObject::doSomething()
89 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 111111111...
89 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 222222222...
89 [3928] TRACE TestAsyncAppender <Thread-3 loop> - ENTER: In SlowObject::doSomething()
90 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 333333333...
90 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 444444444...
90 [4160] TRACE TestAsyncAppender <Thread-2 loop> - EXIT:  In SlowObject::doSomething()
90 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 111111111...
90 [4160] TRACE TestAsyncAppender <Thread-2 loop> - ENTER: In SlowObject::doSomething()
90 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 222222222...
91 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 333333333...
91 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 444444444...
91 [10984] TRACE TestAsyncAppender <Thread-0 loop> - EXIT:  In SlowObject::doSomething()
91 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 111111111...
91 [10984] TRACE TestAsyncAppender <Thread-0 loop> - ENTER: In SlowObject::doSomething()
91 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 222222222...
91 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 333333333...
92 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 444444444...
92 [3936] TRACE TestAsyncAppender <Thread-1 loop> - EXIT:  In SlowObject::doSomething()
92 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 111111111...
92 [3936] TRACE TestAsyncAppender <Thread-1 loop> - ENTER: In SlowObject::doSomething()
92 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 222222222...
92 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 333333333...
92 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 444444444...
93 [3928] TRACE TestAsyncAppender <Thread-3 loop> - EXIT:  In SlowObject::doSomething()
93 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 111111111...
93 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 222222222...
93 [3928] TRACE TestAsyncAppender <Thread-3 loop> - ENTER: In SlowObject::doSomething()
93 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 333333333...
93 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 444444444...
93 [4160] TRACE TestAsyncAppender <Thread-2 loop> - EXIT:  In SlowObject::doSomething()
93 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 111111111...
94 [4160] TRACE TestAsyncAppender <Thread-2 loop> - ENTER: In SlowObject::doSomething()
94 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 222222222...
94 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 333333333...
94 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 444444444...
94 [10984] TRACE TestAsyncAppender <Thread-0 loop> - EXIT:  In SlowObject::doSomething()
94 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 111111111...
95 [10984] TRACE TestAsyncAppender <Thread-0 loop> - ENTER: In SlowObject::doSomething()
95 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 222222222...
95 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 333333333...
95 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 444444444...
95 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 111111111...
95 [3936] TRACE TestAsyncAppender <Thread-1 loop> - EXIT:  In SlowObject::doSomething()
95 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 222222222...
95 [3936] TRACE TestAsyncAppender <Thread-1 loop> - ENTER: In SlowObject::doSomething()
96 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 333333333...
96 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 444444444...
96 [3928] TRACE TestAsyncAppender <Thread-3 loop> - EXIT:  In SlowObject::doSomething()
96 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 111111111...
96 [3928] TRACE TestAsyncAppender <Thread-3 loop> - ENTER: In SlowObject::doSomething()
96 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 222222222...
96 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 333333333...
96 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 444444444...
97 [4160] TRACE TestAsyncAppender <Thread-2 loop> - EXIT:  In SlowObject::doSomething()
97 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 111111111...
97 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 222222222...
97 [4160] TRACE TestAsyncAppender <Thread-2 loop> - ENTER: In SlowObject::doSomething()
97 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 333333333...
97 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 444444444...
97 [10984] TRACE TestAsyncAppender <Thread-0 loop> - EXIT:  In SlowObject::doSomething()
97 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 111111111...
98 [10984] TRACE TestAsyncAppender <Thread-0 loop> - ENTER: In SlowObject::doSomething()
98 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 222222222...
98 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 333333333...
98 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 444444444...
98 [3936] TRACE TestAsyncAppender <Thread-1 loop> - EXIT:  In SlowObject::doSomething()
98 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 111111111...
98 [3936] TRACE TestAsyncAppender <Thread-1 loop> - ENTER: In SlowObject::doSomething()
98 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 222222222...
99 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 333333333...
99 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 444444444...
99 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 111111111...
99 [3928] TRACE TestAsyncAppender <Thread-3 loop> - EXIT:  In SlowObject::doSomething()
99 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 222222222...
99 [3928] TRACE TestAsyncAppender <Thread-3 loop> - ENTER: In SlowObject::doSomething()
99 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 333333333...
100 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 444444444...
100 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 111111111...
100 [4160] TRACE TestAsyncAppender <Thread-2 loop> - EXIT:  In SlowObject::doSomething()
100 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 222222222...
100 [4160] TRACE TestAsyncAppender <Thread-2 loop> - ENTER: In SlowObject::doSomething()
100 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 333333333...
100 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 444444444...
101 [10984] TRACE TestAsyncAppender <Thread-0 loop> - EXIT:  In SlowObject::doSomething()
101 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 111111111...
101 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 222222222...
101 [10984] TRACE TestAsyncAppender <Thread-0 loop> - ENTER: In SlowObject::doSomething()
101 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 333333333...
101 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 444444444...
101 [3936] TRACE TestAsyncAppender <Thread-1 loop> - EXIT:  In SlowObject::doSomething()
101 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 111111111...
102 [3936] TRACE TestAsyncAppender <Thread-1 loop> - ENTER: In SlowObject::doSomething()
102 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 222222222...
102 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 333333333...
102 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 444444444...
102 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 111111111...
102 [3928] TRACE TestAsyncAppender <Thread-3 loop> - EXIT:  In SlowObject::doSomething()
102 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 222222222...
102 [3928] TRACE TestAsyncAppender <Thread-3 loop> - ENTER: In SlowObject::doSomething()
103 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 333333333...
103 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 444444444...
103 [4160] TRACE TestAsyncAppender <Thread-2 loop> - EXIT:  In SlowObject::doSomething()
103 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 111111111...
103 [4160] TRACE TestAsyncAppender <Thread-2 loop> - ENTER: In SlowObject::doSomething()
103 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 222222222...
103 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 333333333...
104 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 444444444...
104 [10984] TRACE TestAsyncAppender <Thread-0 loop> - EXIT:  In SlowObject::doSomething()
104 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 111111111...
104 [10984] TRACE TestAsyncAppender <Thread-0 loop> - ENTER: In SlowObject::doSomething()
104 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 222222222...
104 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 333333333...
104 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 444444444...
105 [3936] TRACE TestAsyncAppender <Thread-1 loop> - EXIT:  In SlowObject::doSomething()
105 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 111111111...
105 [3936] TRACE TestAsyncAppender <Thread-1 loop> - ENTER: In SlowObject::doSomething()
105 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 222222222...
105 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 333333333...
105 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 444444444...
105 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 111111111...
105 [3928] TRACE TestAsyncAppender <Thread-3 loop> - EXIT:  In SlowObject::doSomething()
106 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 222222222...
106 [3928] TRACE TestAsyncAppender <Thread-3 loop> - ENTER: In SlowObject::doSomething()
106 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 333333333...
106 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 444444444...
106 [4160] TRACE TestAsyncAppender <Thread-2 loop> - EXIT:  In SlowObject::doSomething()
106 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 111111111...
106 [4160] TRACE TestAsyncAppender <Thread-2 loop> - ENTER: In SlowObject::doSomething()
106 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 222222222...
107 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 333333333...
107 [10984] INFO TestAsyncAppender <Thread-0 loop> - Actually doing 444444444...
107 [10984] TRACE TestAsyncAppender <Thread-0 loop> - EXIT:  In SlowObject::doSomething()
107 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 111111111...
107 [10984] DEBUG TestAsyncAppender <Thread-0> - Exiting run()...
107 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 222222222...
107 [10984] WARN TestAsyncAppender <> - Thread-0 TestThread.run()- Finished
108 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 333333333...
108 [3936] INFO TestAsyncAppender <Thread-1 loop> - Actually doing 444444444...
109 [3936] TRACE TestAsyncAppender <Thread-1 loop> - EXIT:  In SlowObject::doSomething()
109 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 111111111...
109 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 222222222...
109 [3936] DEBUG TestAsyncAppender <Thread-1> - Exiting run()...
109 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 333333333...
109 [3936] WARN TestAsyncAppender <> - Thread-1 TestThread.run()- Finished
109 [3928] INFO TestAsyncAppender <Thread-3 loop> - Actually doing 444444444...
110 [3928] TRACE TestAsyncAppender <Thread-3 loop> - EXIT:  In SlowObject::doSomething()
110 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 111111111...
110 [3928] DEBUG TestAsyncAppender <Thread-3> - Exiting run()...
110 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 222222222...
110 [3928] WARN TestAsyncAppender <> - Thread-3 TestThread.run()- Finished
110 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 333333333...
111 [4160] INFO TestAsyncAppender <Thread-2 loop> - Actually doing 444444444...
111 [4160] TRACE TestAsyncAppender <Thread-2 loop> - EXIT:  In SlowObject::doSomething()
111 [4160] DEBUG TestAsyncAppender <Thread-2> - Exiting run()...
111 [4160] WARN TestAsyncAppender <> - Thread-2 TestThread.run()- Finished
112 [6608] INFO TestAsyncAppender <> - Exiting main()...
112 [6608] INFO TestAsyncAppender <> - Out SlowObject

5 layout

log4cplus提供了三种类型的Layouts,分别是SimpleLayout、PatternLayout、和TTCCLayout。

5.1 SimpleLayout

代码

#include <iostream>
#include <log4cplus\ndc.h>
#include <log4cplus/logger.h>
#include <log4cplus\helpers\sleep.h>
#include <log4cplus\helpers\pointer.h>
#include <log4cplus/configurator.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>

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

int main()
{
	log4cplus::initialize();
	log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("SimpleLayout.txt"));
	log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("TestSimpleLayout"));
	
	NDCContextCreator _first_ndc(LOG4CPLUS_TEXT("This-is-Thread-Name"));

	LOG4CPLUS_DEBUG(logger, LOG4CPLUS_TEXT("DEBUG-LOG-TEST"));
	LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("INFO-LOG-TEST"));
	LOG4CPLUS_WARN(logger, LOG4CPLUS_TEXT("WARN-LOG-TEST"));
	LOG4CPLUS_ERROR(logger, LOG4CPLUS_TEXT("ERROR-LOG-TEST"));

        log4cplus::Logger::shutdown();
	return 0;
}

配置文件

log4cplus.logger.TestSimpleLayout = ALL, Test
log4cplus.appender.Test = log4cplus::FileAppender
log4cplus.appender.Test.File = Test.log
log4cplus.appender.Test.layout = log4cplus::SimpleLayout

输出结果

DEBUG - DEBUG-LOG-TEST
INFO - INFO-LOG-TEST
WARN - WARN-LOG-TEST
ERROR - ERROR-LOG-TEST

5.2 TTCCLayout

属性标签描述
DateFormat

说明:自定义文件名(可忽略)

类型:String

默认值:无

可选值:参考下表“日期时间输出格式转换符”中的内容。例如:%Y-%m-%d-%H-%M

Use_gmtime

说明:使用哪种类型时间

类型:bool

默认值:false

可选值:true=gmtime false=localtime

ThreadPrinting

说明:是否打印线程ID号

类型:bool

默认值:true

可选值:true false

CategoryPrefixing

说明:是否打印Logger名称

类型:bool

默认值:true

可选值:true false

ContextPrinting

说明:是否打印NDC信息

类型:bool

默认值:true

可选值:true false

代码

#include <iostream>
#include <log4cplus\ndc.h>
#include <log4cplus/logger.h>
#include <log4cplus\helpers\sleep.h>
#include <log4cplus\helpers\pointer.h>
#include <log4cplus/configurator.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>

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

int main()
{
	log4cplus::initialize();
	log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("TTCCLayout.txt"));
	log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("TestTTCCLayout"));	

	NDCContextCreator _first_ndc(LOG4CPLUS_TEXT("This-is-Thread-Name"));

	LOG4CPLUS_DEBUG(logger, LOG4CPLUS_TEXT("DEBUG-LOG-TEST"));
	LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("INFO-LOG-TEST"));
	LOG4CPLUS_WARN(logger, LOG4CPLUS_TEXT("WARN-LOG-TEST"));
	LOG4CPLUS_ERROR(logger, LOG4CPLUS_TEXT("ERROR-LOG-TEST"));

        log4cplus::Logger::shutdown();
	return 0;
}

配置文件

log4cplus.logger.TestTTCCLayout = ALL, Test
log4cplus.appender.Test = log4cplus::FileAppender
log4cplus.appender.Test.File = Test.log
log4cplus.appender.Test.layout = log4cplus::TTCCLayout
log4cplus.appender.Test.layout.DateFormat = %Y-%m@%d

输出结果

格式:时间  线程ID  Logger名称  线程名称  日志内容

2020-04@19 [8844] DEBUG TestSimpleLayout <This-is-Thread-Name> - DEBUG-LOG-TEST
2020-04@19 [8844] INFO TestSimpleLayout <This-is-Thread-Name> - INFO-LOG-TEST
2020-04@19 [8844] WARN TestSimpleLayout <This-is-Thread-Name> - WARN-LOG-TEST
2020-04@19 [8844] ERROR TestSimpleLayout <This-is-Thread-Name> - ERROR-LOG-TEST

5.3  PatternLayout

属性标签描述
NDCMaxDepth

说明:最大NDC输出深度

类型:unsigned int

默认值:0

可选值:0~ Max Unsigned Int

ConversionPattern

说明:格式化日志输出字符串

类型:string

默认值:无

可选值:参考 “日志输出基本转换标识符" 表和 “日期时间输出格式转换符” 表

代码

#include <iostream>
#include <log4cplus\ndc.h>
#include <log4cplus/logger.h>
#include <log4cplus\helpers\sleep.h>
#include <log4cplus\helpers\pointer.h>
#include <log4cplus/configurator.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>

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

int main()
{
	log4cplus::initialize();
	log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("PatternLayout.txt"));
	log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("TestPatternLayout"));

	NDCContextCreator _first_ndc(LOG4CPLUS_TEXT("This-is-Thread-Name"));

	LOG4CPLUS_DEBUG(logger, LOG4CPLUS_TEXT("DEBUG-LOG-TEST"));
	LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("INFO-LOG-TEST"));
	LOG4CPLUS_WARN(logger, LOG4CPLUS_TEXT("WARN-LOG-TEST"));
	LOG4CPLUS_ERROR(logger, LOG4CPLUS_TEXT("ERROR-LOG-TEST"));
        
        log4cplus::Logger::shutdown();
	return 0;
}

配置文件

log4cplus.logger.TestPatternLayout = ALL, Test

# 创建Appender对象
log4cplus.appender.Test = log4cplus::FileAppender
log4cplus.appender.Test.File = Test/FileAppenderLog.txt
log4cplus.appender.Test.ImmediateFlush = true
log4cplus.appender.Test.Append = true
log4cplus.appender.Test.ImmediateFlush = false
log4cplus.appender.Test.CreateDirs = true

# layout类属性
log4cplus.appender.Test.layout = log4cplus::PatternLayout
log4cplus.appender.Test.layout.NDCMaxDepth = 5
log4cplus.appender.Test.layout.ConversionPattern = %d{%Y-%m-%d} %F-%L-%M <%x> %m %n

结果 

2020-04-27 ..\..\tests\appender_test\main.cxx-23-int __cdecl main(void) <This-is-Thread-Name> DEBUG-LOG-TEST 
2020-04-27 ..\..\tests\appender_test\main.cxx-24-int __cdecl main(void) <This-is-Thread-Name> INFO-LOG-TEST 
2020-04-27 ..\..\tests\appender_test\main.cxx-25-int __cdecl main(void) <This-is-Thread-Name> WARN-LOG-TEST 
2020-04-27 ..\..\tests\appender_test\main.cxx-26-int __cdecl main(void) <This-is-Thread-Name> ERROR-LOG-TEST 

5.4 转换标识符 

日志输出基本转换标识符
符号含义
%%转义为%, 即,std::string pattern = "%%" 时输出"%"则
%c输出logger名称,比如std::string pattern ="%c" 时输出: "test_logger.subtest",也可以控制logger名称的显示层次,比如"%c{1}"时输出"test_logger",其中数字表示层次。
%D显示本地时间,当std::string pattern ="%D" 时输出:"2004-10-16 18:55:45"
%d显示标准时间,所以当std::string pattern ="%d" 时输出"2004-10-16 10:55:45" (因为北京时间位于东8区,差8个小时)。可以通过%d{...}定义更详细的显示格式,比如%d{%H:%M:%s}表示要显示小时:分钟:秒。详见下表
%F输出当前记录器所在的文件名称,比如std::string pattern ="%F" 时输出: "main.cpp"。
%L输出当前记录器所在的文件行号,比如std::string pattern ="%L" 时输出: "51"
%l输出当前记录器所在的文件名称和行号,比如std::string pattern ="%l" 时输出"main.cpp:51"。
%m输出原始信息,比如std::string pattern ="%m" 时输出: "teststr",即上述代码中LOG4CPLUS_DEBUG的第二个参数,这种实现机制可以确保原始信息被嵌入到带格式的信息中。
%M输出函数名,比如std::string pattern ="%M" 时输出: "int __cdecl main(void)"
%n换行符,没什么好解释的。
%p输出LogLevel,比如std::string pattern ="%p" 时输出: "DEBUG"。
%t输出记录器所在的线程ID,比如std::string pattern ="%t" 时输出: "1075298944"。
%x嵌套诊断上下文NDC (nested diagnostic context) 输出,从堆栈中弹出上下文信息,NDC可以用对不同源的log信息(同时地)交叉输出进行区分,关于NDC方面的详细介绍会在下文中提到。
格式对齐比如std::string pattern ="%-10m"时表示左对齐,宽度是10,此时会输出"teststr  ",当然其它的控制字符也可以相同的方式来使用,比如"%-12d","%-5p"等等。

 

关于日期时间输出的转换标志符可用在三个地方

1、DailyRollingFileAppender 中的 DatePattern,格式为 %Y-%m-%d

2、TTCCLayout 中的 DateFormat,格式为 %Y-%m-%d

3、PatternLayout 中的 ConversionPattern,格式为 %d{%Y-%m-%d}

日期时间输出格式转换符
%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"

 

6 filter

6.1 继承关系

Appender可以附加Filter组成的链表,如果Filter链中存在过滤器Filter, log4cplus在输出日志之前将调用链表中Filter的过滤方法decide(),根据该方法的返回值决定是否过滤该输出日志。

DENY, 拒绝
NEUTRAL, 暂不处理
ACCEPT, 接受

过滤条件处理机制类似于LinuxIPTABLEResponsibility 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信息。 

6.2 LogLevelMatchFilter

根据特定的日志级别进行过滤,只有当日志的LogLevel值与LogLevelToMatch相同,且AcceptOnMatch为true时才会匹配。

属性标签描述
LogLevelToMatch

说明:匹配的日志等级

类型:LogLevel

默认值:NOT_SET_LOG_LEVEL

可选值:所有日志等级 LogLevel

AcceptOnMatch

说明:是否启动该规则

类型:bool

默认值:true

可选值:true  false

代码

#include <iostream>
#include <log4cplus\ndc.h>
#include <log4cplus/logger.h>
#include <log4cplus\helpers\sleep.h>
#include <log4cplus\helpers\pointer.h>
#include <log4cplus/configurator.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>

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

int main()
{
	log4cplus::initialize();
	log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("Filter.txt"));
	log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("TestFilter"));

	//NDCContextCreator _first_ndc(LOG4CPLUS_TEXT("This-is-Thread-Name"));

	LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("TRACE-LOG-TEST"));
	LOG4CPLUS_DEBUG(logger, LOG4CPLUS_TEXT("DEBUG-LOG-TEST"));
	LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("INFO-LOG-TEST"));
	LOG4CPLUS_WARN(logger, LOG4CPLUS_TEXT("WARN-LOG-TEST"));
	LOG4CPLUS_ERROR(logger, LOG4CPLUS_TEXT("ERROR-LOG-TEST"));
	LOG4CPLUS_FATAL(logger, LOG4CPLUS_TEXT("FATAL-LOG-TEST"));

        log4cplus::Logger::shutdown();
	return 0;
}

配置文件

log4cplus.logger.TestFilter = ALL, Test

# 创建Appender对象
log4cplus.appender.Test = log4cplus::FileAppender
log4cplus.appender.Test.File = Test/FileAppenderLog.txt
log4cplus.appender.Test.ImmediateFlush = true
log4cplus.appender.Test.Append = false
log4cplus.appender.Test.ImmediateFlush = false
log4cplus.appender.Test.CreateDirs = true

# Layout类属性
log4cplus.appender.Test.layout = log4cplus::SimpleLayout

# Filter属性
log4cplus.appender.Test.filters.1 = log4cplus::spi::LogLevelMatchFilter
log4cplus.appender.Test.filters.1.LogLevelToMatch = TRACE
log4cplus.appender.Test.filters.1.AcceptOnMatch = true
log4cplus.appender.Test.filters.2 = log4cplus::spi::DenyAllFilter

结果

TRACE - TRACE-LOG-TEST

6.3 LogLevelRangeFilter

根据根据日志级别的范围进行过滤,只有当日志的LogLevel在LogLevelMin、LogLevelMax之间同时AcceptOnMatch为true时才会匹配。

属性标签描述
LogLevelMin

说明:日志匹配的最低等级

类型:LogLevel

默认值:无

可选值:所有日志等级 LogLevel

LogLevelMax

说明:日志匹配的最高等级

类型:LogLevel

默认值:NOT_SET_LOG_LEVEL

可选值:所有日志等级 LogLevel

AcceptOnMatch

说明:是否启动该规则

类型:bool

默认值:true

可选值:true  false

代码

#include <iostream>
#include <log4cplus\ndc.h>
#include <log4cplus/logger.h>
#include <log4cplus\helpers\sleep.h>
#include <log4cplus\helpers\pointer.h>
#include <log4cplus/configurator.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>

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

int main()
{
	log4cplus::initialize();
	log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("Filter.txt"));
	log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("TestFilter"));

	//NDCContextCreator _first_ndc(LOG4CPLUS_TEXT("This-is-Thread-Name"));

	LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("TRACE-LOG-TEST"));
	LOG4CPLUS_DEBUG(logger, LOG4CPLUS_TEXT("DEBUG-LOG-TEST"));
	LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("INFO-LOG-TEST"));
	LOG4CPLUS_WARN(logger, LOG4CPLUS_TEXT("WARN-LOG-TEST"));
	LOG4CPLUS_ERROR(logger, LOG4CPLUS_TEXT("ERROR-LOG-TEST"));
	LOG4CPLUS_FATAL(logger, LOG4CPLUS_TEXT("FATAL-LOG-TEST"));

        log4cplus::Logger::shutdown();
	return 0;
}

配置文件

log4cplus.logger.TestFilter = ALL, Test

# 创建Appender对象
log4cplus.appender.Test = log4cplus::FileAppender
log4cplus.appender.Test.File = Test/FileAppenderLog.txt
log4cplus.appender.Test.ImmediateFlush = true
log4cplus.appender.Test.Append = false
log4cplus.appender.Test.ImmediateFlush = false
log4cplus.appender.Test.CreateDirs = true

# Layout类属性
log4cplus.appender.Test.layout = log4cplus::SimpleLayout

# Filter属性
log4cplus.appender.Test.filters.1 = log4cplus::spi::LogLevelRangeFilter
log4cplus.appender.Test.filters.1.LogLevelMin = TRACE
log4cplus.appender.Test.filters.1.LogLevelMax = INFO
log4cplus.appender.Test.filters.1.AcceptOnMatch = true
log4cplus.appender.Test.filters.2 = log4cplus::spi::DenyAllFilter

结果

TRACE - TRACE-LOG-TEST
DEBUG - DEBUG-LOG-TEST
INFO - INFO-LOG-TEST

 6.4 StringMatchFilter

根据日志内容是否包含特定字符串进行过滤,只有当日志包含StringToMatch字符串 且AcceptOnMatch为true时会匹配。

属性标签描述
StringToMatch

说明:包含的字符串

类型:String

默认值:空(空即返回 NEUTRAL)

可选值:字符串

AcceptOnMatch

说明:是否启动该规则

类型:bool

默认值:true

可选值:true  false

 代码

#include <iostream>
#include <log4cplus\ndc.h>
#include <log4cplus/logger.h>
#include <log4cplus\helpers\sleep.h>
#include <log4cplus\helpers\pointer.h>
#include <log4cplus/configurator.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>

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

int main()
{
	log4cplus::initialize();
	log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("Filter.txt"));
	log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("TestFilter"));

	//NDCContextCreator _first_ndc(LOG4CPLUS_TEXT("This-is-Thread-Name"));

	LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("TRACE-LOG-TEST"));
	LOG4CPLUS_DEBUG(logger, LOG4CPLUS_TEXT("DEBUG-LOG-TEST"));
	LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("INFO-LOG-TEST"));
	LOG4CPLUS_WARN(logger, LOG4CPLUS_TEXT("WARN-LOG-TEST"));
	LOG4CPLUS_ERROR(logger, LOG4CPLUS_TEXT("ERROR-LOG-TEST"));
	LOG4CPLUS_FATAL(logger, LOG4CPLUS_TEXT("FATAL-LOG-TEST"));

        log4cplus::Logger::shutdown();
	return 0;
}

配置文件

log4cplus.logger.TestFilter = ALL, Test

# 创建Appender对象
log4cplus.appender.Test = log4cplus::FileAppender
log4cplus.appender.Test.File = Test/FileAppenderLog.txt
log4cplus.appender.Test.ImmediateFlush = true
log4cplus.appender.Test.Append = false
log4cplus.appender.Test.ImmediateFlush = false
log4cplus.appender.Test.CreateDirs = true

# Layout类属性
log4cplus.appender.Test.layout = log4cplus::SimpleLayout

# Filter属性
log4cplus.appender.Test.filters.1 = log4cplus::spi::StringMatchFilter
log4cplus.appender.Test.filters.1.StringToMatch = TRACE
log4cplus.appender.Test.filters.1.AcceptOnMatch = true
log4cplus.appender.Test.filters.2 = log4cplus::spi::DenyAllFilter

结果

TRACE - TRACE-LOG-TEST

6.5 DenyAllFilter

禁用所有过滤器。

代码

#include <iostream>
#include <log4cplus\ndc.h>
#include <log4cplus/logger.h>
#include <log4cplus\helpers\sleep.h>
#include <log4cplus\helpers\pointer.h>
#include <log4cplus/configurator.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>

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

int main()
{
	log4cplus::initialize();
	log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("Filter.txt"));
	log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("TestFilter"));

	//NDCContextCreator _first_ndc(LOG4CPLUS_TEXT("This-is-Thread-Name"));

	LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("TRACE-LOG-TEST"));
	LOG4CPLUS_DEBUG(logger, LOG4CPLUS_TEXT("DEBUG-LOG-TEST"));
	LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("INFO-LOG-TEST"));
	LOG4CPLUS_WARN(logger, LOG4CPLUS_TEXT("WARN-LOG-TEST"));
	LOG4CPLUS_ERROR(logger, LOG4CPLUS_TEXT("ERROR-LOG-TEST"));
	LOG4CPLUS_FATAL(logger, LOG4CPLUS_TEXT("FATAL-LOG-TEST"));

        log4cplus::Logger::shutdown();
	return 0;
}

配置文件

log4cplus.logger.TestFilter = ALL, Test

# 创建Appender对象
log4cplus.appender.Test = log4cplus::FileAppender
log4cplus.appender.Test.File = Test/FileAppenderLog.txt
log4cplus.appender.Test.ImmediateFlush = true
log4cplus.appender.Test.Append = false
log4cplus.appender.Test.ImmediateFlush = false
log4cplus.appender.Test.CreateDirs = true

# Layout类属性
log4cplus.appender.Test.layout = log4cplus::SimpleLayout

# Filter属性
log4cplus.appender.Test.filters.2 = log4cplus::spi::DenyAllFilter

结果

TRACE - TRACE-LOG-TEST
DEBUG - DEBUG-LOG-TEST
INFO - INFO-LOG-TEST
WARN - WARN-LOG-TEST
ERROR - ERROR-LOG-TEST
FATAL - FATAL-LOG-TEST

7 NDC

给线程添加备注的函数,两种调用方式

第一种:

函数说明
log4cplus::tstring pop();弹出 + 返回值
void pop_void ();弹出 + 无返回值
log4cplus::tstring const & peek() const;查看最后一个NDC
void push(const log4cplus::tstring& message);添加
void push(tchar const * message);添加
void remove();移除所有NDC
void setMaxDepth(std::size_t maxDepth);设置深度
std::size_t getDepth() const;获取深度

第二种:

NDCContextCreator _ndc(LOG4CPLUS_TEXT("This is NDC "));

代码 1

#include <iostream>
#include <log4cplus/ndc.h>
#include <log4cplus/logger.h>
#include <log4cplus/helpers\sleep.h>
#include <log4cplus/helpers\pointer.h>
#include <log4cplus/configurator.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>

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

int main()
{
	log4cplus::initialize();
	log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("NDC.txt"));
	log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("TestNDC"));

	LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("111"));
		
	NDC& ndc = log4cplus::getNDC();
	ndc.push(LOG4CPLUS_TEXT("NDC-1 "));
	LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("222"));
	
	ndc.push(LOG4CPLUS_TEXT("NDC-2 "));
	LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("333"));

	ndc.push(LOG4CPLUS_TEXT("NDC-3 "));
	LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("444"));

	ndc.pop();
	LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("555"));

	ndc.peek();
	LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("666"));

	ndc.remove();
	LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("777"));

	log4cplus::Logger::shutdown();
	return 0;
}

代码2

#include <iostream>
#include <log4cplus/ndc.h>
#include <log4cplus/logger.h>
#include <log4cplus/helpers\sleep.h>
#include <log4cplus/helpers\pointer.h>
#include <log4cplus/configurator.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>

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

int main()
{
	log4cplus::initialize();
	log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("NDC.txt"));
	log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("TestNDC"));

	LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("111"));

	NDCContextCreator first_ndc(LOG4CPLUS_TEXT("NDC-1 "));
	LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("222"));

	NDCContextCreator second_ndc(LOG4CPLUS_TEXT("NDC-2 "));
	LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("333"));

	NDCContextCreator third_ndc(LOG4CPLUS_TEXT("NDC-3 "));
	LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("444"));

	getNDC().pop();
	LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("555"));

	getNDC().peek();
	LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("666"));

	getNDC().remove();
	LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("777"));

	log4cplus::Logger::shutdown();
	return 0;
}

配置文件


log4cplus.logger.TestNDC = ALL, Test

# 创建Appender对象
log4cplus.appender.Test = log4cplus::FileAppender
log4cplus.appender.Test.File = Test/FileAppenderLog.txt
log4cplus.appender.Test.ImmediateFlush = true
log4cplus.appender.Test.Append = false
log4cplus.appender.Test.ImmediateFlush = false
log4cplus.appender.Test.CreateDirs = true

# Layout类属性
log4cplus.appender.Test.layout = log4cplus::PatternLayout
log4cplus.appender.Test.layout.ConversionPattern = NDC = <%x> %m %n

相同的结果

NDC = <> 111 
NDC = <NDC-1 > 222 
NDC = <NDC-1  NDC-2 > 333 
NDC = <NDC-1  NDC-2  NDC-3 > 444 
NDC = <NDC-1  NDC-2 > 555 
NDC = <NDC-1  NDC-2 > 666 
NDC = <> 777 

8 线程监控脚本的更新

类对象: ConfigureAndWatchThread

代码

#include <iostream>
#include <log4cplus/ndc.h>
#include <log4cplus/logger.h>
#include <log4cplus/helpers\sleep.h>
#include <log4cplus/helpers\pointer.h>
#include <log4cplus/configurator.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>

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

int main()
{
	log4cplus::initialize();
	log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("Watch.txt"));
	ConfigureAndWatchThread configureThread(LOG4CPLUS_TEXT("Watch.txt"), 100);
	log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("TestWatch"));

	for (int i = 0; i < 3; i++)
	{
		LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("111"));
		LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("222"));
	}

	std::cout << "Wait For Change" << endl;
	getchar();

	for (int i = 0; i < 3; i++)
	{
		LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("111"));
		LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("222"));
	}
	

	log4cplus::Logger::shutdown();
	return 0;
	
}

配置文件


log4cplus.logger.TestWatch = ALL, Test

# 创建Appender对象
log4cplus.appender.Test = log4cplus::FileAppender
log4cplus.appender.Test.File = Test/FileAppenderLog.txt
log4cplus.appender.Test.ImmediateFlush = true
log4cplus.appender.Test.Append = true
log4cplus.appender.Test.ImmediateFlush = false
log4cplus.appender.Test.CreateDirs = true

# Filter类属性 程序运行中间时增加的部分
log4cplus.appender.Test.filters.1 = log4cplus::spi::StringMatchFilter
log4cplus.appender.Test.filters.1.StringToMatch = 111
log4cplus.appender.Test.filters.1.AcceptOnMatch = true
log4cplus.appender.Test.filters.2 = log4cplus::spi::DenyAllFilter

结果

TRACE - 111
TRACE - 222
TRACE - 111
TRACE - 222
TRACE - 111
TRACE - 222
TRACE - 111
TRACE - 111
TRACE - 111

说明

当配置文件被修改时,程序认为是一个新的Logger,此时如果Append=false,当配置文件修改后会清空前文所有的日志

9 中文字符输出配置

网上教程

1.设置 log4cplus.appender.FileOut.Locale=chs 

2. 如果完成第一步不管用,设置 std::locale::global(std::locale("chs"));

 Win7测试两个步骤只要设置其中任何一个就可以输出中文字符

代码

#include <iostream>
#include <log4cplus/ndc.h>
#include <log4cplus/logger.h>
#include <log4cplus/helpers/sleep.h>
#include <log4cplus/helpers/pointer.h>
#include <log4cplus/configurator.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>

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

int main()
{
	std::locale::global(std::locale("chs"));
	log4cplus::initialize();
	log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("config.txt"));
	log4cplus::Logger logger = log4cplus::Logger::getRoot();

	LOG4CPLUS_TRACE(logger, LOG4CPLUS_TEXT("TRACE-LOG-TEST 测试中文"));
	LOG4CPLUS_DEBUG(logger, LOG4CPLUS_TEXT("DEBUG-LOG-TEST 测试中文"));
	LOG4CPLUS_INFO(logger, LOG4CPLUS_TEXT("INFO-LOG-TEST 测试中文"));
	LOG4CPLUS_WARN(logger, LOG4CPLUS_TEXT("WARN-LOG-TEST 测试中文"));
	LOG4CPLUS_ERROR(logger, LOG4CPLUS_TEXT("ERROR-LOG-TEST 测试中文"));
	LOG4CPLUS_FATAL(logger, LOG4CPLUS_TEXT("FATAL-LOG-TEST 测试中文"));

	log4cplus::Logger::shutdown();
	return 0;
}

配置文件

log4cplus.rootLogger=ALL, FileOut

log4cplus.appender.FileOut = log4cplus::FileAppender

log4cplus.appender.FileOut.File = Test/FileAppenderLog.txt
log4cplus.appender.FileOut.ImmediateFlush = true
log4cplus.appender.FileOut.Append = true
log4cplus.appender.FileOut.ImmediateFlush = true
log4cplus.appender.FileOut.CreateDirs = true
log4cplus.appender.FileOut.Locale=chs

结果

TRACE - TRACE-LOG-TEST 测试中文
DEBUG - DEBUG-LOG-TEST 测试中文
INFO - INFO-LOG-TEST 测试中文
WARN - WARN-LOG-TEST 测试中文
ERROR - ERROR-LOG-TEST 测试中文
FATAL - FATAL-LOG-TEST 测试中文

 

  • 10
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
log4cplus 是一个开源的日志库,用于 C++ 程序的日志记录。要配置 log4cplus,你可以按照以下步骤进行操作: 1. 引入 log4cplus 库:首先,确保已经将 log4cplus 库添加到你的项目中。你可以从 log4cplus 的官方网站(http://log4cplus.sourceforge.net/)下载最新版本的库,并将其链接到你的项目中。 2. 创建配置文件:在你的项目中创建一个配置文件,通常以 ".properties" 或 ".conf" 为后缀名。配置文件用于指定日志输出的格式、输出目标等参数。下面是一个简单的示例配置文件: ``` # 设置根日志记录器的输出级别为DEBUG log4cplus.rootLogger=DEBUG, STDOUT # 定义输出目标为控制台 log4cplus.appender.STDOUT=log4cplus::ConsoleAppender # 设置控制台输出格式 log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout log4cplus.appender.STDOUT.layout.ConversionPattern=[%D{%Y-%m-%d %H:%M:%S}] [%t] [%p] %m%n ``` 3. 加载配置文件:在你的代码中加载配置文件,并初始化 log4cplus。通常在程序的入口处进行加载和初始化。下面是一个示例代码片段: ```cpp #include <log4cplus/logger.h> #include <log4cplus/configurator.h> int main() { // 加载配置文件 log4cplus::PropertyConfigurator::doConfigure("log4cplus.properties"); // 获取日志记录器 log4cplus::Logger logger = log4cplus::Logger::getRoot(); // 使用日志记录器输出日志 LOG4CPLUS_DEBUG(logger, "This is a debug message."); return 0; } ``` 以上是一个简单的 log4cplus 配置和使用示例。你可以根据你的需求进一步调整和扩展配置文件,以满足你的日志记录需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值