Einführung in das Log-Framework-Slf4j + Logback-Eintragspraxis | JD Cloud-Technikteam

Vorwort

Mit der rasanten Entwicklung des Internets und von Big Data sind verteilte Protokollsysteme und Protokollanalysesysteme weit verbreitet. Fast alle Anwendungen verwenden verschiedene Protokollframeworks, um Programmlaufinformationen aufzuzeichnen. Daher ist es für einen Ingenieur sehr wichtig, die gängigen Protokollierungs-Frameworks zu verstehen. Obwohl die Ausführungsergebnisse der Anwendung durch das Vorhandensein oder Fehlen von Protokollen nicht beeinträchtigt werden, ist eine Anwendung ohne Protokolle unvollständig oder sogar fehlerhaft. Ein hervorragendes Protokollsystem kann Betriebsspuren aufzeichnen , den Betriebsstatus des Systems überwachen und Systemfehler beheben .




Entwicklung des Java Logging Framework

In der Anfangszeit formulierte das Java-Protokollierungsframework keinen einheitlichen Standard, sodass viele Anwendungen gleichzeitig mehrere Protokollierungsframeworks verwendeten. Der Entwicklungsverlauf des Java-Logging-Frameworks lässt sich grob in die folgenden Phasen unterteilen:





 

1. Log4j: Apache Log4j ist ein Java-basiertes Protokollierungstool. Das Projekt wurde 1999 von Ceki Gülcü ins Leben gerufen und ist fast zum De-facto-Standard für Java-Logging-Frameworks geworden.
2. JULI: Apache wollte Log4j in JDK einführen, wurde aber von Sun abgelehnt. Anschließend imitierte Sun Log4j und führte JUL (java.util.logging) in jdk1.4 ein.
3. Commons Logging: Um die Protokollierungsschnittstelle und die Implementierung zu entkoppeln, startete Apache 2002 JCL (Jakarta Commons Logging). JCL definiert eine Reihe von Protokollschnittstellen und die spezifische Implementierung wird durch Log4j oder JUL vervollständigt. Commons Logging verwendet dynamische Bindung, um die Protokollierung zu implementieren. Beim Codieren müssen Sie nur die von ihm definierte Schnittstelle verwenden. Wenn das Programm ausgeführt wird, verwendet es ClassLoader, um die zugrunde liegende Protokollbibliothek zu finden und zu laden, sodass Sie flexibel zwischen Log4j und JUL wählen können Implementieren Sie die Protokollierungsfunktion.
4. Slf4j&Logback: Ceki Gülcü und die Apache Foundation sind sich über den Commons-Logging-Standard nicht einig. Später verließ Ceki Gülcü Apache und erstellte zwei Projekte, Slf4j und Logback. Slf4j ist eine Protokollfassade, die nur Schnittstellen bereitstellt und Protokollimplementierungen wie Logback, JUL und log4j unterstützen kann. Logback bietet eine spezifische Implementierung. Im Vergleich zu log4j bietet Logback eine schnellere Ausführungsgeschwindigkeit und umfassendere Funktionen.
5. Log4j 2: Um seine Position im Java-Logging-Bereich zu behaupten und zu verhindern, dass JCL und Log4j durch Slf4j und Logback ersetzt werden, startete Apache 2014 Log4j 2. Log4j 2 ist nicht mit log4j kompatibel. Nach vielen gründlichen Optimierungen wurde die Leistung erheblich verbessert.



Einführung in das Log-Framework

Wie oben erwähnt, gehören zu den derzeit am häufigsten verwendeten Protokollierungsframeworks Log4j, Log4j 2, Commons Logging, Slf4j, Logback und JUL. Diese Protokollierungsframeworks können in zwei Typen unterteilt werden: Fassadenprotokollierung und Protokollierungssysteme.

Blockfassade

Logging Facade ist ein Entwurfsmuster, das zur Implementierung einer Abstraktionsschicht für die Protokollierung in einer Anwendung verwendet wird. Es stellt einen einheitlichen Satz von Schnittstellen und Methoden bereit , dh entsprechende APIs, ohne spezifische Schnittstellenimplementierungen bereitzustellen. Bei Verwendung der Protokollfassade kann die spezifische Protokoll-Framework-Implementierung dynamisch oder statisch angegeben werden, wodurch Schnittstelle und Implementierung entkoppelt werden und Benutzer das spezifische Protokoll-Implementierungs-Framework flexibel auswählen können.

Protokollierungssystem

Unter Protokollierungssystem versteht man ein Softwaretool oder Framework, das zum Aufzeichnen und Verwalten von Protokollinformationen verwendet wird, die bei der Ausführung einer Anwendung generiert werden. Im Vergleich zur Protokollfassade bietet es eine spezifische Protokollschnittstellenimplementierung , über die die Anwendung Protokolldruckfunktionen ausführt, z. B. Protokollebenenverwaltung, Protokollformatierung, Zieleinstellung für die Protokollausgabe usw. Zu den gängigen Protokollierungssystemen gehören Log4j, Logback, Java Util Logging usw.





 

