Web基礎之日志


Web基礎之日志

  日志在企業開發中有着不可或缺的作用,它可以用以記錄用戶操作、系統運行狀態和錯誤信息。日志記錄的好壞直接關系到系統出現問題時定位的速度。
  最開始的日志一般使用log4j,后來sun公司心有不甘,在jdk 1.4中加入了一個叫java.util.logging的日志包,簡稱jul。兩種日志的api肯定是不同的,此時日志就出現了混亂。log4j的作者Ceki Gülcü就寫了一個叫Jakarta Commons Logging的接口,簡稱jcl,來共同管理log4j和jul,並且jcl中提供了一個日志實現simplelog。接着又改良了下log4j,寫出了logback。再后來Ceki Gülcü覺得jcl不好用(的確用問題),然后寫了一個新的接口slf4j,來共同管理這些日志系統。接着呢Ceki Gülcü又覺得logj4性能不夠了,又寫了一個log4j2,。真是專注日志100年啊。

  所以他們之間的關系是這樣的:

logs

  其中slf4j並不提供日志實現,而是使用外觀模式創建了一個接口,來統一這些日志的api。

  這也是為什么阿里規范上強制使用slf4j的原因:

強制】應用中不可直接使用日志系統(Log4j、Logback)中的 API,而應依賴使用日志框架SLF4J 中的 API,使用門面模式的日志框架,有利於維護和各個類的日志處理方式統一。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(Test.class);

slf4j + log4j / log4j2

  認識了之后接下來就是使用了,首先在maven中導入依賴:

<!-- log4j依賴,好像不更新了,我看版本還是12年的 -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
<!-- slf4j的依賴 -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.28</version>
</dependency>
<!-- 告訴slf4j使用log4j,也就是綁定 -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.28</version>
    <scope>test</scope>
</dependency>

  如果使用log4j2的話這么配:

<!-- log4j2的核心 -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.12.1</version>
</dependency>
<!-- log4j2的api -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.12.1</version>
</dependency>
<!-- slf4j綁定log4j2 -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.12.1</version>
</dependency>
<!-- slf4j的依賴 -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.28</version>
</dependency>

  這里我將使用log4j2的xml和properties兩種方式來簡單配置。


  在resources目錄下創建log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <!-- 輸出源的配置:日志輸出的目的地 -->
    <Appenders>
        <!--
            Console標簽;指定這是一個控制台輸出源。
                name:名稱,需要在被引用才會生效
                target: 控制台字體的顏色
                        SYSTEM_ERR:紅色字體
                        SYSTEM_OUT:黑色字體
                PatternLayout:布局,輸出到控制台日志的格式。
        -->
        <Console name="myConsole" target="SYSTEM_ERR">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %5level %logger{36} - %msg%n"/>
        </Console>

        <!-- 文件輸出源
            fileName:指定保存日志的文件的名字和位置。
                    一般寫絕對路徑。
        -->
        <File name="myFile" fileName="D://demo.log">
            <PatternLayout>
                <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
            </PatternLayout>
        </File>

        <!--
            多文件輸出源:
                fileName:實時記錄日志的文件名和位置
                filePattern : 文件封存的位置和格式
         -->
        <RollingFile name="rollingFile" fileName="D://demo2.log" filePattern="D://logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
            <PatternLayout>
                <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
            </PatternLayout>
            <!-- 多文件拆分的規則 -->
            <Policies>
                <!-- 基於時間的  此處interval屬性值的單位是由filePattern屬性中文件名時間精確的單位 決定的。 -->
                <TimeBasedTriggeringPolicy interval="1" />
                <!-- 基於文件大小的 -->
                <SizeBasedTriggeringPolicy size="512 MB"/>
            </Policies>
        </RollingFile>

    </Appenders>
    <Loggers>
        <!-- 配置日志輸出的級別的
            將當前級別以及比當前級別高的消息進行輸出。
        -->
        <Root level="trace">
            <AppenderRef ref="myConsole"/>
            <!-- 可以同時多種方式輸出日志 -->
            <AppenderRef ref="MyFile"/>
            <AppenderRef ref="RollingFile"/>

        </Root>
    </Loggers>
</Configuration>

  log4j使用properties方式:

# 配置輸出源的   log4j.appender.輸出源名=輸出源的實現類
# 屬性的配置  log4j.appender.輸出源名.屬性名=屬性值
log4j.appender.a=org.apache.log4j.ConsoleAppender
log4j.appender.a.Target=System.out
log4j.appender.a.layout=org.apache.log4j.PatternLayout
log4j.appender.a.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n

log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=D:/mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n

### log4j.rootLogger=輸出級別,輸出源1,輸出源2....
log4j.rootLogger=debug,a,file

log4j2的properties(參考):

status = warn
name = MyApp
 
appender.console.type = Console
appender.console.name = consoleLogDemo
appender.console.filter.threshold.type = ThresholdFilter
appender.console.filter.threshold.level = debug
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %m%n
appender.console.target = System_out
 
appender.rolling.type = File
appender.rolling.name = fileLogDemo
appender.rolling.filter.threshold.type = ThresholdFilter
appender.rolling.filter.threshold.level = error
appender.rolling.layout.type = PatternLayout
appender.rolling.layout.pattern = %d-%m%n
appender.rolling.append = true
appender.rolling.fileName = e:\\propertiesTest.log
 
rootLogger.level = debug
rootLogger.appenderRef.consolelogdemo.ref = consoleLogDemo
rootLogger.appenderRef.filelogdemo.ref = fileLogDemo

輸出格式參數為:

%p:輸出日志信息的優先級,即DEBUG,INFO,WARN,ERROR,FATAL
%d:輸出日志時間點的日期或時間,默認格式為ISO8601,可以指定格式如:%d{yyyy/MM/dd HH:mm:ss,SSS}
%r:輸出自應用程序啟動到輸出該log信息耗費的毫秒數
%t:輸出產生該日志事件的線程名
%l:輸出日志事件的發生位置,相當於%c.%M(%F:%L)的組合,包括類全名、方法、文件名以及在代碼中的行數
%c:輸出日志信息所屬的類目,通常就是類全名
%M:輸出產生日志信息的方法名
%F:輸出日志消息產生時所在的文件名
%L:輸出代碼中的行號
%m:輸出代碼中指定的具體日志信息
%n:輸出一個回車換行符,Windows平台為"rn",Unix平台為"n"
%x:輸出和當前線程相關聯的NDC(嵌套診斷環境)
%%:輸出一個"%"字符

  這是幾種常用的配置,如果覺得不夠的話可以查看官方文檔

  順便這里推薦個講的很詳細的博客

打日志

在log4j2中可以這么用:

public class MyApp {
    private static final Logger logger = LoggerFactory.getLogger(MyApp.class);

    public static void main(String[] args) {
        logger.warn("Hello, {}","slf4j");
    }
}

使用{}作為占位符,性能要比log4j直接字符串拼接性能好(畢竟字符串拼接的底層原理是創建StringBuilder)


至於一大堆jar包的關系如下:

slf4j
關於log4j2的如下:

log4j2

參考關於slf4j log4j log4j2的jar包配合使用的那些事


免責聲明!

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



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