首页  >  文章  >  Java  >  有效的函数日志记录

有效的函数日志记录

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-10-05 14:08:02947浏览

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