Log4j 笔记

Log4j 彷佛已经被淘汰了为何还要写这篇文章?html

log4j、log4j二、logback 从基础思想上三者的实现是一致的,无非就是输出内容到文件,且看配置文件也都大同小异(logger、appender、layout),无非后二者比前者具备更多的高级功能,此块能够单独拎出讲。因此若是想了解本质,从最开始的版本开始会比较好下手。java

简单体验

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
复制代码

测试类:mysql

public static void main(String[] args) {
    Logger logger = Logger.getLogger(Log4jTest.class);
    logger.debug("log4j debug");
    logger.info("log4j info");
    logger.error("log4j error");
}
复制代码

输出到控制台:log4j.propertiessql

# 定义一个名为 csAppender 的日志附加器
log4j.appender.csAppender=org.apache.log4j.ConsoleAppender
log4j.appender.csAppender.Threshold=INFO
log4j.appender.csAppender.Target=System.out
log4j.appender.csAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.csAppender.layout.ConversionPattern=[%d] [%t] [%c.%M:%L] [%-5p]: %m%n

# 配置根日志级别为 debug,并设置输出器为刚定义的 csAppender
log4j.rootLogger=debug,csAppender
复制代码

输出到文件:log4j.properties数据库

# 定义一个名为 fileAppender 的日志附加器
log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender
log4j.appender.fileAppender.Threshold=INFO
log4j.appender.fileAppender.File=D://data//usr//local//logs//home//log4j-log.log
log4j.appender.fileAppender.DatePattern = '.'yyyy-MM-dd'.log'
log4j.appender.fileAppender.Encoding=UTF-8
log4j.appender.fileAppender.Append=true
log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.fileAppender.layout.ConversionPattern=[%d] [%t] [%-5p] [%c.%M:%L]: %m%n
# 配置根日志级别为 debug,并设置输出器为刚定义的 fileAppender
log4j.rootLogger=debug,fileAppender
复制代码

上面示例配置中的 root 日志实例分别使用 csAppender(控制台)、fileAppender(文件)附加器将日志内容输出到目的地。固然也能够同时输出。log4j 官网并无对配置进行说明,但在 org.apache.log4j.PropertyConfigurator#doConfigure 方法注释上可看到完整的说明。apache

第一步须要配置根 Logger 格式以下:多线程

log4j.rootLogger = [level] , appenderName1, appenderName2, …
复制代码
  • level 设定日志记录的最低级别,可设的值有 OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者自定义的级别,好比在这里设定了INFO级别,则应用程序中全部DEBUG级别的日志信息将不会被打印出来。app

  • appenderNamesocket

    就是指定日志信息要输出到哪里。能够同时指定多个输出目的地,用逗号隔开。 例如:log4j.rootLogger=INFO,A1,B2,C3布局

第二步配置日志信息输出目的地(appender)格式以下:

# For appender named
log4j.appender.appenderName=fully.qualified.name.of.appender.class
# Set appender specific options.
log4j.appender.appenderName.option1=value1
...
log4j.appender.appenderName.optionN=valueN
复制代码

三大组件

Log4j has three main components: loggers, appenders and layouts. These three types of components work together to enable developers to log messages according to message type and level, and to control at runtime how these messages are formatted and where they are reported.

Log4j 有三个主要的组件:Loggers(记录器),Appenders (输出源)和 Layouts(布局)。这里可简单理解为日志类别,日志要输出的地方和日志以何种形式输出。综合使用这三个组件能够轻松地记录信息的类型和级别,并能够在运行时控制日志输出的样式和位置。

Logger

Loggers 组件在此系统中被分为五个级别:DEBUG、INFO、WARN、ERROR和FATAL。这五个级别是有顺序的,DEBUG < INFO < WARN < ERROR < FATAL,分别用来指定这条日志信息的重要程度。Log4j 有一个规则:只输出级别不低于设定级别的日志信息。假设 Loggers 级别设定为 INFO,则 INFO、WARN、ERROR 和 FATAL 级别的日志信息都会输出,而级别比 INFO 低的 DEBUG 则不会输出。

定义 logger

Log4J 中老是存在一个 rootLogger,即便没有显示配置也是存在的,而且默认输出级别为 DEBUG。其它的 logger 都继承自这个 rootLogger(若是其余logger未单独定义其输出级别)。

其次,Log4J 中的层次(Hierarchy)是用 '.' 来分隔的,如 log4j.logger.com.example.test,并非说 log4j.logger 后面必定是具体的包名乃至类名,这个名称能够自定义,咱们甚至能够定义一个log4j.logger.A.B.C,以下例所示,创建了 3 个 logger 实例,它们分别是 AA.BA.B.C

## log4j.properties
log4j.logger.A.B.C = ERROR,appenderName
## 在代码中获取名为 A.B 的日志对象
Logger logger = Logger.getLogger("A.B")
复制代码

