欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

如何在Spring Boot中自定义Logback的日志配置文件

最编程 2024-02-18 08:34:31
...
logging:
  level:
    #配置全部的调试级别
    #root: trace
    #配置具体包路径下的调试级别
    com.example.springboot03: trace
  pattern:
    #默认控制台输出格式
    console: '%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSSXXX}}){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}'
#dateformat: -yyyy-MM-dd
  file:
    #设置文件名称,没有设置路径的话,默认在项目相对路径下生成 (name优先级 > path优先级)
    name: F:/WorkSpaceSpringBoot/my.log
    #不可以指定文件名称,必须指定物理文件夹路径,默认使用 spring.log 进行输出
    #path: F:/WorkSpaceSpringBoot/
  logback:
    rolling policy:
      #启动是否清空日志文件,默认false
      clean-history-on-start: false
      #保存文件的默认命名格式
      file-name-pattern: '${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz'
      #最大日志文件大小 日志文件多大归档一次(单位必须大写)
      max-file-size: 2KB
      # 日志保存天数
      max-history: 7
      # 日志保存总大小 超出就删除旧的文档,按时间先后删除 (0B就是没有限制)
      total-size-cap: 4KB

以上文件是springboot logback配置文件。通过application.yml 配置 。自定义logback.xml覆盖全局配置

现在对 %clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSSXXX}}){faint} 这一段进行说明,其他的省略
1.%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSSXXX}}){faint}指定颜色:

等级对应的颜色:
支持的颜色种类:
2.%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSSXXX}}
%d格式说明,其他标识符可以查询logback官网:https://logback.qos.ch/manual/layouts.html#conversionWord

  3. ${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSSXXX}

 ${}  springboot 占位符

LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSSXXX 非空表达式:若属性 LOG_DATEFORMAT_PATTERN 不存在,则使用 -yyyy-MM-dd HH:mm:ss.SSSXXX 格式
LOG_DATEFORMAT_PATTERN 系统属性可以 System.getProperty("LOG_DATEFORMAT_PATTERN") 获取
其他属性和系统属性的对应入下图。springboot官网地址:https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.logging.log-format默认属性配置 查看:https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#appendix.application-properties


自定义配置文件 

 这是以前总结的logback配置文件的说明:https://www.cnblogs.com/ruber/p/16385875.html

此处我再贴一个 logback.xml的配置,注意,这个配置只是参考示例,目的是为了说明各个选项的存在及意义,具体使用还需要根据需要进行选择提取

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

<configuration scan="true" scanPeriod="30 seconds" debug="false">
    <!--通过文件引入appender配置-->
    <!-- <include file="log_logback/src/main/resources/includedConfig.xml"></include>-->
    <!--通过资源文件引入-->
    <include resource="includedConfig.xml"/>
    <!--通过 url 引入文件-->
    <!--<include url="http://some.host.com/includedConfig.xml"/>-->

    <!-- 放到include后面,否则设置失效-->
    <contextName>myAppName</contextName>

    <!--引入属性配置文件-->
    <property resource="source.properties"/>
    <!-- 属性定义-->
    <property name="charset" value="UTF-8"/>
    <property name="console_log_pattern"
              value="%boldWhite(%contextName-) %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}) - %white(%msg%n)"/>


    <!--配置控制台输出-->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender" >
        <!-- encoder 默认使用 ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
        <encoder>
            <pattern>${console_log_pattern}</pattern>
        </encoder>
    </appender>

    <!--文件输出-->
    <appender name="FILE1" class="ch.qos.logback.core.FileAppender">
        <file>testFile.log</file>
        <!-- 将 immediateFlush 设置为 false 可以获得更高的日志吞吐量 但有可能在非正常关机情况下导致日志丢失,默认是true立即写入 -->
        <immediateFlush>true</immediateFlush>
        <!-- 默认为 ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
        <encoder>
            <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
        </encoder>
    </appender>

    <!--轮转文件输出 (轮转策略:TimeBasedRollingPolicy)-->
    <appender name="FILE2" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logFile.log</file>
        <!--LevelFilter 只输出 ==info 的日志-->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天轮转 -->
            <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--保存 30 天的历史记录,最大大小为 30GB -->
            <maxHistory>30</maxHistory>
            <totalSizeCap>3GB</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
        </encoder>
    </appender>

    <!--轮转文件输出 (轮转策略:SizeAndTimeBasedRollingPolicy)-->
    <appender name="FILE3" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>mylog.txt</file>
        <!-- ThresholdFilter 只输出 >=info 的日志-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--按天轮转 -->
            <fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
            <!--每个日志文件最大为100MB-->
            <maxFileSize>100MB</maxFileSize>
            <!--保存 60 天的历史记录,最大大小为 20GB -->
            <maxHistory>60</maxHistory>
            <totalSizeCap>20GB</totalSizeCap>
        </rollingPolicy>

        <encoder>
            <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
        </encoder>
    </appender>

    <!--轮转文件输出 (轮转策略:FixedWindowRollingPolicy)-->
    <appender name="FILE4" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>test.log</file>
        <!--FixedWindowRollingPolicy轮转策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <fileNamePattern>tests.%i.log.zip</fileNamePattern>
            <minIndex>1</minIndex>
            <maxIndex>3</maxIndex>
        </rollingPolicy>
        <!--轮转时机-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <maxFileSize>5MB</maxFileSize>
        </triggeringPolicy>

        <encoder>
            <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
    <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
    <!-- 添加附加的appender,最多只能添加一个 -->
    <appender name="file.async" class="ch.qos.logback.classic.AsyncAppender">
        <discardingThreshold>0</discardingThreshold>
        <queueSize>256</queueSize>
        <includeCallerData>true</includeCallerData>
        <appender-ref ref="FILE3"/>
    </appender>


    <!--logger配置-->
    <logger name="com.test.aaa" level="debug" additivity="false">
        <!--设置 additivity="false" 此时只有 stdout2 输出-->
        <appender-ref ref="STDOUT"/>
    </logger>

    <!--输入级别debug及以上的日志信息-->
    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>