Durch die Verwendung der Protokollfassade können wir eine einheitliche API für die Protokollierung in der Anwendung verwenden und die spezifische Protokollimplementierung kann nach Bedarf ausgewählt und konfiguriert werden. Auf diese Weise können wir das Protokollierungssystem entsprechend den Projektanforderungen und Teampräferenzen flexibel auswählen, wechseln und konfigurieren, ohne zu große Auswirkungen auf den Anwendungscode zu haben.

Vermeiden Sie zirkuläre Abhängigkeiten

Ceki Gülcü, der Autor von Slf4j, hat Slf4j entworfen, weil er der Meinung war, dass die API von Commons-Logging nicht gut gestaltet und die Leistung nicht hoch genug war. Damit Slf4j mit verschiedenen Arten von Protokollsystemimplementierungen kompatibel ist, hat er auch eine ganze Reihe von Adaptern und Brücken für die Verbindung entworfen, wie in der folgenden Abbildung dargestellt:





 

Versuchen Sie daher, die Einführung von Protokoll-Framework-Abhängigkeiten zu vermeiden. Beispielsweise können die folgenden Kombinationen nicht gleichzeitig auftreten:

jcl-over-slf4j und slf4j-jcl
log4j-over-slf4j und slf4j-log4j12
jul-to-slf4j sum slf4j-jdk14

Optionen für die Nutzung des Protokoll-Frameworks

Häufig verwendete Kombinationen sind Slf4j & Logback und Commons Logging & Log4j .

empfehlen :

Slf4j & Logback

Grund :

1. Der Implementierungsmechanismus von Slf4j bestimmt, dass Slf4j weniger Einschränkungen und ein breiteres Anwendungsspektrum aufweist. Im Vergleich zu Commons-Logging bindet Slf4j die lokale Protokollbibliothek während der Kompilierung statisch und ist viel vielseitiger.

2. Logback hat eine bessere Leistung. Logback gibt an, dass die Leistung bestimmter Schlüsseloperationen, z. B. der Bestimmung, ob eine Protokollanweisung aufgezeichnet werden soll, erheblich verbessert wurde. Dieser Vorgang dauert in Logback nur 3 ns, während er in Log4j 30 ns dauert;

3. Slf4j unterstützt die Parametrisierung und verwendet Platzhaltersymbole, um den Code prägnanter zu gestalten, wie im folgenden Beispiel gezeigt:

// 在使用 Commons-Logging 时,通常的做法是 
if(log.isDebugEnabled()){ 
    log.debug("User name: " + user.getName() + " buy goods id :" + good.getId()); 
} 

// 在 Slf4j 阵营,你只需这么做: 
log.debug("User name:{} ,buy goods id :{}", user.getName(),good.getId());

4. Alle Dokumente von Logback werden kostenlos zur Verfügung gestellt, während Log4j nur einige kostenlose Dokumente bereitstellt und Benutzer den Kauf kostenpflichtiger Dokumente erfordert;

5. MDC (Mapped Diagnostic Contexts) Verwenden Sie Filter, um Geschäftsinformationen wie den aktuellen Benutzernamen in den MDC einzufügen. Diese Variable kann in der Protokollformatdefinition verwendet werden. Insbesondere bei der Diagnose eines Problems ist häufig eine Protokollierung erforderlich. Wenn Sie Log4j verwenden, können Sie nur die Protokollebene senken, dies führt jedoch zu einer großen Anzahl von Protokollen und beeinträchtigt die Anwendungsleistung. Wenn Sie Logback verwenden, behalten Sie die ursprüngliche Protokollebene bei und filtern bestimmte Sondersituationen heraus. Zum Beispiel, wenn der Benutzer Wenn Alice sich anmeldet, wird das Protokoll auf DEBUG-Ebene protokolliert, während andere Benutzer auf WARN-Ebene weiterspielen können. Um diese Funktion zu implementieren, müssen Sie nur 4 Zeilen XML-Konfiguration hinzufügen;

6. Protokolle automatisch komprimieren. RollingFileAppender komprimiert die protokollierten Dateien automatisch, wenn neue Dateien generiert werden. Der Komprimierungsprozess ist asynchron, sodass Ihre Anwendung während des Komprimierungsprozesses praktisch nicht beeinträchtigt wird.




Erste Schritte mit Slf4j+Logback

Maven-Abhängigkeit

pom.xml

<!--日志框架接口-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
</dependency>
<!--日志框架接口实现-->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
</dependency>
<!--日志框架核心组件-->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-core</artifactId>
</dependency>

<!--自动化注解工具-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.16</version>
</dependency>

