-
Notifications
You must be signed in to change notification settings - Fork 67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
如何設計/使用 logger? #21
Comments
I am more leaning toward the first option. The code could be cleaner. |
我提供一下我習慣使用的方式:
簡單來說就是只有一個 logger ,但每個 request 都會產生一個屬於自己的 log entry ,這些 log entry 實際上使用了相同的 logger ,在 request 結束前都是使用這個 entry 來記錄發出 log 時所需要的資料,不同的 request 間不會互相影響使用,比較接近第一個做法。 這個做法的好處是如果一個地方出錯時,你可以知道一路上他經過 function 時所帶的參數,找 bug 會變得很輕鬆。 |
|
我原先的想像是沒有context 像是 syslog 那樣子的設計,但是你提到紀錄 context 的設計我認為很好。 不過紀錄 context 的話可能有兩個層次的 context 要考慮,一個是 process 等級的 context, 另外一個是 request 的 context 。 |
原生的 context 套件在使用 WithValue 時需要注意一下,它內部的實作就是個俄羅斯娃娃,而且容易演變成一個 |
的確沒有處理好容易會引發這個問題,這邊我可以研究一下,寫個範例跟大家討論看看,是否可以這樣處理 |
目前在code裡面還看到滿多log的指令的,感覺可以減少一些 我覺得只要request進來後log一下相關資訊一次就好 例如urlpath method ip 之類的 之後如果發生error的話再 log 即可(覺得可以只在 usecase 層 log 就好) 還有建議可以用 defer 來處理 就不必在每個 if err != nil 的地方都各自弄
|
我不推薦 error 時只在 usercase log 一次的作法,原因是 route 層也有可能在解析 request 的 parameter 或是 body 時出錯。
這個也不推薦,defer 的話無法知道實際發生錯誤的行數。 |
抱歉我前面可能有點沒講清楚,我的想法是 delivery 層級的錯誤應該都很類似,譬如你說的解 param 出現錯誤 或著是 middleware 中做 permission check的部分出錯
是說這個可以舉個例子嗎?
以上主要是想減少log的程式碼散落各處 |
疑惑為什麼同一個 function 出現的 error 會差滿多這件事,與此相關想問要怎麼區分 error 發生在上面的 DoSomethingA 還是下面的 DoSomthingA ?
這樣 log 只能知道 call Do 的時候發生了甚麼,但是無法知道 call DoSomethingA 時用了甚麼 parameter,發生了甚麼。
還有一個問題是:有些 function 出 error 是我們期待有可能會發生並且不影響實際執行的,那這時候的 log level 應該要使用較低層級的 level ,或是特別嚴重的 error 時要提高 log level ,但要這樣做的話可能又需要在 defer 裡額外的邏輯判斷。 |
Log Level 的部分一開始是參考 RFC 5424 進行設計的。 |
我打錯了 "一個func下面呼叫的不同func" 所以應該是 DoSomethingA 和 DoSomethingB
如同這邊的 defer 會把 func param 的相關資訊包起來
那我覺得這個像是 warning,可以多打沒關係
或是定義個
defer 時候就可以用個統一個func來處理了 |
Golang 中應該會滿常碰到 function 中會重複呼叫同一個 function 的情形,尤其是當系統變的龐大且複雜的時候就更容易產生以下的關係:
這時候看到有一個 log 顯示 C function 出錯,但是無法直接知道到底是 B call 的時候 C 出錯了,還是 D call 的時候 C 出錯了,就必須要使用 log 中的資訊去慢慢還原,更不用說以下情形:
這時候就只能祈禱 DoSomething 不是 external package 或是 golang origin package 中的 function 了。
這有一個很大的問題上面也提到了,當 DoSomethingA 和/或 DoSomethingB 是使用外部的 function 的時候就無法保證這件事,既然如此,這樣是不是應該要在出錯的當下記錄起足以 debug 的資訊會比較好? |
同意 常常會有這種情況
就可以避免
如果B與D也都有把自己的資訊包起來傳回給A 其實我提的 defer 只是想把那些的紀錄資訊搬到被呼叫的 function 裡面
前面那個 defer 只能處理內部function沒錯 當使用的 DoSomething 是外部 function
但如果真的在很多不同function都會呼叫到DoSomething ,且遇到每個 DoSomething 都必需要記錄當下 param and err 資訊 那我認為把 DoSomething 外面再包一層自己的 func 也是能處理掉重複code的情況
總結一下 我只是想避免太多重複的 log 資訊記錄,把 log 資訊記錄這個行為搬到該function內而已XD |
同意只需要做一次 log 系統邊界處 用例層的物件 因為我自己實作 ddd 整潔架構的時候
我自己定義 系統核心 如果需要支援多種 驅動方式(grpc cli ...)
用 defer 來處理 err 或 log 現在很多編輯器都支援 用 defer 來寫, 就需要另外看 log 的訊息 |
這應該所有語言都會遇到 重複呼叫的問題 照我前面所說 依照這例子 並且在 err 內寫出詳細的訊息 老實說 標準庫的 error pkg 功能很弱 err 套件 我自己 想去使用的有 |
從來沒用過這種東西XD |
這個 ISSUE 目前還有在更新嗎? 不然兩週後要把他先關掉了喔? |
看起來 logger 的部分有兩種做法:
以記憶體使用而言,在 Logger 裡面沒有存放東西的前提下應該是相等(都是零)。
以維護的複雜度而言,其實後面修改 internal logger 裡的東西就行了。
日後如果確定將 #16 的 layout 作法合併進來後還感覺到有不足的地方時再繼續進行討論。
Originally posted by @PichuChen in #16 (comment)
The text was updated successfully, but these errors were encountered: