Logging 的最佳實踐

Logging Best Practice

事先申明,此篇文章只是自己看到的各式文章中,擷取個人覺得不錯的部分。

Log after, not before

在執行後才 log,可以表明之前的操作是成功的。如果 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")

Separate parameters and messages

分離錯誤訊息和參數,不要將參數內容放到錯誤訊息之中。

// 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)

Distinguish between WARNING and ERROR

Log 機制通常都會有明確的 level,分別是 ERROR 和 WARNING。但是通常程式上常常會混用。覺得的確是滿需要去注意的部分。

如果今天操作是可以執行,但是會有一些 issues 那就是 - 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)
}

INFO is for business, DEBUG for technology

INFO 的內容應該要像是一本書,告訴你發生了什麼,而不需要如何發生。所以建議 INFO 應該是要記錄商業相關的 log,DEBUG 才比較是技術方面的資訊。

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 | 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"]

Reference