当前位置: 首页 > news >正文

logback实战详解fileNamePattern配置问题%d多级日期文件夹

为什么写这个呢?

因为我遇到了一个问题多个%d的问题,日志文件要么不按照日期文件目录划分,要么日志文件名字不变,结果处理了好久

原来是因为logback只会根据第一个%d去划分,所以需要忽略前面的%d,添加一个

,aux

很关键,这样他就会忽略前面的按照后面的来滚动划分,具体看实战案例

以下是 基于Logback 1.5.12logback.xml完整配置详解,涵盖核心组件、常用场景和该版本的注意事项。

实战案例

及其简略的案例,可以生产直接使用

<?xml version="1.0" encoding="utf-8"?> <configuration> <contextName>com.cmit</contextName> <property name="pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L -[%X{TRACE_ID}] - %msg %n"/> <property name="LOG_HOME" value="logs"/> <property name="PROJECT_NAME" value="project-name"/> <property name="MAX_FILE_SIZE" value="10MB" /> <property name="MAX_HISTORY" value="200" /> <!-- 控制台输出 --> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>${pattern}</pattern> </encoder> </appender> <!-- 文件输出 --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/${PROJECT_NAME}.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/%d{yyyy-MM,aux}/${PROJECT_NAME}/${PROJECT_NAME}-%d{yyyy-MM-dd}-%i.log.gz</fileNamePattern> <maxFileSize>${MAX_FILE_SIZE}</maxFileSize> <maxHistory>${MAX_HISTORY}</maxHistory> <cleanHistoryOnStart>true</cleanHistoryOnStart> </rollingPolicy> <encoder> <pattern>${pattern}</pattern> </encoder> </appender> <root level="INFO"> <appender-ref ref="CONSOLE"/> <appender-ref ref="FILE"/> </root> </configuration>

文件基础结构

<?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- 属性定义 --> <property name="LOG_HOME" value="./logs"/> <property name="APP_NAME" value="myapp"/> <!-- Appender 定义 --> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> ... </appender> <!-- Logger 定义 --> <logger name="com.example" level="DEBUG"/> <!-- 根 Logger --> <root level="INFO"> <appender-ref ref="CONSOLE"/> </root> </configuration>

核心组件详解

<configuration>根标签属性

属性说明示例
scan是否自动扫描配置文件变更scan="true"
scanPeriod扫描间隔,默认 60 秒scanPeriod="30 seconds"
debug是否打印 logback 内部状态debug="false"
<configuration scan="true" scanPeriod="30 seconds" debug="false">

<property>属性定义

<!-- 直接定义 --> <property name="LOG_PATH" value="/var/log/myapp"/> <!-- 引用系统属性 --> <property name="LOG_PATH" value="${user.home}/logs"/> <!-- 默认值语法(属性不存在时使用默认值) --> <property name="LOG_LEVEL" value="${LOG_LEVEL:-INFO}"/>

Appender 详解

ConsoleAppender(控制台输出)

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <!-- 日志立即刷新,性能会略降但确保不丢失 --> <immediateFlush>true</immediateFlush> <!-- 编码器 --> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> <charset>UTF-8</charset> </encoder> <!-- 过滤器:只输出 INFO 及以上 --> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>INFO</level> </filter> </appender>

常用 Pattern 符号:

