首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 自定義日誌工具類:同步寫入、日期格式化、多行批量記錄

     編輯:Java 相關知識

設計目標

  • 零依賴 (僅 JDK),輕量級嵌入任意專案
  • 線程安全:synchronized 方法級鎖
  • 自動創建目錄/文件
  • 支援單行與批量多行寫入
  • 統一時間戳格式:yyyy-MM-dd HH:mm:ss

完整實現代碼


public final class AndyLogger {
    // 配置
    private static final String ROOT_PATH = "C:\\temp2"; // 建議外部化配置
    private static final String LINE_SEP = System.lineSeparator();
    private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    // 單行記錄
    public static synchronized void log(String fileName, String message) {
        write(fileName, Collections.singletonList(message));
    }

    // 批量記錄
    public static synchronized void log(String fileName, String[] messages) {
        write(fileName, Arrays.asList(messages));
    }

    // 核心寫入邏輯
    private static void write(String fileName, List<String> messages) {
        File dir = new File(ROOT_PATH);
        if (!dir.exists()) dir.mkdirs();

        File logFile = new File(dir, fileName + ".log");
        if (!logFile.exists()) {
            try { logFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); return; }
        }

        // 讀取現有內容 (小文件適用,大文件建議追加模式)
        StringBuilder content = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new FileReader(logFile))) {
            String line;
            while ((line = br.readLine()) != null) {
                content.append(line).append(LINE_SEP);
            }
        } catch (IOException e) { e.printStackTrace(); return; }

        // 追加新記錄
        String timestamp = SDF.format(new Date());
        for (String msg : messages) {
            content.append(timestamp).append(' ').append(msg).append(LINE_SEP);
        }

        // 覆寫文件 (注意:非追加模式,大文件性能差)
        try (BufferedWriter bw = new BufferedWriter(new FileWriter(logFile))) {
            bw.write(content.toString());
        } catch (IOException e) { e.printStackTrace(); }
    }

    // 測試
    public static void main(String[] args) {
        AndyLogger.log("bug223", "timeisjjja");
        AndyLogger.log("bug223", new String[]{"111", "222", "333"});
    }
}

關鍵設計點分析

點實現優缺點
線程安全synchronized 方法鎖簡單可靠,高併發下成瓶頸
文件模式讀全量 → 內存拼接 → 覆寫✅ 保證順序;❌ 大文件 OOM 風險、性能差
時間戳SimpleDateFormat (非線程安全)鎖內使用安全,高併發建議 DateTimeFormatter (Java 8+)
編碼平台默認編碼建議顯式指定 StandardCharsets.UTF_8
配置硬編碼路徑建議外部化 (Properties/YAML/環境變量)

生產級優化建議 (漸進式)

  1. 追加模式:new FileWriter(file, true) 直接追加,無需讀舊內容,O(1) 寫入
  2. 異步寫入:BlockingQueue + 專用寫入線程 或 Log4j2 AsyncAppender,業務線程無阻塞
  3. 滾動策略:按大小/時間分割文件,避免單文件過大
  4. 結構化日誌:JSON 格式,便於 ELK/Splunk 採集分析
  5. 門面模式:對接 SLF4J,底層可切換 Logback/Log4j2/JUL

現代替代方案對比

方案優點缺點適用場景
Logback + SLF4J業界標準、高性能、豐富策略、原生異步學習曲線、依賴體積所有生產項目
Log4j2無 GC、配置熱加載、插件化歷史安全漏洞 (已修復)高性能/低延遲系統
JUL (java.util.logging)零依賴、JDK 內建功能弱、配置繁瑣、性能一般極簡項目/受限環境
自研 (如本類)完全可控、零依賴、適合教學缺乏企業級特性、維護成本教學、嵌入式、臨時腳本

總結

本工具類展示了日誌框架的核心骨架:文件管理、線程同步、格式化、寫入路徑。理解其原理有助於深入掌握成熟框架的內部機制。實際工程中,請直接使用 Logback/Log4j2,僅在極度受限環境或教學場景考慮自研。若必須自研,請務必實現追加寫入、異步落盤、滾動分割三大核心能力。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved