Log4j与Log4j2日志记录详解

时间:2022-05-27 21:52:06

一个完整的项目里,日志是必不可少的,也是很重要的一部分。程序从开发,测试,维护,运行等环节,都需要向控制台等位置输出大量的信息,如果程序出了问题,那么这些信息能快速反映出问题的所在,帮助我们定位到问题。而且这些信息的输出,在很多时候是使用System.out.println()无法完成的,而且使用System.out.println()这是IO操作,这会拖慢系统的效率。
日志信息根据用途与记录内容的不同,可以分为调试日志,运行日志,异常日志等。
Log4j 全称为Log for java ,也就是专门用来记录java语言的日志记录工具。目前有两个版本,Log4j与Log4j2。
Log4j的下载地址:http://logging.apache.org/log4j/1.2/download.html
Log4j2的下载地址:http://logging.apache.org/log4j/2.x/download.html,下载是下载的是后缀为bin.zip,然后再解压即可。
Log4j与Log4j2日志记录详解
使用上面的包的话,直接将下载的依赖包复制粘贴到项目的lib目录下,add to build path就可以了。
如果是使用Maven管理依赖的话,需要添加下面的依赖:

    <!-- 日志文件管理包 -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version> 
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.12</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.12</version>
    </dependency>
            <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!--测试需要的包 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>

由于是使用Maven管理项目,所以在Resources目录下建立log4j.properties文件,如果是使用eclipse直接导包,那么log4j.properties文件应该放在与src相同级别的目录下。
Log4j与Log4j2日志记录详解
下面是log4j.properties文件

### 设置###
log4j.rootLogger = debug,stdout,D,E

### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### 输出DEBUG 级别以上的日志到=D://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
#输出到的文件目录
log4j.appender.D.File = D://logs/log.log
log4j.appender.D.Append = true
#Debug
log4j.appender.D.Threshold = DEBUG 
log4j.appender.D.layout = org.apache.log4j.PatternLayout
#输出的格式
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### 输出ERROR 级别以上的日志到=D://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =D://logs/error.log 
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

测试代码* MyTest.class *

import org.apache.log4j.Logger;

public class MyTest {
    private static Logger logger = Logger.getLogger(MyTest.class.getClass());
    @org.junit.Test
    public void test() {
        // debug级别
        logger.debug("这是一个debug级别的信息");
        // info级别
        logger.info("这是一个info级别的信息");
        // error级别
        logger.error("这是一个error级别的信息");
    }
}

控制台输出结果:
Log4j与Log4j2日志记录详解
查看日志文件信息我们可以看到:
Log4j与Log4j2日志记录详解
如果我们需要输出sql语句,无法使用private static Logger logger = Logger.getLogger(MyTest.class.getClass());这句代码,则只需要在log4j.properties文件里面添加

# mybatis的
#log4j.logger.com.ibatis = debug    
#log4j.logger.com.ibatis.common.jdbc.SimpleDataSource = debug    
#log4j.logger.com.ibatis.common.jdbc.ScriptRunner = debug    
#log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate = debug    
#log4j.logger.java.sql.Connection = debug
# 普通的sql的
log4j.logger.java.sql.Statement = debug    
log4j.logger.java.sql.PreparedStatement = debug    
log4j.logger.java.sql.ResultSet =debug    

如果需要在代码里面自己控制输出,使用:

// 定义一个static Logger对象
private static Logger logger = Logger.getLogger(MyTest.class.getClass());

在配置文件log4j.properties配置的话:
1.配置根Logger,也是最顶层,最重要的配置,level 是日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL,OFF就是所有的信息都不会打印,ALL就是所有信息都会打印,DEBUG模式使用比较多,因为程序出错的时候我们需要去查看日志才能定位问题。

// off 最高等级,用于关闭所有日志记录。
// fatal 指出每个严重的错误事件将会导致应用程序的退出。
// error 指出虽然发生错误事件,但仍然不影响系统的继续运行。
// warm 表明会出现潜在的错误情形。
// info 一般和在粗粒度级别上,强调应用程序的运行全程。
// debug 一般用于细粒度级别上,对调试应用程序非常有帮助。
// all 最低等级,用于打开所有日志记录。
// 基本语法:log4j.rootLogger = [ level ] , appenderN1, appender1, …
// 比如下面的
log4j.rootLogger = debug,stdout,D,E

使用appender输出信息到目的地,每一个目的地后面都有自己的属性,我们可以进行定义。

org.apache.log4j.ConsoleAppender(控制台),  
org.apache.log4j.FileAppender(文件),  
org.apache.log4j.DailyRollingFileAppender(每天一个日志文件),  
org.apache.log4j.RollingFileAppender(文件大小到达指定大小的时候产生一个新的文件),  
org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

上面有一句log4j.appender.stdout.layout = org.apache.log4j.PatternLayout定义了日志输出的layout,那么layout的基本几种如下:

org.apache.log4j.HTMLLayout(HTML表格布局),  
org.apache.log4j.PatternLayout(自定义布局),  
org.apache.log4j.SimpleLayout(包含日志信息级别和信息字符串),  
org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)

自定义布局中,输出的时候的定义比如log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n,格式语法如下:

%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL  
%r 输出消耗的毫秒数  
%c 输出类的全名  
%t 输出产生该日志事件的线程名  
%n 输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”  
%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921  
%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)