一、新建一个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());

  

koa中 log4js使用的更多相关文章

  1. Koa与Node.js开发实战(3)——Nunjucks模板在Koa中的应用(视频演示)

    技术架构: ​ 在Koa中应用Nunjucks,需要先把Nunjucks集成为符合Koa规格的中间件(Middleware),从本质上来讲,集成后的中间件的作用是给上下文对象绑定一个render(vi ...

  2. Koa 中 ejs 模板的使用

    ejs的基本使用 安装 koa-views 和 ejs npm install --save koa-views/cnpm install --save koa-views npm install e ...

  3. 从前端中的IOC理念理解koa中的app.use()

    忙里偷闲,打开平时关注的前端相关的网站,浏览最近最新的前端动态.佼佼者,平凡的我做不到,但还是要争取不做落后者. 前端中的IoC理念,看到这个标题就被吸引了.IoC 理念,不认识呢,点击去一看,果然没 ...

  4. koa中返回404并且刷新后才正常的解决方案

    概述 这几天学习koa2,有一些心得,记录下来,供以后开发时参考,相信对其他人也有用. 起因 这几天学习koa2,写的代码执行时有一个奇怪的bug:明明能够返回数据,却有时正常返回数据,有时偏偏给你返 ...

  5. Koa 中实现 chunked 数据传输

    有关于 Transfer-Encoding:chunked 类型的响应,参见之前的文章HTTP 响应的分块传输.这里看 Koa 中如何实现. Koa 中请求返回的处理 虽然官方文档有描述说明不建议直接 ...

  6. koa 基础(十六)koa 中 session 的使用

    1.app.js /** * koa 中 session 的使用 * 1.npm install koa-session --save * 2.const session = require('koa ...

  7. koa 基础(十一)koa 中 koa-bodyparser 中间件获取表单提交的数据

    1.app.js /** * koa 中 koa-bodyparser 中间件获取表单提交的数据 * 1.npm install --save koa-bodyparser * 2.引入 const ...

  8. koa 基础(十)原生node.js 在 koa 中获取表单提交的数据

    1.app.js // 引入模块 const Koa = require('koa'); const router = require('koa-router')(); /*引入是实例化路由 推荐*/ ...

  9. node.js中log4js的使用

    以前用过forever进程守护的日志记录到指定文件,但是只能保存到一个文件中不能分片,这样到只日志文件越来越大, forever start -s -l ./forever.log app.js -l ...

随机推荐

  1. 索引 _id

    _id索引是绝大多数集合默认建立的索引,对于每个插入的数据,mongodb都会自动生成一条唯一的_id字段 增加一个数据 > db.test2.insert({x:1}) WriteResult ...

  2. #Python绘制 文本进度条,带刷新、时间暂缓的

    #Python绘制 文本进度条,带刷新.时间暂缓的 #文本进度条 import time as T st=T.perf_counter() print('-'*6,'执行开始','-'*6) maxx ...

  3. 那些吓人的 Linux 命令

    本文转载于其它网站,原作者如有问题,请您及时联系我,及时删除! 哪些Linux命令会让人联想到妖魔鬼怪?不妨好好瞧一瞧! 每年一度的万圣节马上就要到来,是时候稍微关注一下Linux那吓人的一面了.哪些 ...

  4. springBoot maven项目打成jar包

    springBoot项目打包springBoot项目打包最常用且最简单的方式是用springBoot的打包plugin <plugin> <groupId>org.spring ...

  5. mysql json数据类型

    概述 Mysql从5.7.8版本开始支持JSON字段,可以高效的处理JSON文档.相比字符串字段,JSON字段有下面的几处优势: 自动的校验JSON格式,无效的文档会产生错误 优化的存储格式(结构化的 ...

  6. BZOJ 3901 棋盘游戏 (找结论+枚举+贪心)

    题面 略 BZOJ 传送门 分析 具体分析见 dalao博客 妙就妙在当i<x,j<xi<x,j<xi<x,j<x时,(i,j)(i,j)(i,j) ^ (i,x) ...

  7. SIGAI机器学习第十四集 支持向量机1

    讲授线性分类器,分类间隔,线性可分的支持向量机原问题与对偶问题,线性不可分的支持向量机原问题与对偶问题,核映射与核函数,多分类问题,libsvm的使用,实际应用 大纲: 支持向量机简介线性分类器分类间 ...

  8. P4160 [SCOI2009]生日快乐 搜索

    思路:无脑搜索 提交:1次 题解: 大力搜索,枚举每个状态\((x,y,l)\)(\(x\)指分配到的长(可能比\(y\)要短),\(y\)指分配到的宽(可能比\(x\)要长),\(l\)指剩余切的次 ...

  9. MySQL 8.0.15 配置 MGR单主多从

    转载自:http://www.cnblogs.com/zhangzihong/p/10443526.html 一.简介 MySQL Group Replication(简称MGR)字面意思是mysql ...

  10. Shell 06 awk

    一.基本操作方法 ######################################### grep 按行进行查找 vim  编辑文档,交互式 ####################### ...