概览
上一篇我们讨论了为什么要使用日志框架,这次我们深入问题的根源,为什么我们需要日志?
大多数开发人员会纠结日志该怎么输出,什么时候输出,输出了会不会有人看等问题,让我们跳出开发人员的局限来考虑这个问题:谁需要日志?日志有几种?日志都需要输出什么?如何输出日志?
谁需要日志?
-
开发者 开发人员在开发过程中需要输出一些变量方便调试,正确的做法是使用日志来输出(使用
System.out
来输出,一不小心发布到线上,会被项目经理痛批);其次线上问题很难重放,用户的表述一般都会失真,况且很多用户发现 bug 就删 app 关网页走人了 -
运维人员 整个系统大部分时间都是运维人员来维护,日志可以帮助运维人员来了解系统状态(很多运维系统接入的也是日志),运维人员发现日志有异常信息也可以及时通知开发来排查
-
运营人员 没错,就是运营人员,比如电商的转化率、视频网站的完播率、普通PV数据等都可以通过日志进行统计,随着大数据技术的普及,这部分日志占比也越来越高
-
安全人员 虽然大多数企业不重视安全,但是安全也可以通过日志来进行预警,比如某个用户突然大额转账、再比如数据库突然出现大量无条件分页查库(拖库)等等
日志有几种?
-
调试日志 用于开发人员开发调试或者线上回溯问题。
-
诊断日志 一般用于运维人员监控系统与安全人员分析预警。
-
埋点日志 一般用于运营决策分析,也有用作微服务调用链路追踪的(运维、调试)。
-
审计日志 与诊断日志类似,诊断日志偏向运维,审计日志偏向安全。
日志都需要输出什么?
注:日志级别会在下面讲解
-
调试日志
-
DEBUG 或者 TRACE 级别,比如方法调用参数,网络连接具体信息,一般是开发者调试程序使用,线上非特殊情况关闭这些日志
-
INFO 级别,一般是比较重要却没有风险的信息,如初始化环境、参数,清理环境,定时任务执行,远程调用第一次连接成功
-
WARN 级别,有可能有风险又不影响系统继续执行的错误,比如系统参数配置不正确,用户请求的参数不正确(要输出具体参数方便排查),或者某些耗性能的场景,比如一次请求执行太久、一条sql执行超过两秒,某些第三方调用失败,不太可能被运行的if分支等
-
ERROR 级别,用于程序出错打印堆栈信息,不应该用于输出程序问题之外的其他信息,需要注意打印了日志异常(Exception)就不应该抛(
throw
)了
-
-
诊断日志 一般输出 INFO 级别,请求响应时间,内存占用等等,线上接入监控系统时打开,建议输出到独立的文件,可以考虑 JSON 格式方便外部工具分析
-
埋点日志 业务按需定制,比如上文提到的转化率可以在用户付款时输出日志,完播率可以在用户播放完成后请求一次后台输出日志,一般可输出 INFO 级别,建议输出到独立的文件,可以考虑JSON格式方便外部工具分析
-
审计日志 大多 WARN 级别或者 INFO 级别,一般是敏感操作即可输出,登陆、转账付款、授权消权、删除等等,建议输出到独立的文件,可以考虑JSON格式方便外部工具分析
一般调试日志由开发者自定义输出,其他三种应该根据实际业务需求来定制。
日志的其他注意点
-
线上日志应尽量谨慎,要思考:这个位置输出日志能帮助排除问题吗?输出的信息与排查问题相关吗?输出的信息足够排除问题吗?做到不少输出必要信息,不多输出无用信息(拖慢系统,淹没有用信息)
-
超级 SessionId 与 RequestId,无论是单体应用还是微服务架构,应该为每个用户每次登陆生成一个超级 SessionId,方便跟踪区分一个用户;RequestId,每次请求生成一个 RequestId,用于跟踪一次请求,微服务也可以用于链路追踪
-
日志要尽量单行输出,一条日志输出一行,否则不方便阅读以及其他第三方系统或者工具分析
-
公司内部应该制定一套通用的日志规范,包括日志的格式,变量名(驼峰、下划线),分隔符(“=”或