如何打印日志

最佳日志实践

日志记录的好坏直接关系到系统出现问题时定位的速度,同时可以通过对日志的观察和分析,提前发现系统可能的风险,避免线上事故的发生。

经验汇总

  • 整个团队(包括运维人员)需要对日志级别有明确的规定,什么日志记入什么级别的日志,什么级别的错误出现要如何处理等

  • 需要定期对日志内容进行优化更新,目的就是通过日志快速准确的定位问题

  • 要明确不同日志的用途,对日志内容进行分类

  • 绝不要打印没有用的日志,防止无用日志淹没重要信息

  • 日志信息要准确全面,努力做到仅凭日志就可以定位问题

  • 要以同样严格的要求对待测试程序的日志

  • 日志的优化是一件持续不断需要投入精力的事,需要不断从错误中学习

  • 在RequestID中尽量编码更多的信息

  • 将一个请求的整个处理流程和唯一的requestID关联起来

  • 让一台机器开启DEBUG日志

  • 新上线服务器后一定要对日志进行观察,特别地,开发人员可以通过观察日志来确认新功能是否工作正常

  • 通过日志级别的提升来发现潜在问题

  • 对日志进行监控报警,比客户先发现系统问题

  • 通过日志中的关键字来确定系统的运行状态

  • 日志格式要统一规范

  • 将错误日志输出到一个单独的文件中进行分析

  • 要把日志的大小,如何切分,如何删除等作为规范建立起来

个人感觉

为什么需要日志?

最初,我们使用 System.out 之类的打印信息,但是这种信息无法持久化,命令行输出之后无法以后查看。

  • 入库

持久化当然也可以入库,比如 MongoDB应用案例:使用 MongoDB 存储日志数据

优点:性能也足够好,更便于发掘信息的价值。

缺点:提升运维成本,对技术的要求提高。

  • log

这个是现在最普遍的一种方式,简单方便。

缺点:数据的信息量较大时,阅读困难,不便于挖掘日志中的更多有价值的信息。

场景:以前分布式系统的日志以 T 为单位,更别说阅读了。

解决方案:

(1)阅读:日志可以和 Elasticsearch 相结合,便于查询和定位。

(2)分析:日志的实时问题定位 大众点评 cat,信息发掘 hadoop 实时分析或者线下分析。

ps: 我们为了解决一个问题总会引入另一个问题,对解决的技术和经验要求越来越高。

我们的日志应该怎么样?

  • 入参和出参

分布式系统(普通)系统,应该打印所有请求的入参和出参,便于甩锅和问题定位。

  • 入库和外部调用

对于入库操作和外部调用的入参和结果一定要有日志记录。

  • 可以准确标识代码的运行位置

线上的问题不可能让你去 debug,好的日志输出应该可以让阅读者知道当前系统每一步在做什么,现在做什么,每一步的关键点一定要有日志记录。

  • 唯一标识

每一个日志都应该有一个唯一标识,贯穿整合请求的生命周期。分布式尤为重要。

  • 整体和部分

整体:记录所有日志,便于详细查看问题。

部分:日志内容针对性强。(如错误级别日志单独一个文件)

一点心得

  • 最少暴露原则

哪怕对于研发,架构时我们也应该将很多细节隐藏起来。让使用者感知不到。

比如:隐藏日志的格式定义,唯一标识贯穿生命周期,入库等等所有的细节。使用者只需要这么用:

log.info("XXX");

优点:便于日志架构的调整,降低使用者的技术门槛。

  • 偷懒原则

比如入参出参,完全可以使用如 Spring Aop 的方式统一处理。

优点:便于统一修改,提升业务代码的可阅读性。