最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Java編寫統(tǒng)一日志工具類搞定雙日志體系的智能打印

 更新時間:2026年05月20日 08:39:00   作者:佛祖讓我來巡山  
這篇文章主要為大家詳細介紹了如何基于Java編寫一個統(tǒng)一日志工具類UnifiedLogger,一把搞定兩套日志的智能過濾,文中的示例代碼講解詳細,有需要的小伙伴可以參考下

作為一名后端開發(fā),不知道你有沒有遇到過這樣的頭疼事:測試環(huán)境日志瘋狂輸出,磁盤內(nèi)存分分鐘告急,生產(chǎn)環(huán)境又必須保留全量日志方便排查問題

最近我就被這個問題狠狠折磨了一把。我們項目里有大量定時任務,用的是XxlJobHelper打印任務日志,業(yè)務代碼又依賴@Slf4j輸出業(yè)務日志,兩套日志體系各自為政。

測試環(huán)境一跑起來,不管是調(diào)試信息、中間參數(shù),還是無關緊要的流程日志,一股腦全打出來,沒幾天日志文件就占滿了磁盤,排查問題時翻半天也找不到關鍵信息;可生產(chǎn)環(huán)境又不敢精簡日志,萬一出問題,少一行日志都可能定位不到故障根因。

改吧?兩套日志寫法,到處都是log.info()XxlJobHelper.log(),手動改成本太高;不改吧,測試環(huán)境內(nèi)存天天報警,運維天天找。

思來想去,我決定寫一個統(tǒng)一日志工具類UnifiedLogger,一把搞定兩套日志的智能過濾:生產(chǎn)環(huán)境全量打印,測試環(huán)境只打關鍵日志,配置一行搞定,不用改動原有業(yè)務邏輯!

一、痛點復盤:我們的日志到底亂在哪?

先跟大家同步下我們項目的日志現(xiàn)狀,相信很多團隊都有同款問題:

  1. 雙日志體系,無法統(tǒng)一管理:業(yè)務層用@Slf4j打印業(yè)務日志,定時任務層用XxlJobHelper打印任務執(zhí)行日志,兩套API完全獨立,想做日志過濾得分別改,工作量翻倍。
  2. 測試環(huán)境日志泛濫,內(nèi)存占用爆表:測試環(huán)境不需要調(diào)試參數(shù)、循環(huán)日志、中間狀態(tài)這些冗余信息,但所有日志都原樣輸出,導致日志文件過大,磁盤IO高,排查問題效率極低。
  3. 生產(chǎn)環(huán)境不能精簡,必須全量保留:生產(chǎn)環(huán)境是底線,任何日志都不能丟,一旦故障,全量日志是定位問題的唯一依據(jù),所以不能直接關閉低級別的日志。
  4. 改造難度大,不能影響原有業(yè)務:項目已經(jīng)上線,不能大規(guī)模修改原有日志代碼,必須做到無侵入、兼容舊代碼、一鍵切換。

面對這些問題,我定下了改造目標:

  • 一套工具兼容@Slf4j+XxlJobHelper雙日志
  • 配置化控制環(huán)境,無需修改代碼
  • 測試環(huán)境只打印關鍵日志,生產(chǎn)環(huán)境全量打印
  • 無侵入改造,原有代碼可平滑遷移

二、核心解決方案:UnifiedLogger 統(tǒng)一日志工具類

我直接把完整的工具類代碼貼出來,復制到項目里就能用,無需額外依賴,完美適配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;
/**
 * 統(tǒng)一日志工具類
 * 支持 slf4j 和 XxlJob 日志的智能過濾
 *
 * 使用方式:
 * 1. UAT/測試環(huán)境:在消息中包含【重要】、【錯誤】、【失敗】等關鍵詞才會輸出
 * 2. 生產(chǎn)環(huán)境:所有日志都輸出
 *
 * 示例:
 * UnifiedLogger.info(log, "【重要】開始執(zhí)行批量任務");
 * UnifiedLogger.info(log, "普通調(diào)試信息"); // UAT環(huán)境不輸出,生產(chǎn)環(huán)境輸出
 * UnifiedLogger.error(log, "發(fā)生異常: {}", errorMsg); // 所有環(huán)境都輸出
 */
