springboot logback 配置文件 自定义logback配置文件
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>
logback 官网地址:https://logback.qos.ch/manual/index.html
logback官网代码:https://logback.qos.ch/xref/
logback中文翻译:https://blog.csdn.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.csdn.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>
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(String msg) { System.err.println(msg); System.err.println("Usage: java " + SocketClient1.class.getName() + " hostname port\n" + " hostname the name of the remote log server\n" + " port (integer) the port number of the server\n"); System.exit(1); } static public void main(String[] args) throws Exception { //if (args.length != 2) { // usage("Wrong number of arguments."); //} //String hostName = args[0]; //int port = Integer.parseInt(args[1]); String hostName = "localhost"; int port = 9999; // Create a SocketAppender connected to hostname:port with a // reconnection delay of 10000 seconds. SocketAppender socketAppender = new SocketAppender(); socketAppender.setRemoteHost(hostName); socketAppender.setPort(port); socketAppender.setReconnectionDelay(new Duration(10000)); LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); socketAppender.setContext(lc); // SocketAppender options become active only after the execution // of the next statement. socketAppender.start(); Logger logger = (Logger) LoggerFactory.getLogger(SocketClient1.class); logger.addAppender(socketAppender); BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); while (true) { System.out.println("Type a message to send to log server at " + hostName + ":" + port + ". Type 'q' to quit."); String s = reader.readLine(); if (s.equals("q")) { break; } else { logger.debug(s); } } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!