何时使用不同的日志级别
logging消息的方式有很多种,按照死亡的顺序排列:
-
FATAL
-
ERROR
-
WARN
-
INFO
-
DEBUG
-
TRACE
我该如何决定何时使用?
什么是一个好的启发式使用?
我通常订阅以下约定:
- 跟踪 – 只有当我将“跟踪”代码,并试图find一个function的一部分具体。
- debugging – 对于人们来说诊断上有用的信息不仅仅是开发人员(IT,系统pipe理员等)。
- 信息 – 通常有用的信息logging(服务启动/停止,configuration假设等)。 信息我想永远有空,但通常情况下通常不关心。 这是我的开箱即用configuration级别。
- 警告 – 任何可能会导致应用程序exception,但我自动恢复。 (如从主服务器切换到备份服务器,重试操作,丢失辅助数据等)
- 错误 – 任何对操作是致命的错误,但不是服务或应用程序(无法打开所需的文件,缺less数据等)。 这些错误将强制用户(pipe理员或直接用户)干预。 这些通常是保留(在我的应用程序)不正确的连接string,缺less的服务等
- 致命 – 任何强制closures服务或应用程序的错误,以防止数据丢失(或进一步的数据丢失)。 我保留这些只为最可怕的错误和情况下,确保有数据损坏或丢失。
你想让这个消息让系统pipe理员在半夜起床吗?
- 是 – >错误
- 没有 – >警告
我发现从查看日志文件的angular度思考严重性会更有帮助。
致命/严重 :应立即调查整体应用程序或系统故障。 是的,唤醒SysAdmin。 由于我们更喜欢我们的SysAdmins警报并且rest得很好,所以这个严重性应该很less使用。 如果它每天都在发生,那不是BFD,它就是失去了意义。 通常,在进程生命周期中只发生一次致命错误,因此如果日志文件与进程绑定,这通常是日志中的最后一条消息。
错误 :绝对是一个应该被调查的问题。 系统pipe理员应该自动通知,但不需要被拖出床。 通过过滤日志来查看错误和以上错误,您可以获得错误频率的概述,并可以快速识别可能导致额外错误级联的启动失败。 跟踪错误率与应用程序使用率的比较可以产生有用的质量指标,如可用于评估整体质量的MTBF。 例如,这个指标可能有助于决定在发布之前是否需要另一个betatesting周期。
警告 :这可能是问题,或者可能不是。 例如,预计的瞬态环境条件(如networking或数据库连接短暂丢失)应logging为“警告”,而不是“错误”。 查看过滤的日志只显示警告和错误,可以快速了解早期提示后续错误的根本原因。 警告应谨慎使用,以免它们变得毫无意义。 例如,networking访问丢失应该是一个警告,甚至在服务器应用程序中的错误,但可能只是一个桌面应用程序中的信息,为偶尔断开的笔记本电脑用户devise的。
信息 :这是在正常情况下应该logging的重要信息,例如成功的初始化,服务启动和停止或成功完成重要事务。 查看显示Info和更高版本的日志应该简要概述过程中的主要状态变化,为理解任何警告或错误提供顶级上下文。 没有太多的信息消息。 我们通常有<5%相对于Trace的Info消息。
跟踪 :跟踪是迄今为止最常用的严重性,应提供上下文来了解导致错误和警告的步骤。 具有正确密度的跟踪消息使得软件更易于维护,但需要一定的努力,因为随着程序的发展,各个跟踪语句的值可能会随时间而改变。 实现这一目标的最佳方法是让开发团队定期检查日志,作为解决客户报告问题的标准部分。 鼓励团队删除不再提供有用上下文的跟踪消息,并在需要了解后续消息上下文的地方添加消息。 例如,logging用户input(如更改显示或选项卡)通常很有帮助。
debugging :我们认为debugging<Trace。 debugging消息是从Release版本编译而来的。 也就是说,我们不鼓励使用debugging消息。 允许debugging消息往往会导致越来越多的debugging消息被添加,并且不会被删除。 随着时间的推移,这使得日志文件几乎是无用的,因为它很难过滤噪声信号。 这导致开发人员不使用继续死亡螺旋的日志。 相比之下,不断修剪跟踪消息鼓励开发人员使用它们,从而导致良性循环。 此外,这消除了由于debugging代码中未包含在发行版本中所需的副作用而引入错误的可能性。 是的,我知道这不应该发生在良好的代码,但更安全,然后抱歉。
如果你能从问题中恢复,那么这是一个警告。 如果它阻止继续执行那么这是一个错误。
我build议采用系统日志的严重性级别: DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY
。
请参阅http://en.wikipedia.org/wiki/Syslog#Severity_levels
他们应该为大多数使用情况提供足够的严格级别,并且被现有的logparsers所认可。 虽然你当然有自由只执行,例如DEBUG, ERROR, EMERGENCY
取决于你的应用程序的要求。
让我们标准化一些历史悠久的东西,而不是为我们制作的每个不同的应用程序提出自己的标准。 一旦你开始聚合日志,并试图检测跨不同的模式,这真的有帮助。
警告您可以从中恢复。 错误,你不能。 这是我的启发,其他人可能有其他的想法。
例如,假设您input了一个有变音符号的欧洲人的姓氏。 你的代码可能只是英文(尽pipe可能不应该在这个时代),并可能警告所有“有趣”的angular色已被转换为普通的英文字符。
与试图将该信息写入数据库并直接获取networking连接消息60秒相反。 这更多的是一个错误,而不是一个警告。
以下是“logging器”的列表。
Apache log4j: §1 , §2
-
FATAL
:[ v1.2 :..]非常严重的错误事件,大概会导致应用程序中止。
[ v2.0 :..]严重的错误,将阻止应用程序继续。
-
ERROR
:[ v1.2 :..]可能仍然允许应用程序继续运行的错误事件。
[ v2.0 :..]在应用程序错误,可能可以恢复。
-
WARN
:[ v1.2 :..]可能有害的情况。
[ v2.0 :..]事件,可能[ 原文如此 ]导致错误。
-
INFO
:[ v1.2 :..]信息性的消息,突出粗粒度级别的应用程序的进展。
[ v2.0 :..]事件以供参考。
-
DEBUG
:[ v1.2 :..]对于debugging应用程序最有用的细粒度的信息事件。
[ v2.0 :..]一般debugging事件。
-
TRACE
:比
DEBUG
更细粒度的信息事件[ v1.2 :..][ v2.0 :..]细粒度的debugging消息,通常捕获通过应用程序的stream程。
Apache的Httpd(像往常一样)喜欢去矫枉过正: §
-
emerg :
紧急情况 – 系统无法使用。
-
警报 :
必须立即采取行动[但系统仍然可用]。
-
暴击 :
关键条件[但不必立即采取行动]。
- “ socket:无法获取套接字,退出子节点 ”
-
错误 :
错误情况[但不重要]。
- “ 脚本标题的提前结束 ”
-
警告 :
警告条件。 [接近错误,但不是错误]
-
注意 :
正常但显着的[ 显着 ]情况。
- “ httpd:抓到
SIGBUS
,试图把核心SIGBUS
… ”
- “ httpd:抓到
-
信息 :
信息[和不可知的]。
- [“ 服务器已经运行了x个小时。 ”]
-
debugging :
debugging级别的消息[也就是为了解除错误而logging的消息]]。
- “ 打开configuration文件… ”
-
trace1 → trace6 :
跟踪消息[即为了跟踪而logging的消息]。
- “ 代理:FTP:控制连接完成 ”
- “ 代理:CONNECT:发送CONNECT请求到远程代理 ”
- “ openssl:握手:开始 ”
- “ 从缓冲的SSL队读取模式0,17字节 ”
- “ map lookup FAILED:
map=rewritemap
key=keyname
” - “ caching查找失败,强制新的地图查找 ”
-
trace7 → trace8 :
跟踪消息,倾销大量的数据
- “
| 0000: 02 23 44 30 13 40 ac 34 df 3d bf 9a 19 49 39 15 |
” - “
| 0000: 02 23 44 30 13 40 ac 34 df 3d bf 9a 19 49 39 15 |
”
- “
Apache公共日志logging: §
-
致命的 :
导致提前终止的严重错误。 期望这些在状态控制台上立即可见。
-
错误 :
其他运行时错误或意外情况。 期望这些在状态控制台上立即可见。
-
警告 :
使用已弃用的API,API使用不当,“几乎”错误,其他运行时情况不理想或意外,但不一定是“错误的”。 期望这些在状态控制台上立即可见。
-
信息 :
有趣的运行时事件(启动/closures)。 期望这些在控制台上立即可见,所以要保守并保持最低限度。
-
debugging :
有关通过系统stream动的详细信息。 期望这些只写入日志。
-
痕迹 :
更详细的信息。 期望这些只写入日志。
Apache公共日志logging“企业使用的最佳实践”根据它们所跨越的界限来区分debugging和信息 。
边界包括:
-
外部边界 – 预期的例外。
-
外部边界 – 意外的例外。
-
内部边界。
-
重要的内部边界。
(请参阅commons-logging指南了解更多信息。)
以下级别可用。 但是您也可以定义自定义级别。
ALL :
所有级别,包括自定义级别。
Trace :
仅开发,可用于跟踪程序执行。
Debug :
仅开发,用于debugging目的。
Info :
生产可选,课程粒度(很less写入信息),我用它来打印configuration初始化,长时间运行的导入作业开始和结束。
Warn :
生产,简单的应用程序错误或意外的行为。 申请可以继续。 警告例如login尝试不良,导入作业期间的意外数据。
Error :
生产,应用程序错误/exception,但应用程序可以继续。 部分应用程序可能无法正常工作。
Fatal :
生产,致命的应用程序错误/exception,应用程序无法继续,例如数据库closures。
Off :
不要login。
正如其他人所说,错误是问题, 警告是潜在的问题。
在开发过程中,我经常使用警告,可能会导致断言失败,但应用程序可以继续工作。 这使我能够发现这种情况是否真的发生过,或者是我的想象。
但是,是的,它回到了可回收和现实的方面。 如果你能恢复,这可能是一个警告; 如果它导致某些事情真的失败了,那是错误的。
错误是错的,错的,没有办法解决的,需要修正。
警告是一种可能是错误的模式的标志,但也可能不是。
说了这么多,我不能拿出一个好的例子来警告,这也不是一个错误。 我的意思是,如果你遇到logging警告的麻烦,那么你也可以解决潜在的问题。
然而,像“SQL执行时间太长”可能是一个警告,而“SQL执行死锁”是一个错误,所以也许有一些情况毕竟。
我认为SYSLOG级别通知和警报/紧急对于应用程序级别的日志来说在很大程度上是多余的,而对于可能触发不同操作和通知的操作员而言,CRITICAL / ALERT / EMERGENCY可能是有用的警报级别,对于应用程序pipe理员来说,致命。 而且我不能充分区分给予通知或一些信息。 如果信息不值得注意,那不是真正的信息:)
我最喜欢Jay Cincotta的解释 – 跟踪你的代码的执行在技术支持方面是非常有用的,应该鼓励将跟踪语句放在代码中,特别是结合dynamic过滤机制来logging来自特定应用程序组件的跟踪消息。 然而,对我来说,DEBUG级别表明我们仍在确定发生了什么事情 – 我将DEBUG级别的输出视为仅限于开发的选项,而不是在生产日志中显示的内容。
然而,当我戴上系统pipe理员的帽子,甚至是开发者OPERATIONAL的OPERATIONAL消息的帽子时,我也喜欢在错误日志中看到日志级别。 我使用它来logging一个时间戳记,被调用的操作types,提供的参数,可能的(唯一的)任务标识符和任务完成。 当例如一个独立的任务被触发时,它被使用,这是一个真正的从长期运行的应用程序中调用的东西。 这是我想要logging的东西,不pipe是否有什么问题,所以我认为OPER的水平高于FATAL,所以你只能通过完全静音模式closures它。 而且它不仅仅是INFO日志数据 – 一个日志级别经常被滥用于垃圾邮件日志,其次是没有任何历史价值的操作信息。
根据具体情况的不同,这些信息可以直接指向一个单独的调用日志,也可以通过从logging更多信息的大日志中过滤出来。 但是,作为历史信息,总是需要知道正在做什么 – 没有下降到AUDIT的水平,另一个与故障或系统操作无关的完全独立的日志级别并不真正适合上述级别(因为它需要自己的控制开关,而不是一个严重性分类),并且确实需要它自己的单独的日志文件。
从Ietf – 页面10
Each message Priority also has a decimal Severity level indicator.
下表描述了它们的数值。 严重性值必须在0到7的范围内。
Numerical Severity Code 0 Emergency: system is unusable 1 Alert: action must be taken immediately 2 Critical: critical conditions 3 Error: error conditions 4 Warning: warning conditions 5 Notice: normal but significant condition 6 Informational: informational messages 7 Debug: debug-level messages
我总是考虑警告第一个日志级别,肯定意味着有问题(例如,也许configuration文件不是应该在哪里,我们将不得不使用默认设置运行)。 一个错误意味着,对我来说,这意味着软件的主要目标现在是不可能的,我们将试图closures干净。
天儿真好,
作为这个问题的必然结果,传达你对日志水平的解释,并确保项目中的所有人都对他们对水平的解释是一致的。
看到严重程度和所选日志级别不一致的大量日志消息是很痛苦的。
提供可能的不同日志logging级别的示例。 并在信息中logging信息一致。
HTH
我之前build立了系统使用以下内容:
- 错误 – 意味着某些事情严重错误,特定的线程/进程/序列无法继续。 一些用户/pipe理干预是必需的
- 警告 – 有些东西是不正确的,但是这个过程可以像以前一样进行(例如,一个100个工作中的一个工作失败,但其余部分可以被处理)
在我build立的系统pipe理员正在指导下对错误做出反应。 另一方面,我们会留意警告,并确定是否需要更改系统,重新configuration等。
顺便说一句,我是一个捕获一切和过滤后的信息的伟大粉丝。
如果您在“警告”级别进行捕获,并希望与警告相关的一些“debugging”信息,但无法重新创build警告,会发生什么情况?
捕获所有内容并稍后过滤!
即使对于embedded式软件也是如此,除非您发现您的处理器无法跟上,在这种情况下,您可能需要重新devise跟踪以使其效率更高,或跟踪对时间产生干扰(您可以考虑debugging一个更强大的处理器,但是这打开了一个蠕虫的整个notherjar)。
捕获一切,然后过滤!
(顺便说一句,捕捉所有的东西也是不错的,因为它可以让你开发工具,而不仅仅是显示debugging跟踪(我从我的消息顺序图和内存使用的直方图中绘制出来),它还为你提供了一个比较基础,将来(保持所有日志,无论是否通过,并确保在日志文件中包含内部版本号))。
我完全同意其他人的看法,并认为GrayWizardx说得最好。
我可以补充的是,这些级别通常对应于他们的字典定义,所以它不会那么难。 如果有疑问,请把它当成一个难题。 对于您的特定项目,请考虑您可能要logging的所有内容。
现在,你能弄清楚什么可能是致命的吗? 你知道什么是美国人的意思,不是吗? 所以,你的名单上的哪些项目是致命的。
好吧,这是致命的处理,现在让我们看看错误…冲洗和重复。
在致命之下,或者也许是错误,我会build议更多的信息总是好于更less,所以错误“向上”。 不确定是信息还是警告? 然后把它作为警告。
我认为,致命的错误应该是我们所有人都清楚的。 其他的可能会更模糊,但是让它们正确无疑是不太重要的。
这里有些例子:
致命 – 无法分配内存,数据库等 – 无法继续错误 – 没有回复消息,事务中止,无法保存文件等警告 – 资源分配达到X%(比如80%) – 这是一个标志您可能要重新维护您的信息 – 用户login/注销,新的事务,文件crated,新的d / b字段,或删除字段debugging – 内部数据结构的转储,任何跟踪级别的文件名和行号跟踪 – 行动成功/失败,d / b更新