express使用morgan+file-stream-rotator实现自定义日志+轮转

import express, {json} from 'express';
import fs from 'fs';
import path from 'path';
import morgan from 'morgan';
import FileStreamRotator from 'file-stream-rotator';

const app = express();

//自动采集一些东西
// 自定义的 token 来获取请求头数据
morgan.token('auth', function (req) {
    return req.headers['token']; // 获取请求头的 token 值
});

// 自定义的 token 来获取本地时间
morgan.token('local-time', () => {
    let d = new Date();
    return d.toLocaleString() + '.' + d.getMilliseconds();
});

// 自定义 token 来获取请求体
morgan.token('request-body', (req) => {
    return JSON.stringify(req.body);
});

// 自定义 token 来记录响应体
morgan.token('response-body', (req, res) => {
    return res.body || '';
});

// 自定义中间件来捕获响应体
app.use((req, res, next) => {
    const originalSend = res.send.bind(res);
    res.send = function (body) {
        res.body = body;
        return originalSend(body);
    };
    next();
});

// 创建日志目录
const __dirname = path.resolve();
const logDirectory = path.join(__dirname, './logs');
fs.promises.access(logDirectory).catch(() => {
    fs.promises.mkdir(logDirectory, {recursive: true}).then(r => "无法创建文件夹");
});

// 配置日志流
const configs = (type) => ({
    date_format: 'YYYY-MM-DD',
    filename: path.join(logDirectory, `%DATE%-${type}`),
    frequency: 'daily',  //每日切分
    verbose: false,     //详细模式,会记录很多冗余信息
    extension: '.log', //文件结尾
    size: '20m',    //单个大小
    max_logs: '30', //最多保存多少
});

// 创建错误日志和自定义日志流
const errorLogStream = FileStreamRotator.getStream(configs('error'));
const dataLog = FileStreamRotator.getStream(configs('data'));

// 自定义 morgan 格式
//:local-time :request-body 这种是上面自定义的token方法
const customFormat =
    ':local-time :method :url :status :res[content-length]B :response-time ms :auth \n  请求 :request-body \n  响应 :response-body \n';
// 自定义中间件记录请求日志
function Log(req,info) {
    const { method, url, headers, body } = req;
    console.log(req)
    let a = {
        method: method,
        url: url,
        body: body,
        info: info
    }
    //由于上面多加了一堆自定义的参数,这里不是纯json
   //可以把morgan.token这些删掉
    dataLog.write(JSON.stringify(a))
}

// 使用 morgan
//中间件自动记录错误日志
app.use(morgan(customFormat, { immediate: false, stream: errorLogStream, skip: (req, res) => res.statusCode < 400 }));
//手动
app.use(morgan(':local-time :method :url :status :res[content-length]B :response-time ms :auth',
    { immediate: false, stream: dataLog }
));
//路由
app.get('/', (req, res) => {
    res.send('Hello world!');
    //dataLog.write("xxsax")
    Log(req,"xcxcxc")
});
//启动
app.listen(3000, () => {
    console.log('Server is running at port 3000');
});

posted @ 2024-11-12 10:57  朝阳1  阅读(22)  评论(0编辑  收藏  举报