按日期创建log文件、error和res分别在两个文件夹
// /config/log4js_config.js
module.exports = {
appenders: {
// 默认日志
console: {
type: 'console',
},
//错误日志
errorLogger: {
// category: 'errorLogger', //logger名称
type: 'dateFile', //日志类型
filename: 'logs/error/error', // 日志输出位置
alwaysIncludePattern: true, // 是否总是有后缀名
pattern: 'yyyy-MM-dd.log', // 后缀
},
//响应日志
resLogger: {
// category: 'resLogger',
type: 'dateFile',
filename: 'logs/response/response',
alwaysIncludePattern: true,
pattern: 'yyyy-MM-dd.log',
},
},
//设置logger名称对应的的日志等级
categories: {
default: {
appenders: ['console'],
level: 'All',
},
errorLogger: {
appenders: ['errorLogger'],
level: 'error',
},
resLogger: {
appenders: ['resLogger'],
level: 'all',
},
},
};
封装打印内容
// /utils/log_util.js
const log4js = require('log4js');
const loggerConfig = require('../config/log4js_config');
// 加载配置文件
log4js.configure(loggerConfig);
const logger = {};
const errorLogger = log4js.getLogger('errorLogger');
const resLogger = log4js.getLogger('resLogger');
// 封装错误日志
logger.logError = (error, resTime, requestBody) => {
if (error) {
errorLogger.error(formatError(error, resTime, requestBody));
}
};
// 封装响应日志
logger.logResponse = (response, resTime, requestBody) => {
if (response) {
resLogger.info(formatRes(response, resTime, requestBody));
}
};
// 封装控制台打印
logger.log = title => {
return log4js.getLogger(title);
};
// 格式化响应日志
const formatRes = (response, resTime, requestBody) => {
let logText = '';
// 响应日志开始
logText += '\n' + '*************** response log start ***************' + '\n';
// 添加请求日志
logText += formatReqLog(response.request, resTime, requestBody);
// 响应状态码
logText += 'response statusCode: ' + response.statusCode + '\n';
// 响应内容
logText += 'response body: ' + '\n' + JSON.stringify(response.body) + '\n';
// 响应日志结束
logText += '*************** response log end ***************' + '\n';
return logText;
};
// 格式化错误日志
const formatError = (err, resTime, requestBody) => {
let logText = '';
// 错误信息开始
logText += '\n' + '*************** error log start ***************' + '\n';
// 添加请求日志
logText += formatReqLog(err.options, resTime, requestBody);
// 错误名称
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;
};
// 格式化请求日志
const formatReqLog = (req, resTime, requestBody) => {
let logText = '';
const method = req.method;
// 访问方法
logText += 'request method: ' + method + '\n';
// 请求原始地址
logText += 'request originalUrl: ' + (req.uri && req.uri.href || req.uri) + '\n';
// 请求参数
if (method === 'GET') {
logText += 'request query: ' + JSON.stringify(req.uri.query) + '\n';
} else {
logText += 'request body: ' + '\n' + JSON.stringify(requestBody) + '\n';
}
// 服务器响应时间
logText += 'response time: ' + resTime + 'ms' + '\n';
return logText;
};
module.exports = logger;
request时使用(同时也是node端请求封装)
// /utils/request.js
const rp = require('request-promise');
const axios = require('axios');
const config = require('../config/constants');
const logger = require('./log_util');
const requestConfig = {
baseUrl: config.baseUrl,
resolveWithFullResponse: false
};
const rpWithLogger = (options, bodyKey) => {
const startTime = new Date();
let ms = 0;
return rp(options).then(
res => {
ms = new Date() - startTime;
logger.logResponse(res, ms, options[bodyKey]);
return res.body;
},
err => {
ms = new Date() - startTime;
logger.logError(err, ms, options[bodyKey]);
return { code: 504, msg: '网关超时', err };
}
);
};
exports.get = (uri, param = {}, opts) => {
const options = {
uri,
method: 'GET',
qs: param,
...requestConfig,
...opts
};
return rpWithLogger(options, 'param');
};
exports.post = (uri, body, opts) => {
const options = {
uri,
method: 'POST',
body: body,
...requestConfig,
...opts,
json: true,
resolveWithFullResponse: true
};
return rpWithLogger(options, 'body');
};
exports.upload = (uri, formData, opts) => {
const options = {
uri,
method: 'POST',
formData: formData,
...requestConfig,
...opts
};
return rp(options);
};
exports.download = (uri, param = {}, opts) => {
// 此处用 axios 请求,定义 responseType 为 stream 进行下载
return axios.get(config.baseUrl + uri, {
responseType: 'stream', // 注意此处要用 stream
params: param,
data: {},
...opts
});
};
配置内容需根据需求自行修改,当然不修改也能用。
完整koa模板示例:https://www.yuque.com/xiebugde/mbz0hg/tg5c7c