将DEBUG日志记录级别保留在生产代码中

时间:2019-02-22 22:14:59

标签: logging

过去,我的客户会打电话告诉我他们的软件出现问题。 我将登录到该站点,然后查看错误日志。

但是,我发现错误日志倾向于解释发生了什么错误,但不能解释为什么会发生错误。要了解导致问题的原因,需要先前的状态信息,该信息仅包含在DEBUG日志中。

因此,几乎每次,我都必须更改日志级别,重新启动软件,并花费大量时间尝试重新创建问题。

我决定让生产代码以DEBUG日志级别运行,但是要进行一次调整: 我使用journald.conf将日志的最大大小限制为10GB。在500GB的计算机上,这对我来说似乎很好。

现在,我可以使用journalctl --sincejournalctl --until来过滤大量日志,直到客户说出错误发生的时间。

现在,当问题出现时,我不再浪费时间来重新创建问题。

我的问题:

让生产代码在详细的DEBUG级别上在客户的站点上运行有什么含义?

我在这里发现答案是不够的: Log levels in Production

2 个答案:

答案 0 :(得分:1)

始终记录每条日志消息的两个主要问题是:

性能

就I / O,内存或CPU而言,日志记录不是免费的。这在写日志的系统以及收集和查询的系统上都很明显。

噪音

如果您99.9%的日志行中包含与问题无关的信息,那么当实际问题发生时,可能很难找到它。

潜在解决方案

具有请求级别日志记录,我已经看到系统会在特定请求的内存中记录调试级别日志,并且仅在给定请求发生应用程序错误时才将其持久保存到磁盘。

在您的给定系统上实现起来可能并不容易,并且在处理所有这些日志并将它们保存在内存中时仍会受到一定的损失,但这对于解决您的特定问题可能是一个不错的选择。

或者,更新现有日志以包含更多上下文信息。例如,默认的.NET Core日志记录框架允许您沿调用链添加上下文信息:

using (logger.BeginScope("UserId: {0}", 123)) 
{
    // will log this message with contextual information UserId: 123
    logger.LogInformation("Password does not match"); 
}  

第三,如果您能够使系统处于可重现问题的状态,并且重新启动应用程序失去了这种能力,那么您可以更新日志记录框架,以便能够在以下位置动态设置日志消息的最低严重性:运行时。

答案 1 :(得分:0)

正如Matthew指出的那样,主要问题是性能和噪音。那该怎么办?

仅在需要时记录调试

three个主要方法可以记录生产中的DEBUG日志。我最喜欢的一种模式是让您的代码始终跟踪调试日志,但直到发生错误时才真正记录它们。这称为事件驱动的调试日志,其工作原理如下:

在不进行特定于语言的实现的情况下,这里的想法是保留内存中最近的DEBUG日志,并仅在必要时将其转储到记录器中。这个“必需的”可能取决于您。未捕获的异常?另一个处于“错误”级别的日志?这取决于您的情况。