跳转至

Java - Log4j输出日志

Java - Log4j输出日志

更新日期:2020-03-30


1. Log4j简介

log4j是一套帮助我们在程序中输出log的开源软件开发包,由Apache软件基金会提供。

它支持的平台非常广泛,这里以Maven创建的Java工程为例来说明如何使用log4j。我几乎照搬了官方网站上的内容,大概做了一下整理。

log4j官方网站 https://logging.apache.org/log4j/2.x/

2. 配置log4j

log4j支持使用如下几种方式进行配置:

  • XML
  • JSON
  • YAML
  • properties

可以任选你比较熟悉的一种。

2.1 log4j配置文件的加载

log4j会在约定的位置自动寻找配置文件,并使用第一个找到的配置文件。查看官方文档可以发现扫描规则如下:

官方文档

  1. Log4j will inspect the log4j.configurationFile system property and, if set, will attempt to load the configuration using the ConfigurationFactory that matches the file extension.
  2. If no system property is set the properties ConfigurationFactory will look for log4j2-test.properties in the classpath.
  3. If no such file is found the YAML ConfigurationFactory will look for log4j2-test.yaml or log4j2-test.yml in the classpath.
  4. If no such file is found the JSON ConfigurationFactory will look for log4j2-test.json or log4j2-test.jsn in the classpath.
  5. If no such file is found the XML ConfigurationFactory will look for log4j2-test.xml in the classpath.
  6. If a test file cannot be located the properties ConfigurationFactory will look for log4j2.properties on the classpath.
  7. If a properties file cannot be located the YAML ConfigurationFactory will look for log4j2.yaml or log4j2.yml on the classpath.
  8. If a YAML file cannot be located the JSON ConfigurationFactory will look for log4j2.json or log4j2.jsn on the classpath.
  9. If a JSON file cannot be located the XML ConfigurationFactory will try to locate log4j2.xml on the classpath.
  10. If no configuration file could be located the DefaultConfiguration will be used. This will cause logging output to go to the console.

可以看到log4j的配置非常人性化,假如你没有配置log4j,它将使用默认配置输出log到控制台。你自己的配置文件只需放到classpath下面就可以了,比如maven工程典型的src/main/resources目录。

假如你想使用固定位置的配置文件,则可以通过配置log4j.configurationFile环境变量来指定。

2.2 使用yml配置log4j

默认情况下并不能支持yml配置文件,因为无法解析。需要先添加如下依赖:

pom.xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<dependency>    
        <groupId>com.fasterxml.jackson.dataformat</groupId> 
        <artifactId>jackson-dataformat-yaml</artifactId>    
        <version>2.9.9</version>    
</dependency>   
<dependency>    
        <groupId>com.fasterxml.jackson.core</groupId>   
        <artifactId>jackson-databind</artifactId>   
        <version>2.9.9.1</version>  
</dependency>   

直接复制一段官网给出的例子:

官网例子

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
Configuration:  
    status: warn    
    name: YAMLConfigTest    
    properties: 
    property:   
        name: filename  
        value: C:/data/test-yaml.log    
    thresholdFilter:    
    level: debug    
    appenders:  
    Console:    
        name: STDOUT    
        PatternLayout:  
        Pattern: "%m%n" 
    File:   
        name: File  
        fileName: ${filename}   
        PatternLayout:  
        Pattern: "%d %p %C{1.} [%t] %m%n"   
        Filters:    
        ThresholdFilter:    
            level: debug    

    Loggers:    
    logger: 
        -   
        name: ConsoleLogger 
        level: debug    
        additivity: false   
        AppenderRef:    
            ref: STDOUT 
        -   
        name: FileLogger    
        level: debug    
        additivity: false   
        AppenderRef:    
            ref: File   
    Root:   
        level: debug    
        AppenderRef:    
        ref: STDOUT 

这里面配置了一个用于控制台和一个用于文件的log配置。文件位置为C:/data/test-yaml.log。

3. 在程序中使用log4j

3.1 添加log4j包依赖

以maven为例,需要添加如下依赖:

pom.xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<dependency>    
        <groupId>org.apache.logging.log4j</groupId> 
        <artifactId>log4j-api</artifactId>  
        <version>2.12.0</version>   
</dependency>   
<dependency>    
        <groupId>org.apache.logging.log4j</groupId> 
        <artifactId>log4j-core</artifactId> 
        <version>2.12.0</version>   
</dependency>   

3.2 在Java中输出log

在Java类中使用Log4j非常简单,仍旧照搬log4j官网上面的例子:

官网例子

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import java.io.IOException; 
import javax.servlet.AsyncContext;  
import javax.servlet.ServletException;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;   
import javax.servlet.http.HttpServletResponse;  

import org.apache.logging.log4j.LogManager; 
import org.apache.logging.log4j.Logger; 
import org.apache.logging.log4j.web.Log4jWebLifeCycle;  
import org.apache.logging.log4j.web.WebLoggerContextUtils;  

public class TestAsyncServlet extends HttpServlet { 
    @Override   
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {   
            final AsyncContext asyncContext = req.startAsync(); 
        asyncContext.start(new Runnable() { 
            @Override   
            public void run() { 
                final Log4jWebLifeCycle webLifeCycle =  
                    WebLoggerContextUtils.getWebLifeCycle(TestAsyncServlet.this.getServletContext());   
                webLifeCycle.setLoggerContext();    
                try {   
                    final Logger logger = LogManager.getLogger(TestAsyncServlet.class); 
                    logger.info("Hello, servlet!"); 
                } finally { 
                    webLifeCycle.clearLoggerContext();  
                }   
            }   
        }); 
    }   
}   

简单来说就是两步:

1
2
Logger logger = LogManager.getLogger(YourClass.class);  
logger.info("Hello world!");    

没了。

3.3 在Web程序中使用log4j

首先除了上面列出的两个依赖的包以外,需要再添加一个额外的依赖:

pom.xml

1
2
3
4
5
<dependency>    
        <groupId>org.apache.logging.log4j</groupId> 
        <artifactId>log4j-web</artifactId>  
        <version>2.12.0</version>   
</dependency>   

在web.xml中需要配置yml配置文件的位置:

web.xml

1
2
3
4
<context-param> 
        <param-name>log4jConfiguration</param-name> 
        <param-value>classpath:log4j2.yml</param-value> 
</context-param>