开发一个项目时,可以通过控制台输出或者debug来获取到项目的运行信息。当项目上线时,我们就需要通过日志来分析。如同Java的log4j,nodejs中也有相关的log4js。使用过log4j的同学应该对此不会陌生。

1、日志级别

log4js共有6种日志级别,分别为:trace、debug、info、warn、error、fatal。权值从小到大,其初始化代码为:

TRACE: new Level(5000, "TRACE"),
DEBUG: new Level(10000, "DEBUG"),
INFO: new Level(20000, "INFO"), WARN: new Level(30000, "WARN"), ERROR: new Level(40000, "ERROR"), FATAL: new Level(50000, "FATAL"),

假如设置默认的日志级别为info,那么权值小于info的日志不会被记录下来,也就是说只有调用log.info(), log.warn(), log.error()或者log.fatal()才会触发记录日志。该部分代码在lib/logger.js中。

Logger.prototype.log = function() {var args = Array.prototype.slice.call(arguments), logLevel = levels.toLevel(args.shift()), loggingEvent;if (this.isLevelEnabled(logLevel)) { loggingEvent = new LoggingEvent(this.category, logLevel, args, this); this.emit("log", loggingEvent); } };

2、集成express

log4js可以作为express的一个中间件来使用。首先需要引入log4js

var express = require("express");
var log4js = require("log4js");var app = express();

接着配置log4js

log4js.configure({appenders: [{ type: 'console' },{ type: 'file', filename: 'cheese.log', category: 'cheese' }]
});

该配置的意思是console是默认的appender,使用cheese这个appender时会将日志记录文件中,日志文件名为cheese.log。

然后用use连接到中间件,我们默认使用的是cheese这个appender,级别为info。

app.use(log4js.connectLogger(log4js.getLogger("cheese"), {level: log4js.levels.INFO}));

其输出与此类似:

[2014-07-04 20:27:21.205] [INFO] cheese - 127.0.0.1 - - "GET / HTTP/1.1" 200 22896 "" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36"

......

3、再修改一下中间件

上面的做法是可以的,只是当中间件太多的时候,都写在同一个文件中也许感觉会有些丑陋。所以我倾向于将其分离出来作为单独的一个模块,也就是一个单独的文件。然后对外暴露接口。

var path = require("path");
var log4js = require("log4js");/** * 日志配置 */ exports.configure = function() { log4js.configure(path.join(__dirname, "log4js.json")); } /** * 暴露到应用的日志接口,调用该方法前必须确保已经configure过 * @param name 指定log4js配置文件中的category。依此找到对应的appender。 * 如果appender没有写上category,则为默认的category。可以有多个 * @returns {Logger} */ exports.logger = function(name) { var dateFileLog = log4js.getLogger(name); dateFileLog.setLevel(log4js.levels.INFO); return dateFileLog; } /** * 用于express中间件,调用该方法前必须确保已经configure过 * @returns {Function|*} */ exports.useLog = function() { return log4js.connectLogger(log4js.getLogger("app"), {level: log4js.levels.INFO}); } 

log4js.json文件内容如下

{"appenders": [{"type": "console"},{"type": "dateFile","filename": "logs/booklist.log","pattern": "-yyyy-MM-dd", "alwaysIncludePattern": true } ] }

配置很简单,配置了两个appender,一个是控制台的,一个是dateFile,意思是每天都产生一个日志文件。注意到我这里并没有配置category,这样的话当没有找到对应的appender时,这两个appender就是默认的appender。有些时候明明感觉配置没有错,但是日志文件并没有产生日志,往往问题就出在这里。

然后在app.js中我们修改为如下

var express = require("express");
// 这个是我们上面自定义的模块
var log4js = require("./log"); var app = express(); app.configure(); app.use(log4js.useLog()); ...

4、单进程与多进程

