一般前端开发同学,对日志其实不太敏感,毕竟前端大多数情况下,不太关心日志。即使有,也可能调用一些第三方的统计,比如百度统计或者别的等。在 Node.js(下文中简称node) 推进过程中,也发现我们平常打日志太随意,该打的日志没有打,打的一些关键日志缺少必要上下文信息,导致在线上定位问题的时候很困难。
本文主要梳理了目前我们团队在nodejs开发中日志方面存在的问题,以及通过统一日志规范,希望达到什么样的效果。
问题
目标
实现方案
日志类型
参考一些日志的最佳实践,目前将node日志分为如下几种类型(scope):
日志级别
只使用 FATAL、ERROR、WARN、INFO 和 DEBUG 等级。
日志格式/字段
日志基础数据
目前使用的 node-bunyan 日志库,官方文档,基础字段包含如下:
日志扩展数据
下面定义的各个数据类型的扩展数据,不是 全部的字段,仅包含该日志类型下,必需的字段。这些必需的扩展字段,需要在 ELK 中建立索引,方便定位各种问题。
{
///////////// 基础数据 ////////
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?include-query",
//客户端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:
开发同学在打日志时,应该谨慎的选择级别,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'});
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持亿速云。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。