Konfigurationsdatei

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <!--默认日志配置-->
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>

    <!-- 控制台日志 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder charset="UTF-8">
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <!-- Info日志 -->
    <appender name="FILE-INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_PATH}/${LOG_FILE}-info.log</file>
        <append>true</append>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>NEUTRAL</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/${LOG_FILE}-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <!-- 日志文件的路径和名称 -->
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>200MB</maxFileSize> <!-- 单个日志文件的最大大小 -->
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>15</maxHistory> <!-- 保留的历史日志文件数量 -->
            <totalSizeCap>2GB</totalSizeCap> <!-- 所有日志文件的总大小上限 -->
            <cleanHistoryOnStart>true</cleanHistoryOnStart> <!-- 在启动时清除历史日志文件 -->
        </rollingPolicy>
        <encoder charset="UTF-8">
            <pattern>${FILE_LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <!-- Warn日志 -->
    <appender name="FILE-WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_PATH}/${LOG_FILE}-warn.log</file>
        <append>true</append>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/${LOG_FILE}-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <!-- 日志文件的路径和名称 -->
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>200MB</maxFileSize> <!-- 单个日志文件的最大大小 -->
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>15</maxHistory> <!-- 保留的历史日志文件数量 -->
            <totalSizeCap>2GB</totalSizeCap> <!-- 所有日志文件的总大小上限 -->
            <cleanHistoryOnStart>true</cleanHistoryOnStart> <!-- 在启动时清除历史日志文件 -->
        </rollingPolicy>
        <encoder charset="UTF-8">
            <pattern>${FILE_LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <!-- Error日志 -->
    <appender name="FILE-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_PATH}/${LOG_FILE}-error.log</file>
        <append>true</append>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/${LOG_FILE}-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>200MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>15</maxHistory>
            <totalSizeCap>2GB</totalSizeCap>
            <cleanHistoryOnStart>true</cleanHistoryOnStart>
        </rollingPolicy>
        <encoder charset="UTF-8">
            <pattern>${FILE_LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <!-- 异步输出 -->
    <appender name="info-asyn" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="FILE-INFO"/>
        <queueSize>512</queueSize> <!-- 异步队列的大小 -->
    </appender>
    <appender name="warn-asyn" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="FILE-WARN"/>
        <queueSize>512</queueSize> <!-- 异步队列的大小 -->
    </appender>
    <appender name="error-asyn" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="FILE-ERROR"/>
        <queueSize>512</queueSize>
    </appender>

    <!-- 应用日志 -->
    <logger name="com.improve.fuqige.bronze" additivity="false">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="FILE-INFO"/>
        <appender-ref ref="FILE-WARN"/>
        <appender-ref ref="FILE-ERROR"/>
    </logger>


    <!-- 总日志出口 -->
    <root level="${logging.level.root}">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="info-asyn"/>
        <appender-ref ref="warn-asyn"/>
        <appender-ref ref="error-asyn"/>
    </root>
</configuration>

applicationion.properties

logging.file=fuqige-bronze
logging.path=XXXXXX/Logs/XXXXXX
logging.level.root=info
logging.level.com.improve.fuqige.bronze=info
logging.pattern.console=%cyan(%d{yyyy-MM-dd HH:mm:ss.SSS}) %yellow([%thread]) %highlight(%-5level) %boldGreen(%logger{80}[LineNumber:%L]): %highlight(%msg%n)
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{requestId}] %-5level --- [%thread] %logger{80}[LineNumber:%L]: %msg%n

Testfall

@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {

    @GetMapping("/hello")
    public String hello() {
        log.info("进来了!");
        log.warn("进来了!");
        log.error("进来了!");
        return "hello, world! requestId=" + MDC.get("requestId");
    }
}






Verweise

Java-Protokollierungsframework: https://zhuanlan.zhihu.com/p/365154773

Allgemeine Verwendung und Best Practices des SLF4J-Frameworks: https://juejin.cn/post/7215569601161166906

Autor: JD Retail Zhang Hong

Quelle: JD Cloud Developer Community Bitte geben Sie beim Nachdruck die Quelle an

Broadcom kündigt die Beendigung des bestehenden Deepin-IDE-Versionsupdates des VMware-Partnerprogramms an und ersetzt das alte Erscheinungsbild durch ein neues Erscheinungsbild Zhou Hongyi: Der gebürtige Hongmeng wird definitiv erfolgreich sein WAVE SUMMIT begrüßt seine zehnte Sitzung, Wen Xinyiyan wird die neueste Enthüllung haben! Yakult Company bestätigt, dass 95 G-Daten durchgesickert sind Die beliebteste Lizenz unter den Programmiersprachen im Jahr 2023 „2023 China Open Source Developer Report“ offiziell veröffentlicht Julia 1.10 offiziell veröffentlicht Fedora 40 plant die Vereinheitlichung von /usr/bin und /usr/sbin Rust 1.75 .0-Version
{{o.name}}
{{m.name}}

Supongo que te gusta

Origin my.oschina.net/u/4090830/blog/10443370
Recomendado
Clasificación