好了,上面对于单进程是适用的,但是如果你的nodejs应用是多进程的,使用上面的配置你会看到日志的输出有点奇怪,比如:

感觉有点像是资源抢占了。

log4js的wiki中有给出multiprocess的配置。但是当时使用的时候也会有问题,当时没有细究。不过社区中有人建立了另外一种方式,我采用了这种。可以参看一下这个issue。下面我们来配置一下。修改我们在上面修改的log模块文件,变为:

var path = require("path");
var log4js = require("log4js");/** * 多进程的日志配置 */ exports.configure = function(mode) { if (mode === "master") { log4js.configure(path.join(__dirname, "./log4js-master.json")); } else { // 多进程的配置项 log4js.configure(path.join(__dirname, "./log4js-worker.json")); // 单进程的配置项 // log4js.configure(path.join(__dirname, "../config/log4js.json"));  } } /** * 暴露到应用的日志接口,调用该方法前必须确保已经configure过 * @param name 指定log4js配置文件中的category。依此找到对应的appender。 * 如果appender没有写上category,则为默认的category。可以有多个 * @returns {Logger} */ exports.logger = function(name) { var dateFileLog = log4js.getLogger(name); dateFileLog.setLevel(log4js.levels.INFO); return dateFileLog; } /** * 用于express中间件,调用该方法前必须确保已经configure过 * @returns {Function|*} */ exports.useLog = function() { return log4js.connectLogger(log4js.getLogger("app"), {level: log4js.levels.INFO}); }

主要是修改了configure方法。

log4js-master.json的内容为:

{"appenders": [{"type": "clustered","appenders": [{"type": "console"},{"type": "dateFile", "filename": "logs/booklist.log", "pattern": "-yyyy-MM-dd", "alwaysIncludePattern": true, "pollInterval": 1, "category": "dateFileLog" } ] }] }

log4js-worker.js的内容为:

{"appenders": [{"type": "clustered"}]
}

假设主进程的内容在文件master.js,工作进程在worker.js。master.js中的配置内容为:

var log4js = require("./lib/log");
log4js.configure("master");

worker.js的配置内容为:

var express = require("express");
// 这个是我们上面自定义的模块
var log4js = require("./log"); var app = express(); app.configure("worker"); app.use(log4js.useLog()); ...

如此就完成了。

需要在某个地方记录日志的时候,我们可以如此

var log = require("./log").logger("index"); // logger中的参数随便起
...
log.info("...");
log.error("...")

5、写在后面

log4js还有挺多好玩的内容,比如smtp。这是个很有用的功能,比如当项目发生某个错误时,你希望程序能发邮件通知你,该功能就能派出用场了。

另外,我开源了一个项目booklist。该项目主要在于探讨nodejs建立应用所需要或者注意的地方,非常期待各位指导与探讨,谢谢!

转载于:https://www.cnblogs.com/lcword/p/8127692.html

nodejs之日志管理相关推荐

  1. 玩转Nodejs日志管理log4js

    玩转Nodejs日志管理log4js 从零开始nodejs系列文章 从零开始nodejs系列文章,将介绍如何利Javascript做为服务端脚本,通过Nodejs框架web开发.Nodejs框架是基于 ...

  2. 喜闻乐见ELK(日志管理分析系统)

    @[TOC] #  1. 简介 ELK(日志管理分析系统),一款能将系统的日志进行分析处理,并且展示到界面上面.集各种强大功能于一身.妈妈再也不用担心我为查日志感到烦恼了. ELK核心的组件是由ela ...

  3. 码农技术炒股之路——配置管理器、日志管理器

    配置管理器和日志管理器是项目中最为独立的模块.我们可以很方便将其剥离出来供其他Python工程使用.文件的重点将是介绍Python单例和logging模块的使用.(转载请指明出于breaksoftwa ...

  4. Linux 日志管理(RHEL7)

    日志管理 系统和程序的日记本 记录系统,程序运行中发生的各种事件 通过查看日志,了解及排除故障 信息安全控制的依据 内核及系统日志 由系统服务rsyslog统一记录/管理 日志消息采用文本格式 主要记 ...

  5. mysql二进制日志管理_MYSQL二进制日志管理脚本

    MYSQL二进制日志管理脚本脚本原理是每小时对进行flush生成新的二进制日志,将二进制日志备份至NFS,并压缩存放:#!/bin/bash#Purpose:管理二进制日志,每小时刷新二进制日志,并将 ...

  6. KBMMW 的日志管理器

    kbmmw 4.82 最大的新特性就是增加了 日志管理器. 新的日志管理器实现了不同类型的日志.断言.异常处理.计时等功能. 首先.引用kbmMWLog.pas 单元后,系统就默认生成一个IkbmMW ...

  7. Kubernetes-基于EFK进行统一的日志管理

    1.统一日志管理的整体方案 通过应用和系统日志可以了解Kubernetes集群内所发生的事情,对于调试问题和监视集群活动来说日志非常有用.对于大部分的应用来说,都会具有某种日志机制.因此,大多数容器引 ...

  8. 日志管理之 Docker logs - 每天5分钟玩转 Docker 容器技术(87)

    高效的监控和日志管理对保持生产系统持续稳定地运行以及排查问题至关重要. 在微服务架构中,由于容器的数量众多以及快速变化的特性使得记录日志和监控变得越来越重要.考虑到容器短暂和不固定的生命周期,当我们需 ...

  9. linux系统中的日志管理

    Linux系统中的日志管理 1 实验环境 2 journald日志服务 2.1 journalctl命令的用法 2.2 用journald服务永久存放日志 3 rsyslog日志服务 3.1 自定义日 ...

最新文章

  1. python实用程序育儿法_Python多线程 简明例子
  2. 你需要知道的有关Selenium异常处理的都在这儿
  3. Centos下安装配置WordPress与nginx教程
  4. 13 个应该记住的最不寻常的搜索引擎
  5. 生产环境几个实用的命令整理(一)
  6. 灯珠电路图_可充电led台灯电路图
  7. [洛谷P5068][Ynoi2015]我回来了
  8. Python--day46--mysql触发器
  9. 可以使用TrafficMonitor查看本机的网速情况
  10. 基于Kinect 2.0深度摄像头的三维重建 and Kinect Fusion
  11. DDFE 技术周刊(第十期)2017.1.9
  12. 如何在物联网低代码平台中使用数据字典功能?
  13. 论文阅读笔记 | 三维目标检测——AVOD算法
  14. 电子电器外贸行业管理解决方案丨汇信
  15. 点对点视频分发:从早期互联网到ZB字节(Zettabyte)时代的分布式网络
  16. docker-compose 安装常用服务
  17. 前端之jquery基础
  18. nginx php 设置时区,laravel5.8(二十)解决时区设置差8个小时解决办法
  19. 鞍部在哪里_富春江,富春江在哪里_富春江在哪个省_属于哪个省_就去旅游网
  20. 5月份华为认证考试,100%通过率!最高分九百多!

热门文章

  1. Spark(1)——spark基本原理与启动
  2. oracle布尔true 1,将.NET布尔数据类型映射到实体框架中的oracle数(1,0)会抛出错误
  3. 402.移掉K位数字,使得剩下数字最小
  4. ResNeXt 之 输入数据预处理代码详解
  5. c++ 回调函数与std::function使用实例
  6. 快速上手ANTLR--在Windows环境下解析计算器指令语法
  7. [算法笔记]二叉树基础
  8. 普通计算机硬件,将普通显示器更改为触摸屏_计算机硬件和网络_IT /计算机_数据...
  9. linux大端小端命令,linux的大小端、网络字节序问题
  10. psql+加载mysql数据库_Go实战--go语言操作PostgreSQL数据库(github.com/lib/pq)