View Code

logback 官网地址:https://logback.qos.ch/manual/index.html

logback官网代码:https://logback.qos.ch/xref/

logback中文翻译:https://blog.****.net/qq_26462567/article/details/115757354

 基本上核心的常用的知识点都在这几章里

第三章:logback的配置

  • logback 的初始化步骤
  • 打印状态信息
  • 属性配置
  • 引入外部的配置文件
  • 停止 logback-classic
  • 自动加载配置文件
  • logger的level属性,基本选择法
  • HOSTNAME 属性
  • CONTEXT_NAME 属性

第四章:Appenders,以下是这个章节的主要知识点,这这一章查看细节

Logback-core
    OutputStreamAppender
        属性:ecoder
        属性:immediateFlush:默认值为 true。立即刷新输出流可以确保日志事件被立即写入
        
        ConsoleAppender:日志事件附加到控制台
            属性:ecoder
            属性:target: System.out 或 System.err。默认为 System.out
            属性:withJansi:的默认值为 false
            
        FileAppender:将日志事件输出到文件中
            属性:append: 默认为 true:日志事件会被追加到文件中,否则的话,文件会被截断
            属性:ecoder
            属性:file:要写入文件的名称。如果文件不存在,则新建
                        正确的值应该像:c:/temp/test.log 或者 c:\\temp\\test.log。没有默认值。
            属性:prudent 严格模式 默认false 在严格模式下,FileAppender 会将日志安全的写入指定文件。
                    即使在不同的 JVM 或者不同的主机上运行 FileAppender 实例
            
            RollingFileAppender:具有轮转日志文件的功能
                属性:file
                属性:append:
                属性:ecoder
                属性:prudent
                属性:rollingPolicy <RollingPolicy> 负责日志轮转的功能(发生什么)
                属性:triggeringPolicy <TriggeringPolicy> 负责日志轮转的时机 (什么时候发生)
                
    Logback Classic
        SocketAppender: 实例序列化再传输到远端机器 明文发送 对应应用程序 SimpleSocketServer 
        SSLSocketAppender: 实例序列化再传输到远端机器 安全的通道传输。 对应应用程序 SimpleSSLSocketServer 

        ServerSocketAppender;不会初始化一个到日志服务器的连接,而是被动的监听 TCP 端口,等待客户端的连接。
                                    日志事件被传输给这个 appender,然后再分发给每个连接的客户端。
                                    如果没有客户端连接,日志事件会被马上丢弃
        SSLServerSocketAppender:它通过一个安全,加密的通道传输日志事件到每个连接的客户端。需要ssl双向认证
        
    Logback Access
        SMTPAppender:收集日志事件到一个或多个固定大小的缓冲区,当用户指定的事件发生时,
                        将从缓冲区中取出适当的内容进行发送。SMTP 邮件是异步发送的。
                        默认情况下,当日志的级别为 ERROR 时,邮件发送将会被触发。
                        而且默认的情况下,所有事件都使用同一个缓冲区。
            属性evaluator:
                CounterBasedEvaluator:当第 1024 个日志事件到来时才会触发邮件发送。
                OnMarkerEvaluator:基于标记(Marker)触发
                JaninoEventEvaluator
                GEventEvaluator

        DBAppender:以一种独立于 JAVA 语言的方式将日志事件插入到三张数据库表中。
                    这三张表分别为:logging_event, logging_event_property 与 logging_event_exception
            ConnectionSource
                DataSourceConnectionSource
                DriverManagerConnectionSource 
                JNDIConnectionSource
    
        SyslogAppender:syslog 发送者将信息发送给 syslog 接收者
        SiftingAppender:根据给定的运行时属性分离或者过滤日志
        AsyncAppender:AsyncAppender 异步的打印 ILoggingEvent。
                            它仅仅是作为一个事件调度器的存在,因此必须调用其它的 appender 来完成操作
            
            
