10

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

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

例子:

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

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


编辑:到目前为止有很多有用的建议,谢谢!澄清一下:我对记录的内容更感兴趣:内容、格式——以及这样做的原因——而不是特定的工具。

你见过的最好的日志是什么让它们最有帮助?

谢谢你的帮助!

4

6 回答 6

10

不要混淆日志记录、跟踪和错误报告,我认识的一些人会这样做,它会创建一个非常糟糕的日志文件以通过 grep 获取我想要的信息。

如果我想把所有东西都做好,我会分成以下几部分:

  • 跟踪-> 转储每个动作和步骤,带有时间戳,以及该阶段的输入和输出数据(最丑和最大的文件)
  • 记录-> 仅记录业务流程步骤,客户端进行查询,因此只记录查询条件和输出数据。
  • 错误报告/调试-> 记录异常,详细说明它发生的位置、时间戳、输入/输出数据(如果可能)、用户信息等

这样,如果发生任何错误并且错误/调试日志不包含我喜欢的足够信息,我总是可以做一个grep -A 50 -B 50 'timestamp' tracing_file以获得更多详细信息。

编辑: 正如已经说过的那样,坚持标准包,例如 python 的内置日志记录模块,总是好的。滚动你自己的不是一个好主意,除非该语言的标准库中没有一个。我确实喜欢将日志记录包装在一个小函数中,该函数通常采用消息和值来确定它转到哪些日志,即。1 - 跟踪,2 - 日志记录,4 - 调试,因此将值 7 发送到所有 3 等等。

于 2009-03-06T13:41:03.493 回答
9

使用任何日志记录框架完成的绝对最有价值的事情是“一键式”工具,即使应用程序部署在属于客户的机器上,它也会收集所有日志并将它们邮寄给我。

并在记录的内容上做出正确的选择,这样您就可以大致遵循应用程序中的主要路径。

作为框架,我使用了标准(log4net、log4java、log4c++)

不要实现你自己的日志框架,当已经有一个好的开箱即用的框架时。大多数人只是重新发明轮子。

于 2009-03-06T13:23:58.260 回答
9

有些人从不使用调试器,但会记录所有内容。那是不同的哲学,你必须做出自己的选择。你可以找到很多这样的建议,或者这个。请注意,这些建议与语言无关...

Coding Horror一篇关于日志记录问题的有趣帖子,以及为什么在某些情况下滥用日志记录可能会浪费时间。

我只是相信日志记录是为了跟踪可能保留在生产中的东西。调试是为了开发。可能是看东西的方式太简单了,导致有些人用日志来调试,因为他们受不了调试器。但是调试器模式也可能是浪费时间:您不必像测试用例那样使用它,因为它没有被记录下来并且会在调试会话后消失。

所以我认为我对此的看法是:

  • 使用日志框架(log4系列工具)在开发和生产环境中记录必要和有用的跟踪,具有开发和生产级别
  • 当事情失控时,用于特殊情况的调试模式
  • 测试用例很重要,可以节省在地狱迷宫式调试会话中花费的时间,用作抗回归方法。请注意,大多数人不使用测试用例。

编码恐怖说抵制记录一切的趋势。没错,但是我已经看到了一个 hudge 应用程序,它以一种漂亮的方式(并通过数据库)完全相反......

于 2013-01-24T09:38:57.807 回答
3

我只是将您的日志记录系统设置为具有多个日志记录级别,在我编写的服务上,我对几乎每个操作都有一个日志记录/审核,并且它被分配了一个审核级别 1-5,数量越高,您获得的审核事件越多。

  1. 最基本的日志记录:启动、停止和重新启动
  2. 基本日志记录:处理 x 个文件等
  3. 标准记录:开始到处理,完成处理等
  4. 高级日志记录:处理中每个阶段的开始和结束
  5. 一切:采取的每一个行动

您在配置文件中设置审核级别,以便可以即时更改它。

于 2009-03-06T14:10:22.080 回答
3

我发现一些通用的经验法则在服务器端应用程序中很有用:

  • requestID - 为每个传入 (HTTP) 请求分配一个请求 ID,然后将其记录在每个日志行上,以便您以后可以轻松地通过该 ID 对这些日志进行 grep 并找到所有相关行。如果您认为将 ID 添加到每个日志语句非常繁琐,那么至少 java 日志框架通过使用映射诊断上下文(MDC) 使其变得透明。
  • objectID - 如果您的应用程序/服务处理一些具有主键的业务对象,那么将该主键也附加到诊断上下文很有用。后来,如果有人提出问题“这个对象是什么时候被操纵的?” 您可以轻松地通过 objectID grep 并查看与该对象相关的所有日志记录。在这种情况下,(有时)实际使用嵌套诊断上下文而不是 MDC 很有用。
  • 何时登录?- 至少当你跨越一个重要的服务/组件边界时,你应该记录。这样,您以后可以重建调用流程并深入到似乎导致错误的特定代码库。

由于我是一名 Java 开发人员,我还将介绍我在 Java API 和框架方面的经验。

API

我推荐使用Simple Logging Facade for Java (SLF4J) - 根据我的经验,它是记录日志的最佳外观:

  • 全功能:它没有遵循最小公分母方法(如 commons-logging);相反,它使用了优雅地降级的方法。
  • 具有适用于几乎所有流行的 Java 日志框架(例如 log4j)的适配器
  • 提供有关如何将所有旧式日志记录 API(log4j、commons-logging)重定向到 SLF4J 的解决方案

实现 与 SLF4J 一起使用的最佳实现是logback - 由创建 SLF4J API 的同一个人编写。

于 2009-03-06T14:26:27.253 回答
0

使用现有的日志格式,例如 Apache 使用的格式,然后您可以搭载许多可用于分析格式的工具。

于 2009-03-06T13:44:01.130 回答