design-patterns - 日志代码应该去哪/什么级别?

标签 design-patterns language-agnostic logging exception-handling

我想知道日志代码应该去哪里。例如,我的存储库应该记录它自己的错误吗?还是应该从UI /控制器记录所有错误?是否有关于此的一般设计原则,或者是否有人链接到好的文章或诸如此类的文章。

最佳答案

日志记录和跟踪是(IMO)的一种美术,它知道要记录什么以及在哪里需要经验。

我发现,学习测井技术的最好(最差?)方法是体验尝试诊断劣质测井问题的痛苦!

我只能为您提供一些建议:

考虑如何使用日志消息。

良好日志记录的关键是考虑问题时如何使用日志消息,相反,不良日志记录最糟糕的事情是,只有在遇到问题并且没有足够的信息时,您才会意识到这一点!

始终考虑日志消息对正在阅读的人说的是什么,例如:


Windows API调用失败了吗?如果是这样,那么您可能需要记录HRESULTGetLastError结果(如果有的话),以使其有用。
在集合中找不到条目?如果没有找不到条目的名称,那么实际上没有人可以推断出太多的信息-知道集合的数量也很方便,这样您就可以知道该集合是否为空。


一个常见的错误是没有考虑日志记录时需要什么信息,但是您也应该仔细考虑何时记录一条消息-如果在正常操作下频繁记录一条消息,那么充其量是有用的,并且在最坏的情况下该日志是有用的信息可能会产生误导。

另外,请确保您可以识别记录消息的内容。如果您在日志中看到的只是一个字符串,该字符串多次出现在您的代码库中(或者更糟糕的是根本没有!),那么您将需要推论并想弄清楚该日志消息的来源(并且没有知道消息的来源,您几乎没有希望理解它)


在多线程/多处理器应用程序中,始终记录线程ID和进程ID。
如果您有任何类型的请求ID,请也进行记录。
如果您认为您将花费任何合理的时间来查看日志文件,那么您应该强烈考虑运送所需的任何pdb等...文件,以便查看源文件和行号。


仅在出现问题时使用日志记录

不要将日志记录与错误处理混淆。错误处理是响应并解决该错误的行为(例如向用户显示一条消息),(通常)仅在出现问题且原因不清楚时才使用日志。

例如:如果用户尝试打开一个不存在的文件,那么如果正确处理了错误(通过告诉用户找不到该文件),则无需记录该错误。

(可能的例外可能是,如果您想要统计该错误发生的频率或发生的某件事,那就是回想起日志的使用方式。)

通常,正确地处理错误比记录日志更可取,但是良好的错误处理要比良好的日志记录更加困难-在这种情况下,需要日志中提供的额外信息。

您也不应将日志记录与审计混淆(尽管在许多系统中两者是重叠的)。

多多益善!

记录过多日志的唯一方法是:


您的存储空间不足。
您会严重影响应用程序的性能。
您会遇到大量日志,这些日志在发生错误时无法轻松处理。
您记录对老板的亵渎。


日志记录纯粹是为了诊断问题的原因(不要将日志记录与审核混为一谈)-如果您没有任何问题,那么没人会看您的日志,并且不会造成任何危害!在出现问题之前,在这种情况下,您需要尽可能多的信息。

如果您不确定是否要记录某些内容,请对其进行记录。

仅记录一次异常。

综上所述,我认为有必要澄清异常的记录。

通常,您只应记录一次异常(在处理异常的地方)。不要试图记录一个异常,然后稍后将其抛出给调用方,以防万一调用方没有正确记录该异常-发生的所有事情是,您最终会多次记录相同的异常从一层到另一层(我已经看到了这种情况的发生,这使得很难看到实际发生了多少错误)。

记录错误是呼叫者的责任-唯一可能的异常可能是在系统边界(例如Web服务)之间传递,因此不可能在所有错误详细信息之间进行传输。

记录任何相关的内容,无论它记录在何处。

例如,如果您正在编写基于服务器的应用程序,则您的日志文件必须位于服务器上,系统管理员可以在其中读取它们-但是,如果在客户端上可能发生错误(例如JavaScript),则您的日志记录代码必须使用JavaScript。解决方案?您的JavaScript日志记录需要将自身提交到服务器(ala log4js

不必担心您应该将日志记录在何处,不应该将日志记录在任何需要的地方。

关于design-patterns - 日志代码应该去哪/什么级别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3658527/

相关文章:

language-agnostic - 什么时候使用调解器设计模式

debugging - 在远程 Glassfish 上进行日志记录和/或调试

javascript - Redux - 复杂图形的建模状态并触发多个更新和副作用以响应单个操作

java - 是否有用于合并来自 2 个队列的项目的企业集成模式?

c# - 具有数据访问层的通用存储库

c# - 确定在运行时使用哪个类

algorithm - 当我想检查一组的所有可能组合时,我使用什么技术?

c - 查询处理 TAB 字符?

java - 如何设置 Jersey JAX-RS 服务器端记录器级别?

java - 将动态值传递给 log4j2 xml 配置