Springboot 日志详解

1. 为什么要有日志

1.1 优点

● 开发调试:根据日志调试定位程序以达到正确的状态;
● 系统运行状态留存:应用系统发布运行投入生成,记录系统运行日志,根据日志排查定位问题;
● 数据收集:将应用日志接入大数据平台,收集用户行为数据,分析用户操作习惯、喜好、用户画像等;

1.2 缺点

● 代码冗余:日志并没有实现具体的业务,没有必要打印不必要的日志,在一定程度上增加代码冗余,降低代码可读性;
● 降低系统性能:有不少因大量日志输出导致系统崩溃的例子;

2. Log4J、Logback、Log4J2 发展轨迹

Log4J 最初是有俄罗斯 Ceki Gülcü 基于 JUL 开发的日志框架,被大范围使用后捐献给 Apache 孵化。
Ceki Gülcü 大神后续不满足 Apache 对 Log4J 的管理,后续又开发了 Logback 和 SLF4J ,Logback 改进了 Log4J 的缺点,性能大幅提升,使用方式几乎不变,用户开始将 Log4J 转到 Logback。
Logback 冲击了 Log4J 的市场后,Apache 开发了 Log4J2,借鉴了 Logback,改进了 Log4J 的缺点,同时号称性能完胜 Logback。

3. 门面模式

3.1 传统日志使用(没有门面模式)

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class Log4jTest {

    private static final Logger LOG = LogManager.getLogger(Log4jTest.class);

    public static void main(String[] args) {
        LOG.info("log4j");
    }
}

3.2 现代日志记录(门面模式)

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Log4jTest2 {

    private static final Logger LOG = LoggerFactory.getLogger(Log4jTest2.class);

    public static void main(String[] args) {
        LOG.info("log4j");
    }
}

3.3 为什么用门面模式

如果一直使用 log4j 或 logback,直接使用是可以的。有一天技术经理说要更换日志框架,那就悲催了,需要一个一个改,门面模式本身不记录日志,依赖log4j 或 Logback 记录日志,更换时只需要更换依赖即可。

3.4 门面模式

Springboot 日志详解_第1张图片

● 门面(Facade)角色:客户端可以调用这个角色的方法。此角色知晓相关的子系统的功能和责任。正常情况下,本橘色会将所有从客户端发来的请求委派到相应的子系统中。
● 子系统(SubSystem)角色:可以同时又一个或多个子系统。每个子系统都不是一个单独的类,而不是一个类的合集。每个子系统都可以被客户端直接调用,或者被门面角色调用。子系统并不知道门面的存在,对于子系统而言,门面仅仅是另一个客户端。
门面模式的优点:
● 解耦:门面模式解耦了客户端与子系统之间的耦合,客户端不需要了解子系统是如何实现的,让子系统更容易扩展和维护;

4. Springboot 集成日志系统

4.1 如何选择日志系统 ?

Springboot 默认使用了 Logback 做日志记录,SLF4J 做门面系统。默认情况下Springboot 提供的日志系统足够使用。考虑到 LOG4J2 的性能出众,可以考虑使用 LOG4J2 + SLF4J 的组合。

4.2 Springboot 默认日志配置示例






<configuration  scan="true" scanPeriod="10 seconds">
    <contextName>logbackcontextName>

    <springProperty scope="context" name="APP_NAME" source="spring.application.name"/>
    <property name="LOG_HOME" value="logs/${APP_NAME}" />

    
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
    
    <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>

    
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUGlevel>
        filter>
        <encoder>
            <Pattern>${CONSOLE_LOG_PATTERN}Pattern>
            
            <charset>UTF-8charset>
        encoder>
    appender>

    
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        
        <file>${LOG_HOME}/log.logfile>
        
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} -%5level ---[%15.15thread] %-40.40logger{39} : %msg%n%npattern>
            <charset>UTF-8charset> 
        encoder>
        
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/%d{yyyy-MM-dd}.%i.logfileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MBmaxFileSize>
            timeBasedFileNamingAndTriggeringPolicy>
            
            <maxHistory>15maxHistory>
        rollingPolicy>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFOlevel>
            <onMatch>ACCEPTonMatch>
            <onMismatch>DENYonMismatch>
        filter>
    appender>

    
    
    
    <springProfile name="dev">
        <logger name="com.alibaba.nacos" level="OFF" addtivity="false"> logger>
        <root level="INFO">
            <appender-ref ref="CONSOLE" />
        root>
    springProfile>

    
    <springProfile name="prod">
        <root level="INFO">
            <appender-ref ref="CONSOLE" />
            <appender-ref ref="FILE" />
        root>
    springProfile>

    
    <springProfile name="k8s">
        <root level="INFO">
            <appender-ref ref="CONSOLE" />
            <appender-ref ref="FILE" />
        root>
    springProfile>

configuration>

4.3 LOG4J2 + SLF4J 配置示例

<dependency>
  <groupId>org.springframework.bootgroupId>
  <artifactId>spring-boot-starter-webartifactId>
  <exclusions>
    <exclusion>
      <artifactId>spring-boot-starter-loggingartifactId>
      <groupId>org.springframework.bootgroupId>
    exclusion>
  exclusions>
dependency>
<dependency>
  <groupId>org.springframework.bootgroupId>
  <artifactId>spring-boot-starter-log4j2artifactId>
dependency>





<Configuration status="ERROR" monitorInterval="30">

    
    <Appenders>
        
        <Console name="Console" target="SYSTEM_OUT">
            
            
            <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5p] %l - %m%n"/>
        Console>
        
        <File name="FileLog" fileName="log/demo.log" append="false">
            <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5p] %l - %m%n"/>
        File>
        <RollingFile name="RollingFileInfo" fileName="log/rolling-info.log" filePattern="log/$${date:yyyy-MM}/rolling-info-%d{yyyy-MM-dd}-%i.log">
            <ThresholdFilter level="info" onMatch="APPCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="50MB"/>
            Policies>
        RollingFile>
        <RollingFile name="RollingFileWarn" fileName="log/rolling-warn.log" filePattern="log/$${date:yyyy-MM}/rolling-warn-%d{yyyy-MM-dd}-%i.log">
            <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="50MB"/>
            Policies>
        RollingFile>
        <RollingFile name="RollingFileError" fileName="log/rolling-error.log" filePattern="log/$${date:yyyy-MM}/rolling-error-%d{yyyy-MM-dd}-%i.log">
            <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="50MB"/>
            Policies>
        RollingFile>
    Appenders>
    <Loggers>

        <root level="info">
            <appender-ref ref="Console"/>
            <appender-ref ref="RollingFileInfo"/>
            <appender-ref ref="RollingFileWarn"/>
            <appender-ref ref="RollingFileError"/>
            <appender-ref ref="FileLog"/>
        root>
    Loggers>
Configuration>

你可能感兴趣的:(Spring,家族,springboot,SLF4j,Log4J,Log4J2,Logback,Springboot日志)