当获取不到当前须要的 logger 时,查找动做会传递,直到 root 节点仍没找到对应名字的 logger,就返回 root logger 实例。

Appender

Each enabled logging request for a given logger will be forwarded to all the appenders in that logger as well as the appenders higher in the hierarchy

log4j 官网这句话的意思是,logger 对象能够继承,且 appender 是能够累加的。当调用层次较低的 logger 对象输出日志时,log4j 会把该请求输出到当前全部附加在此 logger 上的全部 appender。

假设存在以下配置文件:

log4j.rootLogger=DEBUG,consoleAppender

log4j.logger.com=DEBUG,consoleAppender
log4j.logger.com.A.B=INFO,consoleAppender
log4j.logger.com.X=INFO,consoleAppender

## ... 省略 consoleAppender 配置
复制代码

则 log4j 日志容器中存在以下图示实例关系:

对于名为 A.B 的 logger 输出的日志会往控制台输出三次,缘由是 A.B 继承 A 的以及A 的父 logger 的全部 appender,这种继承关系仅仅是把父 logger 的 appender 添加到本身的 appender 列表中,父 logger 的输出 level 不会影响子 logger 的输出。

log4j.rootLogger=DEBUG,consoleAppender
log4j.logger.A=DEBUG,consoleAppender
log4j.logger.A.B=INFO,consoleAppender
log4j.additivity.A.B=false
复制代码

名为 A.B 的 logger 日志仅会输出到本身的 appender 中,不会继承任何父 logger 的 appender。

若想对输出到 appender 中的日志级别进行限制的话,就须要用到 threshold 来控制。

log4j.threshold=ERROR
复制代码

用来控制全部的 appender,即输出到全部appender的日志,无论原来是什么级别的,都不能低于threshold所规定的级别。

log4j.appender.Console.threshold=ERROR 
复制代码

用来控制指定的 appender 的输出级别。

Log4j 日志系统还提供许多强大的功能,好比容许把日志输出到不一样的地方,如控制台(Console)、文件(Files)等,能够根据天数或者文件大小产生新的文件,能够以流的形式发送到其它地方等等。

控制台(console)

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.ImmediateFlush=true
log4j.appender.console.Target=System.err
log4j.appender.console.layout=org.apache.log4j.PatternLayout
复制代码

日志文件(logFile)

log4j.appender.logFile=org.apache.log4j.FileAppender
log4j.appender.logFile.Threshold=DEBUG
log4j.appender.logFile.ImmediateFlush=true
log4j.appender.logFile.Append=true
log4j.appender.logFile.File=D:/logs/log.log4j
log4j.appender.logFile.layout=org.apache.log4j.PatternLayout
复制代码

回滚文件(rollingFile)

  • Threshold=WARN:指定日志信息的最低输出级别,默认为DEBUG
  • ImmediateFlush=true:表示全部消息都会被当即输出,设为false则不输出,默认值是true。
  • Append=false:true表示消息增长到指定文件中,false则将消息覆盖指定的文件内容,默认值是true。
  • File=D:/logs/logging.log4j:指定消息输出到logging.log4j文件中。
  • MaxFileSize=100KB:后缀能够是KB, MB 或者GB。在日志文件到达该大小时,将会自动滚动,即将原来的内容移到logging.log4j.1文件中。
  • MaxBackupIndex=2:指定能够产生的滚动文件的最大数,例如,设为2则能够产生logging.log4j.1,logging.log4j.2两个滚动文件和一个logging.log4j文件。
log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender
log4j.appender.rollingFile.Threshold=DEBUG
log4j.appender.rollingFile.ImmediateFlush=true
log4j.appender.rollingFile.Append=true
log4j.appender.rollingFile.File=D:/logs/log.log4j
log4j.appender.rollingFile.MaxFileSize=200KB
log4j.appender.rollingFile.MaxBackupIndex=50
log4j.appender.rollingFile.layout=org.apache.log4j.PatternLayout
复制代码

按期回滚日志文件(dailyFile)

DatePattern='.'yyyy-MM:即每个月产生一个新的日志文件。当前月的日志文件名为 logging.log4j,前一个月的日志文件名为 logging.log4j.yyyy-MM。另外,也能够指定按周、天、时、分等来滚动日志文件,对应的格式以下:

- yyyy-MM:每个月
- yyyy-ww:每周
- yyyy-MM-dd:天天
- yyyy-MM-dd-a:天天两次
- yyyy-MM-dd-HH:每小时
- yyyy-MM-dd-HH-mm:每分钟
复制代码
log4j.appender.dailyFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.dailyFile.Threshold=DEBUG
log4j.appender.dailyFile.ImmediateFlush=true
log4j.appender.dailyFile.Append=true
log4j.appender.dailyFile.File=D:/logs/log.log4j
log4j.appender.dailyFile.DatePattern='.'yyyy-MM-dd
log4j.appender.dailyFile.layout=org.apache.log4j.PatternLayout
复制代码

