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)

目录按照年-月格式,日志文件名格式为年-月-日-序号,比如logs\2017-02\app-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日志-Log4j2的更多相关文章

  1. [翻译]Java日志终极指南

    本文由 ImportNew - Wing 翻译自 loggly.欢迎加入翻译小组.转载请见文末要求. Java日志基础 Java使用了一种自定义的.可扩展的方法来输出日志.虽然Java通过java.u ...

  2. Java日志记录的事儿

    一.java日志组件 1.common-logging common-logging是apache提供的一个通用的日志接口.用户可以自由选择第三方的日志组件作为具体实现,像log4j,或者jdk自带的 ...

  3. Java日志终极指南

    Java日志基础 Java使用了一种自定义的.可扩展的方法来输出日志.虽然Java通过java.util.logging包提供了一套基本的日志处理API,但你可以很轻松的使用一种或者多种其它日志解决方 ...

  4. Java 日志框架终极教程

    概述 对于现代的 Java 应用程序来说,只要被部署到真实的生产环境,其日志的重要性就是不言而喻的,很难想象没有任何日志记录功能的应用程序被运行于生产环境中.日志 API 所能提供的功能是多种多样的, ...

  5. Java日志框架那些事儿

    文章首发于[博客园-陈树义],点击跳转到原文Java日志框架那些事儿. 在项目开发过程中,我们可以通过 debug 查找问题.而在线上环境我们查找问题只能通过打印日志的方式查找问题.因此对于一个项目而 ...

  6. JAVA日志的前世今生

    这世界上很多事情,看起来就像彩虹一样炫目而神奇,实际上背后蕴含着随处可见的原理.就好像静儿几年前买过一件超贵的防辐射服,当时销售人员把手机严严实实的包在防辐射服里,然后让我打电话测试,果然没有信号. ...

  7. java 日志体系目录

    java 日志体系目录 1.1 java 日志体系(一)log4j1.log4j2.logback.jul.jcl.slf4j 1.2 java 日志体系(二)jcl 和 slf4j 2.1 java ...

  8. java 日志体系(四)log4j 源码分析

    java 日志体系(四)log4j 源码分析 logback.log4j2.jul 都是在 log4j 的基础上扩展的,其实现的逻辑都差不多,下面以 log4j 为例剖析一下日志框架的基本组件. 一. ...

  9. Java 日志体系(二)jcl 和 slf4j

    Java 日志体系(二)jcl 和 slf4j <java 日志体系(一)统一日志>:https://www.cnblogs.com/binarylei/p/9828166.html &l ...

随机推荐

  1. 复习HTML+CSS(6)

    n  表格和表单的嵌套顺序 n  单行文本域 语法格式:<input type="text" 属性="值"> 常用属性 l  Name:文本框的名字 ...

  2. MongoDB 分片集群搭建

    一.概述 分片是一种在多台机器上分配数据的方法.MongoDB使用分片来支持具有非常大的数据集和高吞吐量操作.有两种解决系统增长的方法:垂直扩展和水平扩展. 垂直扩展涉及增加单个服务器的容量,例如使用 ...

  3. 使用控制台调试WinForm窗体程序

    .程序代码结构 .Win32DebuggerHelper.cs using System.Runtime.InteropServices; /* TODO:使用方法 Win32.AllocConsol ...

  4. C++ 前期准备

    在线编译网站: http://www.dooccn.com/cpp/ 刷题: https://leetcode.com/ https://leetcode-cn.com/

  5. Spring Cloud Eureka 自我保护机制

    Eureka Server 在运行期间会去统计心跳失败比例在 15 分钟之内是否低于 85%,如果低于 85%,Eureka Server 会将这些实例保护起来,让这些实例不会过期,但是在保护期内如果 ...

  6. 顺序或者说优先级的重要性---解决dom生成问题有感

    我们的大脑有逻辑,程序也有逻辑,只要一切都刚刚好,那么我们大脑的逻辑和程序的逻辑是没有冲突的:但是,有时候,我们想当然,只顾自己头脑中的逻辑,而随意臆想程序的逻辑,这个时候,就会有很多我们觉得不可思议 ...

  7. springboot+shiro+redis项目整合

    介绍: Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码学和会话管理.使用Shiro的易于理解的API,您可以快速.轻松地获得任何应用程序,从最小的移动应用程序到最 ...

  8. [ Java学习基础 ] Java的封装性与访问控制

    Java面向对象的封装性是通过对成员变量和方法进行访问控制实现的,访问控制分为4个等级:私有.默认.保护和公有,具体规则如下表: 1.私有级别 私有级别的关键字是private,私有级别的成员变量和方 ...

  9. ●BZOJ 2560 串珠子

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2560 题解: 容斥,状压计数dp 首先求出一个数组 g[s] 表示集合内的点的连边方案数(两 ...

  10. [Codeforces]663E Binary Table

    某变换好题.不过听说还有O(2^n*n^2)DP的…… Description 给定一个n*m的01矩阵,你可以选择对任意行和任意列取反,使得最终“1”的数量尽量少. Input 第一行两个整数n,m ...