一、新建一个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 += '\n' + '***************info log start ***************' + '\n';
// 响应内容
logText += 'info detail: ' + '\n' + JSON.stringify(info) + '\n';
// 响应日志结束
logText += '*************** info log end ***************' + '\n';
return logText;
};
// 格式化响应日志
var formatRes = function (ctx, resTime) {
var logText = '';
// 响应日志开始
logText += '\n' + '*************** response log start ***************' + '\n';
// 添加请求日志
logText += formatReqLog(ctx.request, resTime);
// 响应状态码
logText += 'response status: ' + ctx.status + '\n';
// 响应内容
logText += 'response body: ' + '\n' + JSON.stringify(ctx.body) + '\n';
// 响应日志结束
logText += '*************** response log end ***************' + '\n';
return logText;
};
// 格式化错误日志
var formatError = function (ctx, err, resTime) {
var logText = '';
// 错误信息开始
logText += '\n' + '*************** error log start ***************' + '\n';
// 添加请求日志
logText += formatReqLog(ctx.request, 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;
};
// 格式化请求日志
var formatReqLog = function (req, resTime) {
var logText = '';
var method = req.method;
// 访问方法
logText += '\n' + 'request method: ' + method + '\n';
// 请求原始地址
logText += 'request originalUrl: ' + req.originalUrl + '\n';
// 客户端ip
logText += 'request client ip: ' + req.ip + '\n';
// 开始时间
// var startTime;
// 请求参数
if (method === 'GET') {
logText += 'request query: ' + JSON.stringify(req.query) + '\n';
// startTime = req.query.requestStartTime;
} else {
logText += 'request body: ' + '\n' + JSON.stringify(req.body) + '\n';
// startTime = req.body.requestStartTime;
}
// 服务器响应时间
logText += 'response time: ' + resTime + '\n';
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());