最近接手一份代碼,采用的是golang revel web框架,期間不停的有運營,測試來騷擾,新手必須要老實,有問必答,來一個我就去日志文件查看一下,“尼瑪,不停的刷屏,怎么看,大概什么時間,給個訂單號唄”,這是我做的最多的事情。實在是看的心累,日志記錄內容太少,關鍵字太少,并發請求太多,分不清是不是一個請求的。程序員得用程序解放勞動力,怎么能浪費在看日志的時間上。有了需求點,那么對日志的記錄就得規范。總結幾個記日志的關鍵點。
1. 入口打印請求參數,出口打印返回值。--便于和前后端扯皮,什么參數傳錯了,沒返回等等
2.日志關鍵字明確,時間,級別,行號函數名。--便于grep 各種搜索,隨時定位代碼
3.一個請求有一個唯一請求ID ,一路追蹤,無論多少次rpc,或者函數調用
1.2 這兩個問題很好解決,第3個就很麻煩,在網上查了很多問題資料,看到一個google的分布式跟蹤的,但這個主要是基于rpc 的,但是我想的是基于函數調用的,一個請求,無論調用多少層函數,那么函數里面日志都攜帶一個唯一表示此請求的ID,別的請求調用的就攜帶別的ID,不能重。 鑒于需求是這樣,那么我想到一個方案,每一次函數調用時都多傳一個ID,傳入log 這樣,但這樣太麻煩了,還要改動所有log 調用的地方,不可取。其實這個問題,仔細分析變成了找多個請求調用多個函數調用的共同點, 什么是共同的1.請求是共同的,但這個傳入,log 侵入代碼成本太高, 還有一個是共同的,順著函數堆棧往上追,都能追到請求處理的初始函數,但我們還要區分不同請求,不能只是追蹤調用路線,想到一個辦法,就是能不能根據每一個調用堆棧分配一個ID,在各個字函數里面能獲取所在堆棧的ID,但這個只是我的設想不知道,怎么實現。?
終于找到了還有一個共同點,每一次請求都是go 一個協程,而里面的調用各個函數都是在這個協程里的,這樣只需要獲取所在協程的ID 不就是唯一對應這個請求嗎。 問題終于解決了。
下面是golang 獲取協程ID的一些方法 資料。
1. https://www.zhihu.com/question/39863941/answer/83575802?
2.http://blog.sgmansfield.com/2015/12/goroutine-ids/
3.https://github.com/huandu/goroutine