log4j、log4j2和slf4j的基本使用


一、什么是log4j、log4j2和slf4j

  Log4j是Apache的一個開源項目,通過配置來控制日志的輸出。主要是控制日志的輸出級別、輸出位置和輸出內容格式。

  Log4j2是在log4j框架的基礎上進行了優化和改造具有更好的性能。

  slf4j是一個日志輸出接口,其本身是沒有具體實現的,必須的借助上面的日志框架才能更好的實現日志輸出。使用slf4j能夠更好的讓用戶進行日志框架的切換而無需修改代碼。

 

二、log4j的主要組成

  Log4j由三個重要的組成構成:

  1.日志記錄器(Loggers):控制要啟用或禁用哪些日志記錄語句,並對日志信息進行級別限制

    2.輸出端(Appenders) : 指定了日志將打印到控制台還是文件中

    3.日志格式化器(Layout): 控制日志信息的顯示格式

  

三、log4j配置內容

  

  

#######日志級別#############
#Debug     調試信息   級別最低
#Info      一般信息
#Warn      警告信息
#Error     錯誤信息
#Fatal     嚴重錯誤信息  級別最高,錯誤最嚴重的(在slf4j中沒有這個級別)
##########################

#######日志的輸出位置#########
#org.apache.log4j.ConsoleAppender:將日志信息輸出到控制台。
#org.apache.log4j.FileAppender:將日志信息輸出到一個文件。
#org.apache.log4j.DailyRollingFileAppender:將日志信息輸出到一個日志文件,並且每天輸出到一個新的日志文件。
#org.apache.log4j.RollingFileAppender:將日志信息輸出到一個日志文件,當文件大小達到指定尺寸時,會自動把文件改名,同時產生一個新的文件。
#org.apache.log4j.WriteAppender:將日志信息以流格式發送到任意指定地方。
#org.apache.log4j.jdbc.JDBCAppender:通過JDBC把日志信息輸出到數據庫中。
#org.apache.log4j.net.SMTPAppender:將日志輸出到郵件
#########################

#######日志格式化器layout####
#org.apache.log4j.HTMLLayout(以HTML表格形式布局),
#org.apache.log4j.PatternLayout(靈活地指定布局模式),
#org.apache.log4j.SimpleLayout(包含日志信息的級別和信息字符串),
#org.apache.log4j.TTCCLayout(包含日志產生的時間、線程、類別等等信息)
##########################

##########日志信息格式中幾個符號所代表的含義##############
# -X號: X信息輸出時左對齊;
# %p: 輸出日志信息優先級,即DEBUG,INFO,WARN,ERROR,FATAL,
# %d: 輸出日志時間點的日期或時間,默認格式為ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},輸出類似:2002年10月18日 22:10:28,921
# %r: 輸出自應用啟動到輸出該log信息耗費的毫秒數
# %c: 輸出日志信息所屬的類目,通常就是所在類的全名
# %t: 輸出產生該日志事件的線程名
# %l: 輸出日志事件的發生位置,相當於%C.%M(%F:%L)的組合,包括類目名、發生的線程,以及在代碼中的行數。舉例:Testlog4.main (TestLog4.java:10)
# %x: 輸出和當前線程相關聯的NDC(嵌套診斷環境),尤其用到像java servlets這樣的多客戶多線程的應用中。
# %%: 輸出一個"%"字符
# %F: 輸出日志消息產生時所在的文件名稱
# %L: 輸出代碼中的行號
# %m: 輸出代碼中指定的消息,產生的日志具體信息
# %n: 輸出一個回車換行符,Windows平台為"/r/n",Unix平台為"/n"輸出日志信息換行
# 可以在%與模式字符之間加上修飾符來控制其最小寬度、最大寬度、和文本的對齊方式。如:
# 1)%20:最小的寬度是20,如果小於20的話,默認的情況下右對齊。
# 2)%-20:最小的寬度是20,如果小於20的話,"-"號指定左對齊。
# 3)%.30:最大的寬度是30,如果大於30的話,就會將左邊多出的字符截掉,但小於30的話也不會
##################################################

 

四、log4j的使用

  1.引入log4j的jar包

     <!-- 日志相關jar包 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

 

  2.編寫配置文件

#######日志#########

log4j.rootLogger=DEBUG,Console,DayFile,FixedFile,logMail,logDB

###輸出到控制台配置#########
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=[%-5p][%-19d{yyyy/MM/dd HH:mm:ss}][%l]  %m%n
log4j.appender.Console.Threshold=DEBUG
log4j.appender.Console.Target=System.out
log4j.appender.Console.ImmediateFlush=true



###輸出到文件配置(每天一個日志文件)##########
log4j.appender.DayFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.DayFile.layout=org.apache.log4j.PatternLayout
log4j.appender.DayFile.layout.ConversionPattern=[%-5p][%-19d{yyyy/MM/dd HH:mm:ss}][%l]  %m%n
log4j.appender.DayFile.Threshold=INFO
log4j.appender.DayFile.ImmediateFlush=true
log4j.appender.DayFile.Append=true
log4j.appender.DayFile.Encoding=UTF-8
log4j.appender.DayFile.File=/daylogs/log
log4j.appender.DayFile.BufferedIO=true
#緩存單位為byte
log4j.appender.DayFile.BufferSize=8192
log4j.appender.DayFile.DatePattern='.'yyyy-MM-dd
# -DatePattern='.'yyyy-ww:每周滾動一次文件,即每周產生一個新的文件。還可以按用以下參數: # '.'yyyy-MM:每月 # '.'yyyy-ww:每周 # '.'yyyy-MM-dd:每天 # '.'yyyy-MM-dd-a:每天兩次 # '.'yyyy-MM-dd-HH:每小時 # '.'yyyy-MM-dd-HH-mm:每分鍾




###輸出到文件配置(文件大小達到某個值之后就產生一個新的日志文件)##########
log4j.appender.FixedFile=org.apache.log4j.RollingFileAppender
log4j.appender.FixedFile.layout=org.apache.log4j.PatternLayout
log4j.appender.FixedFile.layout.ConversionPattern=[%-5p][%-19d{yyyy/MM/dd HH:mm:ss}][%l]  %m%n
log4j.appender.FixedFile.Threshold=INFO
log4j.appender.FixedFile.Append=true
log4j.appender.FixedFile.ImmediateFlush=true
log4j.appender.FixedFile.MaxFileSize=10MB
log4j.appender.FixedFile.MaxBackupIndex=50
log4j.appender.FixedFile.Encoding=UTF-8
log4j.appender.FixedFile.File=/fixedlogs/log
#開啟緩存
log4j.appender.FixedFile.BufferedIO=true
#緩存單位為byte,默認8k
log4j.appender.FixedFile.BufferSize=8192



#用Email發送日志 
log4j.appender.logMail=org.apache.log4j.net.SMTPAppender
log4j.appender.logMail.layout=org.apache.log4j.PatternLayout
log4j.appender.logMail.layout.ConversionPattern=[%-5p][%-19d{yyyy/MM/dd HH:mm:ss}][%l]  %m%n
log4j.appender.logMail.layout.LocationInfo=TRUE
log4j.appender.logMail.layout.Title=TestLog Mail LogFile
log4j.appender.logMail.Threshold=ERROR
log4j.appender.logMail.SMTPDebug=FALSE
log4j.appender.logMail.SMTPHost=SMTP.163.com
log4j.appender.logMail.From=abcd@163.com
log4j.appender.logMail.To=123456@qq.com
#抄送
#log4j.appender.logMail.Cc=12345@gmail.com
#密送
#log4j.appender.logMail.Bcc=123456@gmail.com
log4j.appender.logMail.SMTPUsername=abcd
log4j.appender.logMail.SMTPPassword=123456
log4j.appender.logMail.Subject=Log4j Log Messages
#單位是KB
log4j.appender.logMail.BufferSize=10
log4j.appender.logMail.SMTPAuth=TRUE


