测试环境日志爆内存?我用一个工具类搞定了双日志体系的智能打印
2026/7/9 9:15:28 网站建设 项目流程

一、痛点复盘:我们的日志到底乱在哪?

先跟大家同步下我们项目的日志现状,相信很多团队都有同款问题:

  1. 双日志体系,无法统一管理
    业务层用@Slf4j打印业务日志,定时任务层用XxlJobHelper打印任务执行日志,两套API完全独立,想做日志过滤得分别改,工作量翻倍。

  2. 测试环境日志泛滥,内存占用爆表
    测试环境不需要调试参数、循环日志、中间状态这些冗余信息,但所有日志都原样输出,导致日志文件过大,磁盘IO高,排查问题效率极低。

  3. 生产环境不能精简,必须全量保留
    生产环境是底线,任何日志都不能丢,一旦故障,全量日志是定位问题的唯一依据,所以不能直接关闭低级别的日志。

  4. 改造难度大,不能影响原有业务
    项目已经上线,不能大规模修改原有日志代码,必须做到无侵入、兼容旧代码、一键切换

面对这些问题,我定下了改造目标:
✅ 一套工具兼容@Slf4j+XxlJobHelper双日志
✅ 配置化控制环境,无需修改代码
✅ 测试环境只打印关键日志,生产环境全量打印
✅ 无侵入改造,原有代码可平滑迁移

二、核心解决方案:UnifiedLogger 统一日志工具类

我直接把完整的工具类代码贴出来,复制到项目里就能用,无需额外依赖,完美适配SpringBoot项目:

