Bootstrap

详解log4j2(下) - Async/MongoDB/Flume Appender 按日志级别区分文件输出

1. 按日志级别区分文件输出

有些人习惯按日志信息级别输出到不同名称的文件中,如info.log,error.log,warn.log等,在log4j2中可通过配置Filters来实现。

假定需求是把INFO及以下级别的信息输出到info.log,WARN和ERROR级别的信息输出到error.log,FATAL级别输出到fatal.log,配置文件如下:

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <Configuration status="WARN" monitorInterval="300">  
  2.     <properties>  
  3.         <property name="LOG_HOME">D:/logs</property>  
  4.     </properties>  
  5.     <Appenders>  
  6.         <Console name="Console" target="SYSTEM_OUT">  
  7.             <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />  
  8.         </Console>  
  9.   
  10.         <RollingRandomAccessFile name="InfoFile"  
  11.             fileName="${LOG_HOME}/info.log"  
  12.             filePattern="${LOG_HOME}/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log">  
  13.             <Filters>  
  14.                 <ThresholdFilter level="warn" onMatch="DENY" onMismatch="NEUTRAL" />  
  15.                 <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY" />  
  16.             </Filters>  
  17.             <PatternLayout pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} %level [%thread][%file:%line] - %msg%n" />  
  18.             <Policies>  
  19.                 <TimeBasedTriggeringPolicy />  
  20.                 <SizeBasedTriggeringPolicy size="10 MB" />  
  21.             </Policies>  
  22.             <DefaultRolloverStrategy max="20" />  
  23.         </RollingRandomAccessFile>  
  24.           
  25.         <RollingRandomAccessFile name="ErrorFile"  
  26.             fileName="${LOG_HOME}/error.log"  
  27.             filePattern="${LOG_HOME}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log">  
  28.             <Filters>  
  29.                 <ThresholdFilter level="fatal" onMatch="DENY" onMismatch="NEUTRAL" />  
  30.                 <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY" />  
  31.             </Filters>  
  32.             <PatternLayout pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} %level [%thread][%file:%line] - %msg%n" />  
  33.             <Policies>  
  34.                 <TimeBasedTriggeringPolicy />  
  35.                 <SizeBasedTriggeringPolicy size="10 MB" />  
  36.             </Policies>  
  37.             <DefaultRolloverStrategy max="20" />  
  38.         </RollingRandomAccessFile>  
  39.           
  40.         <RollingRandomAccessFile name="FatalFile"  
  41.             fileName="${LOG_HOME}/fatal.log"  
  42.             filePattern="${LOG_HOME}/$${date:yyyy-MM}/fatal-%d{yyyy-MM-dd}-%i.log">  
  43.             <Filters>  
  44.                 <ThresholdFilter level="fatal" onMatch="ACCEPT" onMismatch="DENY" />  
  45.             </Filters>  
  46.             <PatternLayout pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} %level [%thread][%file:%line] - %msg%n" />  
  47.             <Policies>  
  48.                 <TimeBasedTriggeringPolicy />  
  49.                 <SizeBasedTriggeringPolicy size="10 MB" />  
  50.             </Policies>  
  51.             <DefaultRolloverStrategy max="20" />  
  52.         </RollingRandomAccessFile>  
  53.     </Appenders>  
  54.   
  55.     <Loggers>  
  56.         <Root level="trace">  
  57.             <AppenderRef ref="Console" />  
  58.             <AppenderRef ref="InfoFile" />  
  59.             <AppenderRef ref="ErrorFile" />  
  60.             <AppenderRef ref="FatalFile" />  
  61.         </Root>  
  62.     </Loggers>  
  63. </Configuration>  
测试代码:

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. public static void main(String[] args) {  
  2.     Logger logger = LogManager.getLogger(Client.class);  
  3.     logger.trace("trace level");  
  4.     logger.debug("debug level");  
  5.     logger.info("info level");  
  6.     logger.warn("warn level");  
  7.     logger.error("error level");  
  8.     logger.fatal("fatal level");  
  9. }  

2 异步写日志