文件唯一命名 (使用时间戳)变量
    <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss" />
    设置为上下文初始化的时间。通过 设置 timeReference 的值为 contextBirth
    <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss" timeReference="contextBirth"/>
    
<RollingPolicy> 负责轮转的方式为:移动文件以及对文件改名
    TimeBasedRollingPolicy:基于时间来定义轮转策略 (轮转策略和触发策略一体)
        属性:fileNamePattern 强制
        属性:maxHistory  保存日志的时间,超过就删除
        属性:totalSizeCap 保存日志的上限 超过后就删除
        属性:cleanHistoryOnStart 如果设置为 true,那么在 appender 启动的时候,归档文件将会被删除。默认的值为 false。
    
    SizeAndTimeBasedRollingPolicy:基于大小以及时间的轮转策略
        属性:fileNamePattern 强制
        属性:maxHistory  保存日志的时间,超过就删除
        属性:totalSizeCap 保存日志的上限 超过后就删除
        属性:maxFileSize 单个文件的大小限制:除了 %d 之外还有 %i。这两个占位符都是强制要求的。
                在当前时间还没有到达周期轮转之前,日志文件达到了 maxFileSize 指定的大小,会进行归档,递增索引从 0 开始。
            <fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
    
    FixedWindowRollingPolicy:根据固定窗口算法重命名文件  (需要跟 triggeringPolicy  结合起来使用,以确定轮转时机)
        属性:minIndex 表示窗口索引的下界
        属性:maxIndex 表示窗口索引的上界
        属性:fileNamePattern 必须包含一个 i% 的占位符,该占位符指明了窗口索引的值应该插入的位置。
        
<TriggeringPolicy> 的实现用于通知 RollingFileAppender 何时轮转。
    SizeBasedTriggeringPolicy:观察当前活动文件的大小,如果已经大于了指定的值,触发轮转
        属性:maxFileSize: 默认值是 10 MB  (后缀 KB,MB 或者 GB)


<filter >
    LevelFilter:基于级别来过滤日志事件。
        如果事件的级别与配置的级别相等,过滤器会根据配置的 onMatch 与 onMismatch 属性,接受或者拒绝事件
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
          <level>INFO</level>
          <onMatch>ACCEPT</onMatch>
          <onMismatch>DENY</onMismatch>
        </filter>
        
    ThresholdFilter:基于给定的临界值来过滤事件.如果事件的级别等于或高于给定的临界值
        <!-- deny all events with a level below INFO, that is TRACE and DEBUG -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>

下面是关于 fileNamePattern 的介绍。决定了滚动策略,和 maxHistory 的单位:

