nodejs之日志记录 node 日志框架
qiyuwang 2024-10-31 15:52 29 浏览 0 评论
前言
近期有新的项目上线,基于nodejs的前后端分离方案,借此机会又顺便深入学习了一下nodejs服务日志记录相关的问题和注意点。对于前端开发人员来讲,如果你的开发工作不涉及服务端的话对日志没有太多概念,尤其是一个服务的运行日志。虽然现在前端(客户端层面)也会涉及一些比如js运行异常日志的收集,但最终还是会上报到后台系统,所以,如果你的开发工作涉及后端服务,如何更合理的记录日志是非常有必要学习和运用的。
原则
首先,要知道记录日志是为了方便我们追踪服务运行状态,在服务出现异常波动时定位问题,什么时候需要记录,记录什么信息,记录什么级别,怎么去分类,这些至关重要。我认为要遵循以下几个要点:
- 分类,要合理的进行日志分类,以方便定位问题的所在范围;
- 错误及时记录,有预期的调用错误或者运行错误要及时记录;
- 重要信息记录,一些重要的接口调用要记录,如接口响应时间;
- 减少非必要的记录,每一次的输出都有IO操作,不能因日志影响性能;
log4js
log4js是java语言中常用的log4j日志组件的 nodejs版,其支持 日志分级,日志分类,日志落盘,配置简单易上手,是近些年大家常用的日志记录模块。
日志等级
{
ALL: new Level(Number.MIN_VALUE, 'ALL', 'grey'),
TRACE: new Level(5000, 'TRACE', 'blue'),
DEBUG: new Level(10000, 'DEBUG', 'cyan'),
INFO: new Level(20000, 'INFO', 'green'),
WARN: new Level(30000, 'WARN', 'yellow'),
ERROR: new Level(40000, 'ERROR', 'red'),
FATAL: new Level(50000, 'FATAL', 'magenta'),
MARK: new Level(9007199254740992, 'MARK', 'grey'),
OFF: new Level(Number.MAX_VALUE, 'OFF', 'grey')
}
以上是日志等级的图示,权限代码和输出颜色,>=所设定的等级日志才会被输出,我们在使用时要根据自己的需求配置。
日志分类
除了设定等级,为了方便我们查阅日志,还需要进行日志分类,log4js 2.0之后 categories和 appenders 需要组合配置,我在项目中分类配置如下:
appenders:{
"rule-console": {"type": "console"},
"errorLogger": {
//设置类型为 dateFile
"type": "dateFile",
// 配置文件罗盘地址并且名为 app_error.log
"filename": "/data/logs/app_error.log",
// 指定编码格式为 utf-8
"encoding":"utf-8",
// 单文件的大小,超过会创建新的文件
"maxLogSize": 104800,
//保留最新的文件数
"backups": 5,
//设置日志输出格式
"layout":{
"type": 'pattern',
"pattern": '%h %d{yyyy-MM-dd hh:mm:ss} | %p | %z | %c | %m%n'
}
},
"infoLogger": {
"type": "dateFile",
"filename": "/data/logs/app_info.log",
"encoding":"utf-8",
"maxLogSize": 104800,
"backups": 5,
"layout":{
"type": 'pattern',
"pattern": '%h %d{yyyy-MM-dd hh:mm:ss} | %p | %z | %c | %m%n'
}
}
},
categories: {
"default": {"appenders": ["rule-console"], "level": "all"},
"infoLogger": {"appenders": ["infoLogger"], "level": "info"},
"errorLogger": {"appenders": ["errorLogger"], "level": "error"}
}
layout
上述配置中layout 是定义日志输出的具体字段和格式,这个要根据自己实际情况去约定,下面列出pattern 中的具体解释:
- %r 日志输出时间,以 toLocaleTimeString 函数格式化
- %p 日志等级
- %c 日志分类
- %h 访问计算机的 hostname
- %m 打印的日志主题内容
- %n 换行标识
- %d 日志输出日期 ( 默认以 ISO8601 方式格式化 )可自定义输出类型 %d{yyyy-MM-dd hh: mm:ss},输出 2020-12-01 15:42:18
- %z 记录进程 pid 号 ( 数据来自 node 方法 process.pid )
- %x{} 输出自定义 tokens 中的项目,例如上述例子中的 user
- %[ 想要输出的内容 %] 用来给被扩起来的内容着色,颜色和日志 level 有关
注意点
上述配置在启动单进程时可正常输出日志,但是如果你是通过pm2 启动集群(Cluster)模式,日志会有丢失现象,原因是 Log4js 在 Cluster 模式下,worker 将日志发送至 master,master 实现日志写入文件。但在 PM2 Cluster 模式下,所有进程皆为 worker,log4官方给出了解释和解决办法:
- pm2 (boolean) (optional) - set this to true if you’re running your app using pm2, otherwise logs will not work (you’ll also need to install pm2-intercom as pm2 module: pm2 install pm2-intercom)
- pm2InstanceVar (string) (optional, defaults to ‘NODE_APP_INSTANCE’) - set this if you’re using pm2 and have changed the default name of the NODE_APP_INSTANCE variable.
我们需要安装 pm2-intercom ,在配置中增加配置如下即可解决
Log4JS.configure({
pm2: true,
pm2InstanceVar: 'INSTANCE_ID'
});
完成以上配置后,我们还需要封装一个日志工具方法,供具体业务代码中调用,以下是我封装后的:
const log4js = require('log4js')
const config = require('../../config');
log4js.configure(config.log4js);
//调用预先定义的日志名称
let errorLogger = log4js.getLogger('errorLogger');
let infoLogger = log4js.getLogger('infoLogger');
let logger = {};
//getIp
const getIp = function(req) {
let ip = req.headers['x-real-ip'] ||
req.headers['x-forwarded-for'] ||
req.socket.remoteAddress || '';
if(ip.split(',').length>0){
ip = ip.split(',')[0];
}
return ip;
};
//封装错误日志,包含 ctx 信息
logger.logError = (ctx, err) => {
let logText = new String();
if(ctx && ctx.request){
//客户端ip
logText += getIp(ctx.request) +" | ";
//访问方法 + 地址
logText += ctx.request.method +" | "+ctx.request.originalUrl+' | ';
}
//错误信息
logText += "errInfo [" + err.name +" , "+err.message+" , "+err.stack+ "] ";
errorLogger.error(logText);
}
//Error日志,记录必要错误信息
logger.error = (info, err) => {
errorLogger.error(info + " , errInfo [" + err.name +" , "+err.message+" , "+err.stack+ "] ");
}
//封装访问日志
logger.logAccess = (ctx, resTime) => {
if(ctx && ctx.request){
let logText = new String();
//客户端ip
logText += getIp(ctx.request);
//访问方法 + 地址
logText += ' | '+ctx.request.method +" | "+ctx.request.originalUrl;
//请求状态
logText += ' | '+ctx.status;
//响应时间
logText += ' | '+resTime + "ms";
//userAgent
logText += ' | '+JSON.stringify(ctx.request.header['user-agent']);
if(ctx.status !== 200){
//请求参数
if (ctx.request.method !== 'GET') {
logText += ' | ' + 'request body [' + JSON.stringify(ctx.request.body)+']';
}
}
infoLogger.info(logText);
}
}
//info日志,记录必要信息
logger.info = (info) => {
if (info){
infoLogger.info(info);
}
}
module.exports = logger;
小结
本文主要记录了我在项目中使用的日志工具和具体配置方法,在生产环境中还是需要多关注服务本身的性能,不能因记录日志影响了服务性能,log4是我目前使用的,可能你在使用其他工具或者有更好的实践经验,欢迎跟我一起分享讨论。
相关推荐
- 你真的会用Word画线吗?(word画线技巧)
-
【你真的会用Word画线吗?】①输入三个“=”回车,是一条双直线;②输入三个“”,回车,就是一条波浪线;③输入三个“”回车,就是一条虚线;④输入三个“-”,回车,就是一条细直线.....新技能get√...
- 「干货」Word技巧知识——进阶篇(2)
-
Hello,大家好,我是无拘无束的分享知识,每天跟大家分享点有用的知识,话不多说。感兴趣的朋友可以点赞、关注、收藏哦。1.将word文档中的硬回车全部消除从事来稿阅读、编辑的工作者,最头痛的事就是打...
- 办公室人员必备! Word快捷键大全(办公中常用的快捷键)
-
【Word里超简单的画线方法!】简历、总结里文字太多怎么办?用线条分隔!Word画线秘籍:①输三个"="回车,是一条双直线②输三个"~"回车,是一条波浪线③输三个"-"回车,就是一条细直线。(来源...
- Word笔记大全(详细步骤)(word怎么写笔记)
-
字处理一、文档的基本操作1.打开/新建2.快速新建ctrl+n3.利用模板创建文件--新建--选择模板officeplus4.保存5.保护文件--信息--保护文档--限制编辑--对话框:勾选每一项...
- 如何删除word文档空白页?(怎么删除word里的空白页?)
-
在日常办公或学习中,我们经常会遇到Word文档中出现空白页的情况,这不仅影响文档的美观,还可能造成打印浪费。下面,我将为大家详细介绍如何在Office和WPS中的Word里轻松删除这些恼人的空白页。...
- Win11学院:如何在Windows 11装机时禁用BitLocker磁盘加密
-
IT之家5月7日消息,微软计划在Windows1124H2装机过程默认启用BitLocker加密,对于用户来说有两方面的影响:其一是影响硬盘的性能,其二是用户如果没有解密密钥,可能...
- 办公小技巧:Word“安全模式”用通透
-
大家都知道Windows的安全模式。其实,Word也有安全模式。那么,Word的安全模式又是什么?何时使用这种模式?使用这种模式有何限制?当Word运行中遇到问题需要启用安全模式运行时,如何按照软件给...
- 段落结束敲回车,下一段格式变样了怎么处理#每天学习一点点
-
段落换行后的格式发生变化。段落结束敲回车键,下一段格式变样了怎么处理?大家有时候遇到文章敲回车键,在下一段打字之后会发现这一段的样子就会和之前的段落不一样,当然可以调整一下或者用格式刷刷一下,但是稍微...
- 硬回车、软回车等介绍(硬回车键和软回车键)
-
1.硬回车:硬回车占两个字节,在word中敲击Enter键即可输入硬回车,硬回车是真正的段落标记,在两个硬回车之间的文字自成一个段落。代码是^p(小写)。2.软回车:用Shift+Enter产...
- Word里超简单的画线方法!(word中如何画线条)
-
小厅分享【Word里超简单的画线方法!】简历、总结里文字太多怎么办?用线条分隔!Word画线秘籍:①输三个"="回车,是一条双直线②输三个"~"回车,是一条波浪线③输三个"-"回车,就是一条细直线...
- Word 如何更改图片、删除与删除背景,勾选图片等问题
-
如果插入到Word文档中的图片想另外换一张,更换方法有两种,一种是把原图删除另外插入一张,另一种是直接更换图片。Word2016提供了更改图片的功能,用此功能更换图片会自动把原图删除,就像...
- Word中批量删除空行(多种方案)(批量删除word中的空行)
-
如下图,在Word文档中存在大量空行(回车),为了文档整洁,需要批量取消这些回车;方法一Ctrl+h,在查找内容中输入”^p^p”,在替换为输入”^p”,单击全部替换即可(^符号在英文输入法下按Shi...
- Word文档如何取消自动编号?(word文档如何取消自动编号功能)
-
在word文档中,当我们编辑有序号的文本内容时,word会自动识别给文本编号,如果直接删除序号再按回车键,序号又会自动填充。但有时候我们并不需要它自动编号或不喜欢它的编号格式,如何才能取消word自动...
- 最全的Word知识点,抓紧时间收藏起来
-
Word知识点1.1word工作界面Word2010的窗口组成∶窗口分标题栏、菜单栏、常用工具栏、格式工具栏、标尺、编辑区滚动条、状态栏、任务窗格。1.标题栏∶显示所编辑的文档名和程序名称。单击标题...
- Word中的页眉横线就是删不掉?其实按下这个键,1秒就能去除
-
不知道大家在用Word的同时,有没有遇到过难删除的页眉横线呢?以前小编就是遇到这条横线,不得已将里面的文字复制到一个新的文档中,如今终于知道该怎样删除这条横线了,下面我们就来看看删除方法。一、删除页眉...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- navicat无法连接mysql服务器 (65)
- 下横线怎么打 (71)
- flash插件怎么安装 (60)
- lol体验服怎么进 (66)
- ae插件怎么安装 (62)
- yum卸载 (75)
- .key文件 (63)
- cad一打开就致命错误是怎么回事 (61)
- rpm文件怎么安装 (66)
- linux取消挂载 (81)
- ie代理配置错误 (61)
- ajax error (67)
- centos7 重启网络 (67)
- centos6下载 (58)
- mysql 外网访问权限 (69)
- centos查看内核版本 (61)
- ps错误16 (66)
- nodejs读取json文件 (64)
- centos7 1810 (59)
- 加载com加载项时运行错误 (67)
- php打乱数组顺序 (68)
- cad安装失败怎么解决 (58)
- 因文件头错误而不能打开怎么解决 (68)
- js判断字符串为空 (62)
- centos查看端口 (64)