摘要:日志規范一般前端開發同學,對日志其實不太敏感,畢竟前端大多數情況下,不太關心日志。本文主要梳理了目前我們團隊在開發中日志方面存在的問題,以及通過統一日志規范,希望達到什么樣的效果。日志格式字段日志格式統一采用,便于解析處理。
nodejs 日志規范一般前端開發同學,對日志其實不太敏感,畢竟前端大多數情況下,不太關心日志。即使有,也可能調用一些第三方的統計,比如百度統計或者別的等。在 Node.js(下文中簡稱node) 推進過程中,也發現我們平常打日志太隨意,該打的日志沒有打,打的一些關鍵日志缺少必要上下文信息,導致在線上定位問題的時候很困難。
本文主要梳理了目前我們團隊在nodejs開發中日志方面存在的問題,以及通過統一日志規范,希望達到什么樣的效果。
問題node日志不規范,打日志太隨意
沒有良好的日志格式、約定的字段,在 ELK 里不能很好的解析&檢索 (PS: ELK文章在路上)
由于node對接的后端服務化,調用鏈不清晰,定位問題困難
數據部門對node日志的使用,沒有明確的記錄。node修改了日志,導致統計數據異常
目標規范日志打印字段&格式,便于 ELK 檢索
增強node上下游(nginx/后端)日志格式,加入惟一 requestId,方便微服務下定位問題
統計應用運行情況,性能數據
維護數據部門對node日志的使用情況
實現方案 日志類型參考一些日志的最佳實踐,目前將node日志分為如下幾種類型(scope):
desc: 系統啟動、運行過程中,打的日志,表明系統的一些啟動日志、啟動參數等,也包含在 不能 捕獲到http上下文的時候,打的日志
stat: 系統性能統計日志,應用會定時收集一些性能信息,便于查詢應用當前狀態
visit: 每個http請求相關的日志,會包含惟一的 requestId,定位該請求相關的所有日志
biz: 業務數據相關日志,主要提供給數據統計使用
日志級別只使用 FATAL、ERROR、WARN、INFO 和 DEBUG 等級。
日志格式/字段FATAL - 導致程序退出的嚴重系統級錯誤,不可恢復,當錯誤發生時,系統管理員需要立即介入,一般應用代碼 不 使用。
ERROR - 運行時異常以及預期之外的錯誤,也需要立即處理,但緊急程度低于FATAL,當錯誤發生時,影響了程序的正確執行。需要注意的是這兩種級別屬于服務自己的錯誤,需要管理員介入,用戶輸入出錯不屬于此分類,請求后端、讀文件、數據庫等超時、返回錯誤結構,屬于ERROR
WARN - 預期之外的運行時狀況,表示系統可能出現問題。對于那些目前還不是錯誤,然而不及時處理也會變成錯誤的情況,也可以記為WARN,如磁盤過低。
INFO - 有意義的事件信息,記錄程序正常的運行狀態,比如收到請求,成功執行。通過查看INFO,可以快速定位WARN,ERROR, FATAL。INFO不宜過多,通常情況下不超過 DEBUG 的10%。
DEBUG - 與程序運行時的流程相關的詳細信息以及當前變量狀態。
日志格式統一采用 JSON ,便于 ELK 解析處理。
日志中的各個字段的值,都應該盡量使用 英文 ,不使用中文。
日志具體字段,分為 基礎數據 + 擴展數據。基礎數據,是底層日志框架自帶的,所有日志都會包含。擴展數據,不同類型的日志,包含不同的字段。
目前使用的 node-bunyan 日志庫,官方文檔,基礎字段包含如下:
v: integer 。bunyan的日志版本號
level: integer。日志級別對應的數字
name: string。服務名
hostname: string。主機名
pid: integer。進程號
time: string。UTC 格式的日期
msg: string。日志主體信息
下面定義的各個數據類型的擴展數據,不是 全部的字段,僅包含該日志類型下,必需的字段。這些必需的擴展字段,需要在 ELK 中建立索引,方便定位各種問題。
desc類型日志,擴展字段:TODO
stat類型日志,擴展字段:{ perf: {rss: xxxx, cpu: xxx} }
visit類型日志,擴展字段:
biz
{
///////////// 基礎數據 ////////
v: 1,
level: 20,
///////////// 擴展字段 ////////
// 標志日志類型
scope: "visit",
//事件類型:在 visit 的日志類型下,還會細分不同的事件,比如 client-req、client-res、 普通trace、請求后端service-start, service-end, service-err等。
event: "trace",
//客戶端ID,追蹤用戶、設備會話。在web端,可以是長期的cookie;在APP端,可以是device-id等
rrdid: "",
//本次請求的惟一ID,串聯本次請求的所有相關日志
req_id: "some-uuid-for-request",
//本次請求的用戶ID
uid: "",
//本次請求的客戶端相關數據,通過 ctx.logger 打日志時,自動加上
d: {
url: "/some/path");,
//客戶端ip
ip: "10.138.10.1",
//客戶端的 userAgent
ua: ""
},
//本次node請求的處理時間,毫秒
tm: 500,
//該日志相關的上下文數據,盡量拼成一個字符串,放在 extra 里
extra: "",
//ERROR 級別日志,最好包含error相關信息,比如請求后端相關參數等
err: {
msg: "",
stack: ""
},
//調用后端服務相關參數和響應
service_req: {
host: "",
path: "",
payload: ""
},
service_res: {
//http狀態碼
http_code: 200,
//響應時間
tm: 100,
//響應的body
body: "",
//異常信息
err: ""
}
}
什么時候打日志
開發者目前只關心 visit 類型的日志,即和某一次http請求相關聯的日志。desc和stat類型的日志,統一由開發框架封裝后實現,業務開發 不用 關心。下面講的,都是針對 visit 類型的日志。
一次http請求,會打出一系列相關聯的日志。在node層,通常一次請求,會進一步轉發給N個后端服務,然后對后端數據進行一些處理、合并等操作,最后渲染頁面或是輸出JSON。因此,一次請求相關的日志,大體分為以下幾種 event:
client-req: client請求到達node層,統一由框架打日志,開發 不 關心
service-start: node對某個后端服務發起請求,由通用請求庫負責打日志,開發 不 關心
service-end: node請求某個后端服務結束,由通用請求庫負責打日志,開發 不 關心
service-err: node請求后端服務異常,由通用請求庫負責打日志,開發 不 關心。調用后端服務異常,日志級別為 WARN,不是 ERROR
trace: node中業務層打的日志,如果異常,能幫助定位本次請求相關問題
client-res: 結束client的請求,打印本次請求的http code,本次請求處理時間等,由框架統一打,開發 不 關心
開發同學在打日志時,應該謹慎的選擇級別,INFO(含)級別以上,都應該能對定位問題、具體業務統計需求有要求,才能使用。大部分情況下,可以使用 DEBUG 級別,線上 不會 開啟DEBUG級別。
具體方法調用針對打印 visit類型的日志,調用 ctx.logger(基于Koa的框架) 屬性打日志,推薦參數都傳遞 JSON,具體方法如下:
ctx.logger.debug({msg: "", "extra": "a=1 b=2 c=value"});
ctx.logger.info({msg: "xxx", "extra": "其他的額外字段"});
ctx.logger.warn({msg: "xxx", "extra": "額外上下文數據"});
//ERROR級別日志,應該提供 Error 對象
ctx.logger.error({msg: "xxx", err: error, extra: ""});
注意1,額外的參數,推薦存放在 extra 字段中,統一拼成 string;如果確實有必要多帶帶出每個字段, 禁止 額外的參數占用上述通用字段名!!
注意2,基礎數據中的msg字段,禁止 包含具體的上下文數據,和該日志相關的上下文數據,應該拼成字符串,放在多帶帶的 extra 字段中。比如,某個用戶登錄接口,希望統計調用次數,可以這樣打印:
ctx.logger.info({msg: "user login", "extra": "mobile=18712387101 code=xxxx k3=value3"});
參考資料
最佳日志實踐(v2.0)
Node 框架接入 ELK 實踐總結
大搜車NodeJS日志規范化與分析監控
請自查!這些優秀日志實踐準則,你做到了幾點?
日志最佳實踐
When to use the different log levels
Java 日志管理最佳實踐
關于日志打印的幾點建議以及非最佳實踐
日志記錄最佳實踐
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/6964.html
摘要:在貓屎氤氳的霧氣里角仰望天花板,手機微信提醒這次構建成功或失敗,并附帶污言穢語。這時他可以開始往工位走,坐下時,微信又會提醒本次部署到成功或失敗。與企業微信的集成在決定使用之前,需要知道的是,是一個高度依賴社區的項目。 前言 相信我,一切事情的發生都是趕鴨子上架,沒有例外。人類所有偉大的變革都是迫不得已,可又是那么順其自然。比如容器(docker)技術的誕生,比如箭在弦上的創業,比如野...
摘要:環境要求由,和容器組成使用日志收集器將日志發送到。若使用自己的部署,分析和可視化日志的概念保持不變。日志可視化以索引數據為基礎創建豐富的可視化和儀表板的能力而聞名,事實上,得到這些數據并不容易。 昨天小數分享的使用ELK處理Docker日志(一)很受歡迎,今天迫不及待的帶來第二篇,側重于分析和可視化,期待給您帶來幫助:) 噓,聽說數人云工程師們在奧斯汀DockerCON2017買了D...
摘要:在中默認開啟端口用于偵聽發送過來的日志報文。至此,在中如何部署一套完整系統已經介紹完了,下面我將介紹如何將容器日志發送到中。下面我將介紹如何收集容器日志。目前日志顯的雜亂無序。,現在我們再去查看發現我們的容器日志已經展示在這里了。 相信大家對于容器和 docker 這個概念并不陌生,很高興的是 docker 為我們提供了多種log-driver。 showImg(https://se...
摘要:但是往往越簡單的東西越容易讓我們忽視,從而導致一些不該有的發生,作為一名嚴謹的程序員,怎么能讓這種事情發生呢所以下面我們就來了解一下關于日志的那些正確使用姿勢。級別表示出現了嚴重錯誤,程序將會中斷執行。 前言 關于日志,在大家的印象中都是比較簡單的,只須引入了相關依賴包,剩下的事情就是在項目中盡情的打印我們需要的信息了。但是往往越簡單的東西越容易讓我們忽視,從而導致一些不該有的bug發...
閱讀 1526·2021-11-25 09:43
閱讀 4069·2021-11-15 11:37
閱讀 3201·2021-08-17 10:13
閱讀 3509·2019-08-30 14:16
閱讀 3540·2019-08-26 18:37
閱讀 2498·2019-08-26 11:56
閱讀 1139·2019-08-26 10:42
閱讀 617·2019-08-26 10:39