@Slf4j
@Component
public class UnifiedLogger {
    private static String logEnv;
    @Value("${log.env:prod}")
    public void setLogEnv(String env) {
        UnifiedLogger.logEnv = env;
    }
    /**
     * 判斷是否應該記錄日志
     * UAT/測試環(huán)境:只記錄包含特定關鍵詞的日志
     * 生產(chǎn)環(huán)境:全部記錄
     */
    private static boolean shouldLog(String message) {
        if ("prod".equalsIgnoreCase(logEnv)) {
            return true;
        }
        if (message == null || message.isEmpty()) {
            return false;
        }
        String upperMsg = message.toUpperCase();
        // UAT/測試環(huán)境:只記錄包含以下關鍵詞的日志
        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 參數(shù)
     */
    public static void info(Logger logger, String message, Object... args) {
        if (shouldLog(message)) {
            logger.info(message, args);
        }
    }
    /**
     * WARN 級別日志 - 所有環(huán)境都記錄(自動添加【警告】標記)
     *
     * @param logger slf4j Logger 實例
     * @param message 日志消息
     * @param args 參數(shù)
     */
    public static void warn(Logger logger, String message, Object... args) {
        String formattedMessage = "【警告】" + message;
        logger.warn(formattedMessage, args);
    }
    /**
     * ERROR 級別日志 - 所有環(huán)境都記錄(自動添加【錯誤】標記)
     *
     * @param logger slf4j Logger 實例
     * @param message 日志消息
     * @param args 參數(shù)
     */
    public static void error(Logger logger, String message, Object... args) {
        String formattedMessage = "【錯誤】" + message;
        logger.error(formattedMessage, args);
    }
    /**
     * DEBUG 級別日志 - 僅生產(chǎn)環(huán)境記錄
     *
     * @param logger slf4j Logger 實例
     * @param message 日志消息
     * @param args 參數(shù)
     */
    public static void debug(Logger logger, String message, Object... args) {
        if ("prod".equalsIgnoreCase(logEnv)) {
            logger.debug(message, args);
        }
    }
    // ==================== XxlJob 日志方法 ====================
    /**
     * XxlJob 智能日志記錄
     * 根據(jù)環(huán)境和消息內(nèi)容決定是否輸出
     *
     * @param message 日志消息,可包含【重要】、【錯誤】等關鍵詞
     * @param args 參數(shù)
     */
    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 詳細日志 - 僅生產(chǎn)環(huán)境記錄
     */
    public static void xxlLogDetail(String message, Object... args) {
        if ("prod".equalsIgnoreCase(logEnv)) {
            XxlJobHelper.log(message, args);
        }
    }
}

核心規(guī)則

  1. 生產(chǎn)環(huán)境(prod):所有日志無條件打印,保證問題可追溯
  2. 測試/UAT環(huán)境(uat/test):只打印包含關鍵標記的日志,自動過濾冗余信息

關鍵標記(測試環(huán)境生效)

只要日志里包含這些關鍵詞,測試環(huán)境就會打印,完美區(qū)分重要日志和調(diào)試日志:

  • 業(yè)務關鍵:【重要】、【關鍵】
  • 異常錯誤:【錯誤】、[ERROR]、【失敗】、[FAIL]
  • 警告提示:【警告】、[WARN]

一行配置搞定環(huán)境切換

不用改代碼,只需要在對應環(huán)境的配置文件加一行配置:

測試/UAT環(huán)境

log:
  env: uat

生產(chǎn)環(huán)境

log:
  env: prod

工具類會自動讀取配置,切換日志打印策略。

三、實戰(zhàn)使用:兼容雙日志體系,用法超簡單

這個工具類最香的地方就是,同時支持@Slf4j和XxlJobHelper,原有代碼改個調(diào)用方法就行,零學習成本。

1. 業(yè)務日志(@Slf4j)用法

原來的log.info()直接替換成工具類方法,自動適配環(huán)境:

@Slf4j
@Service
public class OrderService {

