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

Apache-Log4j

Log4j简单的来说由三大基本构件组成: logger(日志记录器),appender(输出目的地),layout(日志输出格式)。

  • logger记录器对日志信息进行分类筛选。通过指定优先级,控制程序中日志信息的输出:高于优先级的日志可以被输出,低于优先级的日志则被忽略。
  • appender指定日志信息的输出设备,比如文件、控制台等。
  • layout布局指定日志输出的格式。

软件开发人员可以通过这三大构件,根据日志的类型和优先级进行记录,并且可以在程序运行时去控制日志信息输出的格式和往什么地方输出(控制台、日志文件)。

Apache Log4j 2
https://logging.apache.org/log4j/2.x/


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(将日志信息以流格式发送到任意指定的地方)

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

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

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

为不同的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 ");
    }
}

Logger记录器

日志输出级别

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

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

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

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.masikkk.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.masikkk.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


Layout布局格式

Layouts
https://logging.apache.org/log4j/2.x/manual/layouts.html

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

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

Pattern Layout

Pattern Layout
https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout

Pattern Layout 通过提供的模式,来格式化日志信息。
org.apache.Log4j.PatternLayout 继承自抽象类 org.apache.Log4j.Layout,覆盖了其 format() 方法

格式字符

Pattern Layout 采用类似C语言中的 printf 函数的打印格式格式化日志信息: 百分号 %加转换符
例如:

<properties>
  <property name="PATTERN">%d{yyyy-MM-dd HH:mm:ss,SSS} [%-5level] [%thread] %c.%M [%L]: %msg%n</property>
</properties>
%d|%date 时间

%d{pattern}, %date{pattern}, 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如: %d{HH:mm:ss,SSS} 或 %d{dd MMM yyyy HH:mm:ss,SSS}

%p|%level 日志级别

p|level{level=label, level=label, ...},
p|level{length=n},
p|level{lowerCase=true|false},
输出级别,即DEBUG,INFO,WARN,ERROR,FATAL
可以自定义标签映射level=label,则对应的level将打印为映射的label,例如
%level{WARN=Warning, DEBUG=Debug, ERROR=Error, TRACE=Trace, INFO=Info}
则日志输出时,WARN 将打印为 Warning

%t|%thread 线程名

t, tn, thread, threadName, 输出产生该日志事件的线程名。

%c|%logger logger名(类名)

c{precision}, logger{precision}, 删除logger名,通常就是所在类的全名。
precision 指定精度,值是正整数时输出从最右侧开始的对应个数的名字,值是负整数时删除从最左侧开始的对应个数的名字, 包含非整数字符时会根据模式缩写名字
例如 logger 名为 org.apache.commons.Foo, 则
%c{1} 是 Foo
%c{2} 是 commons.Foo
%c{10} 是 org.apache.commons.Foo
%c{-1} 是 apache.commons.Foo
%c{-2} 是 commons.Foo
%c{-10} 是 org.apache.commons.Foo
%c{1.} 是 o.a.c.Foo
%c{1.1..} 是 o.a...Foo
%c{.} 是 ….Foo

%M|%method 方法名

M, method, 输出发起日志请求的方法名

%L|%line 行号

L, line, 输出发起日志请求的行号

%m|%msg 日志消息内容

m{nolookups}{ansi},
msg{nolookups}{ansi},
message{nolookups}{ansi},
日志消息内容

%replace 替换

replace{pattern}{regex}{substitution}
将 pattern 中匹配 regex 正则的部门替换为 substitution
例如:

%replace{%msg}{\s}{} , 删除 msg 中的所有空白
%replace{%logger %msg}{\.}{/}, 将logger和msg中的所有点都替换为斜杠
%replace{%msg}{\"}{'}%replace{%xEx{separator(|)}}{\t}{}, 将msg中的双引号替换为单引号,用 | 做换行符,并删除其中的 \t 制表符
%xEx|%xException|%xThrowable 异常信息
xEx|xException|xThrowable
  {
    ["none" | "short" | "full" | depth]
    [,filters(package,package,...)]
    [,separator(separator)]
  }
  {ansi(
    Key=Value,Value,...
    Key=Value,Value,...
    ...)
  }
  {suffix(pattern)}

%rEx{n} //输出日志信息的前n行
%rEx{none} or %rEx{0} //下面的语句会抑制异常信息的输出
filters(packages) //下面的语句会抑制packages包内的异常输出,packages是一个包名列表
separator(|) //separator可以用来设置换行分隔符,默认的是系统的换行符,下面的语句会根据“|”来换行。

%n 换行

%n, 输出一个回车换行符,Windows平台为 \r\n,Unix平台为\n

%X/%mdc 自定义MDC值

X{key[,key2...]},
mdc{key[,key2...]},
MDC{key[,key2...]},
该字符后跟 MDC 键,比如 X{clientIP} 会输出保存在 MDC 中键 clientIP 对应的值。
例如 %X{request_id} 输出MDC中的 key 是 request_id 的值
request_id 用来追踪一次 Request 请求处理,在请求进入的时候写入:

MDC.put("request_id", RequestIdGenerator.generateRequestId());

请求结束时清除:

MDC.clear();

宽度和精度

宽度和精度控制放在百分号 % 和 格式字符之间, 例如 %-5level 表示日志级别占固定5个字符的宽度,宽度不足时左对齐(即右补空格)
%20c, 长度小于20字符时左补空格(右对齐)
%-20c, 长度小于20字符时右补空格(左对齐)
%.30c, 长度大于30字符时从开头截断
%20.30c, 长度小于20字符时左补空格, 长度大于30字符时从开头截断
%-20.30c, 长度小于20字符时右补空格, 长度大于30字符时从开头截断
%-20.-30c, 长度小于20字符时右补空格, 长度大于30字符时从结尾截断


JSON Layout

properties, boolean, 是否包含 MDC 信息,默认为false
locationInfo, boolean, 是否包含location信息,默认为false
compact, boolean, 是否压缩,默认为false,值为true时没有缩进和换行
eventEol, boolean, 是否在每条记录后增加换行,默认为false. 使用 compact=”true” eventEol=”true” 可保证每行一条记录但又不带缩进的紧凑格式。

<JsonLayout properties="true" locationInfo="true" compact="true" eventEol="true">
</JsonLayout>

NDC和MDC

NDC

NDC(Nested Diagnostic Context)是 Neil Harrison 在名为《 Patterns for Logging Diagnostic Messages 》的书中提出的嵌套诊断环境的机制。这种机制的提出,主要为了减少多线程的系统为每个客户单独记录日志的系统开销。在过去,区分两个客户的日志输出的常用方法是单独为每个客户机实例化新类别,但该方法会增加类别数量,并增加日志记录的管理开销。Neil Harrison 提出的方法就是把用户的上下文信息放到嵌套式诊断环境 (NDC) 中。

NDC 为每一个线程管理一个堆栈。开发人员可以在代码中合适的位置嵌入简单的 push 和 pop 方法,用来维护堆栈。通常 push 进堆栈的是可以唯一标示客户的上下文信息,如 SessionID 或者客户名称,IP 地址等。因为每个客户请求都会有单独的 NDC 堆栈,因此日志系统在输出的时候会根据每个线程找到对应的堆栈,并在输出日志的时候附加上堆栈内的信息。开发人员就可以很容易的在日志中区分出各个不同客户所产生的日志条目。

Log4J 从 1.2 起开始支持 NDC

MDC

MDC ( Mapped Diagnostic Contexts )
MDC 和 NDC 相似,也可以减少多线程的系统为每个客户单独记录日志的系统开销。它同样是为每个线程建立一个独立的存储空间,开发人员可以根据需要把信息存入其中。不同的是 MDC 使用 Map 的机制来存储信息,信息以 key/value 对的形式存储在 Map 中。

Log4J 从 1.3 alpha 版本开始提供对 MDC 的支持,org.apache.log4j.MDC 声明如下:

public class MDC {
   // 清空 map 所有的条目。
   public static void clear();
   // 根据 key 值返回相应的对象
   public static object get(String key);
   // 返回所有的 key 值 .
   public static Enumeration getKeys();
   // 把 key 值和关联的对象,插入 map 中
   public static void put(String key, Object val);
   // 删除 key 对应的对象
   public static  remove(String key);
}

MDC 和 NDC 的使用方法也类似,区别只是在 Log4J 配置文件中,在通过 PatternLayout 的 ConversionPattern 来配置日志的格式的时候,需要使用 %x{key} 来输出相应的用户标志信息对象。

在 Web 应用中增加用户跟踪功能
https://www.ibm.com/developerworks/cn/web/wa-lo-usertrack/index.html

Slf4j MDC 使用和 基于 Logback 的实现分析
https://ketao1989.github.io/2015/04/29/LogBack-Implemention-And-Slf4j-Mdc/


通过注解向MDC中放请求ID

@RequestId 注解的方法,会向当前线程MDC写入新生成的 request_id ,方法结束后清除,在日志layout配置中通过 %X{request_id} 输出,方便跟踪一次请求处理。可以放在Controller方法上。

注解:

package com.masikkk.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

// 记录requestId
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestId {
}

切面:

@Aspect
@Component
public class MDCAspect {
  // 注解切点
  @Pointcut("@annotation(com.masikkk.annotation.RequestId)")
    public void requestIdPointCut() {
  }

  @Around("requestIdPointCut()")
  public Object doRequestIdAspect(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
      MDC.put("request_id", RequestIdGenerator.generateRequestId());
      Object response = proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());
      MDC.clear();
      return response;
  }
}