#將日志登錄到MySQL數據庫 
log4j.appender.logDB=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.logDB.layout=org.apache.log4j.PatternLayout
log4j.appender.logDB.Driver=com.mysql.jdbc.Driver
log4j.appender.logDB.URL=jdbc:mysql://127.0.0.1:3306/zmyproject
log4j.appender.logDB.User=root
log4j.appender.logDB.Password=root
log4j.appender.logDB.Threshold=ERROR
###這里是指緩存的sql條數,默認是1
log4j.appender.logDB.BufferSize=10
log4j.appender.logDB.Sql=INSERT INTO testlog_log4j(project_name,create_date,create_time,log_level,category,file_name,thread_name,line,all_category,message) values('testlog','%d{yyyy-MM-dd}','%d{yyyy-MM-dd HH:mm:ss}','%p','%c','%F','%t','%L','%l','%m')


#配置mybatis的日志(下面的的key對應上dao的路徑即可)
#mybatis的日志必須是DEBUG及以下的級別才會打印
og4j.logger.com.kyle.testlog.dao=DEBUG

 

  3.編寫代碼

  

@RestController
@RequestMapping("user")
public class UserController {
    
    Logger logger = Logger.getLogger(UserController.class);
    
    @Autowired
    private UserService userService;
    
    @RequestMapping("getUserInfoById")
    public String getUserInfoById(String id){
        logger.debug("DEBUG____________________入參:id:"+id);
        logger.info("INFO____________________入參:id:"+id);
        logger.warn("WARN____________________入參:id:"+id);
        logger.error("ERROR____________________入參:id:"+id);
        User user = userService.getUserInfoById(id);
        return user.toString();
    }
}

 

  4.mybatis日志

    mybatis的日志默認不打印sql,需要進行相關的配置

    ①在mybatis的主配置文件mybatis-config.xml中加入相關配置

    

<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <settings>  
        <setting name="logImpl" value="LOG4J"/>  
    </settings>  

</configuration>

 

    ②在log4j.properties文件中指定相應的Mapper文件(也可以是所屬包)

#配置mybatis的日志(下面的的key對應上dao的路徑即可) #mybatis的日志必須是DEBUG一下的級別才會打印
og4j.logger.com.kyle.testlog.dao=DEBUG

 

五、log4j2的使用

  1.引入jar包

  

 <!-- mybatis、數據庫連接池 和mysql驅動相關jar包 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>

        <!-- 日志相關jar包 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.8.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.8.2</version>
        </dependency>
         <!-- 發送日志郵件所需jar包 -->
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>

 

  2.配置文件log4j2.xml

    

<?xml version="1.0" encoding="UTF-8"?>
<!-- status屬性是log4j2自身框架的日志級別 
    monitorInterval自動檢測配置文件的時間間隔(單位:秒),最小間隔為5秒。log4j 2檢測到配置文件有變化,會重新配置自己。
