当前位置 : 首页 » 文章分类 :  开发  »  Apache-Log4j

Apache-Log4j

Log4j简单的来说由3部分组成: logger(日志记录器),appender(日志输出目的地),layout(日志输出格式)。

Log4j简单的来说由3部分组成: logger(日志记录器),appender(日志输出目的地),layout(日志输出格式)。


log4j2

log4j2的DefaultRolloverStrategy max属性要配合日志文件的计数 %i 标识使用,所以我们的日志没有自动删

How does Log4j2 DefaultRolloverStrategy’s max attribute really work?
https://stackoverflow.com/questions/24551768/how-does-log4j2-defaultrolloverstrategys-max-attribute-really-work

RollingFileAppender

RollingFileAppender是Log4j2中的一种能够实现日志文件滚动更新(rollover)的Appender。

rollover的意思是当满足一定条件(如文件达到了指定的大小,达到了指定的时间)后,就重命名原日志文件进行归档,并生成新的日志文件用于log写入。如果还设置了一定时间内允许归档的日志文件的最大数量,将对过旧的日志文件进行删除操作。

RollingFile实现日志文件滚动更新,依赖于TriggeringPolicy和RolloverStrategy。
其中,TriggeringPolicy为触发策略,其决定了何时触发日志文件的rollover,即When
RolloverStrategy为滚动更新策略,其决定了当触发了日志文件的rollover时,如何进行文件的rollover,即How

Log4j2提供了默认的rollover策略DefaultRolloverStrategy。

Log4j2中RollingFile的文件滚动更新机制(讲的非常清晰)
https://www.cnblogs.com/yeyang/p/7944899.html

Policies 何时触发日志滚动(产生新日志文件)

jvm启动,达到20兆,或时间触发满足其中之一则触发rollover

<Policies>
  <OnStartupTriggeringPolicy />
  <SizeBasedTriggeringPolicy size="20 MB" />
  <TimeBasedTriggeringPolicy />
</Policies>

Triggering Policies
https://logging.apache.org/log4j/2.x/manual/appenders.html#TriggeringPolicies

TimeBasedTriggeringPolicy

TimeBasedTriggeringPolicy规定了当日志文件名中的date/time pattern不再符合filePattern中的date/time pattern时,触发rollover操作

比如,filePattern指定文件重命名规则为app-%d{yyyy-MM-dd HH}.log,文件名为app-2017-08-25 11.log,当时间达到2017年8月25日中午12点(2017-08-25 12),将触发rollover操作。

TimeBasedTriggeringPolicy 有两个参数:
interval integer 此参数需要与filePattern结合使用,规定了触发rollover的频率,默认值为1。假设interval为4,若filePattern的date/time pattern的最小时间粒度为小时(如yyyy-MM-dd HH),则每4小时触发一次rollover;若filePattern的date/time pattern的最小时间粒度为分钟(如yyyy-MM-dd HH-mm),则每4分钟触发一次rollover。

modulate boolean 指明是否对interval进行调节,默认为false。若modulate为true,会以0为开始对interval进行偏移计算。例如,最小时间粒度为小时,当前为3:00,interval为4,则以后触发rollover的时间依次为4:00,8:00,12:00,16:00,…。

例如

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <RollingFile name="RollingFile" fileName="logs/app.log"
                 filePattern="logs/app-%d{yyyy-MM-dd HH}-%i.log">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <TimeBasedTriggeringPolicy />
        <SizeBasedTriggeringPolicy size="250 MB"/>
      </Policies>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="RollingFile"/>
    </Root>
  </Loggers>
</Configuration>

上述配置文件中,filePattern中 yyyy-MM-dd HH 最小时间粒度为小时,TimeBasedTriggeringPolicy中interval使用默认值1,将每1小时触发一次rollover。
若将filePattern改为 filePattern="logs/app-%d{yyyy-MM-dd HH-mm}-%i.log” ,yyyy-MM-dd HH-mm最小时间粒度为分钟,将每1分钟触发一次rollover。

Log4j2中RollingFile的文件滚动更新机制(讲的非常清晰)
https://www.cnblogs.com/yeyang/p/7944899.html

DefaultRolloverStrategy 如何滚动日志

Rollover Strategies
https://logging.apache.org/log4j/2.x/manual/appenders.html#RolloverStrategies

Delete

配置说明:
只处理位于logs文件夹下的文件.
只处理以.log.zip结尾的文件 (name match)
只处理最后一次修改时间超过4天的文件

<DefaultRolloverStrategy>
 <Delete basePath="${sys:storm.home}/logs/" maxDepth="1">
   <IfFileName glob="*.log.zip" />
   <IfLastModified age="4d" />
 </Delete>
