日志输出最佳实践

发布于 2022-12-12
第一个例子是反例,这个日志无法说明 REST 调用是否成功,你可能会看到日志输出,并在之后抛出了一个日志,可能会对查看日志的人造成困惑,不知道到底调用成功没。

在动作后打日志

// don't do that
log.info("Making request to REST API")
restClient.makeRequest()

// do that
restClient.makeRequest()
log.info("Made request to REST API")

第一个例子是反例,这个日志无法说明 REST 调用是否成功,你可能会看到日志输出,并在之后抛出了一个日志,可能会对查看日志的人造成困惑,不知道到底调用成功没。

第二个例子为正例,如果业务代码运行正常会输出日志,反之会抛出异常,同时日志也不会打印。

INFO 格式的日志适用此规则,DEBUG 模式还有例外,会在下面介绍。

分离参数和日志信息

// don't do that
restClient.makeRequest()
log.info("Made request to {} on REST API.", url)

// do that
restClient.makeRequest()
log.info("Made request to REST API. [url={}]", url)

日志有两部分,一部分是人工写的帮助判断状态的提示信息,另一部分是实际操作中的参数。 第一个例子中,不容易区分参数到底是哪个,尤其当日志较长时,可读性会大大降低。 第二个例子中,可更清晰的查看参数信息,且便于使用一些表达式解析参数。

区分 WARNING 和 ERROR

简单来说,两者的区别为:

  • WARNING:做了某些操作,但是有问题。
  • ERROR:做了某些操作,但压根没起作用或压根无法做。

如:

try {
    restClient.makeRequest()
    log.info("Made request to REST API. [url={}]", url)
} catch(e: UnauthorizedException) {
    log.warn("Request to REST API was rejected because user is unauthorized. [url={}, result={}]", url, result)
} catch(e: Exception) {
    log.error("Request to REST API failed. [url={}, exception={}]", url, exception)
}

REST 调用可能具有以下三种结果:

  • 它可以正常工作,这是 INFO 级别的(在工作后)
  • 它可能会造成一些预期的异常,这是 WARNING 级别的。
  • 它可能因出现预期外位置的异常导致失败,这是 ERROR 级别的。

注意:当 WARNING 和 ERROR 在无需处理时,不应该记录。如 Java 中 ClientAbortException 异常,一般来说是不需要处理的

业务使用 INFO、技术使用 DEBUG

INFO 日志应该像一本书,它应该告诉你发生了什么:

INFO  | User registered for newsletter. [user="Thomas", email="thomas@tuhrig.de"]
INFO  | Newsletter send to user. [user="Thomas"]
INFO  | User unsubscribed from newsletter. [user="Thomas", email="thomas@tuhrig.de"]

DEBUG 日志应该描述发生该过程的工作原理:

DEBUG | Saved user to newsletter list. [user="Thomas", email="thomas@tuhrig.de"]
DEBUG | Send welcome mail. [user="Thomas", email="thomas@tuhrig.de"]
INFO  | User registered for newsletter. [user="Thomas", email="thomas@tuhrig.de"]
DEBUG | Started cron job to send newsletter of the day. [subscribers=24332]
INFO  | Newsletter send to user. [user="Thomas"]
INFO  | User unsubscribed from newsletter. [user="Thomas", email="thomas@tuhrig.de"]

参考链接

  • https://tuhrig.de/my-logging-best-practices/