-->
<Configuration status="OFF" monitorInterval="60">
    
    <!-- 公共的一些屬性的定義,方便下面的配置重復使用如:${LOG_HOME} -->
    <properties>
        <property name="LOG_HOME">/logs</property>
        <property name="FILE_NAME">log</property>
    </properties>

    <Appenders>
        <!-- 輸出控制台,總共有3個屬性
             name:Appender的名字
             target:SYSTEM_OUT 或 SYSTEM_ERR,默認是SYSTEM_OUT
             layout:如何格式化,如果沒有默認是%m%n
        -->
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n" />
        </Console>
        
        <!-- 
                                    日志輸出到文件,一直會輸出到同一個文件,所以可用性不高
             name:Appender的名字
             fileName:日志輸出目的文件名
             layout:如何格式化,如果沒有默認是%m%n
             bufferedIO:是否設置緩沖區
         -->
        <File name="File" fileName="/logs/log4j2.log" bufferedIO="true">
            <!-- 控制日志的輸出級別(只輸出error及以上的日志) -->
            <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n" />
        </File>
        
        <!-- 
                                    日志按規則輸出到多個文件,只會保留幾個日志文件。
             name:Appender的名字
             fileName:日志輸出目的文件名
             filePattern:指定打包的日志文件的格式,文件的壓縮格式支持的后綴名:".gz",".zip",".bz2",".xz";
                                                                      如果不想壓縮的話就不用壓縮文件格式結尾就行。
             layout:如何格式化,如果沒有默認是%m%n                    
         -->
        <RollingRandomAccessFile name="RollingFile" fileName="${LOG_HOME}/${FILE_NAME}.log" 
                                    filePattern="${LOG_HOME}/$${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd HH-mm}-%i.log.zip">
            <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout  charset="UTF-8"  pattern="%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n"/>
            <Policies>
                <!-- 下面的幾種日志打包壓縮的方式可以同時配置多個規則,只要有一個滿足,日志文件就會被壓縮 -->
                <!-- 基於時間來生成壓縮文件, interval屬性表示每隔多少個時間間隔,其單位為filePatten定義的文件日期最小單位
                                                        下面的配置表示每隔兩分鍾生成一個壓縮文件 -->
                <TimeBasedTriggeringPolicy interval="2"/>
                <!-- 固定大小來壓縮日志文件 -->
                <SizeBasedTriggeringPolicy size="10 KB"/>
                <!-- 日志文件比當前jvm啟動時間更早就會觸發壓縮日志文件 -->
                <OnStartupTriggeringPolicy />
            </Policies>
            <DefaultRolloverStrategy>
                 <!-- 日志文件保留的個數-->
                 <Delete basePath="${LOG_HOME}" maxDepth="2">
                    <!-- 要刪除的日志的名稱匹配 -->
                    <IfFileName glob="*/*.log.zip" />
                    <!-- 保留文件的天數 -->
                    <!-- <IfLastModified age="60d" /> -->
                    <!-- 保留文件的個數 -->
                    <IfAccumulatedFileCount  exceeds="10" />
                </Delete>
            </DefaultRolloverStrategy>
        </RollingRandomAccessFile>
    
        <!-- 日志發送郵件 -->
        <SMTP name="Mail"   subject="LOG4J2  ERROR LOG" 
                            to="123456@qq.com" 
                            from="abcd@163.com" 
                            smtpUsername="abcd" 
                            smtpPassword="12345" 
                            smtpHost="SMTP.163.com" 
                            smtpDebug="false" 
                            smtpPort="25" bufferSize="100">
             <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
             <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n" />
        </SMTP>
        
        <!-- 日志寫入數據庫 -->
        <JDBC name="databaseAppender" tableName="testlog_log4j">  
            <ConnectionFactory class="com.kyle.testlog.util.ConnectionFactory" method="getDatabaseConnection" />
            <Column name="project_name" pattern="testlog4j"/>  
            <Column name="create_date" pattern="%d{yyyy-MM-dd}"/>  
            <Column name="create_time" pattern="%d{yyyy-MM-dd HH:mm:ss}"/>  
            <Column name="log_level" pattern="%p" />  
            <Column name="category" pattern="%C" />  
            <Column name="file_name" pattern="%F" />  
            <Column name="thread_name" pattern="%t" />  
            <Column name="line" pattern="%L" />  
            <Column name="all_category" pattern="%l" />  
            <Column name="message" pattern="%message"/>
            <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
        </JDBC>  

        <Async name="FileAsyncAppender">
            <AppenderRef ref="File"/>
        </Async>
        <Async name="RollingFileAsyncAppender">
            <AppenderRef ref="RollingFile"/>
        </Async>
        <Async name="MailAsyncAppender">
            <AppenderRef ref="Mail"/>
        </Async>
        
    </Appenders>

    <Loggers>
        <!-- 結合mybatis打印sql -->
        <logger name="com.kyle.testlog.dao" level="DEBUG"></logger>
        
        <!-- 自定義logger
            name:如果定義為包名或者類名則匹配的時候會對應包下的類中的日志,
                                                如果自己隨便定義則可以通過LogManager.getLogger("definedLogger")來獲取
            level:日志級別,和appender中的日志級別取交集
            additivity:是否繼承root  默認是true;如果為true則如果該logger與root有相同的appender,則會相同的日志輸出兩遍
         --> 
        <Logger name="definedLogger" level="ERROR" additivity="true">  
            <AppenderRef ref="FileAsyncAppender" />  
            <AppenderRef ref="RollingFileAsyncAppender" />  
        </Logger>
        
        <Logger name="mailLogger" level="ERROR" additivity="false">  
            <AppenderRef ref="MailAsyncAppender" />  
        </Logger>
        
        <!-- 這里定義的日志級別和每個appender定義的日志級共同起作用,取二者的交集 -->
        <Root level="INFO">  
            <AppenderRef ref="Console" />
            <!-- <AppenderRef ref="FileAsyncAppender" />
            <AppenderRef ref="RollingFileAsyncAppender" />
            <AppenderRef ref="MailAsyncAppender" /> -->
            <AppenderRef ref="databaseAppender" />
        </Root> 
    </Loggers> 

