log4j2.xml文件详解及在日志中加入全局guid
作者:zhangxiaomin19921
log4j2.xml文件及在日志中加入全局guid
<Configuration status="WARN" monitorInterval="30"> <Appenders> <!-- 输出到控制台 --> <Console name="STDOUT" target="SYSTEM_OUT"> <!-- %d 日期 %p 日志级别 %c 输出所属的类目,通常就是所在类的全名 [%t] 线程 - %m 输出代码中指定的消息 %n 换行 %L : 日志输出所在行数 %M : 日志输出所在方法名 --> <PatternLayout pattern="%d %p %c [%t] - %m%n"/> </Console> <!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份-日建立的文件夹下面并进行压缩,作为存档 --> <RollingFile name="RollingFileInfo" fileName="${sys:user.home}/logs/info.log" filePattern="${sys:user.home}/logs/provider/${date:yyyy-MM-dd}/info-%d{yyyy-MM-dd}-%i.log.gz"> <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) --> <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY" /> <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n" /> <Policies> <SizeBasedTriggeringPolicy size="100 MB" /> <!-- 切割文件的话最多切割多少个 --> <DefaultRolloverStrategy max="20"/> </Policies> </RollingFile> <!-- 按照天来存储,过了这天的东西会被保存为压缩包,并且配置了大小分割 --> <RollingFile name="InfoFileAppender" fileName="${sys:user.home}/logs/info.log" filePattern="${sys:user.home}/logs/provider/${date:yyyy-MM-dd}/info-%d{yyyy-MM-dd}-%i.log.gz"> <PatternLayout pattern="%d %-5p %c:%L [%t] - %m%n"/> <Policies> <!-- 时间滚动策略,默认1小时 --> <TimeBasedTriggeringPolicy modulate="true" interval="24"/> </Policies> </RollingFile> </Appenders> <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效--> <Loggers> <Logger name="com.opensymphony.xwork2.ognl.OgnlValueStack" level="ERROR"/> <logger name="org.springframework" level="INFO"></logger> <logger name="org.mybatis" level="INFO"></logger> <Logger name="net.sf.ehcache" level="INFO"/> <Logger name="com.alisoft.xplatform.asf" level="WARN"/> <Logger name="com.mbi" level="ERROR"/> <Logger name="net.mlw" level="INFO"/> <Logger name="java.sql" level="INFO"/> <Logger name="org.hibernate.type" level="ERROR"/> <Logger name="com.opensymphony.webwork" level="ERROR"/> <Logger name="org.apache" level="INFO"/> <Logger name="org.jgroups" level="WARN"/> <Logger name="org.jboss.axis" level="INFO"/> <Logger name="org.jboss.management" level="INFO"/> <Logger name="org.apache.commons.httpclient" level="ERROR"/> <Logger name="org.springframework" level="INFO"/> <Logger name="org.springboot" level="INFO" /> <!-- 缺省日志级别,如果package有定制级别,则按package的定制级别走,即使package级别更低 --> <Root level="INFO"> <AppenderRef ref="STDOUT"/> <AppenderRef ref="RollingFileInfo"/> <!-- <AppenderRef ref="InfoFileAppender"/> --> </Root> </Loggers> </Configuration>
<AppenderRef ref="STDOUT"/>
只有定义了这个,上面的才会真实有效
- 日志信息输出到文件中,超过指定大小压缩存档
- 日志信息输出到文件中,按照日期来压缩存档
想在日志中加入全局guid需要修改日志的格式
加入自定义参数H
<PatternLayout pattern="%d %-5p %c:%L [%t] -%H %n"/>
/** * 有时候需要在日志中实现类似aop的效果,统一加进去某些参数。对于这种需要,log4j2则可以使用插件机制 * Plugin 表示的是这是一个插件,name是名称,category为PatternConverter.CATEGORY(目前插件只有这个选择) ConverterKeys表示的就是自定义的参数,可以多个 * @author yp-tc-m-7129 * */ @Plugin(name = "LogPatternConverter", category = PatternConverter.CATEGORY) @ConverterKeys({ "H" }) public class LogPatternConverter extends LogEventPatternConverter { /** * 检查全局guid是否正确 - GUID[45a696c385f341efbebf05fd0b3b1344] - TYPE[MANUAL] * @param args */ /*public static void main(String[] args) { System.out.println(getPayplusLogUUID()); }*/ private static final LogPatternConverter INSTANCE = new LogPatternConverter(); public static LogPatternConverter newInstance(final String[] options) { return INSTANCE; } private LogPatternConverter(){ super("LogId", "logId"); } /** * 另外的格式化日志,在日志中加入一个全局guid * 这里有两个参数,LogEvent是系统已经存在的一些可选数据,StringBuilder 表示的是最终的输出字符流。一般都是将自定义的append进去 */ @Override public void format(LogEvent event, StringBuilder builder) { final Message msg = event.getMessage(); if (msg != null) { String result = msg.getFormattedMessage(); result = getPayplusLogUUID() + result; builder.append(result); } } /** * 业务日志全局UUID * * @return */ protected String getPayplusLogUUID() { StringBuilder builder = new StringBuilder(); if (!ThreadContextUtils.contextInitialized()) { ThreadContextUtils.initContext("applicationName", null, ThreadContextType.MANUAL); } builder.append("- GUID["); builder.append(ThreadContextUtils.getContext().getThreadUID()); builder.append("] - TYPE["); builder.append(ThreadContextUtils.getContext().getType()); builder.append("] "); return builder.toString(); } }
这样就在日志中加入了全局guid用于查询日志处理问题了。
log4j2.x配置文件中各标签
log4j2.0以后我们通常在log4j2.xml中配置相关参数,在配置的时候我们需要理解这些参数的具体含义,下面列出了这些参数的解释。
1、Logger 完成日志信息的处理
<logger name="com.srd.ljzd" level="INFO" additivity="true"> <appender-ref ref="INFO" /> <appender-ref ref="WARN" /> <appender-ref ref="ERROR" /> <appender-ref ref="Mail" /> </logger>
logger中的name是指代码的包名或类名,路径要写全,可以配置不同包中的日志输出到不同的文件中。level是日志输出级别,定义输出的层次和决定信息是否输出,
DEBUG<INFO<WARN<ERROR
additivity设置事件是否在root logger输出,为了避免重复输出,可以在Logger 标签下设置additivity为”false”。
2、Appender 设置在哪输出日志信息
FileAppender
:普通地输出到本地文件FlumeAppender
:将几个不同源的日志汇集、集中到一处。JMSQueueAppender
VS.JMSTopicAppender
:与JMS相关的日志输出RewriteAppender
:对日志事件进行掩码或注入信息RollingFileAppender
:对日志文件进行封存(详细)RoutingAppender
:在输出地之间进行筛选路由SMTPAppender
:将LogEvent发送到指定邮件列表SocketAppender
:将LogEvent以普通格式发送到远程主机SyslogAppender
:将LogEvent以RFC 5424格式发送到远程主机AsynchAppender
:将一个LogEvent异步地写入多个不同输出地ConsoleAppender
:将LogEvent输出到命令行FailoverAppender
:维护一个队列,系统将尝试向队列中的Appender依次输出LogEvent,直到有一个成功为止
其中ConsoleAppender、RollingFileAppender和SMTPAppender较为常用。如果想详细了解,可以参考log4j的官方文档
ConsoleAppender
将输出写到System.err或System.out。如果想将输出写到System.out,设置Console标签下的target为”SYSTEM_OUT”即可;如果想将输出写到System.err,设置Console标签下的target为”SYSTEM_ERR “即可。RollingFileAppender
跟FileAppender的基本用法一样。但RollingFileAppender可以设置log文件的size(单位:KB/MB/GB)上限、数量上限,当log文件超过设置的size上限,会自动被压缩。RollingFileAppender可以理解为滚动输出日志,如果log4j 2记录的日志达到上限,旧的日志将被删除,腾出的空间用于记录新的日志,DefaultRolloverStrategy 标签的max设置压缩文件的上限(默认值为7)。SMTPAppender
主要用来给指定的E-mail发送log event。
<SMTP name="Mail" subject="****SaaS系统正式版异常信息" to="yong.shi@lengjing.info" from="message@lengjing.info" smtpUsername="message@lengjing.info" smtpPassword="LENG****1234" smtpHost="mail.lengjing.info" smtpDebug="false" smtpPort="25" bufferSize="10"> <PatternLayout pattern="[%-5p]:%d{YYYY-MM-dd HH:mm:ss} [%t] %c{1}:%L - %msg%n" /> </SMTP>
SMTPAppender默认情况下只发送ERROR级别以上的日志,在测试的时候会发现低级别的日志是不会通过邮箱发送的。
3、Layout 设置日志信息的输出格式
layout有以下几种:
org.apache.log4j.HTMLLayout
(以HTML表格形式布局)org.apache.log4j.SimpleLayout
(包含日志讯息的级别和讯息字符串)org.apache.log4j.TTCCLayout
(包含日志产生的时间、执行绪、类别等讯息)org.apache.log4j.PatterLayout
(可以灵活地指定布局格式)
详细配置可以参考官方文档。
4、Filters
Filter可以过滤log事件,并控制log输出,详细配置可以参考官方文档。
例如ThresholdFilter 可以实现单个log级别的过滤功能。
5、Status
<Configuration status="OFF" monitorInterval="30">
log4j 2定义的status级别有8个:ALL,TRACE, DEBUG, INFO, WARN, ERROR ,FATAL,OFF。其实status属性是帮助开发者找错用的,它可以检测log4j 2的配置文件是否有错,也可以检测到死循环的logger。
6、monitorInterval
<Configuration status="OFF" monitorInterval="30">
通过设置monitorInterval属性,即可设置log4j 2自动检测配置文件的时间间隔(单位:秒),最小间隔为5秒。log4j 2检测到配置文件有变化,会重新配置自己。
7、Policies 配置日志相关策略
SizeBasedTriggeringPolicy
:设置日志大小达到一定大小后打包生成压缩文件。TimeBasedTriggeringPolicy
:基于时间的触发策略。该策略主要是完成周期性的log文件封存工作。有两个参数:interval
,integer
型,指定两次封存动作之间的时间间隔。单位:以日志的命名精度来确定单位,比如yyyy-MM-dd-HH 单位为小时,yyyy-MM-dd-HH-mm 单位为分钟。modulate
,boolean
型,说明是否对封存时间进行调制。若modulate=true,则封存时间将以0点为边界进行偏移计算。比如,modulate=true,interval=4hours,那么假设上次封存日志的时间为03:00,则下次封存日志的时间为04:00,之后的封存时间依次为08:00,12:00,16:00。
这里将我在项目中常用配置贡献给大家,可以满足大部分需求。
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="OFF" monitorInterval="30"> <properties> <!--设置日志在硬盘上输出的目录--> <property name="logPath">D:/ljzx_log</property> </properties> <Appenders> <!--设置在控制台打印日志--> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="[%-5p]:%d{YYYY-MM-dd HH:mm:ss} [%t] %c{1}:%L - %msg%n" /> </Console> <!--设置级别为INFO日志输出到info.log中--> <RollingFile name="INFO" filename="${logPath}/info.log" filepattern="${logPath}/%d{YYYYMMdd}-%i-info.log.zip"> <Filters> <!--设置只输出级别为INFO的日志--> <ThresholdFilter level="INFO"/> <ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/> </Filters> <PatternLayout pattern="[ %-5p]:%d{YYYY-MM-dd HH:mm:ss} [%t] %c{1}:%L - %msg%n" /> <Policies> <!--设置每天打包日志一次--> <TimeBasedTriggeringPolicy interval="1" modulate="true"/> <!--设置日志文件满1MB后打包--> <SizeBasedTriggeringPolicy size="1 MB" /> </Policies> <DefaultRolloverStrategy max="20" /> </RollingFile> <!--设置级别为WARN日志输出到warn.log中--> <RollingFile name="WARN" filename="${logPath}/warn.log" filepattern="${logPath}/%d{YYYYMMdd}-%i-warn.log.zip"> <Filters> <!--设置只输出级别为WARN的日志--> <ThresholdFilter level="WARN"/> <ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL"/> </Filters> <PatternLayout pattern="[ %-5p]:%d{YYYY-MM-dd HH:mm:ss} [%t] %c{1}:%L - %msg%n" /> <Policies> <!--设置每天打包日志一次--> <TimeBasedTriggeringPolicy interval="1" modulate="true"/> <!--设置日志文件满1MB后打包--> <SizeBasedTriggeringPolicy size="1 MB" /> </Policies> <DefaultRolloverStrategy max="20" /> </RollingFile> <!--设置级别为ERROR日志输出到error.log中--> <RollingFile name="ERROR" filename="${logPath}/error.log" filepattern="${logPath}/%d{YYYYMMdd}-%i-error.log.zip"> <!--设置只输出级别为ERROR的日志--> <ThresholdFilter level="ERROR"/> <PatternLayout pattern="[ %-5p]:%d{YYYY-MM-dd HH:mm:ss} [%t] %c{1}:%L - %msg%n" /> <Policies> <!--设置每天打包日志一次--> <TimeBasedTriggeringPolicy interval="1" modulate="true"/> <!--设置日志文件满1MB后打包--> <SizeBasedTriggeringPolicy size="1 MB" /> </Policies> <DefaultRolloverStrategy max="20" /> </RollingFile> <!--设置通过邮件发送日志信息--> <SMTP name="Mail" subject="XXXXSaaS系统正式版异常信息" to="yong.shi@lengjing.info" from="message@lengjing.info" smtpUsername="message@lengjing.info" smtpPassword="LENG****1234" smtpHost="mail.lengjing.info" smtpDebug="false" smtpPort="25" bufferSize="10"> <PatternLayout pattern="[%-5p]:%d{YYYY-MM-dd HH:mm:ss} [%t] %c{1}:%L - %msg%n" /> </SMTP> </Appenders> <Loggers> <logger name="com.srd.ljzd" level="INFO" additivity="true"> <appender-ref ref="INFO" /> <appender-ref ref="WARN" /> <appender-ref ref="ERROR" /> <appender-ref ref="Mail" /> </logger> <root level="DEBUG"> <appender-ref ref="Console"/> </root> </Loggers> </Configuration>
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。