前言html
Appender按网络释义,有“输出目的地”之意。官网给出的定义是:“Appenders are responsible for delivering LogEvents to their destination.”。Log4j2为使用者提供了13种很是实用的Appenders,使用者可用方便的调用这13种Appender来控制日志的输出。java
摘要web
Log4j2的Appenders充分考虑了日志事件的输出、包装以及过滤转发的可能,包括最基本的输出到本地文件、输出到远程主机,对文件进行封装、注入,而且还能按照日志文件的时间点、文件大小等条件进行自动封存。例如,想要将几个不一样源的日志聚集到一块儿,能够用FlumeAppender;想要在LogEvent中注入信息,能够用RewriteAppender;想要让系统按照设定的时间间隔自动封存日志信息,能够用RollingFileAppender(每隔必定时间自动保存一份新增的日志文件,并按照时间戳等指定格式命名);当产生安全级别达ERROR或FATAL的LogEvent时,给维护人员发送邮件可用SMTPAppender;但愿将日志信息写到远程主机的,可用SocketAppender;但愿可以按照RFC5424格式向远程主机发送日志信息,可用SyslogAppender。等等。apache
下面将按照以下顺序依次介绍每一个Appender的做用及重要参数,并附上完整参数地址及官网配置示例地址。api
目录数组
一、FileAppender 普通地输出到本地文件缓存
二、FlumeAppender 将几个不一样源的日志聚集、集中到一处。安全
三、JMSQueueAppender VS. JMSTopicAppender 与JMS相关的日志输出服务器
四、RewriteAppender 对日志事件进行掩码或注入信息网络
五、RollingFileAppender 对日志文件进行封存(详细)
六、RoutingAppender 在输出地之间进行筛选路由
七、SMTPAppender 将LogEvent发送到指定邮件列表
八、SocketAppender 将LogEvent以普通格式发送到远程主机
九、SyslogAppender 将LogEvent以RFC 5424格式发送到远程主机
十、AsynchAppender 将一个LogEvent异步地写入多个不一样输出地
十一、ConsoleAppender 将LogEvent输出到命令行
十二、FailoverAppender 维护一个队列,系统将尝试向队列中的Appender依次输出LogEvent,直到有一个成功为止
正文:
一、FileAppender
FileAppender用于将LogEvent写入到一个文件中,该文件由fileName参数指定。有几个重要的参数:
① fileName,String,指定写入的log文件的名称。
② append,boolean,指定是不是追加写入(append=true,默认状况),仍是覆盖写入(append=false)。
③ bufferedIO,boolean,是否对数据进行缓冲到缓冲区满后再写入。测试显示,即便在启用immediateFlush的状况下,设置bufferedIO=true也能提升性能。
④ locking,boolean,是否对文件上锁,当有多个线程可能同时写该文件时须要考虑上锁(在《异常处理反模式》中就提到要把在一块儿的日志输出语句写到一句,而不是拆成几句来避免并发线程致使的日志语句之间的错位)。但对文件上锁会影响系统的性能,因此须要谨慎使用。默认值是false。
二、FlumeAppender
FlumeAppender是一个可选的组件,它并不包含在core jar中,若要使用,须要额外加入log4j-flume-ng-2.0-beta4.jar包。FlumeAppender是配合Apache Flume来使用的。Apache Flume是一个能有效地将不一样地方的大量日志数据收集、聚会到一块儿的一个系统。详细信息参见【Apache Flume】
几个比较重要的参数:
① agents,Agent[],用来维护一个将接收log event的数组,若是数组中agent的数量大于1,那么将把第一个agent视为primary agent,剩下的为备选agent。当第一个agent没法链接时,将把log event发送给备选agent。
② batchSize,integer,一次给agent发送的log event的个数。
③ compress,boolean,当设置为true时,发送的message将使用gzip进行压缩。
三、JMSQueueAppender VS. JMSTopicAppender
JMSQueueAppender的做用是将格式化的log event发送到JMSQueue上,一样的,JMSTopicAppender的做用是将格式化的log event发送到JMSTopic上。JMSQueue和JMSTopic的区别是,JMSQueue只将一个message发送给一个consumer,而JMSTopic是将一个message发布(publish)给全部订阅了这个message的订阅者(subscribe)。更详细的二者间的区别能够【戳这里】
几个重要的参数:
JMSQueueAppender:
① queueBindingName,String, 用来定位queue。
② factoryBindingName,String, 用来定位产生上下文信息的QueueConnectionFactory。
JMSTopicAppender:
① topicBindingName,String, 用来定位topic。
② factoryBindingName,String, 用来定位产生上下文信息的QueueConnectionFactory。
四、RewriteAppender
RewriteAppender可让符合筛选条件的log event在被其余appender输出前被加工一下,好比对message中的密码进行掩码,或者向message中注入信息等。RewriteAppender须要一个RewritePolicy来指定重写的规则。
几个重要的参数:
① appender-ref,String,指定被重写后的log event将发往哪一个appender。
② rewritePolicy,RewritePolciy,用来描述重写log event的规则。
RewritePolicy:
RewritePolicy是一个接口,有一个须要实现的方法名为rewrite,该方法接收一个log event对象做为参数,而后通过函数处理后返回该log event或新建一个log event返回。
Log4j2中已实现的两种RewritePolicy有MapRewritePolicy和PropertiesRewritePolicy。
【完整的参数设置、已实现的RewritePolicy和官方配置示例】
五、RollingFileAppender
RollingFileAppender是一个很是有意思的输出器。它将log信息写入一个文件后,会判断是否知足封存文件的要求,若知足,则除非封存文件的动做。RollingFileAppender须要TriggeringPolicy来指定触发封存的条件,另外还须要RolloverStrategy来告诉输出器如何封存文件。
Log4j2中已提供的TriggeringPolicy有以下四种:
① CompositeTriggeringPolicy
复合型触发策略。即将多个触发条件逻辑或到一块儿,只要其中一个条件知足,则触发封存动做。
② OnStartup Triggering Policy
这一触发策略不须要参数设置,它会自行判断log文件的建立时间和JVM的启动时间。若log文件的建立时间早于JVM的启动时间,则将原来的log文件封存,而后建立一个新的空白log文件。
③ SizeBased Triggering Policy
这一触发策略基于对log文件大小的判断。当log文件大于设定的阈值时,将触发封存动做。可设定的log文件大小的单位有bytes、KB、MB或GB。
④ TimeBased Triggering Policy
基于时间的触发策略。该策略主要是完成周期性的log文件封存工做。有两个参数:
interval,integer型,指定两次封存动做之间的时间间隔。
modulate,boolean型,说明是否对封存时间进行调制。若modulate=true,则封存时间将以0点为边界进行偏移计算。好比,modulate=true,interval=4hours,那么假设上次封存日志的时间为03:00,则下次封存日志的时间为04:00,以后的封存时间依次为08:00,12:00,16:00,。。。
Log4j2中实现的RolloverStrategy为Default Rollover Strategy,它有三个参数能够设置,分别为:
fileIndex,String,有两个选择“max”或“min”。设置为“max”意味着将最新的日志信息封存在序号较大的封存文件中。“min”则相反。
min,integer,封存文件的序号的起始值。
max,integer,封存文件的序号的最大值。(超过最大值时,将有文件被删除)
至关于min和max两个参数设置了一个保存窗口,超出这个窗口的日志文件将会被删除。
【完整的参数设置、TriggeringPolicy和RolloverStrategy的用法示例】
六、RoutingAppender
经过路由规则来评价一个log event后,决定它下一个被发往的appender。RoutingAppender有一个重要的参数名为routes,是Routes型数据,用来描述该appender的路由规则。
七、SMTPAppender
SMTPAppender主要用来给指定的E-mail发送log event(这种状况通常用在event的安全级别超过ERROR或FATAL时,event的安全分级能够参考【此文】之日志记录小节)。SMTPAppender有不少重要的参数以完成log event发送到指定E-mail。
① bcc,String,由逗号分隔的几个盲抄送地址。(盲抄送就是说收件人的地址不会显示在邮件信息中)
② cc,String,由逗号分隔的几个明抄送地址。(明抄送就是说收件人的地址将显示在邮件信息中)
③ bufferSize,integer,信中所能包含的最大log event的数量。
④ from,String,发件人的地址。
⑤ layout,Layout,log event的布局格式。默认为SerializedLayout。
⑥ replyTo,String,回信的地址。
⑦ smtpHost,String,要发送到的SMTP的主机名。(此参数是必需的)
⑧ smtpPassword,String,经过SMTP服务器所需的密码。
⑨ smtpPort,integer,SMTP服务的端口号。
⑩ smtpProtocol,String,使用的协议。默认为"smtp"。
其余还有smtpUsername(经过SMTP server所需的用户名),to(接收者的邮件地址)等。
八、SocketAppender
将log event输出到一个远程服务器上(需指定服务器名和端口号),数据能够以任意指定的格式经由TCP或UDP协议发送。
SocketAppender中比较重要的参数有:
① host,String,指定服务器的主机名。(必需)
② immediateFlush,boolean,是否当即flush,仍是等待缓存到必定大小后在flush。
③ layout,Layout,log event输出的格式。
④ port,integer,远程服务器坚挺log event的应用的端口号。
⑤ protocol,String,发送log event所使用的协议,"TCP" 或"UDP"。
⑥ reconnectionDelay,integer,当链接断开时,延迟等待的ms数。
九、SyslogAppender
SyslogAppender跟SocketAppender同样,是将log event发送到远程服务器上,可是使用的是BSD Syslog格式。关于Syslog格式能够【戳这里】
十、AsynchAppender
将一个LogEvent异步地写入多个不一样输出地。在AsynchAppender中有一个参数,名为“appender-ref”,用来指定要发送到的appender的名称。AsynchAppender维护了一个队列,队列中存放了须要异步发送的LogEvent,队列中LogEvent的个数能够经过“bufferSize”参数来指定。另外,还有一个“blocking”参数来指定是否对AsynchAppender的LogEvent队列上锁,若是blocking=true,那么在队列满员的状况下,新到达的LogEvent将等待,直到有空位。若blocking=false,那么在队列满员的状况下,将把新到的LogEvent转到error appender。
十一、ConsoleAppender
将LogEvent输出到命令行。有两个比较有意思的参数,一个是layout,用来指定输出字串的格式(format);另外一个是target,用来指定输出的是 "SYSTEM_OUT" 仍是 "SYSTEM_ERR",默认状况下是"SYSTEM_ERR"。
十二、FailoverAppender
维护一个failover appenders队列,系统先尝试一个主appender(primary appender),若不成功,则尝试failover队列中的Appenders,直到有一个成功为止,或都不成功。比较重要的参数有:
primary(String型):用来指定主appender的名称。
failovers(String[]型):一个appender数组,指定的备选的其余appenders。
retryInterval(integer型):用来设定隔多少秒从新尝试主appender,默认为60秒。
参考资料:
一个最经常使用的log4j2的配置:
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="ERROR"> <Appenders> <RollingFile name="RollingFile" fileName="E:/webapp/logs/yadou-manage.log" filePattern="E:/webapp/logs/$${date:yyyy-MM}/yadou-manage-%d{MM-dd-yyyy}-%i.log.gz"> <PatternLayout> <Pattern>%d %-5level [%t]%l - %msg%n</Pattern> </PatternLayout> <Policies> <TimeBasedTriggeringPolicy/> <SizeBasedTriggeringPolicy size="250 MB"/> </Policies> </RollingFile> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%highlight{%d %-5level [%t]%l - %msg%n}"/> </Console> </Appenders> <Loggers> <!--控制输出debug,不继承--> <Logger name="com.jia.yadou.manage" level="debug" additivity="false"> <!--保存文件,只存储info级别以上的日志--> <AppenderRef ref="RollingFile" level="info"/> <!--控制台打印指定包路径下面的debug--> <AppenderRef ref="Console"/> </Logger> <!--默认info级别--> <Root level="info"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration>
项目中注意事项:
一般咱们的项目有时候是以jar包的形式发布出去,可是此时若是你直接使用lo4j2的api的话,至关于别人依赖你的jar的项目也必须加入log4j2的jar包。这样是高度耦合的。咱们不建议这样使用,log4j2官方给出了适配slf4j,咱们只须要在项目中加入如下依赖:
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-slf4j-impl --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>2.6.2</version> </dependency> <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.21</version> </dependency>
而后项目中,咱们使用slf4j的api而不要使用lo4j2的api例如:
将LogManager.getLogger(xxx);替换为LoggerFactory.getLogger(xx);
这样当其余项目引入你的jar后,就能够不用强制他们使用log4j2,也不会由于没有log4j2的jar而报错。
log4j2最强的是支持异步写日志,这个是个人简单配置:
异步输出,官方有两种方案。第一种是采用配置开关,第二种则是基于异步标签。注意:异步输出日志须要disruptor-3.3.0.jar或者以上的版原本支持。下面我具体的说明下两种状况:
添加一个名字为:log4j2.component.properties文件,放到classpath下面,log4j2会在启动的时候自动加载。而后你的日志输出已经变成了异步输出了。(注意:这种状况,本人在main方法启动函数测试的时候,常常出现不成功,可能须要附加其余配置参数,我也推荐你们使用第二种方式)
Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
你只须要将你要异步输出的块改成AsyncLogger标签就好了。
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="ERROR"> <Properties> <!--定义变量--> <Property name="filename">E:/webapp/logs/hnmcc_sso/sso.log</Property> <Property name="filenameError">E:/webapp/logs/hnmcc_sso/ssoError.log</Property> </Properties> <Appenders> <!--控制台输出--> <Console name="STDOUT"> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %l - %msg%n"/> </Console> <!--入文件--> <RollingFile name="RollingFile" fileName="${filename}" filePattern="/webapp/logs/hnmcc_sso/${date:yyyy-MM}/sso-%d{yyyy-MM-dd}-%i.log.gz"> <PatternLayout pattern="%d %-5level [%t]%l - %msg%n"/> <Policies> <SizeBasedTriggeringPolicy size="200 MB"/> <TimeBasedTriggeringPolicy/> </Policies> <!--自动删除超过120天的日志压缩文件--> <DefaultRolloverStrategy> <Delete basePath="${baseDir}" maxDepth="2"> <IfFileName glob="*/sso-*.log.gz"/> <IfLastModified age="120d"/> </Delete> </DefaultRolloverStrategy> </RollingFile> <!--错误日志入文件--> <RollingFile name="RollingFileError" fileName="${filenameError}" filePattern="/webapp/logs/hnmcc_sso/${date:yyyy-MM}/ssoError-%d{yyyy-MM-dd}-%i.log.gz"> <PatternLayout pattern="%d %-5level [%t]%l - %msg%n"/> <Policies> <SizeBasedTriggeringPolicy size="200 MB"/> <TimeBasedTriggeringPolicy/> </Policies> <!--自动删除超过120天的日志压缩文件--> <DefaultRolloverStrategy> <Delete basePath="${baseDir}" maxDepth="2"> <IfFileName glob="*/sso-*.log.gz"/> <IfLastModified age="120d"/> </Delete> </DefaultRolloverStrategy> </RollingFile> </Appenders> <Loggers> <!--采用异步输出日志--> <AsyncLogger name="com.xwtec.util.Transport" level="info"> <!--写入info级别--> <AppenderRef ref="RollingFile"/> <!--写入error级别--> <AppenderRef ref="RollingFileError" level="error"/> </AsyncLogger> <Root level="debug"> <AppenderRef ref="STDOUT"/> </Root> </Loggers> </Configuration>