maxHistory;记录的周期数,周期由fileNamePattern 决定
fileNamePattern 轮转周期 示例
/wombat/foo.%d 每天轮转(晚上零点)。由于省略了指定 %d 的日期格式,所以默认为 yyyy-MM-dd 没有设置 file 属性:在 2006.11.23 这一天的日志都会输出到 /wombat/foo.2006-11-23这个文件。晚上零点以后,日志将会输出到 wombat/foo.2016-11-24 这个文件。
设置 file 的值为 /wombat/foo.txt:在 2016.11.23 这一天的日志将会输出到 /wombat/foo.txt 这个文件。在晚上零点的时候,foo.txt 将会被改名为 /wombat/foo.2016-11-23。然后将创建一个新的 foo.txt,11.24 号这一天的日志将会输出到这个新的文件中。
/wombat/%d{yyyy/MM}/foo.txt 每个月开始的时候轮转 没有设置 file 属性:在 2016.10 这一个月中的日志将会输出到 /wombat/2006/10/foo.txt。在 10.31 晚上凌晨以后,11 月份的日志将会被输出到 /wombat/2006/11/foo.txt
设置 file 的值为 /wombat/foo.txt:在 2016.10,这个月份的日志都会输出到 /wombat/foo.txt。在 10.31 晚上零点的时候,/wombat/foo.txt 将会被重命名为 /wombat/2006/10/foo.txt,并会创建一个新的文件 /wombat/foo.txt ,11 月份的日志将会输出到这个文件。依此类推。
/wombat/foo.%d{yyyy-ww}.log 每周的第一天(取决于时区) 每次轮转发生在每周的第一天,其它的跟上一个例子类似
/wombat/foo%d{yyyy-MM-dd_HH}.log 每小时轮转 跟之前的例子类似
/wombat/foo%d{yyyy-MM-dd_HH-mm}.log 每分钟轮转 跟之前的例子类似
/wombat/foo%d{yyyy-MM-dd_HH-mm, UTC}.log 每分钟轮转 跟之前的例子类似,不过时间格式是 UTC
/foo/%d{yyyy-MM, aux}/%d.log 每天轮转。归档文件在包含年月的文件夹下 第一个 %d 被辅助标记。第二个 %d 为主要标记,但是日期格式省略了。因此,轮转周期为每天(由第二个 %d 控制),文件夹的名字依赖年与月。例如,在 2016.11 的时候,所有的归档文件都会在 /foo/2006-11/ 文件夹下,如:/foo/2006-11/2006-11-14.log

第五章 Encoder:这一章东西不多,主要看一下

  • LayoutWrappingEncoder 
  • PatternLayoutEncoder

将格式化字符串插入到日志文件的顶部。可以为相关的 PatternLayoutEncoder 设置 outputPatternAsHeader 属性的值为 true 来开启这个功能 <outputPatternAsHeader>true</outputPatternAsHeader>

第六章:Layouts:主要关注一些格式配置

  • 转换字符与它们的可选参数
  • % 有特殊的含义
  • 转换字符对字面量的限制
  • 格式修改器
  • 只输出日志等级的一个字符
  • 转换字符的选项
  • 特殊的圆括号
  • 着色

第七章:Filters:主要关注两个fiter 

  • LevelFilter

  • ThresholdFilter

 

  • EvaluatorFilter

 

 

GEventEvaluator

 

 

JaninoEventEvaluator

Matchers

 

  • DuplicateMessageFilter
  • CountingFilterLogback

第八章:MDC(Mapped Diagnostic Context) 通过mdc可以为输出动态传参

MDC.put("first", "Dorothy");

MDC.put("last", "Parker");

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> 
  <layout>
    <Pattern>%X{first} %X{last} - %m%n</Pattern>
  </layout> 
</appender>

 

下面是一个日志服务器的例子:参考地址:https://blog.****.net/weixin_43002202/article/details/118483805

server:

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

<configuration>
    <!--配置控制台输出-->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} 控制台输出- %msg%n</pattern>
        </encoder>
    </appender>

    <!--文件输出-->
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>testFile.log</file>
        <!-- 将 immediateFlush 设置为 false 可以获得更高的日志吞吐量 但有可能在非正常关机情况下导致日志丢失,默认是true立即写入 -->
        <immediateFlush>true</immediateFlush>
        <!-- 默认为 ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} 文件输出- %msg%n</pattern>
        </encoder>
    </appender>

    <!--输入级别debug及以上的日志信息-->
    <root level="debug">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILE" />
    </root>
</configuration>
server1.xml
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.classic.net.SimpleSocketServer;
import ch.qos.logback.core.joran.spi.JoranException;
import org.slf4j.LoggerFactory;
/**
 * @authour cyf
 * 2023/8/1 10:50
 */
public class MyServer {
    public static void main(String[] args) throws JoranException {
        LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
        configureLC(lc, "F:\\WorkSpaceSpringBoot\\AllLogTest\\log_parent\\log_logback_server1\\src\\main\\resources\\server1.xml");
        SimpleSocketServer sss = new SimpleSocketServer(lc, 9999);
        sss.start();
    }
    static public void configureLC(LoggerContext lc, String configFile) throws JoranException {
        JoranConfigurator configurator = new JoranConfigurator();
        lc.reset();
        configurator.setContext(lc);
        configurator.doConfigure(configFile);
    }
}

client:

import java.io.BufferedReader;
import java.io.InputStreamReader;

import ch.qos.logback.core.util.Duration;
import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.net.SocketAppender;

/**
 * This application uses a SocketAppender that log messages to a
 * server on a host and port specified by the user. It waits for the
 * user to type a message which will be sent to the server.
 */
public class SocketClient1 {
    static void usage(Strin