首頁  >  文章  >  Java  >  有效的函數日誌記錄

有效的函數日誌記錄

Mary-Kate Olsen
Mary-Kate Olsen原創
2024-10-05 14:08:02944瀏覽

Effective Logging for Function

掌握函數級日誌記錄是理解和實現整個軟體系統全面日誌記錄的關鍵步驟。透過專注於功能的粒度級別,我們可以建立堅實的基礎,使擴展到複雜的系統變得輕而易舉。

為函數寫日誌時要記住以下五個重點:

  1. 指定日誌的來源:

    • 總是記下日誌的來源。這可以包括創建時間、文件名稱、相關功能以及許多其他詳細資訊。這在故障排除時很有幫助,因為開發人員可以專注於特定文件或函數。
  2. 在撰寫時牢記調試:

    • 編寫日誌時,請考慮可能出現的潛在問題。日誌的編寫方式應有助於解決這些問題(如果發生)。
  3. 說故事:

    • 日誌應該像一個故事,既抓住重點,又涵蓋所有重要細節。每個函數都應該有自己的敘述,從它收到的參數開始,到它所傳回的資料結束。日誌可以包括執行時間、它所呼叫的任何內部函數、它收到的輸入以及它所傳回的輸出。
  4. 徹底測試日誌:

    • 就像完成後測試功能一樣,日誌也應該進行測試。確保日誌顯示成功和不成功案例的正確資訊。始終從嘗試解決問題的人的角度查看日誌。
  5. 避免過度記錄:

    • 並非所有內容都應該被記錄下來。應省略敏感訊息,特別是與使用者資料有關的資訊。例如,不應記錄所有使用者詳細信息,而應僅記錄使用者 ID 或代碼中使用的信息。

請記得以正確的等級登入:

  • INFO - 記錄有關應用程式操作的非敏感詳細資訊。
  • 警告 - 標記潛在問題而不影響使用者體驗。
  • 錯誤 - 表示影響使用者體驗的嚴重問題。
  • FATAL - 標記嚴重影響使用者體驗的重大錯誤。
  • DEBUG - 提供開發人員除錯資訊。

函數日誌記錄的最佳實踐

日誌字串中的基本元素: 包含TimestampApplicationNameFileNameFunctionNameLEVEL 以及任何其他相關詳細資訊都可以顯著提高應用程式日誌的有效性。這些元素提供了關鍵的上下文,並使追蹤事件流變得更加容易,尤其是在偵錯或監視應用程式時。請記住,我們的目標是創建資訊豐富且有用的日誌,同時尊重隱私和安全考慮。

訊息應傳達:預期的操作、操作的發起者、輸入和輸出。

考慮以下非結構化日誌條目:


2019-06-20T17:21:00.002899+00:00 myApp [c.d.g.UserRequestClass]: [getUser]: DEBUG: Fetching mailing list 14777
2019-06-20T17:21:00.002899+00:00 myApp [c.d.g.UserRequestClass]: [getUser]: DEBUG: User 3654 opted out
2019-06-20T17:21:00.002899+00:00 myApp [c.d.g.UserRequestClass]: [getUser]: DEBUG: User 1334563 plays 4 of spades in game 23425656


透過將這些條目建構為 JSON,我們增強了可讀性和易於解析:


2019-06-20T17:21:00.002899+00:00 myApp [c.d.g.UserRequestClass]: [getUser]: DEBUG: Fetching mailing list {"listid":14777}
2019-06-20T17:21:00.002899+00:00 myApp [c.d.g.UserRequestClass]: [getUser]: DEBUG: User opted out {"userid":3654}
2019-06-20T17:21:00.002899+00:00 myApp [c.d.g.UserRequestClass]: [getUser]: DEBUG: User plays {'user':1334563, 'card':'4 of spade', 'game':23425656}


透過堅持這些實踐,我們可以確保我們的日誌資訊豐富、易於閱讀並且對偵錯有價值。

