一、新建一个log4js.js配置文件
let path = require('path'); // 日志根目录 let baseLogPath = path.resolve(__dirname, '../logs'); // 错误日志目录 let errorPath = '/error'; // 错误日志文件名 let errorFileName = 'error'; // 错误日志输出完整路径 let errorLogPath = baseLogPath + errorPath + '/' + errorFileName; // 请求日志目录 let reqPath = '/request'; // 请求日志文件名 let reqFileName = 'request'; // 请求日志输出完整路径 let reqLogPath = baseLogPath + reqPath + '/' + reqFileName; // 响应日志目录 let responsePath = '/response'; // 响应日志文件名 let responseFileName = 'response'; // 响应日志输出完整路径 let responseLogPath = baseLogPath + responsePath + '/' + responseFileName; module.exports = { // 日志格式等设置 appenders: { console: { type: 'console' }, errorLogger: { type: 'dateFile', filename: errorLogPath, pattern: '-yyyy-MM-dd-hh.log', alwaysIncludePattern: true, encoding: 'utf-8', maxLogSize: 1000, numBackups: 3, path: errorPath, layout: { type: 'basic' } }, http: { type: 'dateFile', filename: reqLogPath, pattern: '-yyyy-MM-dd-hh.log', alwaysIncludePattern: true, encoding: 'utf-8', maxLogSize: 1000, numBackups: 3, path: reqPath, layout: { type: 'basic'// 'messagePassThrough' } }, resLogger: { type: 'dateFile', filename: responseLogPath, pattern: '-yyyy-MM-dd-hh.log', alwaysIncludePattern: true, encoding: 'utf-8', maxLogSize: 1000, numBackups: 3, path: responsePath, layout: { type: 'basic' } } }, // 供外部调用的名称和对应设置定义 categories: { default: { appenders: ['console'], level: 'all' }, resLogger: { appenders: ['resLogger'], level: 'info' }, errorLogger: { appenders: ['errorLogger'], level: 'error' }, http: { appenders: ['http'], level: 'info' } }, baseLogPath, replaceConsole: true };
二、新建log4Util.js
var log4js = require('log4js'); var logConfig = require('../config/log4js'); // 加载配置文件 log4js.configure(logConfig); var logUtil = {}; // 调用预先定义的日志名称 var resLogger = log4js.getLogger('resLogger'); var reqLogger = log4js.getLogger('http'); var errorLogger = log4js.getLogger('errorLogger'); var consoleLogger = log4js.getLogger(); // 封装错误日志 logUtil.logError = function (ctx, error, resTime) { if (ctx && error) { errorLogger.error(formatError(ctx, error, resTime)); } }; // 封装请求日志 logUtil.reqLog = function (ctx, resTime) { if (ctx) { reqLogger.info(formatReqLog(ctx, resTime)); } }; // 封装响应日志 logUtil.logResponse = function (ctx, resTime) { if (ctx) { resLogger.info(formatRes(ctx, resTime)); } }; logUtil.logInfo = function (info) { if (info) { consoleLogger.info(formatInfo(info)); } }; var formatInfo = function (info) { var logText = ''; // 响应日志开始 logText += ' ' + '***************info log start ***************' + ' '; // 响应内容 logText += 'info detail: ' + ' ' + JSON.stringify(info) + ' '; // 响应日志结束 logText += '*************** info log end ***************' + ' '; return logText; }; // 格式化响应日志 var formatRes = function (ctx, resTime) { var logText = ''; // 响应日志开始 logText += ' ' + '*************** response log start ***************' + ' '; // 添加请求日志 logText += formatReqLog(ctx.request, resTime); // 响应状态码 logText += 'response status: ' + ctx.status + ' '; // 响应内容 logText += 'response body: ' + ' ' + JSON.stringify(ctx.body) + ' '; // 响应日志结束 logText += '*************** response log end ***************' + ' '; return logText; }; // 格式化错误日志 var formatError = function (ctx, err, resTime) { var logText = ''; // 错误信息开始 logText += ' ' + '*************** error log start ***************' + ' '; // 添加请求日志 logText += formatReqLog(ctx.request, resTime); // 错误名称 logText += 'err name: ' + err.name + ' '; // 错误信息 logText += 'err message: ' + err.message + ' '; // 错误详情 logText += 'err stack: ' + err.stack + ' '; // 错误信息结束 logText += '*************** error log end ***************' + ' '; return logText; }; // 格式化请求日志 var formatReqLog = function (req, resTime) { var logText = ''; var method = req.method; // 访问方法 logText += ' ' + 'request method: ' + method + ' '; // 请求原始地址 logText += 'request originalUrl: ' + req.originalUrl + ' '; // 客户端ip logText += 'request client ip: ' + req.ip + ' '; // 开始时间 // var startTime; // 请求参数 if (method === 'GET') { logText += 'request query: ' + JSON.stringify(req.query) + ' '; // startTime = req.query.requestStartTime; } else { logText += 'request body: ' + ' ' + JSON.stringify(req.body) + ' '; // startTime = req.body.requestStartTime; } // 服务器响应时间 logText += 'response time: ' + resTime + ' '; return logText; }; module.exports = () => { return async (ctx, next) => { ctx.logger = logUtil; ctx.logger.reqLog(ctx, 0); await next(); }; };
三、再app.js引入log4Util.js
// logger app.use(async (ctx, next) => { const start = new Date(); let ms = new Date() - start; await next(); try { // 开始进入到下一个中间件 if (ctx.status === 404) { ctx.throw(404); } ms = new Date() - start; // 记录响应日志 ctx.logger.logResponse(ctx, ms); } catch (error) { ms = new Date() - start; // 记录异常日志 ctx.logger.logError(ctx, error, ms); } }); // routes app.use(index.routes()); app.use(index.allowedMethods());