3.1 事件級別列表

日誌記錄是記錄程序運行時發生的任何事件的過程。你作為程序員的職責是,record everything important因為那時,當production出現奇怪和/或嚴重的錯誤時,除了這些日誌之外,你將一無所有。

如果您掌握了有關錯誤的所有信息以及所有調用歷史記錄,那麼消除任何錯誤的速度將快很多倍。但是從這裡可以得出一個簡單的結論 - 記錄一般的一切:所有方法的調用,所有參數的值。

這也不是一個選擇——信息太多和太少一樣糟糕。我們需要智能日誌記錄。人為人而造。在這裡,我們談到了關於日誌記錄的第一個事實 - 日誌中的所有條目甚至在創建時就被分為幾類。

事件級別列表

程序員在將事件寫入日誌時,必須自己決定該信息的重要性。事件的嚴重級別由消息的作者選擇。log4j記錄的信息重要性有 5 個級別:

  • DEBUG
  • INFO
  • WARN
  • ERROR
  • FATAL

下面我們將更詳細地介紹它們。

3.2 調試

該級別DEBUG被認為是最不重要的。以這種重要性級別寫入日誌的信息僅在應用程序調試期間需要。為了記錄調試過程中需要的信息,使用了該方法debug()

例子:

class Manager {
    private static final Logger logger = LoggerFactory.getLogger(Manager.class);

    public boolean processTask(Task task) {
        logger.debug("processTask id = " + task.getId());
        try {
            task.start();
            task.progress();
            task.complete();
            return true;
        } catch (Exception e) {
            logger.error("Unknown error", e);
            return false;
        }
    }
}

注意,方法debug在方法的最開始(方法還沒有來得及做任何事情)並將傳遞給方法的變量值寫入日誌。這是該方法最常見的用例debug()

3.3 信息和警告

接下來的兩個級別是INFOWARN。它們有兩種方法 -info()warn().

該級別INFO僅用於信息性消息:發生這種情況。當您開始解析日誌中的錯誤時,閱讀其背景會非常有用。該方法非常適合這個info()

級別WARN用於編寫警告(來自warning一詞)。通常,在這種重要程度下,會寫入出錯信息,但程序知道在這種情況下該怎麼做。

比如在寫一個文件到磁盤的過程中,結果發現已經存在這樣一個文件。這裡的程序可以記錄警告(warning),但會向用戶顯示一個對話框並提議選擇不同的文件名。

例子:

class FileManager {
    private static final Logger logger = LoggerFactory.getLogger(FileManager.class);

    public boolean saveFile(FileData file) {
        logger.info(“save the file ” + file.getName());
        boolean resultOK = SaveUtils.save(file);
        if (resultOK) return true;

        logger.warn(“file writing problem ” + file.getName());
        String filename = Dialog.selectFile();
        boolean result = SaveUtils.save(file, filename);
        return result;
    }

3.4 錯誤和致命錯誤

最後,兩個最重要的日誌記錄級別是ERRORFATAL。對於它們,還有一些同名的特殊方法:error()fatal()

他們還決定將錯誤分為兩類——普通錯誤致命錯誤。致命錯誤通常會導致應用程序崩潰(對於桌面應用程序)或 Web 服務崩潰(對於 Web 應用程序)。

另一個很好的例子是 Windows 操作系統。如果你的程序剛剛崩潰,那麼從操作系統的角度來看,這是Error. 而如果操作系統本身已經崩潰,你看到的是 Windows 藍屏死機,那麼這已經是Fatal error.

在 Java 應用程序中,事件Error通常Fatal與引發的異常相關聯。例子:

class Manager {
    private static final Logger logger = LoggerFactory.getLogger(Manager.class);

    public boolean processTask(Task task) {
        logger.debug("processTask id = " + task.getId());
        try {
            task.start();
            task.progress();
            task.complete();
            return true;
        } catch (Exception e) {
            logger.error("Unknown error", e);
            return false;
        }
    }
}

3.5 記錄什麼

當然,連續記錄所有內容是不值得的。在大多數情況下,這會急劇惡化日誌的可讀性,畢竟日誌首先是為了被讀取而寫入的。

此外,您不能將各種個人和財務信息寫入日誌。現在,嚴格而輕鬆地執行此操作可能會導致罰款或訴訟。這樣的日誌遲早會漏到一邊,到時候就沒有問題了。

那麼應該記錄什麼?

首先,您需要記錄應用程序的啟動。應用程序啟動後,建議記錄其運行模式和各種重要設置 - 這將使以後更容易閱讀日誌。

其次,您需要記錄與您的應用程序一起工作的所有第三方服務的狀態:郵件系統、任何外部服務。至少,您需要確保與它們的連接時刻安全,以確保它們正常工作。

第三,需要記錄所有異常。如果它們是預期的,那麼可以緊湊地編寫有關它們的信息。在搜索錯誤時,關於異常的完整信息提供了 50%-80% 的重要信息。

您還需要記錄應用程序關閉。應用程序必須正常終止,並且不會在日誌中拋出大量錯誤。通常在這個地方你會發現卡住的任務,線程池的問題,或者刪除臨時文件的問題。

請務必記錄與安全和用戶授權相關的所有內容。如果用戶連續 10 次嘗試登錄或重置密碼,則此信息應反映在日誌中。

盡可能多地記錄有關異步任務的信息——異常通常會在此類線程中丟失。對於異步任務,一定要記錄它的開始和結束。成功完成的記錄方式應與有問題的完成記錄方式相同。

還有什麼?啟動定時任務,啟動存儲任務SQL-procedures,同步數據,分佈式事務相關的一切。我認為這足以作為一個開始。您將來會添加到此列表中。