符号含义
%d{...}日期时间
%thread线程名
%-5level日志级别,左对齐占5字符
%logger{36}Logger 名,最长36字符
%msg/%m日志消息
%n换行
%line/%L输出代码行号(性能开销大,生产慎用
%M方法名(性能开销大

FileAppender(单文件输出)

<appender name="FILE" class="ch.qos.logback.core.FileAppender"> <file>${LOG_HOME}/app.log</file> <append>true</append> <!-- true=追加,false=覆盖 --> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %level %logger - %msg%n</pattern> </encoder> </appender>

RollingFileAppender(滚动日志)⭐最常用

<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 当前正在写入的文件 --> <file>${LOG_HOME}/app.log</file> <!-- 滚动策略 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 归档文件名格式,%d 触发按天滚动 --> <fileNamePattern>${LOG_HOME}/app.%d{yyyy-MM-dd}.log</fileNamePattern> <!-- 保留最近 30 天的归档日志 --> <maxHistory>30</maxHistory> <!-- 启动时清理超期日志 --> <cleanHistoryOnStart>true</cleanHistoryOnStart> <!-- 单个归档文件最大 100MB(TimeBasedRollingPolicy 不支持,需用 SizeAndTimeBasedRollingPolicy) --> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender>

SizeAndTimeBasedRollingPolicy(按时间和大小双重滚动)⭐推荐

<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/app.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!-- %i 是序号,同一天内超过大小则递增 --> <fileNamePattern>${LOG_HOME}/app.%d{yyyy-MM-dd}.%i.log</fileNamePattern> <!-- 单个文件最大 100MB --> <maxFileSize>100MB</maxFileSize> <!-- 保留 30 天的日志 --> <maxHistory>30</maxHistory> <!-- 所有日志总大小上限(防止磁盘满) --> <totalSizeCap>10GB</totalSizeCap> <!-- 启动时清理 --> <cleanHistoryOnStart>true</cleanHistoryOnStart> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender>

注意SizeAndTimeBasedRollingPolicyTimeBasedRollingPolicy的子类,功能更强大,生产环境建议直接使用这个

Logger 层级配置

<!-- 设置特定包的日志级别 --> <logger name="com.example.dao" level="DEBUG" additivity="false"> <appender-ref ref="CONSOLE"/> <appender-ref ref="ROLLING_FILE"/> </logger> <!-- Spring 框架日志 --> <logger name="org.springframework" level="WARN"/> <logger name="org.springframework.jdbc" level="DEBUG"/> <!-- MyBatis 日志 --> <logger name="com.ibatis" level="DEBUG"/> <logger name="java.sql" level="DEBUG"/> <!-- 根 Logger,所有日志的默认配置 --> <root level="INFO"> <appender-ref ref="CONSOLE"/> <appender-ref ref="ROLLING_FILE"/> </root>

additivity="false"的重要性:

  • true(默认):日志会同时输出到当前 logger 的 appender 和父 logger(root)的 appender,导致重复打印

  • false:只输出到当前 logger 配置的 appender

过滤器(Filter)

<!-- 级别过滤器:精确匹配级别 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <!-- 阈值过滤器:该级别及以上通过 --> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>WARN</level> </filter>

高级配置

异步日志(AsyncAppender)

<!-- 先定义同步 appender --> <appender name="FILE_SYNC" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/app.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/app.%d{yyyy-MM-dd}.%i.log</fileNamePattern> <maxFileSize>100MB</maxFileSize> <maxHistory>30</maxHistory> </rollingPolicy> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <!-- 包装为异步 appender --> <appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender"> <!-- 队列大小,默认 256 --> <queueSize>512</queueSize> <!-- 队列满时的策略:false=丢弃,true=阻塞 --> <discardingThreshold>0</discardingThreshold> <!-- 不丢失日志事件 --> <neverBlock>false</neverBlock> <!-- 引用同步 appender --> <appender-ref ref="FILE_SYNC"/> </appender> <root level="INFO"> <appender-ref ref="ASYNC_FILE"/> </root>

按日志级别分离文件

<!-- INFO 及以上 --> <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/info.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/info.%d{yyyy-MM-dd}.log</fileNamePattern> <maxHistory>30</maxHistory> </rollingPolicy> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>INFO</level> </filter> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss} %level %logger - %msg%n</pattern> </encoder> </appender> <!-- 仅 ERROR --> <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/error.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/error.%d{yyyy-MM-dd}.log</fileNamePattern> <maxHistory>90</maxHistory> </rollingPolicy> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %logger{36} - %msg%n%ex{full}</pattern> </encoder> </appender>

彩色控制台输出(Logback 1.5.x 支持)

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{HH:mm:ss.SSS} %highlight(%-5level) %cyan(%logger{36}) - %msg%n</pattern> </encoder> </appender>

高亮颜色:

  • %highlight():根据级别自动着色(ERROR=红,WARN=黄,INFO=绿等)

  • %cyan()%magenta()%yellow()

Logback 1.5.x 版本注意事项

安全性增强

  • 1.5.x 修复了CVE-2023-6378(序列化漏洞)等安全问题

  • 建议确保logback.xml不要配置从 JNDI / 远程加载配置,避免被利用

maxHistorycleanHistoryOnStart的行为

  • maxHistory归档文件时间戳计算,不是按文件创建时间

  • cleanHistoryOnStart=true只在应用启动时执行一次清理

  • 如果应用长期不重启,超期文件不会被自动清理(需依赖定时任务或确保会重启)

推荐的最小完整配置

<?xml version="1.0" encoding="UTF-8"?> <configuration scan="true" scanPeriod="60 seconds" debug="false"> <property name="LOG_HOME" value="${user.home}/logs/myapp"/> <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/> <!-- 控制台 --> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{HH:mm:ss.SSS} %highlight(%-5level) %cyan(%logger{36}) - %msg%n</pattern> <charset>UTF-8</charset> </encoder> </appender> <!-- 文件滚动 --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/app.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/app.%d{yyyy-MM-dd}.%i.log</fileNamePattern> <maxFileSize>100MB</maxFileSize> <maxHistory>30</maxHistory> <totalSizeCap>5GB</totalSizeCap> <cleanHistoryOnStart>true</cleanHistoryOnStart> </rollingPolicy> <encoder> <pattern>${LOG_PATTERN}</pattern> <charset>UTF-8</charset> </encoder> </appender> <!-- 第三方框架降噪 --> <logger name="org.springframework" level="WARN"/> <logger name="org.apache.http" level="WARN"/> <logger name="com.zaxxer.hikari" level="INFO"/> <root level="INFO"> <appender-ref ref="CONSOLE"/> <appender-ref ref="FILE"/> </root> </configuration>
http://www.jsqmd.com/news/1106742/

相关文章:

  • Dify接入高德地图MCP服务详细配置教程
  • 当反射内存环网中出现“Own Data”指示灯不亮的情况,可能的原因和排查步骤
  • 记一次内存溢出的分析经历
  • 耶鲁牛津剑桥等全球EMBA精英集聚复旦,拓数派董事长冯雷全英文授课“用Ontology实现零代码构建智能体”
  • 洗牙并非简单清洁:规范洁牙科普指南
  • Gemini AI工具全家桶深度应用指南
  • Java毕业设计-基于 SpringBoot 的线上手办周边商城系统的设计与实现 基于 SpringBoot 的动漫手办周边电商管理系统(源码+LW+部署文档+全bao+远程调试+代码讲解等)
  • LabVIEW让故障排查从“猜“变“算“
  • 2026年7月电锅炉厂家的选择应该考虑哪些因素?
  • 最近体验了一下 Visible Coding,AI 编程方式确实变了
  • SIGMOD 2025论文深度解读
  • AI 写了 500 行代码,上线后发现漏了 3 个接口、2 个路由、1 个菜单 —— 这套方法论让这种事再也没发生过
  • AI Agent实战:我用Gemini批量完成了《道德经》解读
  • 魔兽争霸3优化终极指南:如何免费解锁300帧高帧率游戏体验
  • 产品 | 《深渊世界》:潜入深海,开启生存冒险之旅!
  • 好用还专业!AI论文工具2026最新测评与推荐
  • 计算机Java毕设实战-基于 SpringBoot 的医院床位调度管理系统的设计与实现 基于 SpringBoot 的住院信息登记与运维系统【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • Java毕业设计-基于 SpringBoot 的医院住院部综合管理系统的设计与实现 基于 SpringBoot 的住院患者病房管控系统(源码+LW+部署文档+全bao+远程调试+代码讲解等)
  • CSDN-视频采集芯片选型指南
  • 量子修正黑洞热力学:模型构建与数值计算实践
  • 编写轻量级框架
  • 摩尔投票法:线性时间寻找多数元素的优雅算法
  • 基于LTC6903与PIC18的数字控制振荡器设计与实现
  • AI落地五大硬核挑战与可验证工程解决方案
  • CS2200-CP与PIC18F25K40高精度计时系统设计指南
  • python下载
  • AI交互数字人:智能一体机场景落地核心优势
  • 深度解析 diff-cover 架构设计:企业级代码覆盖率分析实战指南
  • 闭源大模型的信任红利正在耗尽,企业 AI 必将走向本地模型和开源 Agent——以端脑科技为例
  • 机器人技术全景指南:从机械躯壳到自主智能的进化之路