配置文件:

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <Configuration status="WARN" monitorInterval="300">  
  2.     <properties>  
  3.         <property name="LOG_HOME">D:/logs</property>  
  4.         <property name="FILE_NAME">mylog</property>  
  5.     </properties>  
  6.   
  7.     <Appenders>  
  8.         <Console name="Console" target="SYSTEM_OUT">  
  9.             <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />  
  10.         </Console>  
  11.         <RollingRandomAccessFile name="MyFile"  
  12.             fileName="${LOG_HOME}/${FILE_NAME}.log"  
  13.             filePattern="${LOG_HOME}/$${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd HH-mm}-%i.log">  
  14.             <PatternLayout  
  15.                 pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} %level [%thread][%file:%line] - %msg%n" />  
  16.             <Policies>  
  17.                 <TimeBasedTriggeringPolicy interval="1" />  
  18.                 <SizeBasedTriggeringPolicy size="10 MB" />  
  19.             </Policies>  
  20.             <DefaultRolloverStrategy max="20" />  
  21.         </RollingRandomAccessFile>  
  22.         <Async name="Async">  
  23.             <AppenderRef ref="MyFile" />  
  24.         </Async>  
  25.     </Appenders>  
  26.   
  27.     <Loggers>  
  28.         <Logger name="asynclog" level="trace" additivity="false" >  
  29.             <AppenderRef ref="Async" />  
  30.         </Logger>  
  31.         <Root level="error">  
  32.             <AppenderRef ref="Console" />  
  33.         </Root>  
  34.     </Loggers>  
  35. </Configuration>  
测试代码:

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. public static void main(String[] args) {  
  2.     Logger logger = LogManager.getLogger("asynclog");  
  3.     logger.trace("trace level");  
  4.     logger.debug("debug level");  
  5.     logger.info("info level");  
  6.     logger.warn("warn level");  
  7.     logger.error("error level");  
  8.     logger.fatal("fatal level");  
  9. }  

3 输出到MongoDB

添加依赖:

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <dependency>  
  2.     <groupId>org.apache.logging.log4j</groupId>  
  3.     <artifactId>log4j-nosql</artifactId>  
  4.     <version>2.5</version>  
  5. </dependency>  
  6. <dependency>  
  7.     <groupId>org.mongodb</groupId>  
  8.     <artifactId>mongo-java-driver</artifactId>  
  9.     <version>3.2.2</version>  
  10. </dependency>  
配置文件:

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <Configuration status="WARN" monitorInterval="300">  
  2.     <Appenders>  
  3.         <Console name="Console" target="SYSTEM_OUT">  
  4.             <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />  
  5.         </Console>  
  6.   
  7.         <NoSql name="databaseAppender">  
  8.             <MongoDb databaseName="test" collectionName="errorlog"  
  9.                 server="localhost" port="27017" />  
  10.         </NoSql>  
  11.     </Appenders>  
  12.   
  13.     <Loggers>  
  14.         <Logger name="mongolog" level="trace" additivity="false">  
  15.             <AppenderRef ref="databaseAppender" />  
  16.         </Logger>  
  17.         <Root level="error">  
  18.             <AppenderRef ref="Console" />  
  19.         </Root>  
  20.     </Loggers>  
  21. </Configuration>  

4 输出到Flume

Flume配置(flume-conf.properties)

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. agent1.sources=source1   
  2. agent1.sinks=sink1   
  3. agent1.channels=channel1   
  4.   
  5. agent1.sources.source1.type=avro  
  6. agent1.sources.source1.channels=channel1  
  7. agent1.sources.source1.bind=0.0.0.0  
  8. agent1.sources.source1.port=41414  
  9.   
  10. agent1.sinks.sink1.type=file_roll   
  11. agent1.sinks.sink1.sink.directory=D:/log  
  12. agent1.sinks.sink1.channel=channel1  
  13. agent1.sinks.sink1.sink.rollInterval=86400  
  14. agent1.sinks.sink1.sink.batchSize=100  
  15. agent1.sinks.sink1.sink.serializer=text  
  16. agent1.sinks.sink1.sink.serializer.appendNewline = false  
  17.   
  18. agent1.channels.channel1.type=file   
  19. agent1.channels.channel1.checkpointDir=D:/log/checkpoint   
  20. agent1.channels.channel1.dataDirs=D:/log/data  
启动Flume(注:测试环境为windows)
[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. flume-ng.cmd agent --conf ../conf/ --conf-file ../conf/flume-conf.properties -name agent1  
添加依赖:

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <dependency>  
  2.     <groupId>org.apache.logging.log4j</groupId>  
  3.     <artifactId>log4j-flume-ng</artifactId>  
  4.     <version>2.5</version>  
  5. </dependency>  
配置文件:

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <Configuration status="WARN" monitorInterval="300">  
  2.     <Appenders>  
  3.         <Flume name="eventLogger" compress="false">  
  4.             <Agent host="127.0.0.1" port="41414" />  
  5.             <RFC5424Layout enterpriseNumber="18060" includeMDC="true" appName="MyApp" />  
  6.         </Flume>  
  7.     </Appenders>  
  8.     <Loggers>  
  9.         <Root level="trace">  
  10.             <AppenderRef ref="eventLogger" />  
  11.         </Root>  
  12.     </Loggers>  
  13. </Configuration>  
;