Optimal Logging
by Anthony Vallone
Channeling Goldilocks
Never log too much. Massive, disk-quota burning logs are a clear indicator that little thought was put in to logging. If you log too much, you’ll need to devise complex approaches to minimize disk access, maintain log history, archive large quantities of data, and query these large sets of data. More importantly, you’ll make it very difficult to find valuable information in all the chatter.
The only thing worse than logging too much is logging too little. There are normally two main goals of logging: help with bug investigation and event confirmation. If your log can’t explain the cause of a bug or whether a certain transaction took place, you are logging too little.
Good things to log:
- Important startup configuration
- Errors
- Warnings
- Changes to persistent data
- Requests and responses between major system components
- Significant state changes
- User interactions
- Calls with a known risk of failure
- Waits on conditions that could take measurable time to satisfy
- Periodic progress during long-running tasks
- Significant branch points of logic and conditions that led to the branch
- Summaries of processing steps or events from high level functions - Avoid logging every step of a complex process in low-level functions.
Bad things to log:
- Function entry - Don’t log a function entry unless it is significant or logged at the debug level.
- Data within a loop - Avoid logging from many iterations of a loop. It is OK to log from iterations of small loops or to log periodically from large loops.
- Content of large messages or files - Truncate or summarize the data in some way that will be useful to debugging.
- Benign errors - Errors that are not really errors can confuse the log reader. This sometimes happens when exception handling is part of successful execution flow.
- Repetitive errors - Do not repetitively log the same or similar error. This can quickly fill a log and hide the actual cause. Frequency of error types is best handled by monitoring. Logs only need to capture detail for some of those errors.
There is More Than One Level
Don't log everything at the same log level. Most logging libraries offer several log levels, and you can enable certain levels at system startup. This provides a convenient control for log verbosity.
The classic levels are:
- Debug - verbose and only useful while developing and/or debugging.
- Info - the most popular level.
- Warning - strange or unexpected states that are acceptable.
- Error - something went wrong, but the process can recover.
- Critical - the process cannot recover, and it will shutdown or restart.
Practically speaking, only two log configurations are needed:
- Production - Every level is enabled except debug. If something goes wrong in production, the logs should reveal the cause.
- Development & Debug - While developing new code or trying to reproduce a production issue, enable all levels.
Test Logs Are Important Too
Log quality is equally important in test and production code. When a test fails, the log should clearly show whether the failure was a problem with the test or production system. If it doesn't, then test logging is broken.
Test logs should always contain:
- Test execution environment
- Initial state
- Setup steps
- Test case steps
- Interactions with the system
- Expected results
- Actual results
- Teardown steps
Conditional Verbosity With Temporary Log Queues
When errors occur, the log should contain a lot of detail. Unfortunately, detail that led to an error is often unavailable once the error is encountered. Also, if you’ve followed advice about not logging too much, your log records prior to the error record may not provide adequate detail. A good way to solve this problem is to create temporary, in-memory log queues. Throughout processing of a transaction, append verbose details about each step to the queue. If the transaction completes successfully, discard the queue and log a summary. If an error is encountered, log the content of the entire queue and the error. This technique is especially useful for test logging of system interactions.
Failures and Flakiness Are Opportunities
When production problems occur, you’ll obviously be focused on finding and correcting the problem, but you should also think about the logs. If you have a hard time determining the cause of an error, it's a great opportunity to improve your logging. Before fixing the problem, fix your logging so that the logs clearly show the cause. If this problem ever happens again, it’ll be much easier to identify.
If you cannot reproduce the problem, or you have a flaky test, enhance the logs so that the problem can be tracked down when it happens again.
Using failures to improve logging should be used throughout the development process. While writing new code, try to refrain from using debuggers and only use the logs. Do the logs describe what is going on? If not, the logging is insufficient.
Might As Well Log Performance Data
Logged timing data can help debug performance issues. For example, it can be very difficult to determine the cause of a timeout in a large system, unless you can trace the time spent on every significant processing step. This can be easily accomplished by logging the start and finish times of calls that can take measurable time:
- Significant system calls
- Network requests
- CPU intensive operations
- Connected device interactions
- Transactions
Following the Trail Through Many Threads and Processes
You should create unique identifiers for transactions that involve processing across many threads and/or processes. The initiator of the transaction should create the ID, and it should be passed to every component that performs work for the transaction. This ID should be logged by each component when logging information about the transaction. This makes it much easier to trace a specific transaction when many transactions are being processed concurrently.
Monitoring and Logging Complement Each Other
A production service should have both logging and monitoring. Monitoring provides a real-time statistical summary of the system state. It can alert you if a percentage of certain request types are failing, it is experiencing unusual traffic patterns, performance is degrading, or other anomalies occur. In some cases, this information alone will clue you to the cause of a problem. However, in most cases, a monitoring alert is simply a trigger for you to start an investigation. Monitoring shows the symptoms of problems. Logs provide details and state on individual transactions, so you can fully understand the cause of problems.
Optimal Logging的更多相关文章
- 读书摘要,Hackable Projects
完整读完Google的三篇谈Hackable Projects的文章,以及一篇从Test Pyramid看UnitTest的比重.一篇谈Optimal Logging的文章,感觉这5篇在测试.日志两个 ...
- Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
学习架构探险,从零开始写Java Web框架时,在学习到springAOP时遇到一个异常: "C:\Program Files\Java\jdk1.7.0_40\bin\java" ...
- Oracle补全日志(Supplemental logging)
Oracle补全日志(Supplemental logging)特性因其作用的不同可分为以下几种:最小(Minimal),支持所有字段(all),支持主键(primary key),支持唯一键(uni ...
- Java程序日志:java.util.logging.Logger类
一.Logger 的级别 比log4j的级别详细,全部定义在java.util.logging.Level里面.各级别按降序排列如下:SEVERE(最高值)WARNINGINFOCONFIGFINEF ...
- python 学习笔记 -logging模块(日志)
模块级函数 logging.getLogger([name]):返回一个logger对象,如果没有指定名字将返回root loggerlogging.debug().logging.info().lo ...
- python logging colorlog
import logging LOG_LEVEL = logging.NOTSET LOGFORMAT = "[%(log_color)s%(levelname)s] [%(log_colo ...
- [转]ASP.NET Core 开发-Logging 使用NLog 写日志文件
本文转自:http://www.cnblogs.com/Leo_wl/p/5561812.html ASP.NET Core 开发-Logging 使用NLog 写日志文件. NLog 可以适用于 . ...
- python 之 logging
#coding=utf-8 import logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(filename ...
- Python Logging模块的简单使用
前言 日志是非常重要的,最近有接触到这个,所以系统的看一下Python这个模块的用法.本文即为Logging模块的用法简介,主要参考文章为Python官方文档,链接见参考列表. 另外,Python的H ...
随机推荐
- ACM ICPC Asia Regional 2011 Kuala Lumpur C题
看了逆波兰表达式之后,发现真是强悍的数据结构,栈的应用怎么感觉一辈子也学不完了呢 后缀表达式即逆波兰表达式,就是将所有的运算符按照一定的等级全部都安排到数字的后面去,实现正确的运算法则. OK,代码要 ...
- html5 svg 第八章 文字text
虽然它可能是真实的,每一个画面讲述了一个故事,这是完全正确的,用言语来帮助讲故事.因此,SVG有几个元素,让你将文本添加到您的图形. 文本术语 Text Terminology 在我们调查的主要方法添 ...
- HTTP 304 Response
当一个客户端(通常是浏览器)向web服务器发送一个请求,如果web服务器返回304响应,则表示此请求的本地缓存是最新的,可以直接使用.这种方法可以节省带宽,避免重复响应. 一般来说,可以将一个请求分为 ...
- .Net 程序的运行
1. 用.Net开发的程序运行的某台机器上必须安装.Net FrameWork 2. .Net FrameWork向下兼容的实现 在安装4.0的时候,会把3.5,2.0等低版本的都装上,从而实现向下兼 ...
- [原]H264帧内预测
帧内预测模块大小 说明 4x4(亮度) 预测方式9种 8x8(亮度) 预测方式9种.只有high profile才有 16x16(亮度) 预测方式4种,只依赖左,上数据. 8x8(色度) 预测方式4种 ...
- Unity 时间缩放状态下的特效播放
时间缩放状态下,比如 Time.timeScale 缩小为 0 或者 0.000001 等极小值时,若想将特效的播放速度放大相同的倍数,即修改 ParticleSystem.playbackSpeed ...
- [SCOI2009]游戏
Time Limit: 1 Sec Memory Limit: 162 MB Description windy学会了一种游戏.对于1到N这N个数字,都有唯一且不同的1到N的数字与之对应.最开始wi ...
- Java笔记(六)……程序流程控制
判断结构 三种结构: 1: if(条件表达式) 2: { 3: 执行语句; 4: } 5: 6: if(条件表达式) 7: { 8: 执行语句; 9: } 10: else 11: { 12: 执行 ...
- linux find用法总结
前言:我们为什么要学会使用find命令? 转自:http://blog.chinaunix.net/uid-24648486-id-2998767.html 每一种操作系统都有成千上万的文件组成,对于 ...
- Mac IDEA快捷键积累
切来切去:Ctrl+Tab 在打开的不同类中切换来切换去 完美代码结构:Alt+Command+L 不同编辑点跳转:Alt+Command+↔️ 快速重写:Ctrl+N 快速选择代码:Alt+Shif ...