package com.at.mrp.bll.log; import com.xxl.job.core.context.XxlJobHelper; import lombok.extern.slf4j.Slf4j; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /** * 统一日志工具类 * 支持 slf4j 和 XxlJob 日志的智能过滤 * * 使用方式: * 1. UAT/测试环境:在消息中包含【重要】、【错误】、【失败】等关键词才会输出 * 2. 生产环境:所有日志都输出 * * 示例: * UnifiedLogger.info(log, "【重要】开始执行批量任务"); * UnifiedLogger.info(log, "普通调试信息"); // UAT环境不输出,生产环境输出 * UnifiedLogger.error(log, "发生异常: {}", errorMsg); // 所有环境都输出 */ @Slf4j @Component public class UnifiedLogger { private static String logEnv; @Value("${log.env:prod}") public void setLogEnv(String env) { UnifiedLogger.logEnv = env; } /** * 判断是否应该记录日志 * UAT/测试环境:只记录包含特定关键词的日志 * 生产环境:全部记录 */ private static boolean shouldLog(String message) { if ("prod".equalsIgnoreCase(logEnv)) { return true; } if (message == null || message.isEmpty()) { return false; } String upperMsg = message.toUpperCase(); // UAT/测试环境:只记录包含以下关键词的日志 return upperMsg.contains("【重要】") || upperMsg.contains("【错误】") || upperMsg.contains("【失败】") || upperMsg.contains("【警告】") || upperMsg.contains("【关键】") || upperMsg.contains("[ERROR]") || upperMsg.contains("[FAIL]") || upperMsg.contains("[WARN]") || upperMsg.contains("[IMPORTANT]"); } // ==================== slf4j 日志方法 ==================== /** * INFO 级别日志 - 智能过滤 * * @param logger slf4j Logger 实例 * @param message 日志消息 * @param args 参数 */ public static void info(Logger logger, String message, Object... args) { if (shouldLog(message)) { logger.info(message, args); } } /** * WARN 级别日志 - 所有环境都记录(自动添加【警告】标记) * * @param logger slf4j Logger 实例 * @param message 日志消息 * @param args 参数 */ public static void warn(Logger logger, String message, Object... args) { String formattedMessage = "【警告】" + message; logger.warn(formattedMessage, args); } /** * ERROR 级别日志 - 所有环境都记录(自动添加【错误】标记) * * @param logger slf4j Logger 实例 * @param message 日志消息 * @param args 参数 */ public static void error(Logger logger, String message, Object... args) { String formattedMessage = "【错误】" + message; logger.error(formattedMessage, args); } /** * DEBUG 级别日志 - 仅生产环境记录 * * @param logger slf4j Logger 实例 * @param message 日志消息 * @param args 参数 */ public static void debug(Logger logger, String message, Object... args) { if ("prod".equalsIgnoreCase(logEnv)) { logger.debug(message, args); } } // ==================== XxlJob 日志方法 ==================== /** * XxlJob 智能日志记录 * 根据环境和消息内容决定是否输出 * * @param message 日志消息,可包含【重要】、【错误】等关键词 * @param args 参数 */ public static void xxlLog(String message, Object... args) { if (shouldLog(message)) { XxlJobHelper.log(message, args); } } /** * XxlJob 错误日志(自动添加【错误】标记) */ public static void xxlLogError(String message, Object... args) { String formattedMessage = "【错误】" + message; XxlJobHelper.log(formattedMessage, args); } /** * XxlJob 警告日志(自动添加【警告】标记) */ public static void xxlLogWarn(String message, Object... args) { String formattedMessage = "【警告】" + message; XxlJobHelper.log(formattedMessage, args); } /** * XxlJob 重要日志(自动添加【重要】标记) */ public static void xxlLogImportant(String message, Object... args) { String formattedMessage = "【重要】" + message; XxlJobHelper.log(formattedMessage, args); } /** * XxlJob 详细日志 - 仅生产环境记录 */ public static void xxlLogDetail(String message, Object... args) { if ("prod".equalsIgnoreCase(logEnv)) { XxlJobHelper.log(message, args); } } }

核心规则

  1. 生产环境(prod):所有日志无条件打印,保证问题可追溯
  2. 测试/UAT环境(uat/test):只打印包含关键标记的日志,自动过滤冗余信息

关键标记(测试环境生效)

只要日志里包含这些关键词,测试环境就会打印,完美区分重要日志和调试日志:

  • 业务关键:【重要】、【关键】
  • 异常错误:【错误】、[ERROR]、【失败】、[FAIL]
  • 警告提示:【警告】、[WARN]

一行配置搞定环境切换

不用改代码,只需要在对应环境的配置文件加一行配置:
测试/UAT环境

log: env: uat

生产环境

log: env: prod

工具类会自动读取配置,切换日志打印策略。

三、实战使用:兼容双日志体系,用法超简单

这个工具类最香的地方就是,同时支持@Slf4j和XxlJobHelper,原有代码改个调用方法就行,零学习成本。

1. 业务日志(@Slf4j)用法

原来的log.info()直接替换成工具类方法,自动适配环境:

@Slf4j @Service public class OrderService { public void syncOrder() { // 【重要日志】测试/生产环境都会打印 UnifiedLogger.info(log, "【重要】开始同步订单,总数量:{}", orderCount); // 普通调试日志:测试环境不打印,生产环境打印 UnifiedLogger.info(log, "订单详情参数:{}", JSON.toJSONString(order)); // 错误日志:自动加【错误】标记,所有环境必打印 UnifiedLogger.error(log, "订单同步失败:{}", e.getMessage()); // 警告日志:自动加【警告】标记,所有环境必打印 UnifiedLogger.warn(log, "订单库存不足,请及时处理"); } }

2. 定时任务日志(XxlJobHelper)用法

定时任务里的XxlJobHelper.log()也能一键替换:

@XxlJob("batchTaskJob") public void batchTask() { // 重要任务日志:全环境打印 UnifiedLogger.xxlLog("【重要】定时任务开始执行"); // 详细任务日志:仅生产环境打印 UnifiedLogger.xxlLog("任务入参:{}", param); // 任务错误日志:全环境打印 UnifiedLogger.xxlLogError("定时任务执行失败:{}", errorMsg); }

工具类核心亮点

  1. 自动加标记:error/warn方法自动拼接【错误】【警告】,不用手动写
  2. 智能过滤:测试环境自动过滤无关键词的普通日志
  3. 无性能损耗:生产环境直接打印,无额外逻辑开销
  4. 静态方法:直接调用,无需注入,使用超方便

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询