log4js日志管理(基于Nodejs)
log4js日志管理
0 码云仓库代码(欢迎Start)
码云仓库代码-https://gitee.com/hongjunyong/markdown-collect/tree/master
1 基本介绍
1.1 源码及文档
https://github.com/log4js-node/log4js-node
1.2 介绍
-
显示程序运行状态 -
帮助开发者排除问题故障 -
结合专业的日志分析工具(如 ELK )给出预警
1.3 log4j的8个日志级别
log4j定义了8个级别的log(除去OFF和ALL,可以说分为6个级别),优先级从高到低依次为:OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、 ALL。
-
ALL 最低等级的,用于打开所有日志记录。 -
TRACE designates finer-grained informational events than the DEBUG.Since:1.2.12,很低的日志级别,一般不会使用。 -
DEBUG 指出细粒度信息事件对调试应用程序是非常有帮助的,主要用于开发过程中打印一些运行信息。 -
INFO 消息在粗粒度级别上突出强调应用程序的运行过程。打印一些你感兴趣的或者重要的信息,这个可以用于生产环境中输出程序运行的一些重要信息,但是不能滥用,避免打印过多的日志。 -
WARN 表明会出现潜在错误的情形,有些信息不是错误信息,但是也要给程序员的一些提示。 -
ERROR 指出虽然发生错误事件,但仍然不影响系统的继续运行。打印错误和异常信息,如果不想输出太多的日志,可以使用这个级别。 -
FATAL 指出每个严重的错误事件将会导致应用程序的退出。这个级别比较高了。重大错误,这种级别你可以直接停止程序了。 -
OFF 最高等级的,用于关闭所有日志记录。
如果将log level设置在某一个级别上,那么比此级别优先级高的log都能打印出来。例如,如果设置优先级为WARN,那么OFF、FATAL、ERROR、WARN 4个级别的log能正常输出,而INFO、DEBUG、TRACE、 ALL级别的log则会被忽略。Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。
1.4 安装
npm install log4js --save-dev // log4js
npm install ip --save-dev // 获取ip地址
1.5 文件解析
1 目录结构
|- middleware
|- log4js
|- access.js 记录和配置客户端信息
|- index.js 对日志中间件进行错误处理
|- logger.js log4js记录日志
2 记录说明
2 代码解析
2.1 在koa入口文件(app.js)注册日志中间件
// 引入日志中间件
const logger = require("../middleware/log4js/index");
const ip = require("ip");
// 注册中间件
app.use(logger({
// koa提供的环境变量
env: app.env,
// 项目名,记录在日志中的项目信息
projectName: 'vue-vant',
// 指定记录的日志级别
applogLevel: 'debug',
// 指定日志存放的目录名
dir: 'logs',
// 默认情况下服务器 ip 地址
serverIp: ip.address()
}));
2.2 index.js入口文件 --> 对日志中间件进行错误处理
const logger = require('./logger');
module.exports = (options) => {
const loggerMiddleware = logger(options);
return (ctx, next) => {
return loggerMiddleware(ctx, next)
.catch((e) => {
// 如果中间件里面有抛出错误,这里将通过 catch 函数捕捉到并处理,将状态码小于 500 的错误统一按照 500 错误码处理,以方便后面的 http-error 中间件显示错误页面。
if (ctx.status < 500) {
ctx.status = 500;
}
// 异常日志打印
ctx.log.error(e.stack);
ctx.state.logged = true;
ctx.throw(e);
})
}
}
2.3 logger.js记录日志
2.3.1 参数定义
// 将日志的不同级别提取为数组,方便后面做处理
const methods = ['trace', 'debug', 'info', 'warn', 'error', 'fatal', 'mark'];
let contextLogger = {};
// 提取默认公用参数对象(以防注册中间件,用户没有传入参数)
const defaultInfo = {
// 开发环境
env: 'dev',
// 输出的文件夹名称
dir: 'logs',
// 错误级别
applogLevel: 'info'
};
// 继承自 defaultInfo 默认参数(options会把defaultInfo里的参数覆盖掉)
const opts = Object.assign({}, defaultInfo, options || {});
// 需要的变量解构 方便使用
const { env, dir, applogLevel } = opts;
2.3.2 日志文件命名、日志切割
const appenders = { cheese: {
// 日志类型
type: 'dateFile',
// 输出日志文件名称
filename: `server/${dir}/task`,
// 名称后面添加年月日
pattern: '-yyyy-MM-dd.log',
// 是否总是有后缀名
alwaysIncludePattern: true
} };
2.3.3 把日志在终端输出(默认关闭,需要时可以把注释去掉)
// if (env === 'dev' || env === 'local' || env === 'development') {
// appenders.out = {
// type: 'console'
// }
// }
2.3.4 指定日志的默认配置项
const config = {
appenders: appenders,
/**
* 指定日志的默认配置项
* 如果 log4js.getLogger 中没有指定,默认为 cheese 日志的配置项
* 指定 cheese 日志的记录内容为 error 及 error 以上级别的信息
*
* var obj = {'a':'123','b':'345'};
* console.log(Object.keys(obj)); //['a','b']
*
* Object.keys(appenders) // cheese
*/
categories: {
default: {
appenders: Object.keys(appenders),
level: applogLevel
}
}
};
2.3.5 计算响应时间
1 记录请求开始的时间
const start = Date.now();
log4js.configure(config);
await next();
2 记录请求结束的时间
const end = Date.now();
const responseTime = end - start;
3 响应时间
响应时间为${responseTime/1000}s
2.3.5 循环methods将所有方法挂载到ctx上
methods.forEach((method, i) => {
contextLogger[method] = (message) => {
// 将入参换为函数返回的字符串
logger[method](access(ctx, message, {}))
}
});
ctx.log = contextLogger;
-
调用:ctx.log.error('错误啦')
2.3.6 把日志输出在指定的文件里,并且把options操作过滤
// 过滤掉options操作(跨域)
if (ctx.request.method != 'OPTIONS') {
logger.info(access(ctx, `响应时间为${responseTime/1000}s`, {}));
}
2.4 access.js封装打印信息
2.4.1 获取用户提交数据、服务端返回的json
// 请求方法
var getMethod = ctx.request.method;
// 用户提交的数据
var params = '';
// 服务端返回的json
var data = '';
if (getMethod === 'GET') {
params = ctx.query
} else if (getMethod === 'POST') {
params = ctx.request.body
} else if (getMethod === 'PUT') {
params = ctx.request.body
} else if (getMethod === 'DELETE') {
params = ctx.query
}
data = ctx.body
2.4.2 获取参数
const {
// 请求方法 get post或其他
method,
// 请求链接
url,
// 发送请求的客户端的host
host,
// 请求中的headers
headers
} = ctx.request;
2.4.3 返回打印信息
const client = {
method,
url,
host,
message,
params,
data,
// 请求的源地址
referer: headers['referer'],
// 客户端信息设备 及 浏览器信息
userAgent: headers['user-agent'],
};
// client的参数拷贝给commonInfo
return JSON.stringify(Object.assign(commonInfo, client));