最近接了个新需求,让在服务器通过Nodejs去打日志文件,捕捉请求日志。。。

然后我就想到了log4js……

废话不多说,上代码

安装log4js

npm install log4js --save

对log4js不熟的查看文档 log4js;

在config文件夹下新建log_config.js文件:

var log4js = require("log4js");
var path = require("path");
var fs = require("fs");
var basePath = path.resolve(__dirname, "../logs");var errorPath = basePath + "/errors/";
var resPath = basePath + "/responses/";var errorFilename = errorPath + "/error";
var resFilename = resPath + "/response";/*** 确定目录是否存在,如果不存在则创建目录*/
var confirmPath = function(pathStr) {if (!fs.existsSync(pathStr)) {fs.mkdirSync(pathStr);console.log("createPath: " + pathStr);}
};
log4js.configure({appenders: {errorLog: {type: "dateFile", //日志类型filename: errorFilename, //日志输出位置alwaysIncludePattern: true, //是否总是有后缀名pattern: "-yyyy-MM-dd.log" //后缀,每小时创建一个新的日志文件},responseLog: {type: "dateFile",filename: resFilename,alwaysIncludePattern: true,pattern: "-yyyy-MM-dd.log"}},categories: {errorLog: { appenders: ['errorLog'], level: 'error' },responseLog: { appenders: ["responseLog"], level: "info" },default: { appenders: ['responseLog','errorLog',], level: 'trace' }},// pm2: true,// pm2InstanceVar: 'INSTANCE_ID',disableClustering: true
});
//创建log的根目录'logs'
if (basePath) {confirmPath(basePath);//根据不同的logType创建不同的文件目录confirmPath(errorPath);confirmPath(resPath);
}module.exports = log4js;

这段代码中有解释,照着官方文档配置就行;

在config文件夹下新建log.js文件:

var log4js = require("./log_config");var errorLog = log4js.getLogger("errorLog"); //此处使用category的值
var resLog = log4js.getLogger("responseLog"); //此处使用category的值var log = {};
log.i = function(req, resTime) {if (req) {resLog.info(formatRes(req, resTime));}
};log.e = function(ctx, error, resTime) {if (ctx && error) {errorLog.error(formatError(ctx, error, resTime));}
};//格式化请求日志
var formatReqLog = function(req, resTime) {let getClientIp = function (req) {return req.headers['x-forwarded-for'] ||req.connection.remoteAddress ||req.socket.remoteAddress ||req.connection.socket.remoteAddress || '';};let ip = getClientIp(req).match(/\d+.\d+.\d+.\d+/);var logText = new String();//访问方法var method = req.method;logText += "request method: " + method + "\n";//请求原始地址logText += "request originalUrl:  " + req.originalUrl + "\n";//客户端iplogText += "request client ip:  " + ip + "\n";//请求参数if (method === "GET") {logText += "request query:  " + JSON.stringify(req.query) + "\n";} else {logText += "request body: " + "\n" + JSON.stringify(req.body) + "\n";}//服务器响应时间logText += "response time: " + resTime + "\n";return logText;
};//格式化响应日志
var formatRes = function(res, resTime) {var logText = new String();//响应日志开始logText += "\n" + "*************** response log start ***************" + "\n";//添加请求日志logText += formatReqLog(res, resTime);//响应状态码logText += "response status: " + res.res.statusCode + "\n";//响应内容logText += "response body: " + "\n" + JSON.stringify(res.body) + "\n";//响应日志结束logText += "*************** response log end ***************" + "\n";return logText;
};//格式化错误日志
var formatError = function(ctx, err, resTime) {var logText = new String();//错误信息开始logText += "\n" + "*************** error log start ***************" + "\n";//添加请求日志logText += formatReqLog(ctx, resTime);//错误名称logText += "err name: " + err.name + "\n";//错误信息logText += "err message: " + err.message + "\n";//错误详情logText += "err stack: " + err.stack + "\n";//错误信息结束logText += "*************** error log end ***************" + "\n";return logText;
};module.exports = log;

这里边就是写个三个函数,

  1. 格式化请求日志 formatReqLog;
  2. 格式化响应日志 formatRes;
  3. 格式化错误日志 formatError;

在app.js中配置使用

const log = require("./config/log");
// logger
app.all("*", async (req, res, next) => {//响应开始时间const start = new Date();//响应间隔时间var ms;try {//开始进入到下一个中间件await next();//记录响应日志ms = new Date() - start;log.i(req, ms);} catch (error) {//记录异常日志ms = new Date() - start;log.e(req, error, ms);}console.log(`${req.method} ${req.url} - ${ms}ms-${res.statusCode}`);
});

代码没啥可讲的,照着使用就行,这里我来谈谈踩过的坑吧

故障1: pm2 + log4js启动项目时候报错

Nodejs application Error: bind EADDRINUSE when use pm2 deploy

sudo lsof -i -P | grep 3000

解决该问题戳这里;

故障2: log4js搭配pm2集群异常日志

参考如下链接:log4js搭配pm2集群异常日志的解决方案

这是pm2在cluster模式下启动,导致log4js不正常输出日志,有两种解决方案吗,

  1. 只需要在log_config.js里添加如下命令就行
disableClustering: true

i. 安装pm2的pm2-intercom进程间通信模块

ii. 然后需要在log_config.js里添加如下命令就行

pm2: true,
pm2InstanceVar: 'INSTANCE_ID'

iii. pm2.json 如下

{ "apps": [{ "name": "testing","script": "pm2.js","instances": 0,"instance_var": "INSTANCE_ID", // 添加这一行"exec_mode": "cluster"}]
}

两种解决方法的区别是:(摘自log4js作者的原话,能得到他的帮助,我特开心?)

 you don’t need `disableClustering` and `pm2` in your config.`pm2: true` turns on support for using pm2-intercom, `disableClustering: true` turns off all clustering support so it won’t use pm2-intercom.Use one or the other, but not both.

部署到服务器上就能正常输出日志了,如下

欢迎沟通交流

最后参考文章如下:

官方文档链接

pm2官方文档

pm2的用法解析

log4js

  1. log4js译文;
  2. log4js搭配pm2集群异常日志的解决方案
  3. PM2 && log4js && winston 日志管理
  4. vim的命令;
  5. log4js的配置;

再说打日志你不会,pm2 + log4js,你值得拥有相关推荐

  1. NODEJS项目实践0.4 [domain,pm2,log4js,md5]

    一.前言 ⋅⋅⋅上节我们基于mongo数据存取的操作,实现了用户注册.登录.退出功能,并应用了初级的权限验证.本节将处理nodejs异常情况.加密.日志及进程守护. git : https://git ...

  2. 玩转Nodejs日志管理log4js

    玩转Nodejs日志管理log4js 从零开始nodejs系列文章 从零开始nodejs系列文章,将介绍如何利Javascript做为服务端脚本,通过Nodejs框架web开发.Nodejs框架是基于 ...

  3. pm2 多个线程输出一个日志_PM2 源码分析

    近期有需求需要了解 PM2 一些功能的实现方式,所以趁势看了一下 PM2 的源码,也算是用了这么多年的 PM2,第一次进入内部进行一些探索. PM2 是一个 基于 node.js 的进程管理工具,本身 ...

  4. pm2日志文件过大问题解决

    输入指令查看当前磁盘容量   df -h 定位大容量磁盘位置  du -h --max-depth=1 解决pm2 日志文件过大问题 日志文件占用的磁盘容量,那我就尝试清除日志文件,看能否解决问题 1 ...

  5. Node.js学习笔记(九)#log4js日志管理

    目录 一.log4js简介 二.log4js使用[图片] 1.安装 2.导入 3.配置 4.添加实例 5.输出日志 三.log4js日志等级 四.log4js配置信息 1.appenders 输出源 ...

  6. log4js 关于 Appender 的介绍及回滚生成日志文件的方法 “dateFile ”

    Log4js - Appenders appender 将日志事件序列化为某种形式的输出.可以写文件,发送电子邮件,通过网络发送数据.所有的 appender 都有一个 type 来决定哪个 appe ...

  7. log4js linux,如何在项目中使用log4.js的方法步骤

    pm2中自带的日志内容是不能满足日常的需求的,因此需要在项目中加上日志管理,这里研究了下log4的使用方法,效果挺好的,想要查看的都可以找到,记录下简单的使用步骤 log4的配合 // config. ...

  8. nodejs之日志管理

    开发一个项目时,可以通过控制台输出或者debug来获取到项目的运行信息.当项目上线时,我们就需要通过日志来分析.如同Java的log4j,nodejs中也有相关的log4js.使用过log4j的同学应 ...

  9. nodejs的PM2进程管理

    PM2 PM2 node.js进程管理工具(npm i pm2 -g) 守护进程: 服务挂掉后自动重启 多进程:更好的里有cpu和内存 PM2使用 启动服务 在package.json的scripts ...

  10. PM2怎么保持Node应用程序永久活动?

    官网介绍: PM2是守护进程管理器,它将帮助您管理和保持应用程序在线.PM2入门非常简单,它是一个简单直观的CLI,可以通过NPM安装. PM2是Node.js应用程序的生产流程管理器,内置负载均衡. ...

最新文章

  1. CTF web题总结--上传文件绕过
  2. 数据结构Java01【数据结构概述、数组基本使用】
  3. 【软件设计师】2020-08-07
  4. Mybatis(2)-注解使用-IDEA
  5. 老人言 摘自云风的blog
  6. (15)FPGA面试题存储器资源区别
  7. C++之++操作符重载
  8. jQuery LigerUI 插件介绍及使用之ligerDrag和ligerResizable
  9. tensorflow精进之路(二十五)——Object Detection API目标检测(下)(VOC数据集训练自己的模型进行目标检测)
  10. FFmpeg学习(3)——视频中音频文件提取
  11. 2021年“泰迪杯”数据分析技能赛A题任务1:数据分析与预测
  12. 计算机实用知识风云初动,风云初动 第一节 养气韬光
  13. 站大爷代理IP工具主要功能介绍
  14. Share Creators公开课:游戏美术如何提升出海游戏转化
  15. css3实现3d图片旋转效果
  16. Perl变量作用域和自定义函数小结
  17. java multi tenancy_java工程積累——saas之multi-tenancy解析
  18. 建立基于IP地址访问的网站
  19. win10老是弹出计算机管理器,win10系统Ie11老是弹出“管理加载项”提示框取消的处理办法...
  20. 楼教主(楼天成)的ACM心路历程

热门文章

  1. lol1.7更新服务器维护,lol12月20日维护公告 v3.0.7.1版本更新内容一览
  2. 方舟服务器维护为什么要藏好,方舟生存进化芯片藏哪儿好
  3. Mac连接Ubuntu服务器并用屏幕共享app显示远程应用图形界面
  4. NMS中的 offset by class 是什么意思?
  5. 云通讯 发送短信模板代码
  6. MAC强制卸载软件 如遇“不能修改或删除“*”,因为macOS需要它”
  7. 农夫山泉2面面试经历
  8. EasyUI Menu 菜单和按钮
  9. TscanCode代码扫描工具
  10. T229473 D. 背单词的小智(二分)