Log4j使用

不要直接使用 Log4j, 应该使用日志门面 SLF4J, 屏蔽不同日志实现的差异。
阿里巴巴Java开发规范中也做了强制规定:

  1. 【强制】应用中不可直接使用日志系统(Log4j、Logback)中的API,而应依赖使用日志框架SLF4J中的API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    private static final Logger logger = LoggerFactory.getLogger(Abc.class);
    

配置Log4j
http://www.blogjava.net/zJun/archive/2006/06/28/55511.html

Log4j – 如何配置多个logger?
http://blog.csdn.net/evatian/article/details/8501517

log4j配置文件中的additivity属性
http://blog.csdn.net/junshao90/article/details/8364812

最详细的Log4j使用教程
http://www.codeceo.com/article/log4j-usage.html


一个xml配置实例

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <properties>
    <property name="PATTERN">@%d{yyyy-MM-dd HH:mm:ss,SSS} [%-5level] RID=%X{requestId} -- [%thread] %c [%L]: %msg%n
    </property>
  </properties>

  <appenders>
    <Console name="Console" target="system_out">
      <PatternLayout pattern="${PATTERN}"/>
    </Console>

    <!-- 按天滚动日志 -->
    <RollingRandomAccessFile name="RollingRandomAccessFile"
      fileName="/data/log/app/app.log"
      filePattern="/data/log/app/app-%d{yyyy-MM-dd}.log">
      <PatternLayout pattern="${PATTERN}"/>
      <Policies>
        <TimeBasedTriggeringPolicy interval="1" />
      </Policies>
      <!-- 保留5天 -->
      <DefaultRolloverStrategy>
        <Delete basePath="/data/log/app/" maxDepth="1">
          <IfFileName glob="app-*.log" />
          <IfLastModified age="5d" />
        </Delete>
      </DefaultRolloverStrategy>
    </RollingRandomAccessFile>

    <!-- json格式的按天滚动日志 -->
    <RollingRandomAccessFile name="RollingRandomAccessJsonFormatFile"
      fileName="/data/log/app/app-json.log"
      filePattern="/data/log/app/app-json-%d{yyyy-MM-dd}.log">
      <JsonLayout properties="true" locationInfo="true" compact="true" eventEol="true">
      </JsonLayout>
      <Policies>
        <TimeBasedTriggeringPolicy interval="1"/>
      </Policies>
      <DefaultRolloverStrategy>
        <Delete basePath="/data/log/app/" maxDepth="1">
          <IfFileName glob="app-json*.log" />
          <IfLastModified age="2d" />
        </Delete>
      </DefaultRolloverStrategy>
    </RollingRandomAccessFile>
  </appenders>

  <loggers>
    <AsyncRoot level="info" includeLocation="true">
      <appenderref ref="Console"/>
      <appenderref ref="RollingRandomAccessFile"/>
      <appenderref ref="RollingRandomAccessJsonFormatFile"/>
    </AsyncRoot>
    <!-- com.app.falcon类的只输出warn及以上级别日志 -->
    <logger name="com.app.falcon" level="WARN" additivity="false">
      <appender-ref ref="Console"/>
    </logger>
  </loggers>
</configuration>

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

下一篇 JDK-Tools-概览

阅读
评论
5,030
阅读预计22分钟
创建日期 2016-05-23
修改日期 2019-09-20
类别

页面信息

location:
protocol:
host:
hostname:
origin:
pathname:
href:
document:
referrer:
navigator:
platform:
userAgent:

评论