【问题标题】:Logging, when and what?记录,何时以及什么?
【发布时间】:2010-09-16 16:42:13
【问题描述】:

我目前正在开发一个相当大的多层应用程序,该应用程序将部署到海外。虽然我希望它一旦解散就不会倒下或炸毁,但我不能 100% 确定这一点。因此,很高兴知道我可以请求日志文件,以准确找出问题所在以及原因。

所以基本上正如标题所示,我想知道何时以及记录什么?我想知道这一点,以确保我有全面的日志文件,如果我的应用崩溃,可以轻松检查这些文件以确定发生了什么。

【问题讨论】:

    标签: logging error-logging


    【解决方案1】:

    1 - 使用标准化格式制作单个日志。它是什么并不重要,但要确保每个条目都具有相同的基本字段。只是调用“printf”可能不会削减它(替换 System.err.println 或其他适当的)

    2 - 允许至少一个字段为任意字符串...开发人员会比您更了解需要存在的内容。

    3 - 在每个条目上包含一个高分辨率时间戳。你最终会需要它的,相信我。

    4 - 如果可能,包括错误来源的文件和行号。这在 C 中很容易,而在 Java 中则有点痛苦。但它在以后难以置信很有用,尤其是当人们开始剪切和粘贴代码时,包括错误消息。

    5 - 确保日志位于任何级别的代码都可以使用它的位置。

    6 - 我经常使用“Primary”和“Secondary”错误标签,其中“Primary”表示“我是检测到问题的人”,“Secondary”表示“我调用了一个函数报错”。这样可以很容易地找到问题的根源(“Primary: file not found”)并且仍然报告错误的含义(“Secondary: can't load tracking table”)。

    7 - 包括一些记录非错误和错误的功能。

    我发现最难的部分是错误不一定是错误。如果您使用文件调用函数,并且该文件不存在,那么是否应该记录一个错误?有时它是一个严重的失败,有时它是意料之中的。这几乎取决于函数的 API;如果函数有办法返回错误,我通常会让它在不记录的情况下这样做;那么更高级别代码的工作就是决定是否需要报告该错误或是否需要报告。

    【讨论】:

      【解决方案2】:

      首先,为自己准备一个日志框架——你没有提到任何特定的语言,但任何基于 Apache log4j 的框架都是安全的选择。最重要的是该框架支持不同级别的详细信息(调试消息、警告、错误消息)。您可以在运行时配置记录器,以确定它将实际写入哪些消息以及写入位置 - 重新发明轮子来处理记录是没有意义的。

      在您的源代码中实现您的日志记录框架。作为最低要求,您应该记录并为您的应用程序中可能发生的异常“增加价值”。将堆栈跟踪写入日志文件固然很好,但很少能够诊断问题 - 考虑在 catch {} 中记录方法参数值等内容。

      在更高的级别上,您可以利用不同级别的详细程度来记录应用程序中发生的事情。如果错误仅发生在无法附加远程调试器的生产系统上,这将特别有用 - 您可以在日志框架配置文件中增加详细级别,并观察所有调试(“使用参数调用方法 X Y") 消息出现在日志中。

      【讨论】:

        【解决方案3】:

        我只想补充一点,对于大型任务关键型应用程序,问题只能调查,一旦部署,通过客户端发送的日志的帮助,可以很好地了解何时何地记录日志应用程序成熟的时间(成熟度与应用程序在一个地方部署和使用的时间量直接相关,以及应用程序在不同客户端/位置的不同部署数量)。

        【讨论】:

          【解决方案4】:

          只要您不必为性能付出太多,日志记录就很重要。

          根据我的经验,您要记录的最重要的事情是那些警告、糟糕、健全性检查失败、雨天场景等,在编写晴天场景时往往会忽略它们,有时甚至会放弃它们关闭打印“我们不应该到达这里”等。这些东西倾向于在测试期间不出现,但在部署期间开始弹出,当然不会被捕获。

          如果您记录并打算通过远程读取结果,请确保捕获确切的时间戳、位置和某种会话 ID(以防多个实例同时运行并写入日志文件) .您越容易确定哪些消息是一次执行的一部分,您就越好。

          错误级别和类型也很重要。进行搜索以确保您没有从多个位置编写相同的消息也很重要,否则跟踪将很困难。

          最后,如果您的用户运行 Mac OS X,请格外小心记录错误:出于某种奇怪的原因,即使在 Leopard 中,默认的日志记录机制的处理成本也很高,并且会占用大量 CPU。

          【讨论】:

            【解决方案5】:

            我们开发了一个在全球范围内使用的大型电话系统,并且多年来一直将我们自己的日志记录系统用于应用程序。调试级别非常重要,我们的应用程序附带的调试设置为“仅错误”,除了对时间最敏感的之外,所有的都启用了日志到文件。我们还支持将我们的输出转移到调试跟踪系统(这是 Windows,所以它是对 OutputDebugString 的简单调用,我们的工程师可以访问一个名为 DBWIN32 的调试捕获器)。这很重要,因为某些类别的错误要求您能够查看来自多个应用程序的输出,并进行序列化。通过应用这种技术,我已经解决了一些非常棘手的多应用交互错误。应用程序通常会在输出中添加一个人类可读的标签,这样我们就可以在这种情况下判断哪一行来自哪个应用程序。

            我们使用的级别通常是:关闭、仅错误、基本、详细、“详细”(其中详细是一个占位符,表示投票结果、用户操作、消息内容等多项内容 - 任何作者认为重要的内容)。

            哦,应用程序写入其日志文件的第一件事是提供其版本资源的标头,因此我们可以知道我们正在处理的构建 - 不要相信用户或本地工程师知道:- )

            【讨论】:

              【解决方案6】:

              AOP 对于非侵入式日志记录非常有用。例如,您可以使用 AOP 记录每个方法调用的参数值和返回值,而无需实际将日志记录语句添加到每个方法中。

              如何执行此操作的具体细节显然取决于您的目标语言和平台(您没有指定)。有关如何将此类记录器添加到基于 Java Spring 的应用程序的示例,请参阅here

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2017-01-16
                • 2019-03-26
                • 2010-12-25
                • 2019-03-26
                • 2018-05-13
                • 2016-08-12
                • 1970-01-01
                • 2016-02-11
                相关资源
                最近更新 更多