# Logging 的最佳實踐

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

### 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

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