    public void syncOrder() {
        // 【重要日志】測試/生產(chǎn)環(huán)境都會打印
        UnifiedLogger.info(log, "【重要】開始同步訂單,總數(shù)量:{}", orderCount);
        
        // 普通調(diào)試日志:測試環(huán)境不打印,生產(chǎn)環(huán)境打印
        UnifiedLogger.info(log, "訂單詳情參數(shù):{}", JSON.toJSONString(order));
        
        // 錯誤日志:自動加【錯誤】標記,所有環(huán)境必打印
        UnifiedLogger.error(log, "訂單同步失?。簕}", e.getMessage());
        
        // 警告日志:自動加【警告】標記,所有環(huán)境必打印
        UnifiedLogger.warn(log, "訂單庫存不足,請及時處理");
    }
}

2. 定時任務日志(XxlJobHelper)用法

定時任務里的XxlJobHelper.log()也能一鍵替換:

@XxlJob("batchTaskJob")
public void batchTask() {
    // 重要任務日志:全環(huán)境打印
    UnifiedLogger.xxlLog("【重要】定時任務開始執(zhí)行");
    
    // 詳細任務日志:僅生產(chǎn)環(huán)境打印
    UnifiedLogger.xxlLog("任務入?yún)ⅲ簕}", param);
    
    // 任務錯誤日志:全環(huán)境打印
    UnifiedLogger.xxlLogError("定時任務執(zhí)行失?。簕}", errorMsg);
}

工具類核心亮點

  1. 自動加標記:error/warn方法自動拼接【錯誤】【警告】,不用手動寫
  2. 智能過濾:測試環(huán)境自動過濾無關鍵詞的普通日志
  3. 無性能損耗:生產(chǎn)環(huán)境直接打印,無額外邏輯開銷
  4. 靜態(tài)方法:直接調(diào)用,無需注入,使用超方便

四、改造效果:測試環(huán)境日志直接瘦身90%

上線這個工具類后,效果立竿見影:

  • 測試環(huán)境日志量直接減少90%,磁盤內(nèi)存不再報警
  • 排查問題效率翻倍:打開日志全是關鍵信息,沒有冗余干擾
  • 生產(chǎn)環(huán)境完全無影響:全量日志正常保留
  • 改造零 風險:原有代碼逐步遷移,不影響業(yè)務運行

最關鍵的是,后續(xù)新增日志只需要按照規(guī)則加關鍵詞,不用再擔心日志泛濫問題,一次封裝,長期受益。

五、總結與最佳實踐

最后給大家總結下使用心得:

  1. 關鍵業(yè)務流程:務必加【重要】標記,保證測試環(huán)境可觀測
  2. 異常/錯誤:統(tǒng)一用error方法,自動標記,全環(huán)境必打
  3. 調(diào)試/參數(shù)日志:不加標記,測試環(huán)境自動過濾,不占用內(nèi)存
  4. 環(huán)境切換:純配置化,一行代碼搞定,不用重新發(fā)布

如果你也在被測試環(huán)境日志泛濫、雙日志體系難管理的問題困擾,不妨試試這個統(tǒng)一日志工具類,低成本解決這個麻煩!

我一直覺得,好的工具不是花里胡哨的功能,而是能實實在在解決日常開發(fā)的痛點,讓我們少加班、多高效。這個小小的UnifiedLogger,就是我為團隊日志痛點交出的最優(yōu)解~

以上就是基于Java編寫統(tǒng)一日志工具類搞定雙日志體系的智能打印的詳細內(nèi)容,更多關于Java統(tǒng)一日志工具類的資料請關注腳本之家其它相關文章!

相關文章

  • Java實現(xiàn)手寫線程池的示例代碼

    Java實現(xiàn)手寫線程池的示例代碼

    在我們的日常的編程當中,并發(fā)是始終離不開的主題,而在并發(fā)多線程當中,線程池又是一個不可規(guī)避的問題。本文就來分享一下如何自己手寫一個線程池,需要的可以參考一下
    2022-08-08
  • Java以struts2為例介紹如何實現(xiàn)圖片上傳