程式碼範例和最佳實踐

  • 維護日誌一致性和統一性:無論有多少開發人員編寫程式碼,確保日誌在整個程式中保持一致至關重要。這有助於更輕鬆地調試、理解操作流程以及更好地追蹤程式碼執行。
  • 建立日誌模板並使用相同的日誌模式:為整個團隊開發標準日誌模板,並鼓勵團隊中的每個開發人員遵循相同的日誌模式。這促進了一致性,並使其更容易閱讀和理解日誌。
  • 提供並參考範例函數:提供一些範例函數,在程式碼中示範良好的日誌記錄實作。這些可以為開發者提供參考。允許開發人員在編寫自己的程式碼時參考這些範例。這有助於他們遵守既定的日誌記錄實踐並保持一致性。
這是一個例子:


import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class UserService {

    private static final Logger logger = LogManager.getLogger(UserService.class);
    private Database database;

    public UserService(Database database) {
        this.database = database;
    }

    public int getTotalLikesInLast30Days(String userId) {
        logger.info("Request received to get all total likes in last 30 days 
                for: {userId: " + userId + "}");
        long startTime = System.nanoTime();

        try {
            logger.debug("Fetching user with id: {userId: " + userId + "}");
            User user = database.getUserById(userId);

            if (user == null || user.isDeleted() || user.isDeactivated()) {
                logger.warn("User not found or deactivated: {userId: " + userId + "}");
                return 0;
            }

            LocalDate thirtyDaysAgo = LocalDate.now().minus(30, ChronoUnit.DAYS);
            logger.debug("Fetching posts for user since: {userId: " + userId + ", 
                    since: " + thirtyDaysAgo + "}");
            List<Post> posts = database.getPostsByUserSince(user, thirtyDaysAgo);

            int totalLikes = 0;
            for (Post post : posts) {
                totalLikes += post.getLikes().size();
            }

            long endTime = System.nanoTime();
            // compute the elapsed time in nanoseconds
            long duration = (endTime - startTime);  
            logger.info("Execution time: {timeInNanoseconds: " + duration + "}");
            logger.info("Returning total likes in last 30 days for: {userId: " + 
                    userId + ", totalLikes: " + totalLikes + "}");

            return totalLikes;
        } catch (Exception e) {
            logger.error("An error occurred: {message: " + e.getMessage() + "}", e);
            return 0;
        }
    }
}



以下是成功案例中日誌的外觀:


2024-01-07 14:00:00,001 [INFO]  UserService.java:10 [com.example.UserService] (getTotalLikesInLast30Days) : Request received to get all total likes in last 30 days for: {userId: 123}
2024-01-07 14:00:00,002 [DEBUG] UserService.java:12 [com.example.UserService] (getTotalLikesInLast30Days) : Fetching user with id: {userId: 123}
2024-01-07 14:00:00,010 [DEBUG] UserService.java:18 [com.example.UserService] (getTotalLikesInLast30Days) : Fetching posts for user since: {userId: 123, since: 2023-12-08}
2024-01-07 14:00:00,020 [INFO]  UserService.java:26 [com.example.UserService] (getTotalLikesInLast30Days) : Execution time: {timeInNanoseconds: 19000000}
2024-01-07 14:00:00,021 [INFO]  UserService.java:28 [com.example.UserService] (getTotalLikesInLast30Days) : Returning total likes in last 30 days for: {userId: 123, totalLikes: 999}


下面是發生異常時的樣子,例如當 Post 表不存在時:


2024-01-07 14:00:00,001 [INFO]  UserService.java:10 [com.example.UserService] (getTotalLikesInLast30Days) : Request received to get all total likes in last 30 days for: {userId: 123}
2024-01-07 14:00:00,002 [DEBUG] UserService.java:12 [com.example.UserService] (getTotalLikesInLast30Days) : Fetching user with id: {userId: 123}
2024-01-07 14:00:00,010 [DEBUG] UserService.java:18 [com.example.UserService] (getTotalLikesInLast30Days) : Fetching posts for user since: {userId: 123, since: 2023-12-08}
2024-01-07 14:00:00,015 [ERROR] UserService.java:18 [com.example.UserService] (getTotalLikesInLast30Days) : An error occurred: {message: "Post table does not exist"}


Packages like log4j, slf4j, and many others can be used for better management of logs in large software programs.

Focusing on creating effective logs for each function can significantly improve the overall quality of logs for the entire software. This approach ensures that each part of the software is well-documented and can facilitate easier debugging and maintenance. Remember, a well-logged function contributes to a well-logged application.

Thank you for reading this blog. _Sayonara!

以上是有效的函數日誌記錄的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn