在单进程单线程或单进程多线程下实现log4cplus写日志并按大小分割

基于脚本配置来过滤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

时间: 2024-10-20 06:47:50

在单进程单线程或单进程多线程下实现log4cplus写日志并按大小分割的相关文章

arm下如何烧写指定分区大小的内核和文件系统

最近在海思3518e平台下烧写内核和文件系统,由于项目需要,需要运行海思SDK中的测试软件HiIspTool,不能使用精简后的文件系统,需要刷一个比较大的文件系统,但在此过程中由于各种原因,弄坏了一个板子,烧坏了一个uboot,由于要卸下SPI NOR FLASH,重新烧写实在太过麻烦,放弃了该板子.在此过程中走了些弯路,在此记录下主要过程和注意事项,希望能够提醒自己和刚如何这方面的新手,共勉! 1.板子上电时按住ctrl+c进入uboot模式 2.设置UBOOT模式的板子的IP和PC服务端的I

Redis为什么使用单进程单线程方式也这么快

[转] http://www.syyong.com/db/Redis-why-the-use-of-single-process-and-single-threaded-way-so-fast.html Redis采用的是基于内存的采用的是单进程单线程模型的KV数据库,由C语言编写.官方提供的数据是可以达到100000+的qps.这个数据不比采用单进程多线程的同样基于内存的KV数据库Memcached差. Redis快的主要原因是: 完全基于内存 数据结构简单,对数据操作也简单 使用多路 I/O

Redis 为什么使用单进程单线程方式也这么快

Redis 采用的是基于内存的采用的是单进程单线程模型的 KV 数据库,由 C 语言编写.官方提供的数据是可以达到100000+的 qps.这个数据不比采用单进程多线程的同样基于内存的 KV 数据库 Memcached 差. Redis 快的主要原因有: 完全基于内存: 数据结构简单,对数据操作也简单: 使用多路 I/O 复用模型: 第一.二点不细讲,主要围绕第三点采用多路 I/O 复用技术来展开. 多路 I/O 复用模型是利用 select.poll.epoll 可以同时监察多个流的 I/O

Redis为什么使用单进程单线程方式

Redis采用的是基于内存的采用的是单进程单线程模型的KV数据库,由C语言编写.官方提供的数据是可以达到100000+的qps.这个数据不比采用单进程多线程的同样基于内存的KV数据库Memcached差. Redis快的主要原因是: 完全基于内存 数据结构简单,对数据操作也简单 使用多路 I/O 复用模型 第一.二点不细讲,主要围绕第三点采用多路 I/O 复用技术来展开. 多路 I/O 复用模型是利用select.poll.epoll可以同时监察多个流的 I/O 事件的能力,在空闲的时候,会把当

sevlet是单线程还是多线程,在多线程下如何编写安全的servlet程序

sevlet是单线程还是多线程,在多线程下如何编写安全的servlet程序 首先明确:Servlet是单实例的,即对于同一种业务请求只有一个是实例.不同的业务请求可以通过分发来产生多个实例.其次:单实例的原因我想是因为单实例足可以处理某一个请求,就像ibatis的Querydao.UpdateDao一样都是单实例的.再次:为什么单实例足可以处理某一个请求,因为Servlet是单实例多线程的.http://hiyachen.cublog.cn  [email protected]先看一段代码:pa

多线程下HashMap与Hashtable

最近在多线程环境下操作HashMap,在程序中执行最多的是“查询”,但同时也要维护数据的“添加”和“删除” 早在开发前就知道Hashtable是同步的,而HashMap是异步的. 好吧在这里承认错误:限于没有犯过这个错误也没有见过实例场景,开发前未做好评估 现在说说我的这次需求吧: 1.要求新增一个功能页面,点击功能按钮弹出页面 2.页面前后台校验器两个(在这里不做追述) 3.提交修改后,提交按钮并disabled该按钮,页面特定区域显示动态Loading图标,并要求不影响主功能进程,若关闭弹出

普通int值在多线程下的递增操作

Java针对多线程下的数值安全计数器设计了一些类,这些类叫做原子类,其中一部分如下:  java.util.concurrent.atomic.AtomicBoolean;  java.util.concurrent.atomic.AtomicInteger;  java.util.concurrent.atomic.AtomicLong;  java.util.concurrent.atomic.AtomicReference;  下面是一个对比 AtomicInteger 与 普通 int

多线程下HashMap的死循环问题

多线程下[HashMap]的问题: 1.多线程put操作后,get操作导致死循环. 2.多线程put非NULL元素后,get操作得到NULL值. 3.多线程put操作,导致元素丢失. 本次主要关注[HashMap]-死循环问题. 为何出现死循环? 大家都知道,HashMap采用链表解决Hash冲突,具体的HashMap的分析可以参考一下Java集合---HashMap源码剖析 的分析.因为是链表结构,那么就很容易形成闭合的链路,这样在循环的时候只要有线程对这个HashMap进行get操作就会产生

多线程下C#如何保证线程安全?

多线程编程相对于单线程会出现一个特有的问题,就是线程安全的问题.所谓的线程安全,就是如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码.如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的. 线程安全问题都是由全局变量及静态变量引起的. 为了保证多线程情况下,访问静态变量的安全,可以用锁机制来保证,如下所示: 1 //需要加锁的静态全局变量 2 private static bool _isOK = false; 3 //lock只能锁定一