前言

没有日志系统的后台应用是没有灵魂的,

平时工作中每次我们遇到接口报错的时候,

都会叫后台的童鞋看下怎么回事,

这时后台的童鞋都会不慌不忙的打开一个骚骚的黑窗口。

一串噼里啪啦的命令输进去,

哐哐哐,一堆报错信息出现了... 不明觉厉~

so, 我们今天也为我们的应用加上日志系统。

正文

node中写日志一般都用 log4js 具体不详细介绍

请移步 https://www.npmjs.com/package/log4js

废话不多说直接上代码

1.1 安装log4js

npm install --save log4js

1.2 增加配置文件

根目录下新建config目录 conifg目录下全为配置文件

config目录下 新建文件 logs.js

var path = require('path');

//日志根目录
var baseLogPath = path.resolve(__dirname, '../logs') /*报错输出日志*/
//错误日志目录、文件名、输出完整路径
var errorPath = "/error";
var errorFileName = "error";
var errorLogPath = baseLogPath + errorPath + "/" + errorFileName; /*请求数据得到响应时输出响应日志*/
//响应日志目录、文件名、输出完整路径
var responsePath = "/response";
var responseFileName = "response";
var responseLogPath = baseLogPath + responsePath + "/" + responseFileName; /*操作数据库进行增删改等敏感操作记录日志*/
//操作日志目录、文件名、输出完整路径
var handlePath = "/handle";
var handleFileName = "handle";
var handleLogPath = baseLogPath + handlePath + "/" + handleFileName; module.exports = {
//日志格式等设置
appenders:
{
"rule-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
},
"resLogger": {
"type": "dateFile",
"filename": responseLogPath,
"pattern": "-yyyy-MM-dd-hh.log",
"alwaysIncludePattern": true,
"encoding": "utf-8",
"maxLogSize": 1000,
"numBackups": 3,
"path": responsePath
},
"handleLogger": {
"type": "dateFile",
"filename": handleLogPath,
"pattern": "-yyyy-MM-dd-hh.log",
"alwaysIncludePattern": true,
"encoding": "utf-8",
"maxLogSize": 1000,
"numBackups": 3,
"path": responsePath
},
},
//供外部调用的名称和对应设置定义
categories: {
"default": {"appenders": ["rule-console"], "level": "all"},
"resLogger": {"appenders": ["resLogger"], "level": "info"},
"errorLogger": {"appenders": ["errorLogger"], "level": "error"},
"handleLogger": {"appenders": ["handleLogger"], "level": "all"},
"http": {"appenders": ["resLogger"], "level": "info"}
},
"baseLogPath": baseLogPath
}

1.3 增加工具方法

新建 utils 目录, utils 目录下放置工具类方法

utils 下新建 logs.js 放置输出日志的工具方法

