(1)Apache log4j-1.2.17源码学习笔记 | http://blog.csdn.net/zilong_zilong/article/details/78715500 |
(2)Apache log4j-1.2.17问答式学习笔记 | http://blog.csdn.net/zilong_zilong/article/details/78916626 |
(3)JDK Logging源码学习笔记 | http://aperise.iteye.com/blog/2411850 |
本文主要回答了关于log4j-1.2.17的如下问题:
1.为什么大部分人使用log4j-1.2.17都是配置log4j.properties文件?log4j.properties文件找不到是否影响日志输出?是否影响正常业务代码运行?
2.log4j-1.2.17是如何解析配置文件的?log4j-1.2.17提供了哪些解析器?
3.log4j-1.2.17是在哪个地方读取配置文件进行初始化的?
4.log4j-1.2.17中log4j.properties有哪些配置项?各自作用?
5.配置中log4j-1.2.17中log4j.properties中配置项区分大小写吗?
6.log4j-1.2.17里有哪些日志级别?
7.如何让log4j-1.2.17打印它自己的日志?
8.log4j-1.2.17中日志logger有哪几种?如何获取?各自区别?是单例还是每次创建?
9.如何将某些日志(接口访问记录、登录日志记录)打印在一个独立日志文件中,里面不包含INFO WARN ERROR这些日志?
10.log4j-1.2.17如何让日志不再输出?
11.过滤器Filter如何使用?如何控制只打印日志级别为WARN的日志?如何拒绝所有日志?如何控制只打印日志级别在INFO和ERROR的日志?如何控制打印只包含Chinese字符串的日志?
12.为什么日志会在2个文件中都输出?如何避免?
13.log4j-1.2.17日志格式化ConversionPattern参数有哪些?含义是啥?
14.log4j-1.2.17提供了哪些appender?
15.如何使用ConsoleAppender将日志输出到命令窗口?它的所有配置项有哪些?使用的哪种IO流?
16.如何使用FileAppender将日志输出到文件?它的所有配置项有哪些?使用的哪种IO流?
17.如何使用DailyRollingFileAppender将日志输出到文件?它的所有配置项有哪些?每月输出一个文件?每周输出一个文件?每半天(12小时)输出一个文件?每小时输出一个文件?每分钟输出一个文件?使用的哪种IO流?
18.如何使用RollingFileAppender将日志输出到文件?它的所有配置项有哪些?使用的哪种IO流?
19.如何使用JDBCAppender将日志输出到数据库mysql?它的所有配置项有哪些?
20.如何使用JMSAppender将日志输出到JMS?它的所有配置项有哪些?
21.如何使用SocketAppender将日志输出到socket?它的所有配置项有哪些?
22.如何使用SMTPAppender将日志通过邮件通知运维人员?它的所有配置项有哪些?
23.如何使用SyslogAppender将日志写入到linux的syslog?它的所有配置项有哪些?
24.如何使用TelnetAppender将日志写入到linux的telnet?它的所有配置项有哪些?
25.log4j-1.2.17日志输出对正常业务处理有性能影响吗?哪些地方有影响?如何避免和优化?
1.为什么大部分人使用log4j-1.2.17都是配置log4j.properties文件?log4j.properties文件找不到是否影响日志输出?是否影响正常业务代码运行?
答:首先通过一张图来了解下log4j-1.2.17加载配置文件的过程和先后顺序:
上图说明:
- 如果操作系统的环境变量log4j.configuration有值,那么优先以此配置代表的文件来初始化log4j;
- 如果操作系统环境变量log4j.configuration无值,那么默认加载项目的资源文件中的log4j.xml来初始化log4j;
- 如果找不到log4j.xml,那么默认加载项目的资源文件中的log4j.properties文件来初始化log4j;
- 如果找不到log4j.properties,那么就放弃初始化log4j,也即项目中log4j将不生效,不会产生任何日志,也不会影响正常项目的业务逻辑处理。
了解了上述加载顺序后,不难理解为什么大部分人都直接配置log4j.properties这个文件了,这算是使得log4j-1.2.17生效的最后防线了,如果连log4j.properties都找不到,那么无非就是无法打印日志而已,也不会影响正常的业务代码的运行。
这里以一张图来诠释log4j.properties配置内容:
上面log4j.properties配置文件对应的logger及其输出位置用图表示如下:
2.log4j-1.2.17是如何解析配置文件的?log4j-1.2.17提供了哪些解析器?
答:首先回答第一个问题:
1)如果操作系统没有配置环境变量log4j.configuratorClass,并且配置文件的结尾是".xml",那么就以org.apache.log4j.xml.DOMConfigurator解析器来解析配置文件;
2)如果配置了操作系统的环境变量log4j.configuratorClass,那么首先反射log4j.configuratorClass对应的类的无参构造函数创建解析器对象,然后解析配置文件,如果反射失败,就直接退出,也即项目中log4j将不生效,不会产生任何日志,也不会影响正常项目的业务逻辑处理;
3)如果操作系统没有配置环境变量log4j.configuratorClass,并且配置文件的结尾不是是".xml",那么就以org.apache.log4j.PropertyConfigurator解析器来解析配置文件;
第一个问题回答完毕,这里也告诉我们,如果我们使用log4j.yaml可以么,当然可行,前提是你得自己写个YamlConsigurator类用于解析log4j.yaml文件,然后配置环境变量如下:
开始回答第二个问题,log4j-1.2.17提供了四个解析器实现,分别是:
1)org.apache.log4j.PropertyConfigurator
2)org.apache.log4j.lf5.DefaultLF5Configurator
3)org.apache.log4j.xml.DOMConfigurator
4)org.apache.log4j.varia.ReloadingPropertyConfigurator
其类继承关系和能解析的文件格式如下图所示:
3.log4j-1.2.17是在哪个地方读取配置文件进行初始化的?
答:log4j-1.2.17在org.apache.log4j.LogManager类的static静态代码块里读取配置文件进行初始化的,想了解详细过程参见我的另外一篇博客 Apache log4j-1.2.17源码学习笔记
4.log4j-1.2.17中log4j.properties有哪些配置项?各自作用?
答:
配置项前缀 | 分类 | 作用 |
log4j.debug | log4j自身日志控制开关 |
1)格式:log4j.debug=true/false
2)log4j.debug=true,开启log4j自身日志, 开启后能查看log4j加载配置文件,解析配置文件, 打印日志等操作相关日志
3)默认为false,表示未开启log4j自身日志 |
log4j.configDebug | log4j自身日志控制开关 |
1)格式:log4j.configDebug=true/false
2)作用和log4j.debug类似, 当前已被标记为deprecated,建议改用log4j.debug
3)log4j.configDebug=true,开启log4j自身日志, 开启后能查看log4j加载配置文件,解析配置文件, 打印日志等操作相关日志
4)默认为false,表示未开启log4j自身日志;
5)优先使用log4j.debug, 无配置log4j.debug再使用log4j.configDebug |
log4j.reset | rootLogger设置 |
1)格式:log4j.reset=true/false
2)log4j.reset=true,会重置rootLogger的日志级别为DEBUG, 重置rootLogger的threshold为ALL
3)默认为false |
log4j.threshold | rootLogger设置 |
1)格式:log4j.threshold=ALL/TRACE/DEBUG/INFO/WARN/ERROR/FATAL/OFF
2)ALL/TRACE/DEBUG/INFO/WARN/ERROR/FATAL/OFF 是日志级别,默认代表的值从小到大,默认值为ALL
3)日志事件级别小于threshold的将被禁止打印,也即不输出 比如log4j.threshold=INFO,logger.debug("debug")不会打印; 比如log4j.threshold=INFO,logger.info("info")会打印; |
log4j.rootLogger | rootLogger设置 |
1)格式:log4j.rootLogger=日志级别 (ALL/TRACE/DEBUG/INFO/WARN/ERROR/FATAL/OFF),appenderName1,appenderName2,......
2)用于设置rootLogger配置,log4j里的日志分为rootLogger和logger, 这是两类不同日志,以log4j.logger打头的为用户logger,其parent属性 指向rootLogger,意图是防止用户logger未配置appender时,默认将所有日志事件传播给rootLogger的appender执行
3)日志事件大于或者等于日志级别的才会被打印 比如log4j.rootLogger=INFO,apname1,log.debug("debug")不会打印; 比如log4j.rootLogger=INFO,appname1,log.info("info")会被打印;
4)log4j.rootLogger和log4j.rootCategory作用一样,只需配置一个即可; 默认先使用log4j.rootLogger,如果log4j.rootLogger找不到才使用log4j.rootCategory |
log4j.rootCategory | rootLogger设置 |
1)格式:log4j.rootCategory=日志级别 (ALL/TRACE/DEBUG/INFO/WARN/ERROR/FATAL/OFF),appenderName1,appenderName2,......
2)用于设置rootLogger配置,log4j里的日志分为rootLogger和logger, 这是两类不同日志,以log4j.logger打头的为用户logger,其parent属性 指向roogLogger,意图是防止用户logger未配置appender时,默认将所有日志事件传播给rootLogger的appender执行
3)日志事件大于或者等于日志级别的才会被打印 比如log4j.rootCategory=INFO,apname1,log.debug("debug")不会打印; 比如log4j.rootCategory=INFO,appname1,log.info("info")会被打印;
4)log4j.rootLogger和log4j.rootCategory作用一样,只需配置一个即可; 默认先使用log4j.rootLogger,如果log4j.rootLogger找不到才使用log4j.rootCategory |
log4j.appender.*.* | appender配置 |
1)格式:log4j.appender.appenderName.attribute-key=attribute-value
2)attribute-key是不同的appender实现类的具体属性, 属性名不要大小写随便写,必须遵循JavaBean规范,默认是通过反射机制调用setXXX进行设置
3)attribute-key有3个属性必须小写,这三个属性如下: log4j.appender.appenderName.layout log4j.appender.appenderName.errorhandler log4j.appender.appenderName.filter
4)每个appender的实现类不同,其配置属性也各不相同,属性个数也不同,视具体实现类而定 |
log4j.loggerFactory | logger工厂类配置 |
1)格式:log4j.loggerFactory=com.xxx.xxx.MyLoggerFactory
2)默认值为org.apache.log4j.DefaultCategoryFactory
3)这个参数主要是为了让用户自己可以定义自己的logger工厂类实现
4)log4j.loggerFactory和log4j.factory作用一样,只需配置一个即可; 默认先使用log4j.loggerFactory,如果log4j.loggerFactory找不到才使用log4j.factory |
log4j.factory | logger工厂类配置 |
1)格式:log4j.factory=com.xxx.xxx.MyLoggerFactory
2)默认值为org.apache.log4j.DefaultCategoryFactory
3)这个参数主要是为了让用户自己可以定义自己的logger工厂类实现
4)log4j.loggerFactory和log4j.factory作用一样,只需配置一个即可; 默认先使用log4j.loggerFactory,如果log4j.loggerFactory找不到才使用log4j.factory
|
log4j.category.* | 用户logger设置 |
1)格式:log4j.category.loggerName=日志级别 (ALL/TRACE/DEBUG/INFO/WARN/ERROR/FATAL/OFF),appenderName1,appenderName2,......
2)用于设置用户logger配置,log4j里的日志分为rootLogger和logger, 这是两类不同日志,以log4j.logger打头的为用户logger,其parent属性 指向rootLogger,意图是防止用户logger未配置appender时,默认将所有日志事件传播给rootLogger的appender执行
3)日志事件大于或者等于日志级别的才会被打印 比如log4j.category.loggerName=INFO,apname1,log.debug("debug")不会打印; 比如log4j.category.loggerName=INFO,appname1,log.info("info")会被打印;
4)log4j.category.和log4j.logger.作用一样,只需配置一个即可; 默认先使用log4j.category.,如果log4j.category.找不到才使用log4j.logger. |
root.logger.* | 用户logger设置 |
1)格式:log4j.logger.loggerName=日志级别 (ALL/TRACE/DEBUG/INFO/WARN/ERROR/FATAL/OFF),appenderName1,appenderName2,......
2)用于设置用户logger配置,log4j里的日志分为rootLogger和logger, 这是两类不同日志,以log4j.logger打头的为用户logger,其parent属性 指向rootLogger,意图是防止用户logger未配置appender时,默认将所有日志事件传播给rootLogger的appender执行
3)日志事件大于或者等于日志级别的才会被打印 比如log4j.logger.loggerName=INFO,apname1,log.debug("debug")不会打印; 比如log4j.logger.loggerName=INFO,appname1,log.info("info")会被打印;
4)log4j.category.和log4j.logger.作用一样,只需配置一个即可; 默认先使用log4j.category.,如果log4j.category.找不到才使用log4j.logger. |
log4j.additivity. | 用户logger设置 |
1)格式:log4j.additivity.loggerName=true/false
2)默认log4j.additivity.loggerName=true,用户logger的parent属性指向rootLogger,日志事件经用户logger后都会传播给rootLogger,会造成日志打印两遍,可以设置log4j.additivity.loggerName=false,告诉名字为loggerName的用户logger不要将日志事件传播给rootLogger |
log4j.renderer. | render设置 |
1)格式: log4j.render.myrender1 log4j.render.A myrender1=com.xxx.xxx.MyObjectRender A=com.xxx.xxx.MyObjectRender
2)对于日志事件log.info(Object),log4j并不知道Object的类型,log4j需要将Object转为String,这时候的处理逻辑先去查找是否有Object对应的Render转换类,比如A.classs对应Render类为com.xxx.MyObjectRender,此时就调用MyObjectRender.doRender方法返回字符串String,如果找不到,那么就调用A.class的toString方法,毕竟toString是所有类的父类Object的方法
3)默认com.xxx.xxx.MyObjectRender必须实现接口org.apache.log4j.or.ObjectRenderer |
log4j.throwableRenderer | render设置 |
1)格式:log4j.throwableRenderer=com.xxx.xxx.MyThrowableRenderer
2)默认会将rootLogger的throwableRenderer=null,如果用户配置了log4j.throwableRenderer,那么会将此值设置给rootLogger的throwableRenderer,当有异常发生时会调用throwableRenderer的 public String[] doRender(Throwable t)将异常转换为String数组
3)com.xxx.xxx.MyThrowableRenderer必须实现接口org.apache.log4j.spi.ThrowableRenderer |
5.配置中log4j-1.2.17中log4j.properties中配置项区分大小写吗?
答:在上面的"4.log4j-1.2.17中log4j.properties有哪些配置项?各自作用?"中已经介绍了关于log4j的所有配置项,大小写有些地方是区分的,有些地方不区分,原则如下:
1)配置项前缀必须全部小写,配置项前缀参见"4.log4j-1.2.17中log4j.properties有哪些配置项?各自作用?"中表格里的配置项前缀;
2)3个配置项必须全部小写:
log4j.appender.appenderName.layout layout必须小写
log4j.appender.appenderName.errorhandler errorhandler必须小写
log4j.appender.appenderName.filter filter必须小写
3)除了上述2个原则,其他的配置属性遵从如下规则:
- 属性名为null或者为空白字符,直接返回属性名;
- 属性名长度大于或者等于2,并且属性名的前2位都是大写,那么直接返回属性名;
- 非上面两种情况,则直接将首字母转换为小写然后返回属性名。
举例如下:
log4j.appender.appenderName.File会将“File”先转为file,然后找设值方法setFile;
log4j.appender.appenderName.file会将“file”先转为file,然后找设值方法setFile;
log4j.appender.appenderName.FILE会将“FILE”先转为FILE,然后找设值方法setFILE;
所以appenderName这个对应的appender对象必须有setFile或者setFILE方法,否则java反射就会失败。
6.log4j-1.2.17里有哪些日志级别?
答:
level | levelStr | syslogEquivalent | |
Level.ALL | -2147483648 | ALL | 7 |
Level.TRACE | 5000 | TRACE | 7 |
Level.DEBUG | 10000 | DEBUG | 7 |
Level.INFO | 20000 | INFO | 6 |
Level.WARN | 30000 | WARN | 4 |
Level.ERROR | 40000 | ERROR | 3 |
Level.FATAL | 250000 | FATAL | 0 |
Level.OFF | 2147483647 | OFF | 0 |
7.如何让log4j-1.2.17打印它自己的日志?
答:log4j-1.2.17可以打印自己解析log4j.properties过程相关日志,开启这个功能只需在配置文件log4j.properties中添加log4j.debug=true或者log4j.configDebug=true,当前log4j.configDebug=true已经不建议使用,建议使用log4j.debug=true,配置文件解析时候也是优先使用log4j.debug=true,当log4j.debug=true找不到才使用log4j.configDebug=true。
举例如下,在log4j.properties中添加log4j.debug=true,log4j.properties配置内如如下:
测试类如下:
测试后打印的log4j-1.2.17自身日志如下:
所以,如果想了解log4j-1.2.17如何解析配置文件log4j.properties的过程,可以开启log4j.debug=true来查看相关日志。
8.log4j-1.2.17中日志logger有哪几种?如何获取?各自区别?是单例还是每次创建?
答:1)log4j-1.2.17中分为2种:
第一类为rootLogger,也即根节点日志,这个一般是在log4j.properties中通过关键字log4j.rootLogger配置;
第二类为logger,也称之为用户日志,默认用户logger的parent属性指向rootLogger,并且用户logger的属性additivity=true,意思是所有用户logger相关日志事件都会像流感病毒一样传送给rootLogger,这里也是有些日志在不同的文件都记录问题产生的根本原因,不想日志事件传播给rootLogger,那么就配置log4j.additivity.用户logger名=false,即可关闭传播这种特性。
2)开始回答第二个问题和第三个问题,获取logger有以下几种方法:
获取途径 | 日志分类 | 作用与区别 |
log4j.properties 中配置log4j.rootLogger |
rootLogger |
(1)rootLogger是所有用户logger的父节点,默认用户logger所有 日志事件都会传播给rootLogger,这是为了防止用户logger 在未设置appender时,日志能转交给rootLogger进行输出; (2)这种方式产生的是rootLogger,其父节点为null; (3)区别是在log4j中哈希表中记录的该logger的key=root; (4)默认在log4j.properties都会配置appender; |
log4j.properties 中配置log4j.logger.* |
用户logger |
(1)这种方式主要用于将一些日志(接口访问记录、登录日志记录) 单独记录在某个独立的文件,单独进行管理; (2)这种方式产生的仍然是用户logger,其父节点为rootLogger; (3)区别是在log4j中哈希表中记录的该logger的key=log4j.properties配置的logger名; (4)默认在log4j.properties都会配置appender; |
java 类中 Logger.getLogger(Test.class) |
用户logger |
(1)这种方式产生的仍然是用户logger,其父节点为rootLogger; (2)区别是在log4j中哈希表中记录的该logger的key=com.xxx.Test; (3)默认没有自己的appender,只能依赖rootLogger的appender输出日志; |
java 类中Logger.getLogger("test")获取的logger | 用户logger |
(1)这种方式产生的仍然是用户logger,其父节点为rootLogger; (2)区别是在log4j中哈希表中记录的该logger的key=test; (3)默认没有自己的appender,只能依赖rootLogger的appender输出日志,除非在log4j.properties文件中以log4j.logger.test配置了独立的appender; |
3)回答第4个问题,所有的logger,不管是rootLogger还是logger,都是单例的,不会每次都创建,只会创建一次,创建完毕后通过key-value方式存储在哈希表中,其中key是logger的名字,名字规则如下:
log4j.properties中log4j.rootLogger配置的rootLogger的key=root;
log4j.properties中log4j.logger.loggername配置的logger的key=loggername;
java 类中Logger.getLogger(Test.class)获取的logger的key=com.xxx.xxx.Test;
java 类中Logger.getLogger("test")获取的logger的key=test
9.如何将某些日志(接口访问记录、登录日志记录)打印在一个独立日志文件中,里面不包含INFO WARN ERROR这些日志?
答:在上面的问题8中这个已经有部分回答了,在问题8中我们已经知道所有在java类中获取的用户logger都是没有自己的appender的,那么就意味着这些logger都没有自己的日志输出能力,都是转交给rootLogger的appender进行输出,要做到日志文件独立,那么就需要在log4j.properties文件中配置log4j.logger.*,独立配置其appender,举例如下:
目标:将所有接口访问日志记录全部记录到文件interface.log文件,每天产生一个文件,这部分日志不要在其他日志文件中进行输出
实现:
(1)在log4j.properties文件中添加如下内容:
(2)测试代码如下:
10.log4j-1.2.17如何让日志不再输出?
答:前面在问题6中已经提到过log4j-1.2.17的日志级别,如果不想让日志或者某个级别的日志输出,正是通过修改log4j.properties文件中的相应日志级别控制的,相应设置参见下图:
11.过滤器Filter如何使用?如何控制只打印日志级别为WARN的日志?如何拒绝所有日志?如何控制只打印日志级别在INFO和ERROR的日志?如何控制打印只包含Chinese字符串的日志?
答:这几个问题都可以通过log4j-1.2.17的appender里的filter实现,举例如下:
(1)LevelMatchFilter控制只打印日志级别为WARN的日志
上面配置针对appender=Info,启用了类型为LevelMatchFilter的过滤器,设置了过滤器LevelMatchFilter的属性levelToMatch=WARN且acceptOnMatch=true,含义是这个appender只打印级别为WARN的日志。
(2)DenyAllFilter控制拒绝所有日志
上面配置针对appender=Info,启用了类型为DenyAllFilter的过滤器,含义是这个appender对于一切日志都不打印,如果某天你不想打印日志了,那么这个配置能帮上你大忙哦。
(3)LevelRangeFilter控制打印日志级别INFO和ERROR的日志
上面配置针对appender=Info,启用了类型为LevelRangeFilter的过滤器,设置了过滤器LevelRangeFilter的属性levelMin=INFO且levelMax=ERROR且acceptOnMatch=true,含义是这个appender只打印级别在INFO到ERROR这个范围的日志,也即级别为INFO、WARN和ERROR的日志。
(4)StringMatchFilter控制打印日志中包含字符Chinese的日志
上面配置针对appender=Info,启用了类型为StringMatchFilter的过滤器,设置了过滤器StringMatchFilter的属性stringToMatch=Chinese且acceptOnMatch=true,含义是这个appender只处理日志中包含字符串"Chinese"的日志事件。
12.为什么日志会在2个文件中都输出?如何避免?
答:(1)回答第一个问题,碰到这种问题首先对于log4j-1.2.17中的两类日志认识不够,第一类是rootLogger,通过log4j.rootLogger配置,它是所有其他logger的父logger;第二类是用户logger,通过log4j.logger.loggername或者java代码中通过Logger.getLogger生成,这种logger的属性parent默认指向rootLogger。
碰到这种问题其次是对log4j-1.2.17中日志事件传播属性additivity了解不深,默认所有的用户logger的属性additivity=true,意思是日志事件不仅会用用户logger处理,还会像流感病毒一样传播给rootLogger处理,所以用户logger的appender会在对应的日志中输出一次,也会转交给rootLogger的appender进行再次输出。
(2)第二个问题,解决的办法是设置用户logger的属性additivity=false,禁止日志事件向外传播,配置如下:
如果是通过java类中Logger.getLogger(Test.class)获取logger,那么其对应的logger的名字为com.xxx.xxx.Test,这种情况下禁用日志传播属性的配置如下:
13.log4j-1.2.17日志格式化ConversionPattern参数有哪些?含义是啥?
答:在log4j-1.2.17的源代码org.apache.log4j.PatternLayout中对于ConversionPattern参数解释如下:
转换字符 | 作用 |
c | Used to output the category of the logging event. The category conversion specifier can be optionally followed by precision specifier, that is a decimal constant in brackets.
If a precision specifier is given, then only the corresponding number of right most components of the category name will be printed. By default the category name is printed in full. For example, for the category name "a.b.c" the pattern %c{2} will output "b.c". |
C【请慎用】 | Used to output the fully qualified class name of the caller issuing the logging request. This conversion specifier can be optionally followed by precision specifier, that is a decimal constant in brackets.
If a precision specifier is given, then only the corresponding number of right most components of the class name will be printed. By default the class name is output in fully qualified form. For example, for the class name "org.apache.xyz.SomeClass", the pattern %C{1} will output "SomeClass". WARNING Generating the caller class information is slow. Thus, use should be avoided unless execution speed is not an issue. 注意:使用此种转换字符获取打印日志所在类名会拖慢正常的业务处理,毕竟日志对于正常代码处理还是有影响的,请慎用。 |
d | Used to output the date of the logging event. The date conversion specifier may be followed by a date format specifier enclosed between braces. For example, %d{HH:mm:ss,SSS} or %d{dd MMM yyyy HH:mm:ss,SSS}. If no date format specifier is given then ISO8601 format is assumed.
The date format specifier admits the same syntax as the time pattern string of the For better results it is recommended to use the log4j date formatters. These can be specified using one of the strings "ABSOLUTE", "DATE" and "ISO8601" for specifying These dedicated date formatters perform significantly better than 注意:这里告诉我们其实还有比java的SimpleDateFormat更好的日期格式化工具类,似乎无意中又学习到了新知识 |
F【请慎用】 | Used to output the file name where the logging request was issued.
WARNING Generating caller location information is extremely slow and should be avoided unless execution speed is not an issue. 注意:使用此种转换字符获取打印日志所在源代码文件名比如Myclass.java会严重拖慢正常的业务处理,毕竟日志对于正常代码处理还是有影响的,请慎用。 |
l | Used to output location information of the caller which generated the logging event.
The location information depends on the JVM implementation but usually consists of the fully qualified name of the calling method followed by the callers source the file name and line number between parentheses. The location information can be very useful. However, its generation is extremely slow and should be avoided unless execution speed is not an issue. |
L【请慎用】 | Used to output the line number from where the logging request was issued.
WARNING Generating caller location information is extremely slow and should be avoided unless execution speed is not an issue. 注意:使用此种转换字符获取源代码里调用打印日志是哪一行代码发起的会严重拖慢正常的业务处理,毕竟日志对于正常代码处理还是有影响的,请慎用。 |
m | Used to output the application supplied message associated with the logging event. |
M【请慎用】 | Used to output the method name where the logging request was issued.
WARNING Generating caller location information is extremely slow and should be avoided unless execution speed is not an issue. 注意:使用此种转换字符获取源代码里调用打印日志是哪个方法发起的会严重拖慢正常的业务处理,毕竟日志对于正常代码处理还是有影响的,请慎用。 |
n | Outputs the platform dependent line separator character or characters.
This conversion character offers practically the same performance as using non-portable line separator strings such as "\n", or "\r\n". Thus, it is the preferred way of specifying a line separator. |
p | Used to output the priority of the logging event. |
r | Used to output the number of milliseconds elapsed from the construction of the layout until the creation of the logging event. |
t | Used to output the name of the thread that generated the logging event. |
x | Used to output the NDC (nested diagnostic context) associated with the thread that generated the logging event. |
X |
Used to output the MDC (mapped diagnostic context) associated with the thread that generated the logging event. The X conversion character must be followed by the key for the map placed between braces, as in %X{clientNumber} where See |
% | The sequence %% outputs a single percent sign. |
用网友的翻译如下:
14.log4j-1.2.17提供了哪些appender?
答:log4j-1.2.17提供的appender如下图所示,如果感兴趣可以参见我的另外一篇关于log4j-1.2.17源代码分析的博客 Apache log4j-1.2.17源码学习笔记
15.如何使用ConsoleAppender将日志输出到命令窗口?它的所有配置项有哪些?使用的哪种IO流?
答:ConsoleAppender使用优先使用java里已经打开的流System.err和System.out,这两个类型对应的IO流为java.io.PrintStream,如果配置了属性follow=false就是用java的IO流java.io.OutputStream;
使用ConsoleAppender将日志输出到命令窗口的完整配置如下:
16.如何使用FileAppender将日志输出到文件?它的所有配置项有哪些?使用的哪种IO流?
答:FileAppender使用的是java的IO流java.io.Writer;
使用FileAppender将日志输出到文件的完整配置如下:
17.如何使用DailyRollingFileAppender将日志输出到文件?它的所有配置项有哪些?每月输出一个文件?每周输出一个文件?每半天(12小时)输出一个文件?每小时输出一个文件?每分钟输出一个文件?使用的哪种IO流?
答:DailyRollingFileAppender使用的java的IO流java.io.Writer;
DailyRollingFileAppender的属性datePattern控制着文件按月,按周,按半天,按小时,按分钟进行拆分,这个属性说明见下表:
'.'yyyy-MM |
按照月份存储文件 | At midnight of May 31st, 2002 /foo/bar.log will be copied to /foo/bar.log.2002-05 . Logging for the month of June will be output to /foo/bar.log until it is also rolled over the next month. |
'.'yyyy-ww |
按照周存储文件,每周的第一由当前系统的时区决定,比如美国以SUNDAY为一周第一天 | Assuming the first day of the week is Sunday, on Saturday midnight, June 9th 2002, the file /foo/bar.log will be copied to /foo/bar.log.2002-23. Logging for the 24th week of 2002 will be output to /foo/bar.log until it is rolled over the next week. |
'.'yyyy-MM-dd |
按照天存储文件,每天晚上的12点会变更文件名字 | At midnight, on March 8th, 2002, /foo/bar.log will be copied to /foo/bar.log.2002-03-08 . Logging for the 9th day of March will be output to /foo/bar.log until it is rolled over the next day. |
'.'yyyy-MM-dd-a |
按照半天存储文件,中午的12点和晚上的12点时候会变更文件名字 | At noon, on March 9th, 2002, /foo/bar.log will be copied to /foo/bar.log.2002-03-09-AM . Logging for the afternoon of the 9th will be output to /foo/bar.log until it is rolled over at midnight. |
'.'yyyy-MM-dd-HH |
按照小时存储文件 | At approximately 11:00.000 o'clock on March 9th, 2002, /foo/bar.log will be copied to /foo/bar.log.2002-03-09-10 . Logging for the 11th hour of the 9th of March will be output to /foo/bar.log until it is rolled over at the beginning of the next hour. |
'.'yyyy-MM-dd-HH-mm |
按照分钟存储文件 | At approximately 11:23,000, on March 9th, 2001, /foo/bar.log will be copied to /foo/bar.log.2001-03-09-10-22 . Logging for the minute of 11:23 (9th of March) will be output to /foo/bar.log until it is rolled over the next minute. |
使用DailyRollingFileAppender将日志输出到文件的完整配置如下:
18.如何使用RollingFileAppender将日志输出到文件?它的所有配置项有哪些?使用的哪种IO流?
答:RollingFileAppender使用的java的IO流为java.io.writer;
使用RollingFileAppender将日志输出到文件的完整配置如下:
19.如何使用JDBCAppender将日志输出到数据库mysql?它的所有配置项有哪些?
答:使用JDBCAppender将日志输出到数据库mysql的完整配置如下:
20.如何使用JMSAppender将日志输出到JMS?它的所有配置项有哪些?
答:使用JDBCAppender将日志输出到JMS的完整配置如下:
21.如何使用SocketAppender将日志输出到socket?它的所有配置项有哪些?
答:使用SocketAppender将日志输出到socket的完整配置如下:
22.如何使用SMTPAppender将日志通过邮件通知运维人员?它的所有配置项有哪些?
答:使用SMTPAppender将日志通过邮件通知运维人员的完整配置如下:
23.如何使用SyslogAppender将日志写入到linux的syslog?它的所有配置项有哪些?
答:syslogd是UNIX系统的一个常见的组件,用于执行系统日志记录活 动。syslogd从一组日志源(如:/dev/log和/dev/klog)中读取数据,并按/etc/syslog.conf中的说明处理这些日志消 息。通过syslog()调用,将应用程序日志消息记录到syslog中。
使用SyslogAppender将日志写入到linux的syslog的完整配置如下:
24.如何使用TelnetAppender将日志写入到linux的telnet?它的所有配置项有哪些?
答:默认是将log4j日志输出到其所在linux服务器的端口23.
使用TelnetAppender将日志写入到linux的telnet的完整配置如下:
25.log4j-1.2.17日志输出对正常业务处理有性能影响吗?哪些地方有影响?如何避免和优化?
答:第一个问题,日志输出是肯定影响正常业务代码的总体性能的,一个庞大的业务系统会产生成千上万的日志,每个日志处理都会消耗CPU或者磁盘IO,但log4j-1.2.17的设计原则是速度第一,灵活第二,一般日志输出相对于正常的业务代码逻辑处理来说,影响相当小,就那输出日志到linux的文件来说,当前linux的服务器写文件的能力已经达到100万行每秒,所以日志输出占据的时间很小。
第二个问题,哪些地方对性能有影响呢?
(1)有人测试过如果完全通过log4j.properties关闭掉所有日志输出,但是里面的log.debug("debug")在233 MHz的奔腾II处理器上耗时大概在5~50纳秒;
(2)以logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]))来讲,log4j消耗的时间在于将整数i转为String,将entry[i]转为String,然后将这些字符串拼接,如果日志量相当大,耗时会更大;
(3)PatternLayout中对于ConversionPattern参数中%C、%F、%L、%M分别用于获取logger对象所在类的完整包名路径、logger对象所在java源代码文件的文件名、logger对象被调用所在代码的行数、logger对象被调用所在的方法名,这四个在log4j-1.2.17的源代码PatternLayout是明确指出消耗性能的,不推荐使用;
(4)代码中有logger.debug,但是日志级别是INFO以上,那么每次debug还是会执行,这里建议代码里先判断logger.isDebugEnabled()的值是否为true,否则频繁的debug被执行也是一笔开销;
第三个问题,从第二个问题的分析中我们已经知道响应举措:
(1)不要将多个对象转string的动作交给log4j进行转换,更不要将多个string交给log4j进行拼接,原则上交给log4j的已经是String类型;
(2)如果你的日志中已经有logger.debug这类日志操作,那么切记这么干:
调用debug之前都提前做个判断;
(3)尽量不要使用PatternLayout中的ConversionPattern的参数%C、%F、%L、%M,PatternLayout能省则省,能简单则简单,不要过多打印你不需要的信息;
(4)尽量给每个产生的logger一个默认的日志级别,否则logger找不到日志级别的时候,会去默认寻找其父logger的日志级别;
相关推荐
赠送jar包:apache-log4j-extras-1.2.17.jar; 赠送原API文档:apache-log4j-extras-1.2.17-javadoc.jar; 赠送Maven依赖信息文件:apache-log4j-extras-1.2.17.pom; 包含翻译后的API文档:apache-log4j-extras-...
log4j-1.2.17.jar及配置文件,消耗1积分 log4j-1.2.17.jar及配置文件,消耗1积分 log4j-1.2.17.jar及配置文件,消耗1积分 log4j-1.2.17.jar及配置文件,消耗1积分 log4j-1.2.17.jar及配置文件,消耗1积分
《深入理解Log4j:基于log4j-1.2.17.jar的解析与应用》 在Java编程领域,日志记录是一项至关重要的任务,它对于程序的调试、问题定位以及性能分析都有着不可忽视的作用。Log4j,作为Apache软件基金会的一个开源项目...
1. **log4j-1.2.17.jar**: 这是Log4j的主要库文件,包含了所有Log4j的类和接口。通过这个库,开发者可以方便地在代码中插入日志语句,记录程序运行时的信息、警告、错误等。 2. **commons-logging-1.2.jar**: 这是...
这个名为"apache-log4j-1.2.17"的压缩包包含的是Log4j 1.2.17版本的源码、库文件和其他相关资源,用于解决在开发或运行过程中可能遇到的日志导入和输出问题。 1. **Log4j介绍** - **日志框架**:Log4j是一个开源的...
开发工具 log4j-1.2.17开发工具 log4j-1.2.17开发工具 log4j-1.2.17开发工具 log4j-1.2.17开发工具 log4j-1.2.17开发工具 log4j-1.2.17开发工具 log4j-1.2.17开发工具 log4j-1.2.17开发工具 log4j-1.2.17开发工具 ...
"log4j-1.2.17.jar"是Log4j的一个版本,尽管现在已经有更新的Log4j 2.x系列,但1.2版本因其稳定性和广泛支持,仍然在许多项目中被采用。 1. **日志级别控制**:Log4j支持多个日志级别,包括DEBUG、INFO、WARN、...
在强调可重用组件开发的今天,除了自己从头到尾开发一个可重用的日志操作类外,Apache为我们提供了一个强有力的日志操作包-Log4j。 Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的...
在标题“spring jar 包 _ log4j-1.2.17.jar_commons-logging.jar”中,提到了两个重要的库文件:log4j-1.2.17.jar和commons-logging.jar,它们都是Spring框架常用的日志处理工具。现在,我们将深入探讨这两个库以及...
赠送jar包:log4j-1.2.17.jar; 赠送原API文档:log4j-1.2.17-javadoc.jar; 赠送源代码:log4j-1.2.17-sources.jar; 赠送Maven依赖信息文件:log4j-1.2.17.pom; 包含翻译后的API文档:log4j-1.2.17-javadoc-API...
标题提及的是"log4j-API-最新稳定版本log4j-1.2.17",这表明我们关注的是日志框架Log4j的一个特定版本,即1.2.17。Log4j是Apache软件基金会开发的一个用于Java应用程序的日志记录工具,它提供了灵活的日志记录功能,...
Apache Log4j_1.2.17 完整依赖包,在jdk1.8.201中测试通过。使用教程https://www.tutorialspoint.com/springmvc/springmvc_log4j.htm
在给定的文件中,我们关注的是三个关键的JAR文件:`log4j-1.2.17.jar`、`slf4j-api-1.7.21.jar`以及`slf4j-log4j12-1.7.2.jar`。这些文件在配置Hibernate和Spring框架时起着核心作用。 首先,让我们深入了解`log4j-...
免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累成果,供大家学习参考与交流。收取的费用仅用于收集和整理资料耗费时间的酬劳。 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,...
总的来说,Log4j 1.2.17是一个强大的日志框架,它的源码和JAR包为开发者提供了丰富的学习和使用材料。通过深入理解和使用,我们可以更有效地监控和调试我们的应用程序,提升开发效率和产品质量。
通过研究`apache-log4j-1.2.17`的源码,我们可以深入了解日志框架的设计原理,学习如何优化日志系统,以及如何基于Log4j进行自定义扩展。尽管Log4j后续有更先进的版本,如Log4j2,但对1.2.17版本的学习仍有助于理解...
《深入理解log4j-1.2.17:日志管理的核心工具》 日志管理在软件开发中扮演着至关重要的角色,它为开发者提供了系统运行情况的详细记录,帮助排查错误,优化性能。而log4j作为Java平台上的经典日志框架,自其诞生...