应用于 socket

log4j.appender.socket=org.apache.log4j.RollingFileAppender
log4j.appender.socket.RemoteHost=localhost
log4j.appender.socket.Port=5001
log4j.appender.socket.LocationInfo=true
复制代码

发送日志到指定邮件

log4j.appender.mail=org.apache.log4j.net.SMTPAppender
log4j.appender.mail.Threshold=FATAL
log4j.appender.mail.BufferSize=10
log4j.appender.mail.From = xxx@mail.com
log4j.appender.mail.SMTPHost=mail.com
log4j.appender.mail.Subject=Log4J Message
log4j.appender.mail.To= xxx@mail.com
log4j.appender.mail.layout=org.apache.log4j.PatternLayout
复制代码

应用于数据库

log4j.appender.database=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.database.URL=jdbc:mysql://localhost:3306/test
log4j.appender.database.driver=com.mysql.jdbc.Driver
log4j.appender.database.user=root
log4j.appender.database.password=
log4j.appender.database.sql=INSERT INTO LOG4J (Message) VALUES('=[%-5p] %d(%r) --> [%t] %l: %m %x %n')
log4j.appender.database.layout=org.apache.log4j.PatternLayout
复制代码

Layout

有时用户但愿根据本身的喜爱格式化本身的日志输出,Log4j 能够在 Appenders 的后面附加Layouts来完成这个功能。Layouts 提供四种日志输出样式,如根据HTML样式、自由指定样式、包含日志级别与信息的样式和包含日志时间、线程、类别等信息的样式。常使用的类以下:

- org.apache.log4j.HTMLLayout(以HTML表格形式布局)
- org.apache.log4j.PatternLayout(能够灵活地指定布局模式)
- org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串)
- org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等信息)
复制代码

格式化符号说明

%p:输出日志信息的优先级,即DEBUG,INFO,WARN,ERROR,FATAL。
%d:输出日志时间点的日期或时间,默认格式为ISO8601,也能够在其后指定格式,如:%d{yyyy/MM/dd HH:mm:ss,SSS}。
%r:输出自应用程序启动到输出该log信息耗费的毫秒数。
%t:输出产生该日志事件的线程名。
%l:输出日志事件的发生位置,至关于%c.%M(%F:%L)的组合,包括类全名、方法、文件名以及在代码中的行数。例如:test.TestLog4j.main(TestLog4j.java:10)。
%c:输出日志信息所属的类目,一般就是所在类的全名。
%M:输出产生日志信息的方法名。
%F:输出日志消息产生时所在的文件名称。
%L::输出代码中的行号。
%m::输出代码中指定的具体日志信息。
%n:输出一个回车换行符,Windows平台为"rn",Unix平台为"n"。
%x:输出和当前线程相关联的NDC(嵌套诊断环境),尤为用到像java servlets这样的多客户多线程的应用中。
%%:输出一个"%"字符。
另外,还能够在%与格式字符之间加上修饰符来控制其最小长度、最大长度、和文本的对齐方式。如:
1) c:指定输出category的名称,最小的长度是20,若是category的名称长度小于20的话,默认的状况下右对齐。
2)%-20c:"-"号表示左对齐。
3)%.30c:指定输出category的名称,最大的长度是30,若是category的名称长度大于30的话,就会将左边多出的字符截掉,但小于30的话也不会补空格。
复制代码

实战分析

定义两个 appender 分别输出到控制台和文件,针对名为 com.fingard.rh.rhf.ryb.manager.UnifiedServiceManager 日志输出级别调成 ERROR,且禁用 appender 继承,只在当前 logger 的 appender 中输出。在类 UnifiedServiceManager 中如果使用以下方式获取 logger 则日志只有在 ERROR 级别及以上会输出

Logger logger1 = Logger.getLogger(UnifiedServiceManager.class)
复制代码

分析 Logger getLogger(Class clazz) 源码可知,默认使用类全路径做为 loggerName 传入。故获取到的 logger1 即为配置文件中指定名为 com.fingard.rh.rhf.ryb.manager.UnifiedServiceManager 的日志对象。

使用技巧

在 .properties 配置文件中定义变量

LOG_HOME=D://data//usr//local//logs//home1

log4j.rootLogger=debug,fileAppender
# ...
log4j.appender.fileAppender.File=${LOG_HOME}//log4j-log.log
复制代码

差很少是隐藏功能了...

log4j 不一样模块输出到不一样的文件

不一样模块:以包名为 loggerName 定义多个 logger 实例

不一样文件:定义多个 fileAppender,并与对应的 loggerName 的 logger 实例关联

参考:www.cnblogs.com/0201zcr/p/5…

日志输出动态改变路径

参考:blog.csdn.net/wiwipetter/…

参考

相关文章
相关标签/搜索