</DefaultRolloverStrategy>

Log Archive Retention Policy: Delete on Rollover
https://logging.apache.org/log4j/2.x/manual/appenders.html#CustomDeleteOnRollover

RollingRandomAccessFileAppender


logs4j

logger的继承属性

Logger之间是具有java的继承特性的。
Log4j有一个rootLogger,所有普通logger都默认继承rootLogger。而普通logger之间的继承关系是通过logger name来实现的。
例如,叫”com.foo.Bar”名字的logger就继承于叫”com.foo”名字的logger。就好像java中”java.util” 和”java.util.Vector”的关系一样。
而这些继承关系决定了logger的Level和Appender这两个属性的确定:如果一个普通logger定义了Level,则其level就使用它定义的,如果没有定义,就使用其父logger的。

additivity属性

它是 子Logger 是否继承 父Logger 的 输出源(appender) 的标志位。具体说,默认情况下子Logger会继承父Logger的appender,也就是说子Logger会在父Logger的appender里输出。若是additivity设为false,则子Logger只会在自己的appender里输出,而不会在父Logger的appender里输出。

例如

log4j.rootLogger=info, A7

log4j.logger.push=info, A14
log4j.additivity.push=false

log4j.appender.A7=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A7.file=/opt/applog/re-ras/warning/re-ras-warning.log
log4j.appender.A7.DatePattern='_'yyyy-MM-dd'.log'
log4j.appender.A7.encoding=UTF-8
log4j.appender.A7.layout=org.apache.log4j.PatternLayout
log4j.appender.A7.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

log4j.appender.A14=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A14.file=/opt/applog/re-ras/warning/push.log
log4j.appender.A14.DatePattern='_'yyyy-MM-dd'.log'
log4j.appender.A14.encoding=UTF-8
log4j.appender.A14.layout=org.apache.log4j.PatternLayout
log4j.appender.A14.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

如果不加log4j.additivity.push=false配置项,名为push的logger的日志文件push.log中的内容也会输出在其父logger(即rootLogger)的文件re-ras-warning.log中。

Log4j additivity则使指是否输出到顶层包定义的Appender中,如com.pa中定义了一个Appender A1,而com.pa.pb中又定义了一个Appender A2,则程序运行时,com.pa.pb中的类若有日志输出,则既会输出到A1中,也会输出到A2中。
有些时候,A2的处理可能比较专职化,不希望其日志掺杂到全局或高层的日志记录中,则可以使用additivity功能来实现。

单独设定指定类的日志级别

com.nio.uds.common.falcon 类的日志级别设为 WARN,不打印到文件appenders RollingRandomAccessFile 中,只在控制台打印

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <loggers>
    <AsyncRoot level="${sys:log.level}" includeLocation="true">
      <appenderref ref="Console"/>
      <appenderref ref="RollingRandomAccessFile"/>
    </AsyncRoot>
    <logger name="com.nio.uds.common.falcon" level="WARN" additivity="false">
      <appender-ref ref="Console"/>
    </logger>
  </loggers>
</configuration>

log4j additivity解说
https://blog.csdn.net/hongweigg/article/details/14169477

Configuration - Additivity (log4j2官方文档)
https://logging.apache.org/log4j/2.x/manual/configuration.html#Additivity


Log4j配置

Log4J的配置文件(Configuration File)就是用来设置记录器的级别、存放器和布局的。Log4j支持两种配置文件格式,一种是XML格式的文件,一种是Java特性文件log4j.properties(键=值)。下面将介绍使用log4j.properties文件作为配置文件的方法。

properties配置基本格式

Log4J配置文件的基本格式如下:

# 配置根Logger
log4j.rootLogger  =   [ level ]   ,  appenderName1 ,  appenderName2 ,  …

# 配置日志信息输出目的地Appender
log4j.appender.appenderName  =  fully.qualified.name.of.appender.class
log4j.appender.appenderName.option1  =  value1
... ...
log4j.appender.appenderName.optionN  =  valueN
# 配置日志信息的格式(布局)
log4j.appender.appenderName.layout  =  fully.qualified.name.of.layout.class
log4j.appender.appenderName.layout.option1  =  value1
... ...
log4j.appender.appenderName.layout.optionN  =  valueN

日志输出级别

其中 [level] 是日志输出级别,共有5级:

  • FATAL 0
  • ERROR 3
  • WARN 4
  • INFO 6
  • DEBUG 7

Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。比如在这里定义了INFO级别,只有等于及高于这个级别的才进行处理,则应用程序中所有DEBUG级别的日志信息将不被打印出来。ALL: 打印所有的日志,OFF:关闭所有的日志输出。


