• Java日志-Log4j2


    Log4j2参考资料

    Log4j2 官方配置文档

    1. Log4j2基本概念:

    Logger

    在代码中产生日志信息的。比如logger.info("some log message")
    有name属性,并与LoggerConfig(Logger的配置信息)相关联。使用LogManager.getLogger方法获得。一般来说在每个需要记录日志的类中都需要一个logger.

    Logger x = LogManager.getLogger("wombat");
    Logger y = LogManager.getLogger("wombat");
    

    x与y指向同样的Logger.

    LogLevel

    从低到高,TRACE, DEBUG, INFO, WARN, ERROR, FATAL。设置某一等级的LogLevel,所有高于该等级的日志均会输出。比如设置了INFO,所有INFO、WARN、ERROR、FATAL等级的信息都会输出。
    一般,在catch子句中使用logger.error,一般性的程序输出信息使用logger.info,调试的时候使用logger.debug,需要详细输出日志信息的使用logger.trace.

    Appender

    日志输出目的地,可以使console,文件,远端socket服务器,数据库,Apache Flume等等。可以在appender中设置输出格式(PatternLayout)、过滤器(ThresholdFilter)。

    Appender Additivity

    可以设置additivity=false放置同一条信息被输出多次。

    Layout

    可以定制日志的输出格式,采用类似c语言printf格式化输出的语法。常用的设置选项如PatternLayout
    例子:比如格式为"%r [%t] %-5p %c - %m%n",对应的输出为176 [main] INFO org.foo.Bar - Located nearest gas station.
    %r程序启动后经过多少毫秒
    %t发起log请求的线程
    %-5plog级别,-5表示左对齐并且固定输出5个字符
    %cLogger名
    %m输出消息
    %n回车换行
    更多参数解释

    2.入门学习步骤:

    1. 项目导入log4j-api-2.x.jarlog4j-core-2.x.jar,并将一个简单的配置文件log4j2.xml放入Java项目的classpath路径,
    2. 学会使用在控制台下输出日志。掌握日志输出级别,主要掌握INFOERROR。掌握配置文件Appenders(控制日志输出格式、输出目的、过滤器等)与Loggers(控制使用哪些Appender)的配置。
    3. 学会使用在控制台和文件下输出日志,掌握ThresholdFilter控制输出不同级别的日志。比如控制台输出trace以上级别日志,error.log文件输出error以上级别的日志。
    4. 学会使用RollingFile让Log4j2自动分文件输出。

    3. 例子

    说明:例子主要来源于Log4j2官网。

    3.1 LogHelloWorld,无配置文件

    如果没有任何配置文件,则只在控制台输出ERROR以上等级的信息。

    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    
    public class LogHelloWorld {
        
        private static final Logger logger = LogManager.getLogger(LogHelloWorld.class);
        
        public static void main(String[] args) {
            logger.trace("trace");
            logger.debug("debug");
            logger.info("info");
            logger.warn("warn");
            logger.error("error");
            logger.fatal("fatal");       
        }
    }
    

    输出:

    ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
    12:20:31.479 [main] ERROR testLog.LogHelloWorld - error
    12:20:31.480 [main] FATAL testLog.LogHelloWorld - fatal
    

    如果不提供配置文件,Log4j2将提供一个默认配置,在DefaultConfiguration类中定义。主要设置:

    1. ConsoleAppender连接到root logger上
    2. ConsoleAppenderPatternLayout设置为"%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"
      格式说明:
      %d{HH:mm:ss.SSS}时、分、秒、毫秒
      %t线程
      %-5level日志等级
      %loggerlogger名
      %msg日志信息
      %n回车换行

    将上述代码修改成

    class Foo{
    	private static final Logger logger = LogManager.getLogger(Foo.class);
    	
    	public static void test(){
                    logger.trace("trace");    
                    logger.debug("debug");
                    logger.info("info");
                    logger.warn("warn");
    		logger.error("error");
    		logger.fatal("fatal");
    	}
    }
    
    public class LogHelloWorld {
        
        private static final Logger logger = LogManager.getLogger(LogHelloWorld.class);
        
        public static void main(String[] args) {
            logger.trace("trace");
            logger.debug("debug");
            logger.info("info");
            logger.warn("warn");
            logger.error("error");
            logger.fatal("fatal");
            Foo.test();
            
        }
    
    }
    

    输出:

    12:22:16.481 [main] ERROR testLog.LogHelloWorld - error
    12:22:16.482 [main] FATAL testLog.LogHelloWorld - fatal
    12:22:16.482 [main] ERROR testLog.Foo - error
    12:22:16.482 [main] FATAL testLog.Foo - fatal
    

    比较两次输出可以发现两个类LogHelloWorldFoo中使用不同的logger,分别为testLog.LogHelloWorldtestLog.Foo

    3.2 LogHelloWorld,有配置文件

    在项目的classpath路径下(在Eclipse项目中直接放到src目录下即可)放置一个log4j2.xml配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="WARN">
    	<Appenders>
    		<Console name="Console" target="SYSTEM_OUT">
    			<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
    		</Console>
    	</Appenders>
    	<Loggers>
    		<Root level="error">
    			<AppenderRef ref="Console" />
    		</Root>
    	</Loggers>
    </Configuration>
    

    再次运行上面的程序中,输出如下:

    12:39:54.493 [main] ERROR testLog.LogHelloWorld - error
    12:39:54.495 [main] FATAL testLog.LogHelloWorld - fatal
    12:39:54.495 [main] ERROR testLog.Foo - error
    12:39:54.496 [main] FATAL testLog.Foo - fatal
    

    可以看到没有这个ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.说明Log4j2使用了log4j2.xml这个配置文件。
    配置文件简单说明:
    <Console>代表输出到控制台。
    PatternLayout表示日志输出的格式
    <Loggers>中定义了root这个logger,并且输出级别为error,在其中通过<AppenderRef ref="Console" />引用了上面定义的Console这个Appender。可以尝试将error改成trace,再看控制台输出。可以看到所有trace以上级别的日志均输出。

    定义一个新的Logger:用来专门控制Foo的日志输出信息。比如,期望只有Foo这个类输出Trace以上的信息,而其他类只输出Error以上的信息,可以在配置文件中新增一个专门用于Foo的Logger。

    <Loggers>
        <Logger name="testLog.Foo" level="TRACE"/>
        <Root level="ERROR">
            <AppenderRef ref="Console" />
        </Root>
    </Loggers>
    

    输出如下:

    19:53:57.368 [main] ERROR testLog.LogHelloWorld - error
    19:53:57.371 [main] FATAL testLog.LogHelloWorld - fatal
    19:53:57.372 [main] TRACE testLog.Foo - trace
    19:53:57.372 [main] DEBUG testLog.Foo - debug
    19:53:57.372 [main] INFO  testLog.Foo - info
    19:53:57.372 [main] WARN  testLog.Foo - warn
    19:53:57.373 [main] ERROR testLog.Foo - error
    19:53:57.373 [main] FATAL testLog.Foo - fatal
    

    Additivity:
    如果将配置文件改为:

    <Loggers>
    	<Logger name="testLog.Foo" level="trace">
    		<AppenderRef ref="Console" />
    	</Logger>
    	<Root level="ERROR">
    		<AppenderRef ref="Console" />
    	</Root>
    </Loggers>
    

    输出为:

    19:54:36.498 [main] ERROR testLog.LogHelloWorld - error
    19:54:36.500 [main] FATAL testLog.LogHelloWorld - fatal
    19:54:36.501 [main] TRACE testLog.Foo - trace
    19:54:36.501 [main] TRACE testLog.Foo - trace
    19:54:36.501 [main] DEBUG testLog.Foo - debug
    19:54:36.501 [main] DEBUG testLog.Foo - debug
    19:54:36.501 [main] INFO  testLog.Foo - info
    19:54:36.501 [main] INFO  testLog.Foo - info
    19:54:36.501 [main] WARN  testLog.Foo - warn
    19:54:36.501 [main] WARN  testLog.Foo - warn
    19:54:36.502 [main] ERROR testLog.Foo - error
    19:54:36.502 [main] ERROR testLog.Foo - error
    19:54:36.502 [main] FATAL testLog.Foo - fatal
    19:54:36.502 [main] FATAL testLog.Foo - fatal
    

    可以看到testLog.Foo的日志信息输出了两次。这时候我们应该设置additivity="false",具体配置如下:

    <Loggers>
    	<Logger name="testLog.Foo" level="trace" additivity="false">
    		<AppenderRef ref="Console" />
    	</Logger>
    	<Root level="ERROR">
    		<AppenderRef ref="Console" />
    	</Root>
    </Loggers>
    

    Logger的配置:每个配置都有一个root logger。如果一个Configure没有配置,则使用前面提到的默认的root LoggerConfig。
    Logger的name属性::要给其一个合适的名字。比如上例中name="testLog.Foo"代表该Logger的配置适用所有testLog.Foo开头的Logger。如果将其设置为name="testLog",则该Logger配置适用于所有name以testLog开头的配置。

    3.3 设置多个Appender

    项目被部署后,除了使用控制台输出日志信息,还需要使用文件存储日志信息,这就需要多个Appender。
    现在使用Console(控制台)来输出所有的info以上级别的信息,而使用File(文件)来存储error以上级别的日志信息。配置文件如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="WARN">
    	<Appenders>
    		<Console name="Console" target="SYSTEM_OUT">
    			<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
    		</Console>
    		
    		<File name="ErrorFile" fileName="logs/error.log">
    			<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%n" />
    		</File>
    	</Appenders>
    	<Loggers>
    		<Root level="trace">
    			<AppenderRef ref="Console" level="info"/>
    			<AppenderRef ref="ErrorFile" level="error"/>
    		</Root>
    	</Loggers>
    </Configuration>
    

    运行后,控制台输出:

    20:15:12.247 [main] INFO  testLog.LogHelloWorld - info
    20:15:12.249 [main] WARN  testLog.LogHelloWorld - warn
    20:15:12.249 [main] ERROR testLog.LogHelloWorld - error
    20:15:12.250 [main] FATAL testLog.LogHelloWorld - fatal
    20:15:12.251 [main] INFO  testLog.Foo - info
    20:15:12.251 [main] WARN  testLog.Foo - warn
    20:15:12.251 [main] ERROR testLog.Foo - error
    20:15:12.251 [main] FATAL testLog.Foo - fatal
    

    logs/error.log文件中的内容如下:

    20:15:12.249 ERROR testLog.LogHelloWorld 28 main - error
    20:15:12.250 FATAL testLog.LogHelloWorld 29 main - fatal
    20:15:12.251 ERROR testLog.Foo 14 test - error
    20:15:12.251 FATAL testLog.Foo 15 test - fatal
    

    这里ErrorFile这个appender中的PatternLayout多出了%L %M,分别代表行号与方法。
    而Logger配置中<AppenderRef ref="ErrorFile" level="error"/>的level设置为error,代表该appender输出的日志级别为error。

    3.4 根据配置动态生成文件夹与日志文件(RollingAppender)

    目录按照年-月格式,日志文件名格式为年-月-日-序号,比如logs2017-02app-2017-02-11-1,并且每次日志文件超过50MB,就按照指定格式生成相应的目录与日志文件。
    配置文件如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="WARN">
    	<Appenders>
    		<Console name="Console" target="SYSTEM_OUT">
    			<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
    		</Console>		
    		<File name="ErrorFile" fileName="logs/error.log">
    			<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%n" />
    		</File>
    		<RollingFile name="RollingFile" 
                         filePattern="logs/$${date:yyyy-MM}/app-%d{yyyy-MM-dd}-%i.log.gz">
                    <PatternLayout pattern="%d %p %c{1.} [%t] %m%n"/>
                    <SizeBasedTriggeringPolicy size="50MB"/>
            </RollingFile>
    	</Appenders>
    	<Loggers>
    
    		<Root level="trace">
    			<AppenderRef ref="Console" level="info"/>
    			<AppenderRef ref="ErrorFile" level="error"/>
    			<AppenderRef ref="RollingFile" level="trace"/>
    		</Root>
    	</Loggers>
    </Configuration>
    

    现在根据上面这份配置文件,日志信息会被输出到3个Appender。

    1. Console name="Console":所有info级别以上的日志信息都会输出到控制台。
    2. <File name="ErrorFile":所有error级别以上的日志信息都会输出到logs/error.log文件
    3. RollingFile name="RollingFile":所有trace级别以上的日志信息都会按照指定格式生成相应的目录与文件。

    3.5 设置append属性覆盖日志文件

    调试某个类(如Foo)的时候,有如下要求:

    1. 有关Foo类的调试信息尽可能详细(比如trace级别)。
    2. 日志信息输入到某个指定文件,如FooError.log
    3. 每次重新运行都覆盖重写该文件。
      配置文件如下:
    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="WARN">
    	<Appenders>
    		<Console name="Console" target="SYSTEM_OUT">
    			<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
    		</Console>
    		<File name="ErrorFile" fileName="logs/error.log">
    			<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%n" />
    		</File>
    		<File name="FooFile" fileName="logs/FooError.log" append="false">
    			<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%n" />
    		</File>
    		<RollingFile name="RollingFile"
    			filePattern="logs/$${date:yyyy-MM}/app-%d{yyyy-MM-dd}-%i.log.gz">
    			<PatternLayout pattern="%d %p %c{1.} [%t] %m%n" />
    			<SizeBasedTriggeringPolicy size="50MB" />
    		</RollingFile>
    	</Appenders>
    	<Loggers>
    		<Logger name="testLog.Foo" level="trace">
    			<AppenderRef ref="FooFile" />
    		</Logger>
    		<Root level="trace">
    			<AppenderRef ref="Console" level="info" />
    			<AppenderRef ref="ErrorFile" level="error" />
    			<AppenderRef ref="RollingFile" level="trace" />
    		</Root>
    	</Loggers>
    </Configuration>
    

    FooFile这个Appender的append="false"代表会覆盖以前的日志文件。
    testLog.Foo这个Logger等级设置为trace代表输出trace以上级别的日志信息。

    3.6 Tomcat下Web项目的日志的设置

    Servle3.0以上Tomcat7.043以上(不包括7.043)的项目设置比较简单,Log4j2可以随着项目的启动而启动,随着项目的停止而停止。

    1. 除了log4j-api-2.8.jar,log4j-core-2.8.jar还需要log4j-web-2.8.jar。
    2. 将配置文件log4j2.xml放入WEB-INF目录下。(或者放到classpath路径下)
    3. log4j2.xml配置文件中文件输出的路径改要加上${web:rootDir},比如<File name="ErrorFile" fileName="${web:rootDir}/logs/error.log">

    如果不需要改变Log4j的行为,比如日志文件的位置,那么按照上面3个步骤不是即可。否则,可以在web.xml中添加相关配置信息,如下:

      <context-param>
            <param-name>log4jContextName</param-name>
            <param-value>demo</param-value>
        </context-param>
    
        <context-param>
            <param-name>log4jConfiguration</param-name>
            <param-value>/WEB-INF/log4j2.xml</param-value>
        </context-param>
    

    修改了LoggerContext 的name,并指定log4j2的配置文件是/WEB-INF/log4j2.xml。

    官网参考资料
    在web应用中使用Log4j2

    4.Log4j2其他资料

    log4j2 使用详解-较简单
    详解log4j2(上) - 从基础到实战
    Log4j2 使用详解
    Log4j2的基本使用,较详细
    Log4j2的使用,原理

  • 相关阅读:
    Java多线程详解
    自动化构建工具Maven
    解决 安装cocoapods失败,提示 requires Ruby version >=2.2.2
    安装Cocoapods时候ERROR: While executing gem ... (Errno::EPERM)
    iOS可执行文件瘦身方法
    ios webview自适应实际内容高度4种方法
    iOS8 tableview separatorInset cell分割线左对齐,ios7的方法失效了
    Reveal1.5破解,iOS_UI调试利器Reveal最新版本破解方法
    Xcode安装插件,错误选择了Skip Bundles,重新出现Load Bundles方法
    10分钟搞定支付宝支付 的 各种填坑
  • 原文地址:https://www.cnblogs.com/zhrb/p/6387957.html
Copyright © 2020-2023  润新知