fastlog 的使用
C++ 通用框架的设计 作者: naven
1 fastlog 介绍
fastlog 是参考 log4j 和 log4cplus 框架使用 javen c++ 库设计实现的日志记录库,具有 log4j 库类似的优点,记录日志非常方便,扩展和配置也非常容易。 Log4j 日志库我想应该在 java 的领域已经应用很广泛了,这样的日志库可以非常方便地将日志输出到屏幕、文件、 syslog 、远程服务器等任何地方,而日志输出的格式也可以任意调整,可以很容易控制输出的日志级别,而这一切仅需修改一下配置文件,应用程序不用作任何修改。
fastlog 主要有如下一些模块
Appenders 挂接器,定义一些日志输出的设备终端,如文件、屏幕等
Layouts 布局器,定义输出的日志格式
Hierarchies 分类器,用于对日志信息分类,即对日志分级,用户不能直接调用
LoglevelManager 日志级别管理器,即 TRACE, DEBUG, INFO, WARNING, ERROR 等
Logger 记录器,即记录日志的对象,每个应用模块应该拥有一个 Logger
PropertyConfigurator 配置器,用于通过配置文件配置 Logger 和 Appender 、 Layout 等
2 Hello World!
下面的程序示例如何使用 fastlog 记录日志:
// 定义一个该应用模块使用的Logger记录器,命名为”log”
static Logger _logger = Logger::getInstance( " log " );
void main()
{
// 配置器读取配置文件fastlog.properties初始化Logger,只初始化一次
PropertyConfigurator::doConfigure( " fastlog.properties " );
// 输出日志
_logger.notice( " This is the NOTICE log message”);
}
日志输出可能(与 fastlog.properties 配置有关)如下:
2006-08-10 21:44:37 [log]-[NOTICE] This is the NOTICE log message
1 fastlog 配置文件
fastlog 配置文件可能会较复杂,下面先介绍一个典型的 fastlog.properties 如下:
# 这一行不可缺少,定义 fastlog 的日志级别和输出设备
# fastlog.rootLogger 是 fastlog 的配置标识,不可更改
# = 号后面即为具体设置,后面第一个逗号 ”,” 前是设置日志输出级别,后面是设置输出设备
# INFO & ERROR 表示同时输出 INFO 和 ERROR 级别日志,所以可以任意定义输出的级别,这跟 log4j 不一样的
# A1, R 是表示两个输出设备,这个名字可以自己定义的,改成 OUT1, OUT2 等都可以
# 这个设备在下面定义输出设备的详细设置就会用到
fastlog.rootLogger = INFO & ERROR & CRIT & WARN & FATAL & ALERT & NOTICE & DEBUG, A1, R
# 这部分定义名为 ”A1” 的输出设备,定义的名称规则是 fastlog.appender. 加设备名,再加 . 设备属性
# 这一行定义输出的设备,即输出到 Console 控制台
fastlog.appender.A1 = fastlog::ConsoleAppender
# 这是定义输出的日志格式,使用 PatternLayout ,即用可配置格式的 Layout 输出
fastlog.appender.A1.layout = fastlog::PatternLayout
# 这就是定义具体的输出格式,后面会详细讲
fastlog.appender.A1.layout.ConversionPattern = %D{%Y-%m-%d %H:%M:%S.%q} [%c:%R:%T]-[%5p] %m %n
# 这是定义第二个输出设备,即 DailyFileAppender 按日期文件输出,后面详细讲
fastlog.appender.R = fastlog::DailyFileAppender
fastlog.appender.R.File = fastlog.log
fastlog.appender.R.Path = .
fastlog.appender.R.FilePrefixName =
fastlog.appender.R.FileExtendName = .log
fastlog.appender.R.TimeFormatPattern = %Y%m%d%H
fastlog.appender.R.Schedule = HOURLY
fastlog.appender.R.layout = fastlog::PatternLayout
fastlog.appender.R.layout.ConversionPattern = %D{%Y-%m-%d %H:%M:%S.%q} [%c:%R:%T]-[%5p] %m %n
下面讲讲主要用到的 Appender 和 Layout 的用法
2 fastlog::ConsoleAppender 输出设备
输出到控制台的 Appender ,比较简单就不详细讲了。
还有 fastlog::FileAppender 也比较简单,实际用处也不大,配置跟下面类似。
还有 fastlog::NullAppender 比较特殊,哪里也不输出,主要用于测试。
3 fastlog::DailyFileAppender 输出设备
按日期时间等自动切分日志的 Appender ,意思是会输出到带时间格式命名的文件,到新的时间段如下一天,则自动生成新的日期命名的文件输出,日志会自动切分,推荐使用。
举例,按上面的例子,如果当前时间是 2006-8-10 12:00:00 ,日志会自动输出到 2006081012.log 的文件中,如果当前时间变成 2006-8-10 13:01:00 ,则日志系统会自动创建名为 2006081013.log 的文件,并将新日志输出到此新文件中。
配置定义如下:
# 定义日志输出设备为 fastlog::DailyFileAppender
fastlog.appender.R = fastlog::DailyFileAppender
# 这个名字可以不用管它
fastlog.appender.R.File = fastlog.log
# 日志输出的目录,此例为当前目录
fastlog.appender.R.Path = .
# 日志文件名的前缀,如果定义了如 mylog ,则日志文件名前会带此名字
fastlog.appender.R.FilePrefixName =
# 日志文件名的扩展名,一般都为 .log 吧
fastlog.appender.R.FileExtendName = .log
# 日志文件的日期名格式,与其他日期格式化类似,详见后面的 PatternLayout
fastlog.appender.R.TimeFormatPattern = %Y%m%d%H
# 日志自动切分可以按如下几种自动滚动日志
# MONTHLY( 每月 ) WEEKLY( 每周 ) DAILY( 每天 ) TWICE_DAILY( 每两天 )
# HOURLY( 每小时 ) MINUTELY( 每分钟 )
fastlog.appender.R.Schedule = HOURLY
# 日志输出的 Layout 定义
fastlog.appender.R.layout = fastlog::PatternLayout
fastlog.appender.R.layout.ConversionPattern = %D{%Y-%m-%d %H:%M:%S.%q} [%c:%R:%T]-[%5p] %m %n
4 fastlog::RollingFileAppender 输出设备
按文件大小自动滚动日志的 Appender ,这种方式 Unix 的 syslog 用的比较多。当日志文件达到一定大小后就自动换一个名字备份起来,所以当前日志文件始终不会超过一定大小。
配置定义如下:
# 定义日志输出设备为 fastlog:: RollingFileAppender
fastlog.appender.R2 = fastlog::RollingFileAppender
# 定义日志输出的文件,可以带具体路径
fastlog.appender.R2.File = fastlog.log
# 定义滚动日志的文件大小,超过此大小则滚动日志,可以用 KB 或 MB 等表示
fastlog.appender.R2.MaxFileSize = 200KB
# 定义最多备份的日志文件数目
fastlog.appender.R2.MaxBackupIndex = 10
# 日志输出的 Layout 定义
fastlog.appender.R2.layout = fastlog::PatternLayout
fastlog.appender.R2.layout.ConversionPattern = %D{%Y-%m-%d %H:%M:%S.%q} [%c:%R:%T]-[%5p] %m %n
5 fastlog::DailyRollingFileAppender 输出设备
按日期自动滚动日志的 Appender 。它与上面的 RollingFileAppender 类似,不同就是时间经过一定时间段就自动滚动日志备份起来。而时间的处理又与 fastlog::DailyFileAppender 类似。
配置定义如下:
# 定义日志输出设备为 fastlog:: DailyRollingFileAppender
fastlog.appender.R3 = fastlog::DailyRollingFileAppender
# 定义日志输出的文件,可以带具体路径
fastlog.appender.R3.File = fastlog.log
# 日志文件的日期名格式,与其他日期格式化类似,详见后面的 PatternLayout
fastlog.appender.R3.TimeFormatPattern = %Y%m%d%H
# 日志自动切分可以按如下几种自动滚动日志
# MONTHLY( 每月 ) WEEKLY( 每周 ) DAILY( 每天 ) TWICE_DAILY( 每两天 )
# HOURLY( 每小时 ) MINUTELY( 每分钟 )
fastlog.appender.R3.Schedule = HOURLY
# 日志输出的 Layout 定义
fastlog.appender.R3.layout = fastlog::PatternLayout
fastlog.appender.R3.layout.ConversionPattern = %D{%Y-%m-%d %H:%M:%S.%q} [%c:%R:%T]-[%5p] %m %n
6 fastlog::SocketAppender 输出设备
这个比较特殊,它可以将日志输出到某台服务器,通过指定日志服务器的 IP/ 域名和端口。
配置定义如下:
# 定义日志输出设备为 fastlog:: SocketAppender
fastlog.appender.R4 = fastlog::SocketAppender
# 定义日志服务器的 hostname ,此服务器的服务可以统一保存日志
fastlog.appender.R4.host = 192.168.2.1
# 日志服务器的服务端口
fastlog.appender.R4.port = 9998
# 连接超时时间,按秒
fastlog.appender.R4.TimeOut = 10
# 日志输出的 Layout 定义
fastlog.appender.R4.layout = fastlog::PatternLayout
fastlog.appender.R4.layout.ConversionPattern = %D{%Y-%m-%d %H:%M:%S.%q} [%c:%R:%T]-[%5p] %m %n
下面介绍几种 Layout
7 fastlog::SimpleLayout 布局器
这个非常,只是在输出的原始日志前加个 Loglevel 和一个 ”-” ,如:
DEBUG - This is the simple formatted log message
8 fastlog::TTCCLayout 布局器
这是一种缺省的带格式输出的布局器,其格式由时间、线程 ID 、 Logger 和 NDC 组成( consists of time, thread, Logger and nested diagnostic context information, hence the name )。 TTCCLayout 在使用时可以选择显示本地时间或 GMT 时间,缺省是按照本地时间显示。
典型输出如下:
10-16-06 12:12:23,321 [1075298944] DEBUG log <> - this is a TTCCLayout log format
9 fastlog::PatternLayout 布局器
这是一种有词法分析功能的模式布局器,应用最广泛,也最强大,推荐使用,下面详细介绍。
用户可以根据一些定义好的标识符自定义输出格式,如上面的例子:
# 日志输出的 Layout 定义
fastlog.appender.R4.layout = fastlog::PatternLayout
fastlog.appender.R4.layout.ConversionPattern = %D{%Y-%m-%d %H:%M:%S.%q} [%c:%R:%T]-[%5p] %m %n
其中的 %D{%Y-%m-%d %H:%M:%S.%q} [%c:%R:%T]-[%5p] %m %n 即是一种输出模式。
下面详细介绍这些标识符的定义:
( 1 ) "%%" ,转义为 % ,即 pattern = "%%" 时输出 "%"
( 2 ) "%c" ,输出 logger 名称,比如 pattern ="%c" 时输出 : "test.logger.mytest " ,也可以控制 logger 名称的显示层次,比如 "%c{1}" 时输出 "test_logger" ,其中数字表示层次。
( 3 ) "%D" ,显示本地时间,当 pattern ="%D" 时输出 :"2006-8-10 20:55:25" , %d 显示标准时间。还可以通过 %d{} 定义更详细的显示格式,比如 %d{%H:%M:%s} 表示要显示小时:分钟:秒。
大括号中可显示的预定义标识符如下:
%a 表示礼拜几,英文缩写形式,比如 "Fri"
%A 表示礼拜几,比如 "Friday"
%b 表示几月份,英文缩写形式,比如 "Oct"
%B 表示几月份, "October"
%c 标准的日期+时间格式,如 "Sat Oct 16 18:56:19 2006"
%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 标准的日期格式,如 "08/10/06"
%X 标准的时间格式,如 "19:02:34"
%y 两位数的年份 (0-99) ,如 "06"
%Y 四位数的年份,如 "2006"
%Z 时区名,比如 "GMT"
( 4 ) "%F" ,输出当前记录器所在的文件名称,比如 pattern ="%F" 时输出 : "main.cpp"
( 5 ) "%L" ,输出当前记录器所在的文件行号,比如 pattern ="%L" 时输出 : "51"
( 6 ) "%l" ,输出当前记录器所在的文件名称和行号,比如 pattern ="%L" 时输出 : "main.cpp:51"
( 7 ) "%m" ,输出原始信息,比如 pattern ="%m" 时输出 : "this a test log" 。
( 8 ) "%n" ,换行符
( 9 ) "%p" ,输出 LogLevel ,比如 pattern ="%p" 时输出 : "DEBUG"
( 10 ) "%R" ,输出记录器所在的进程 ID ,比如 pattern ="%R" 时输出 : "567"
( 11 ) "%T" ,输出记录器所在的线程 ID ,比如 pattern ="%T" 时输出 : "2332"
( 12 ) "%x" ,嵌套诊断上下文 NDC (nested diagnostic context) 输出,从堆栈中弹出上下文信息。
( 13 )格式对齐,比如 pattern ="%-10m" 时表示左对齐,宽度是 10 ,此时会输出 "teststr " ,当然其它的控制字符也可以相同的方式来使用,比如 "%-12d" , "%-5p" 等。
C++ 通用框架的设计 作者: naven 日期: 2006-8-10