    Java以struts2為例介紹如何實現(xiàn)圖片上傳

    這篇文章主要介紹了Java struts2中如何實現(xiàn)圖片上傳的相關資料,需要的朋友可以參考下
    2015-11-11
  • 使用Java WebSocket獲取客戶端IP地址的示例代碼

    使用Java WebSocket獲取客戶端IP地址的示例代碼

    在開發(fā)Web應用程序時,我們通常需要獲取客戶端的 IP 地址用于日志記錄、身份驗證、限制訪問等操作,本文將介紹如何使用Java WebSocket API獲取客戶端IP地址,以及如何在常見的WebSocket框架中獲得客戶端 IP地址,需要的朋友可以參考下
    2023-11-11
  • MyBatis核心配置文件深入分析

    MyBatis核心配置文件深入分析

    這篇文章主要介紹了MyBatis核心配置文件,MyBatis的前身就是iBatis,iBatis本是由Clinton Begin開發(fā),后來捐給Apache基金會,成立了iBatis開源項目。2010年5月該項目由Apahce基金會遷移到了Google Code,并且改名為MyBatis
    2022-12-12
  • Java while(scanner.hasNext())無法跳出的解決方案

    Java while(scanner.hasNext())無法跳出的解決方案

    這篇文章主要介紹了Java while(scanner.hasNext())無法跳出的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • SpringBoot+WebSocket向前端推送消息的實現(xiàn)示例

    SpringBoot+WebSocket向前端推送消息的實現(xiàn)示例

    WebSocket是一種在單個TCP連接上進行全雙工通信的協(xié)議,允許服務器主動向客戶端推送信息,同時也能從客戶端接收信息,本文主要介紹了SpringBoot+WebSocket向前端推送消息的實現(xiàn)示例,感興趣的可以了解一下
    2024-08-08
  • 基于Spring MVC的文件上傳和下載實現(xiàn)方法

    基于Spring MVC的文件上傳和下載實現(xiàn)方法

    在Web應用程序中,文件上傳和下載是常見的功能,Spring MVC框架提供了方便的方式來實現(xiàn)這些功能,本文將介紹如何使用Spring MVC實現(xiàn)文件上傳和下載,需要的朋友可以參考下
    2023-05-05
  • SpringBoot的全局異常攔截實踐過程

    SpringBoot的全局異常攔截實踐過程

    SpringBoot中使用@ControllerAdvice和@ExceptionHandler實現(xiàn)全局異常攔截,@RestControllerAdvice默認返回JSON格式,@ResponseStatus指定HTTP狀態(tài)碼,@ExceptionHandler捕獲異常,自定義BusinessException和HttpCodeEnum類,便于統(tǒng)一異常處理和返回格式
    2025-12-12
  • 詳解Mybatis框架SQL防注入指南

    詳解Mybatis框架SQL防注入指南

    這篇文章主要介紹了詳解Mybatis框架SQL防注入指南,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-07-07
  • RPC框架之Thrift的入門教程

    RPC框架之Thrift的入門教程

    Thrift是一個跨語言的服務部署框架,主要用于各個服務之間的RPC通信,支持跨語言,下面小編就來和大家講講Thrift框架的具體使用,希望對大家有所幫助
    2023-10-10

最新評論

曲靖市| 白水县| 济阳县| 自贡市| 纳雍县| 吉水县| 横山县| 辽宁省| 仁怀市| 富平县| 辽阳县| 新巴尔虎左旗| 城口县| 鹤壁市| 沽源县| 梁河县| 青龙| 广平县| 成安县| 项城市| 新巴尔虎右旗| 翁源县| 靖西县| 马山县| 凤台县| 武宣县| 婺源县| 革吉县| 伊吾县| 伊金霍洛旗| 新河县| 榆树市| 嘉禾县| 库伦旗| 通许县| 本溪| 固阳县| 阳西县| 翼城县| 浑源县| 洛扎县|