如何打印日志
日志记录的好坏直接关系到系统出现问题时定位的速度,同时可以通过对日志的观察和分析,提前发现系统可能的风险,避免线上事故的发生。
经验汇总
-
整个团队(包括运维人员)需要对日志级别有明确的规定,什么日志记入什么级别的日志,什么级别的错误出现要如何处理等
-
需要定期对日志内容进行优化更新,目的就是通过日志快速准确的定位问题
-
要明确不同日志的用途,对日志内容进行分类
-
绝不要打印没有用的日志,防止无用日志淹没重要信息
-
日志信息要准确全面,努力做到仅凭日志就可以定位问题
-
要以同样严格的要求对待测试程序的日志
-
日志的优化是一件持续不断需要投入精力的事,需要不断从错误中学习
-
在RequestID中尽量编码更多的信息
-
将一个请求的整个处理流程和唯一的requestID关联起来
-
让一台机器开启DEBUG日志
-
新上线服务器后一定要对日志进行观察,特别地,开发人员可以通过观察日志来确认新功能是否工作正常
-
通过日志级别的提升来发现潜在问题
-
对日志进行监控报警,比客户先发现系统问题
-
通过日志中的关键字来确定系统的运行状态
-
日志格式要统一规范
-
将错误日志输出到一个单独的文件中进行分析
-
要把日志的大小,如何切分,如何删除等作为规范建立起来
个人感觉
为什么需要日志?
最初,我们使用 System.out
之类的打印信息,但是这种信息无法持久化,命令行输出之后无法以后查看。
- 入库
持久化当然也可以入库,比如 MongoDB应用案例:使用 MongoDB 存储日志数据
优点:性能也足够好,更便于发掘信息的价值。
缺点:提升运维成本,对技术的要求提高。
- log
这个是现在最普遍的一种方式,简单方便。
缺点:数据的信息量较大时,阅读困难,不便于挖掘日志中的更多有价值的信息。
场景:以前分布式系统的日志以 T 为单位,更别说阅读了。
解决方案:
(1)阅读:日志可以和 Elasticsearch 相结合,便于查询和定位。
(2)分析:日志的实时问题定位 大众点评 cat,信息发掘 hadoop 实时分析或者线下分析。
ps: 我们为了解决一个问题总会引入另一个问题,对解决的技术和经验要求越来越高。
我们的日志应该怎么样?
- 入参和出参
分布式系统(普通)系统,应该打印所有请求的入参和出参,便于甩锅和问题定位。
- 入库和外部调用
对于入库操作和外部调用的入参和结果一定要有日志记录。
- 可以准确标识代码的运行位置
线上的问题不可能让你去 debug,好的日志输出应该可以让阅读者知道当前系统每一步在做什么,现在做什么,每一步的关键点一定要有日志记录。
- 唯一标识
每一个日志都应该有一个唯一标识,贯穿整合请求的生命周期。分布式尤为重要。
- 整体和部分
整体:记录所有日志,便于详细查看问题。
部分:日志内容针对性强。(如错误级别日志单独一个文件)
一点心得
- 最少暴露原则
哪怕对于研发,架构时我们也应该将很多细节隐藏起来。让使用者感知不到。
比如:隐藏日志的格式定义,唯一标识贯穿生命周期,入库等等所有的细节。使用者只需要这么用:
log.info("XXX");
优点:便于日志架构的调整,降低使用者的技术门槛。
- 偷懒原则
比如入参出参,完全可以使用如 Spring Aop 的方式统一处理。
优点:便于统一修改,提升业务代码的可阅读性。