Appender

Log4j Appender则可理解为定义一个输出方式,例如可以输出到控制台,也可以输出到文件(固定周期,每天使用一个日志文件记录;固定大小,超过指定大小则记录到一个新问价中),还可以输出到数据库,甚至可以远程输出到一个日志接口程序中进行记录。

Appender配置好以后,记录哪个程序包运行时的日志呢?
答案是通过log4j.logger来指定,log4j.logger后带的包名即为Appender要记录的程序包范围,如下面的例子:
log4j.logger.com.sgcc=debug, platform1

platform1是事先定义好的一个Appender,log4j.logger.com.sgcc表示对程序包com.sgcc中的程序使用Appender(名为:platform1)。

下面是一个Appender platformat1的配置:

log4j.appender.platform1=org.apache.log4j.RollingFileAppender
log4j.appender.platform1.File=${LOG_DIR}/trace.log
log4j.appender.platform1.MaxBackupIndex=100
log4j.appender.platform1.MaxFileSize=5000000
log4j.appender.platform1.layout=org.apache.log4j.PatternLayout
log4j.appender.platform1.layout.ConversionPattern=[%d{ISO8601}] :%-5p %-x %X{user} %n     %m%n

一个程序包可以指定多个Appender,也就是说,一个程序包的日志可以输出到多个不同的目的地中去。例如:
log4j.logger.com.sgcc=debug, platform1,platform2,platform3

使用该配置,程序包com.sgcc的日志可以输出到platform1,platform2,platform3三个Appender中。

Appender类型

Appender 为日志输出目的地,Log4j提供的appender有以下几种:

  • org.apache.log4j.ConsoleAppender(控制台),
  • org.apache.log4j.FileAppender(文件),
  • org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),
  • org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件),
  • org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

Layout布局格式

日志输出格式,Log4j提供的layout有以下几种:

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

打印参数

Log4J采用类似C语言中的printf函数的打印格式格式化日志信息,如下:

  • %m 输出代码中指定的消息
  • %p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
  • %r 输出自应用启动到输出该log信息耗费的毫秒数
  • %c 输出所属的类目,通常就是所在类的全名
  • %t 输出产生该日志事件的线程名
  • %n 输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n”
  • %d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss , SSS},输出类似:2002年10月18日 22 : 10 : 28 , 921
  • %l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java: 10 )

Log4j使用

在代码中使用Log4j

  • 1.获得记录器
    使用Log4j,第一步就是获取日志记录器,这个记录器将负责控制日志信息。其语法为:
    public static Logger getLogger( String name)
    通过指定的名字获得记录器,如果必要的话,则为这个名字创建一个新的记录器。Name一般取本类的名字,比如:
    static Logger logger = Logger.getLogger( ServerWithLog4j.class.getName() )
  • 2.读取配置文件
    第二步读取log4j配置文件,其语法为:
    BasicConfigurator.configure(); //自动快速地使用缺省Log4j环境。
    PropertyConfigurator.configure( String configFilename); //读取使用Java的特性文件编写的配置文件。
    DOMConfigurator.configure( String filename ); //读取XML形式的配置文件。
    
  • 3.写入日志
    Logger.info(msg), Logger.error(msg)等

为不同的Appender设置日志输出级别

当调试系统时,我们往往注意的只是异常级别的日志输出,但是通常所有级别的输出都是放在一个文件里的,如果日志输出的级别是debug,那就慢慢去找吧。
这时我们也许会想要是能把异常信息单独输出到一个文件里该多好啊。当然可以,Log4j已经提供了这样的功能,我们只需要在配置中修改Appender的Threshold 就能实现,比如下面的例子:

配置文件:

### set log levels ###
log4j.rootLogger = debug ,  stdout ,  D ,  E

### 输出到控制台 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern =  %d{ABSOLUTE} %5p %c{ 1 }:%L - %m%n

### 输出到日志文件 ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG ## 输出DEBUG级别以上的日志
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### 保存异常信息到单独文件 ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File = logs/error.log ## 异常日志文件名
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR ## 只输出ERROR级别以上的日志!!!
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

java代码:

 public   class  TestLog4j  {
     public   static   void  main(String[] args)  {
        PropertyConfigurator.configure( "D:/Code/conf/log4j.properties" );
        Logger logger  =  Logger.getLogger(TestLog4j.class);
        logger.debug(" debug ");
        logger.error(" error ");
    }
}

参考


上一篇 Hexo博客(07)访问量统计

下一篇 JDK-Tools-概览

阅读
3,228
阅读预计14分钟
创建日期 2016-05-23
修改日期 2019-01-02
类别
百度推荐