标记全量链接日志有助于更好的解决bug和分析接口性能。本文使用node作为示例代码示例。本文地址为github。当一个请求来的时候,会生成什么?日志本次请求报文本次请求涉及的数据库操作本次请求涉及的缓存操作本次请求涉及的服务请求本次请求遇到的异常本次请求执行的关键函数本次请求对应如何查询响应体本次所有日志来自请求到响应链接使用requestId来唯一标识每个请求,有时也称为sessionId或transactionId。使用requestId标记每个请求的完整链接日志。需要标记的日志类型如上所示。通过在请求头中标记X-Request-Id(X-Session-Id),在整个链路中传输异步函数上下文(ctx:KoaContext,next:any){constrequestId=ctx.header['x-request-编号']||uuid()ctx.res.setHeader('requestId',requestId)ctx.requestId=requestIdawaitnext()}app.use('/todos/:id',(ctx)=>{User.findByPk(ctx.body.id,{logging(){//logctx.requestId}})})以一种不那么侵入的方式标记每个请求的方式如上,每次数据库都手动标记requestId太麻烦了查询。记录器功能可统一设计用于打标。具体代码可以看我的脚手架里的logger.ts。这里我使用流行的日志库winston(13582Star)importwinston,{format}from'winston'constrequestId=format((info)=>{info.requestId=session.get('requestId')returninfo})constlogger=winston.createLogger({format:format.combine(format.timestamp(),requestId(),format.json())})如何在logger.ts中绑定requestId或者如何获取整个请求响应中的requestIdlogger.ts中的生命周期。通过async_hooks,可以追踪异步行为的生命周期。通过cls-hooked可以获取到每个异步请求的requestId。具体代码可以看session.tsimport{createNamespace}from'cls-hooked'constsession=createNamespace('hello,world')export{session}sentry收到异常告警时如何受益于全链接日志(alertsystem),通过requestId可以获取elk(logsystem)中异常的所有关键日志(sql、redis、关键函数的输入输出)。当客户端请求太慢时,可以通过elk中的请求头获取requestId,分析所有请求的数据库查询时间,请求响应时间,是否命中缓存等指标查找对应的SQL语句和API执行的SQL语句条数,判断是否存在多余的SQL语句查询。另外,可以使用zipkin来跟踪整个链路的耗时。
欢迎关注我的公众号山月游,记录我的技术成长,欢迎交流