</Configuration>

 

  mybatis-config.xml配置

  

<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <settings>  
        <setting name="logImpl" value="LOG4J2"/>  
    </settings>  

</configuration>

 

 

  3.相關代碼

  

package com.kyle.testlog.util;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDataSource;
import org.apache.commons.pool.impl.GenericObjectPool;


public class ConnectionFactory {

    private static interface Singleton {
        final ConnectionFactory INSTANCE = new ConnectionFactory();
    }

    private final DataSource dataSource;

    private ConnectionFactory() {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.exit(0);
        }

        Properties properties = new Properties();
        properties.setProperty("user", "root");
        properties.setProperty("password", "root");

        GenericObjectPool pool = new GenericObjectPool();
        
        DriverManagerConnectionFactory connectionFactory = new DriverManagerConnectionFactory(
                "jdbc:mysql://localhost:3306/zmyproject", properties);

        new PoolableConnectionFactory(connectionFactory, pool, null, null, false, true);

        this.dataSource = new PoolingDataSource(pool);
    }

    public static Connection getDatabaseConnection() throws SQLException {
        
        return Singleton.INSTANCE.dataSource.getConnection();
    }

}

 

  

@RestController
@RequestMapping("user")
public class UserController {
    
    Logger logger = LogManager.getLogger(UserController.class);
    //Logger logger = LogManager.getLogger("definedLogger");
    
    @Autowired
    private UserService userService;
    
    @RequestMapping("getUserInfoById")
    public String getUserInfoById(String id){
        logger.debug("DEBUG____________________入參:id:"+id);
        logger.info("INFO____________________入參:id:"+id);
        logger.warn("WARN____________________入參:id:"+id);
        logger.error("ERROR____________________入參:id:"+id);
        logger.fatal("FATAL____________________入參:id:"+id);
        User user = userService.getUserInfoById(id);
        return user.toString();
    }
}

 

  

六、結合log4j和log4j2來使用

  1.log4j和slf4j

    ①引入jar包:maven項目只需要引入一個jar包代替原來的log4j的jar包即可(要注意版本的問題,可能會導致項目無法啟動

     <!-- 日志相關jar包 -->
        <!-- <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency> -->
        <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>1.7.7</version>
        </dependency> 

 

     將項目中的獲取logger的方式修改一下即可 Logger logger = Logger.getLogger(UserController.class); 改為 Logger logger = LoggerFactory.getLogger(UserController.class); 即可

 

   2.log4j2和slf4j

    ①引入jar包

      

 <!-- 日志相關jar包 -->
        <!-- <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.11.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.11.0</version>
        </dependency> -->
        
        <!-- 使用slf4j -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.11.1</version>
        </dependency>

    

    將項目中的獲取logger的方式修改一下即可   Logger logger = LogManager.getLogger(UserController.class); 改為 Logger logger = LoggerFactory.getLogger(UserController.class); 即可

   

 

 

 

 

 

 

 

 

 

 

 

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM