要理解为什么日志在产品或者系统中扮演着重要的角色,我们必须了解它的价值。至少到现在,日志被应用最广泛的是报警、故障排除和业务数据可视化。
日志可以作为我们业务系统监控的重要数据来源;成熟的产品系统都有报警系统,如果系统中出现超过某个已定义的某个指标的问题,日志系统会自动将报警信息发送到通知平台,On-call 的人就可以根据报警信息定位解决问题了。
Alerting With Log - From Grafana
这种情况非常普遍;想象一下你最近负责开发维护的系统被他人发现有问题,在你梳理完思路之后第一件事是干什么?肯定是查看系统信息验证自己的假设是否成立, 这里打印在服务器上的日志就是最好的辅助信息。而作为程序员的我们,日志是我们最熟悉不过的解决问题的利器。
Logs Effective Debugging - From Grafana
很多公司可以利用存储在自己数据库里的生产环境的日志,结合相应的工具可以对业务进行业务数据可视化。这里最典型的代表是 Grafana 和 SumoLogic。
Fitbit Health MonitorDebug With Logs - From Grafana
Slack File And App Audit - From SumoLogic
为了更好的支持上面的各种情况,我们需要对我们的日志格式进行梳理,按照一定的规范来写日志。而不是随便写一句废话。
Log format
基础版本
对于日志,时间,日志级别,和日志信息最为重要,所以一个合格的日志应该至少包含这些信息。
高级版本
在基础版的基础上,加入线程名,方法名,类名,方法对应的行数;
线程名:多数应用的用户都不是单一的,对于单实例的服务对同一个接口很多用户访问应用会将在不同的线程中执行,这时如果要区分对应用户的业务流程,那么通过线程名是最好的。
主机名:现在的应用大都部署在 Cloud 中都是多实例的,所以在单节点的基础上,日志在多实例上就需要实例级别的区分,而主机名是最好的区分方式。
方法名:打印了日志的方法名,方便区分相同日志的出处。
类名:打印了日志的类名,方便快速定位业务流程。
行数:打印了日志的行数,方便快速定位日志的具体位置。
格式化
对于常规的请求(Request)、响应(Response)或者其他业务日志,可以在自定义信息和参数之间用下划线分割;多个参数之间用逗号分隔,当然参数也是可选的;
对于错误信息格式化,也可以按照 Key:Value 的形式进行组织。
为了提高日志的可读性,我们可以对日志进行修饰。
对日志级别、主机名和线程名前后加中括号;
对方法名所在的类名和行号加括号,并在类名与行号中间用冒号隔开;
在行号和日志信息中间加入一个横线来分割;
对于日志信息也可以进行特定的格式化
日志的输出都是分级别的,不同的场景需要打印不同级别的日志;以下是几个比较重要的日志级别。
Debug: 记录技术细节,和一些帮助理解系统运行的日志
Info: 记录业务信息的日志
Warn: 非紧急且可控的可接受的错误信息
Error: 非期望的错误或者系统表现,通常是由系统bug或者环境问题导致
同时不是所有的日志都需要记录,我们要做到按需记录。
下表是推荐在不同的环境选择不同的日志级别。
Environment | Log Leave |
---|---|
Dev | Debug |
Test | Debug |
UAT | Info |
Prod | Info |
不同的编程语言有不同的日志工具;比较著名的是 Apache 的 Log4j, Log4j是高度可配置的,并可通过在运行时的外部文件配置。它根据记录的优先级别,并提供机制以指示记录信息到许多的目的地,诸如:数据库,文件,控制台,UNIX系统日志等;而且 log4j 已经被移植到了其他编程语言中了,如 Python 中的 logging, NodeJS 中的log4js, Rust 中的log4rs。
避免打印或记录任何敏感信息,包括但不限于各种PII,PCI信息,一定要记得遵守当地的各种法律法规,如中国的《个人信息保护法》(PILI), 欧洲的一般数据保护条例GDPR等
按需选择合适的日志级别
…...
好的日志不仅可以为程序开发提供便利,为故障排除提供最重要的辅助信息,更可以为业务或基础设施提供优化建议或数据统计。
THE TOP 25 GRAFANA DASHBOARD EXAMPLES
Grafana lab
SumoLogic
Log4j