var log4js = require('log4js');
var logsConfig = require('../config/logs.js');
//加载配置文件
log4js.configure(logsConfig);
//调用预先定义的日志名称
var resLogger = log4js.getLogger("resLogger");
var errorLogger = log4js.getLogger("errorLogger");
var handleLogger = log4js.getLogger("handleLogger");
var consoleLogger = log4js.getLogger(); // 格式化日志文本 加上日志头尾和换行方便查看 ==> 普通日志、请求日志、响应日志、操作日志、错误日志
var formatText = {
info: function(info) {
var logText = new String();
//响应日志头信息
logText += "\n" + "***************info log start ***************" + "\n";
//响应内容
logText += "info detail: " + "\n" + JSON.stringify(info) + "\n";
//响应日志结束信息
logText += "*************** info log end ***************" + "\n";
return logText;
},
request: function(req, resTime) {
var logText = new String();
var method = req.method;
//访问方法
logText += "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;
},
response: function(ctx, resTime) {
var logText = new String();
//响应日志开始
logText += "\n" + "*************** response log start ***************" + "\n";
//添加请求日志
logText += formatText.request(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;
},
handle: function(info) {
var logText = new String();
//响应日志开始
logText += "\n" + "***************info log start ***************" + "\n";
//响应内容
logText += "handle info detail: " + "\n" + JSON.stringify(info).replace(/\\n/g, "\n") + "\n";
//响应日志结束
logText += "*************** info log end ***************" + "\n";
return logText;
},
error: function(ctx, err, resTime) {
var logText = new String();
//错误信息开始
logText += "\n" + "*************** error log start ***************" + "\n";
//添加请求日志
logText += formatText.request(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;
}
} module.exports = {
//封装普通日志
logInfo: function(info) {
if (info) {
consoleLogger.info(formatText.info(info));
}
},
//封装响应日志
logResponse: function(ctx, resTime) {
if (ctx) {
resLogger.info(formatText.response(ctx, resTime));
}
},
//封装操作日志
logHandle: function(res) {
if (res) {
handleLogger.info(formatText.handle(res));
}
},
//封装错误日志
logError: function(ctx, error, resTime) {
if (ctx && error) {
errorLogger.error(formatText.error(ctx, error, resTime));
}
}
};

1.4 改造app.js

// logger
const logsUtil = require('./utils/logs.js');
app.use(async (ctx, next) => {
const start = new Date(); // 响应开始时间
let intervals; // 响应间隔时间
try {
await next();
intervals = new Date() - start;
logsUtil.logResponse(ctx, intervals); //记录响应日志
} catch (error) {
intervals = new Date() - start;
logsUtil.logError(ctx, error, intervals);//记录异常日志
}
})

如图:

1.5 运行、使用日志系统

大工告成, 运行一下项目吧, 看是否自动在根目录下创建了一个logs目录。 如下



目前我们现在只记录的响应日志和 错误日志。

下面演示一下 如何打印操作日志。

我们打开 routes 文件夹。 然后打开 index.js 如图所示。



假装我们做了这些操作。 访问 http://localhost:3000/json

看一下日志文件夹和控制台是否和下面一样?





这就是我们在utils中写的四个输出日志的方法。

如果觉得不够用还可以仿照格式继续写其他方法。

ps: .gitignore中已设置忽略上传logs文件夹,git中不可见。

作者 HoChine

2019 年 04月 03日

GitHub地址:https://github.com/HoChine/Koa2-demo/tree/02

koa2学习笔记02 - 给koa2添加系统日志 —— node日志管理模块log4js的更多相关文章

  1. koa2学习笔记03 - 给koa2配置session ——koa2结构分层、配置数据库、接口

    前言 这一章写的很没有底气,因为我完全不懂一个正经的后台应用是怎么结构分层的, 所有只能按照我自己的理解去写,即使这样也仅仅只分离出了controller层, 至于所谓的service层,dao层,完 ...

  2. 软件测试之loadrunner学习笔记-02集合点

    loadrunner学习笔记-02集合点 集合点函数可以帮助我们生成有效可控的并发操作.虽然在Controller中多用户负载的Vuser是一起开始运行脚本的,但是由于计算机的串行处理机制,脚本的运行 ...

  3. OpenCV 学习笔记 02 使用opencv处理图像

    1 不同色彩空间的转换 opencv 中有数百种关于不同色彩空间的转换方法,但常用的有三种色彩空间:灰度.BRG.HSV(Hue-Saturation-Value) 灰度 - 灰度色彩空间是通过去除彩 ...

  4. Redis:学习笔记-02

    Redis:学习笔记-02 该部分内容,参考了 bilibili 上讲解 Redis 中,观看数最多的课程 Redis最新超详细版教程通俗易懂,来自 UP主 遇见狂神说 4. 事物 Redis 事务本 ...

  5. 机器学习实战(Machine Learning in Action)学习笔记————02.k-邻近算法(KNN)

    机器学习实战(Machine Learning in Action)学习笔记————02.k-邻近算法(KNN) 关键字:邻近算法(kNN: k Nearest Neighbors).python.源 ...

  6. SaToken学习笔记-02

    SaToken学习笔记-02 如果排版有问题,请点击:传送门 常用的登录有关的方法 - StpUtil.logout() 作用为:当前会话注销登录 调用此方法,其实做了哪些操作呢,我们来一起看一下源码 ...

  7. Hadoop学习笔记—5.自定义类型处理手机上网日志

    转载自http://www.cnblogs.com/edisonchou/p/4288737.html Hadoop学习笔记—5.自定义类型处理手机上网日志 一.测试数据:手机上网日志 1.1 关于这 ...

  8. OGG学习笔记02

    实验环境:源端:192.168.1.30,Oracle 10.2.0.5 单实例目标端:192.168.1.31,Oracle 10.2.0.5 单实例 1.模拟源数据库业务持续运行 2.配置OGG前 ...

  9. [学习笔记] 在Eclipse中添加用户库 Add User Libraries ,在项目中引用用户库

    如果还没有安装Eclipse, 则请参考前文:  [学习笔记] 下载.安装.启动 Eclipse(OEPE) 添加用户库 本文主要介绍在项目中直接使用第三方库的情况.就是把第三方的jar文件直接放到某 ...

随机推荐

  1. 【node】用koa搭建一个增删改服务(一)

    前文,vue分类里有一个日志demo的练习,这篇文章就是介绍针对日志demo的服务是怎么写的 一.koa搭建项目 1. npm init 2. npm install koa 二.建数据库 下面是项目 ...

  2. 线程间的通信方式2--管道流Pipes

    “管道”是java.io包的一部分.它是Java的特性,而不是Android特有的.一条“管道”为两个线程建立一个单向的通道.生产者负责写数据,消费者负责读取数据. 下面是一个使用管道流进行通信的例子 ...

  3. java jvm概述及工作过程中的内存管理

    java jvm 有分层的思想.   java类..java文件,源文件,源代码,源程序   编译器不能把源代码直接编译成0101,除非是java语言写的操作系统.   windows认识的可执行文件 ...

  4. 使用 PowerShell 创建和修改 ExpressRoute 线路的对等互连

    本文可帮助使用 PowerShell 在资源管理器部署模型中创建和管理 ExpressRoute 线路的路由配置. 还可以检查 ExpressRoute 线路的状态,更新.删除和取消预配其对等互连. ...

  5. Oracle EBS 更新客户地点

    --更新客户地点 declare x_return_status ); x_msg_count NUMBER; x_msg_data ); x_profile_id NUMBER; l_locatio ...

  6. REST Framework组件的解析源码

    首先我们要知道解析器的作用 解析器就是对你请求体中的数据进行反序列化.封装 把你的所有的请求数据都封装在request.data中 以后就在request.data中获取数据 我们先导入rest_fr ...

  7. makedown 软件

    windows上的新手使用makedownpad 很适合的 下载之后你需要激活makedownpad MarkdownPad 2 Pro 注册码(邮箱+许可密钥) 邮箱 Soar360@live.co ...

  8. 设置UINavigationController标题的属性

    设置UINavigationController标题的属性 self.title = @"产品详情"; [self.navigationController.navigationB ...

  9. Custom Settings.ini 和 bootstrap.ini 配置

    [Settings]Priority=DefaultProperties=MyCustomProperty [Default] ;SkipWizard=YES 如果跳过部署向导,则即使 SkipCap ...

  10. PSR规范学习笔记

    PSR已经经历了5次变革,如今PSR4就是最新的标准,但是还是有必要了解下5个版本的内容的,于是去php-fig网站看了下英文原版: 大概看了遍,发现这规范很多的必须很多时候只是建议,但是PHP解析器 ...