標記全鏈路日誌有助於更好的解決 bug 和分析接口性能,本篇文章使用 node
來做爲示例javascript
使用 requestId
惟一標識每一個請求,有時它又被稱爲 sessionId
或者 transactionId
。java
requestId
標記每次請求全鏈路日誌,所要標記的日誌種類如上所示X-Request-Id
(X-Session-Id) 標記在請求頭中,在整個鏈路進行傳遞async function context (ctx: KoaContext, next: any) { const requestId = ctx.header['x-request-id'] || uuid() ctx.res.setHeader('requestId', requestId) ctx.requestId = requestId await next() } app.use('/todos/:id', (ctx) => { User.findByPk(ctx.body.id, { logging () { // log ctx.requestId } }) })
如上,在每次數據庫查詢時手動對 requestId
進行標記過於繁瑣。能夠統一設計 logger
函數進行標記node
具體代碼可見我一個腳手架中的 logger.tsgit
這裏使用了流行的日誌庫 winston (13582 Star)github
import winston, { format } from 'winston' const requestId = format((info) => { info.requestId = session.get('requestId') return info }) const logger = winston.createLogger({ format: format.combine( format.timestamp(), requestId(), format.json() ) })
或者說如何在 logger.ts
如何得到整個請求響應生命週期中的 requestId
redis
具體代碼可見 session.tssql
import { createNamespace } from 'cls-hooked' const session = createNamespace('hello, world') export { session }
sentry
(警報系統) 中收到一條異常警報時,經過 requestId
能夠在 elk
(日誌系統) 中獲取到關於該異常的全部關鍵日誌 (sql, redis, 關鍵函數的輸入輸出)requestId
能夠在 elk
中分析該請求的全部數據庫查詢時間,請求響應時間,緩存是否命中等指標另外能夠經過 zipkin 來追蹤全鏈路耗時。typescript
<hr/>數據庫
歡迎關注個人公衆號山月行,在這裏記錄着個人技術成長,歡迎交流json