日志记录与调试的区别

12

背景:我继承了一个旨在创建本地和远程设备之间即时连接的Web应用程序。最近有很多组成部分不断变化:应用程序本身发生了重大变化;开发工具链刚刚更新;本地和远程设备都已经“修改”以支持这些变化。

好的一面是它有一个合理的日志记录系统,可以将调试消息写入文件,并将其记录到文件和实时用户屏幕中。我有机会重新设计整个日志/调试机制。

示例:

  • 所有消息都带有时间戳并带有严重性级别前缀。
  • 日志是为了客户而存在的。它们记录系统对他/她的请求的响应。
  • 任何标识问题的日志也会提供解决方案。
  • 调试是为开发人员和技术支持而准备的。它们揭示了系统内部。
  • 调试指出产生它们的函数和/或行。
  • 客户可以动态调整调试级别以设置详细程度。

问题:作为开发人员,您使用过哪些最佳实践或作为消费者看到哪些最佳实践,以生成有用的日志和调试信息?


编辑:到目前为止,已经提供了许多有用的建议,谢谢!为了澄清:我更感兴趣的是要记录什么:内容、格式等,以及这样做的原因,而不是具体的工具。

您看到的最佳日志的哪些方面使它们最有帮助?

感谢您的帮助!

6个回答

12
不要混淆记录日志、追踪和错误报告,我认识的有些人会混淆,这将创建一个非常庞大而难以查找所需信息的日志文件。
如果我想要获取所有内容,我将分为以下几个部分:
- 追踪 -> 记录每个操作和步骤,带有时间戳,该阶段的输入和输出数据(最丑陋和最大的文件) - 记录日志 -> 仅记录业务流程步骤,客户端询问,因此记录查询条件和输出数据,不多不少。 - 错误报告/调试 -> 记录异常详细信息,包括发生位置,时间戳,输入/输出数据(如果可能),用户信息等。
这样,如果发生任何错误,而错误/调试日志中的信息不足以满足我的需求,我始终可以执行"grep -A 50 -B 50'timestamp' tracing_file"来获取更多详细信息。
编辑:正如也已经提到的,最好使用标准软件包,例如Python内置的logging模块。除非语言没有此功能库,否则自己编写不是一个好主意。我通常喜欢在一个小函数中封装日志记录,将消息和值作为参数传递,以确定它将被记录到哪个日志文件中,例如1-追踪,2-记录日志,4-调试,因此发送值为7会记录到所有三个文件中。

感谢您提出“围绕时间戳收集”的建议,这将非常有帮助。但我特别关注要记录什么内容,以便日志本身也能够有用。 - Adam Liss

9
有些人从不使用调试器,但会记录每件事。这是不同的哲学观,你必须自己做出选择。您可以找到许多建议,例如这些这个。请注意,这些建议与编程语言无关...

Coding Horror guy发布了一篇有关日志问题的有趣文章the problem with logging,阐述了在某些情况下滥用日志可能是浪费时间的原因。

我认为记录日志是为了追踪可能留存在生产环境中的内容,而调试则是为了开发。也许这是一个太简单的看法,因为有些人使用日志进行调试,因为他们无法使用调试器。但调试模式也可能是浪费时间的:您不必像测试用例一样使用它,因为它没有被记录下来,将在调试会话后消失。

所以我的观点是:

  • 记录必要和有用的跟踪信息,通过开发和生产环境,使用日志框架(log4 family工具)
  • 调试模式是为了特殊情况下当事物失控时使用
  • 测试用例很重要,可以节省在地狱般的调试会话中花费的时间,作为防止回归的方法,注意大多数人不使用测试用例。

Coding horror说:抵制记录所有内容的倾向。这是正确的,但我已经看到一个巨大的应用程序以相反的方式(通过数据库)做到了这一点...


9
绝对最有价值的日志记录框架功能是一个“一键式”工具,即使应用程序部署在客户机上,也可以收集所有日志并将其发送给我。同时,要做出良好的选择,记录主要路径,以便更好地跟踪应用程序。作为框架,我使用了标准的log4net、log4java和log4c++等。请不要自己实现日志记录框架,因为已经有一个好的开箱即用的框架了。大多数人只是重复造轮子。

2
是的,一个“发送给技术支持”按钮会为我们节省大量时间……一旦我让日志比“我在这里!”更具信息性。我的工作很艰巨。 - Adam Liss

3
我建议您设置多个日志级别的日志系统。在我编写的服务中,几乎每个操作都有一个日志/审计,它被分配了1-5个审计级别,数字越高,获得的审计事件越多。
以下是不同级别的日志:
1. 基本日志:启动、停止和重新启动 2. 基本日志:处理x个文件等 3. 标准日志:开始处理、完成处理等 4. 高级日志:处理每个阶段的开始和结束 5. 所有内容:记录每个操作
您可以在配置文件中设置审计级别,以便随时更改。

3

以下是对服务器端应用程序有用的几个经验法则:

  • 请求 ID - 给每个传入(HTTP)请求分配一个请求ID,然后在每个日志行中记录该ID,这样您就可以轻松地通过该ID搜索日志并找到所有相关行。如果您认为在每个日志语句中添加该ID非常繁琐,则至少Java日志框架使用Mapped Diagnostic Context(MDC)使其透明。
  • 对象ID - 如果您的应用程序/服务处理某些具有主键的业务对象,则将该主键附加到诊断上下文中也很有用。稍后,如果有人问“何时操作此对象?”,您可以轻松地按objectID搜索并查看与该对象相关的所有日志记录。在这种情况下,访问Nested Diagnostic Context而不是MDC有时很有用。
  • 何时记录日志? - 至少在跨越重要的服务/组件边界时应该记录日志。这样,您可以随后重建调用流程并深入到似乎导致错误的特定代码库。

作为Java开发人员,我还将提供我的Java API和框架经验。

API

我建议使用Simple Logging Facade for Java(SLF4J) - 据我的经验,这是最好的日志门面:

  • 完整功能: 它没有遵循最小公共分母方法(如commons-logging),而是采用了优雅降级方法。
  • 适配器适用于几乎所有受欢迎的Java日志框架(例如log4j)
  • 有可用的解决方案,可以将所有传统的日志API(log4j, commons-logging)重定向到SLF4J

实现: 使用SLF4J的最佳实现是由创建SLF4J API的同一家伙编写的logback


非常有用的建议 - 谢谢。虽然我在这个项目中没有21世纪语言的奢侈条件,但是您的技巧仍然完全适用。 - Adam Liss

0
使用现有的日志格式,比如 Apache 使用的格式,你可以利用许多可用于分析该格式的工具。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接