koa框架29 日志
我找了很多个插件,发现都好难用,npm哪里的说明等于没有,你根本不知道他哪些配置参数怎么弄,百度的文章真的是五花八门,不是抄就是缺胳膊短腿, 想来想去还是自己写好了。
日志的格式我是仿 koa-logger,我感觉他这个样式还不错,但是他这个插件只能console输出,如果是测试环境,还行,但是上线后作为日志保存,就不太行。
我尝试去用他的方法去保存,会乱码,编码我也设置为utf8了,所以无解啊。(超蛋疼有没有)
预览
相对来说还是比较简单。
原理
通过中间件的形式,正常请求和发生错误,为此,我们需要创建一个全局的错误处理中间件,在这个里面我们触发自己写的日志方法。
const logger = require("./libs/logger");
//全局错误处理
server.use(async (ctx, next) => {
try {
await next();
//日志
logger(ctx);
} catch (e) {
//日志
logger(ctx, e);
}
});
我们可以看到,我们将ctx对象和e对象传入了,有e的话就是报错了,没有就是正常。
然后我们创建一个模块logger.js
const fs = require("promise-fs");
const path = require("path");
const {
log_path
} = require("../config");
const moment = require("moment");
const option = {
flag: "a"
};
//定时删除文件 7day
setInterval(async () => {
try {
const dirArr = await fs.readdir(log_path);
// [ '2020-09-05.log', '2020-09-06.log' ]
if (dirArr.length) {
dirArr.forEach(async dir => {
//如果这个文件已经超过七天了就删除
const currentTime = moment().format("YYYY-MM-DD");
const outTime = moment(dir.split(".")[0]).add(7, "d").format("YYYY-MM-DD");
if (moment(outTime).isBefore(currentTime)) {
await fs.unlink(path.join(log_path, dir));
}
});
}
} catch (e) {
console.log("自动删除日志文件失败", e);
}
}, 7 * 24 * 60 * 60 * 1000);
module.exports = async function(ctx, error) {
//解构
const {
request,
response
} = ctx;
//文件路径
const filePath = path.join(log_path, `${moment().format("YYYY-MM-DD")}.log`);
//信息
let message = `>> ${request.method} ${request.url} ${moment().format("YYYY-MM-DD HH:mm:ss")} \r\n`;
//是否有错误
if (!error) {
//信息
message += `<< ${request.method} ${response.status} ${response.message} ${moment().format("YYYY-MM-DD HH:mm:ss")} \r\n`;
} else {
//信息
message += `<< ${request.method} ${response.status} ${response.message} error: ${error.message} ${moment().format("YYYY-MM-DD HH:mm:ss")} \r\n`;
}
//写入
await fs.writeFile(filePath, message, option);
}
使用了promise-fs,他的方法和fs差不多,不过是promise封装,然后还使用了path进行地址拼接,从config配置文件里读取日志的目录,使用了moment 用于时间操作。
fs模块支持第三个参数为配置,默认是覆盖文件模糊,我们改为a模式,这样就是追加模式。
然后就是对ctx对象的信息进行提取,然后合成一个字符,然后fs写入。
难点可能就是自动清理日志文件了。
我设置7天清理一次,先读取目录,获取一个目录下所有文件名的数组,通过split获取到文件名,文件名是时间。
然后通过moment 的方法,判断过期时间是否在当前时间之前。
比如15号是否在23号之前,15号是过期时间,在他之前肯定就是已经过期了,需要删除,然后我们进行删除。
需要注意一下就是这个重复定时间时间不要设置太短,你设置个10ms,肯定会报错的,因为文件可能刚删除了,你又来删除,速度太快也是不行的。
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿站点。未经许可,禁止转载。
暂无评论数据