log4js用法-程序员宅基地

开发过程中,日志记录是必不可少的事情,尤其是生产系统中经常无法调试,因此日志就成了重要的调试信息来源。

Node.js,已经有现成的开源日志模块,就是log4js,源码地址:点击打开链接

项目引用方法: npm install log4js

1、配置说明(仅以常用的dateFile日志类型举例,更多说明参考log4js-wiki):

[javascript] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. {   
  2.   "appenders": [   
  3.   // 下面一行应该是用于跟express配合输出web请求url日志的  
  4.   { "type""console""category""console"},   
  5.   // 定义一个日志记录器  
  6.   {        
  7.     "type""dateFile",                 // 日志文件类型,可以使用日期作为文件名的占位符  
  8.     "filename""e:/weblogs/logs/",     // 日志文件名,可以设置相对路径或绝对路径  
  9.     "pattern""debug/yyyyMMddhh.txt",  // 占位符,紧跟在filename后面  
  10.     "absolute"true,                   // filename是否绝对路径  
  11.     "alwaysIncludePattern"true,       // 文件名是否始终包含占位符  
  12.     "category""logInfo"               // 记录器名  
  13.   } ],  
  14.   "levels":{ "logInfo""DEBUG"}        // 设置记录器的默认显示级别,低于这个级别的日志,不会输出  
  15. }  

pattern可以使用的占位符说明,不属于下列占位符格式,均会原样输出为文件名(注:不支持单个M、d、h、m):
yy 两位年份
yyyy 四位年份
MM 两位月份
dd  两位日期
hh  两位的小时数,按24小时制
mm 两位的分数数
ss  两位的秒数
SSS 三位的毫秒数
O    时区,大写字母O,占位符输出结果为+0800

假设当前是2014年6月20月15点,那么上面的配置最终将会记录到 e:\weblogs\logs\debug\2014062015.txt这个文件中。


2、输出日志代码,首先请把上面的配置代码保存为log4js.json文件,用于代码从文件加载配置(配置独立也便于修改和发布):
注意:json文件不支持任何形式的注释// 或 /**/,因此上面的配置代码里的注释要全部移除,不然会编译出错的

[javascript] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. var log4js = require('log4js');  
  2.   
  3. // 注:配置里的日志目录要先创建,才能加载配置,不然会出异常  
  4. log4js.configure("./log4js.json");  
  5. var logInfo = log4js.getLogger('logInfo');  
  6. logInfo.info("测试日志信息");  


上述配置和代码,比较简单,我这边参考之前用的C#版本的日志记录类,重新封装了一下log4js,定义了一个logHelper.js

1、log4js.json配置文件内容(定义了4个日志记录器,分别写入到不同的日志目录;并自定义了2个属性,把一些公共属性提取到自定义属性中):

[javascript] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. {  
  2.     "customBaseDir" :"e:/weblogs/logs/",  
  3.     "customDefaultAtt" :{  
  4.         "type""dateFile",  
  5.         "absolute"true,  
  6.         "alwaysIncludePattern"true  
  7.     },  
  8.     "appenders": [  
  9.             { "type""console""category""console"},  
  10.             { "pattern""debug/yyyyMMddhh.txt""category""logDebug"},  
  11.             { "pattern""info/yyyyMMddhh.txt""category""logInfo"},  
  12.             { "pattern""warn/yyyyMMddhh.txt""category""logWarn"},  
  13.             { "pattern""err/yyyyMMddhh.txt""category""logErr"}  
  14.         ],  
  15.         "replaceConsole"true,  
  16.         "levels":{ "logDebug""DEBUG""logInfo""DEBUG""logWarn""DEBUG""logErr""DEBUG"}  
  17. }  

2、logHelper.js封装的文件内容:
[javascript] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. var helper = {};  
  2. exports.helper = helper;  
  3.   
  4. var log4js = require('log4js');  
  5. var fs = require("fs");  
  6. var path = require("path");  
  7.   
  8. // 加载配置文件  
  9. var objConfig = JSON.parse(fs.readFileSync("log4js.json""utf8"));  
  10.   
  11. // 检查配置文件所需的目录是否存在,不存在时创建  
  12. if(objConfig.appenders){  
  13.     var baseDir = objConfig["customBaseDir"];  
  14.     var defaultAtt = objConfig["customDefaultAtt"];  
  15.   
  16.     for(var i= 0, j=objConfig.appenders.length; i<j; i++){  
  17.         var item = objConfig.appenders[i];  
  18.         if(item["type"] == "console")  
  19.             continue;  
  20.   
  21.         if(defaultAtt != null){  
  22.             for(var att in defaultAtt){  
  23.                 if(item[att] == null)  
  24.                     item[att] = defaultAtt[att];  
  25.             }  
  26.         }  
  27.         if(baseDir != null){  
  28.             if(item["filename"] == null)  
  29.                 item["filename"] = baseDir;  
  30.             else  
  31.                 item["filename"] = baseDir + item["filename"];  
  32.         }  
  33.         var fileName = item["filename"];  
  34.         if(fileName == null)  
  35.             continue;  
  36.         var pattern = item["pattern"];  
  37.         if(pattern != null){  
  38.             fileName += pattern;  
  39.         }  
  40.         var category = item["category"];  
  41.         if(!isAbsoluteDir(fileName))//path.isAbsolute(fileName))  
  42.             throw new Error("配置节" + category + "的路径不是绝对路径:" + fileName);  
  43.         var dir = path.dirname(fileName);  
  44.         checkAndCreateDir(dir);  
  45.     }  
  46. }  
  47.   
  48. // 目录创建完毕,才加载配置,不然会出异常  
  49. log4js.configure(objConfig);  
  50.   
  51. var logDebug = log4js.getLogger('logDebug');  
  52. var logInfo = log4js.getLogger('logInfo');  
  53. var logWarn = log4js.getLogger('logWarn');  
  54. var logErr = log4js.getLogger('logErr');  
  55.   
  56. helper.writeDebug = function(msg){  
  57.     if(msg == null)  
  58.         msg = "";  
  59.     logDebug.debug(msg);  
  60. };  
  61.   
  62. helper.writeInfo = function(msg){  
  63.     if(msg == null)  
  64.         msg = "";  
  65.     logInfo.info(msg);  
  66. };  
  67.   
  68. helper.writeWarn = function(msg){  
  69.     if(msg == null)  
  70.         msg = "";  
  71.     logWarn.warn(msg);  
  72. };  
  73.   
  74. helper.writeErr = function(msg, exp){  
  75.     if(msg == null)  
  76.         msg = "";  
  77.     if(exp != null)  
  78.         msg += "\r\n" + exp;  
  79.     logErr.error(msg);  
  80. };  
  81.   
  82. // 配合express用的方法  
  83. exports.use = function(app) {  
  84.     //页面请求日志, level用auto时,默认级别是WARN  
  85.     app.use(log4js.connectLogger(logInfo, {level:'debug', format:':method :url'}));  
  86. }  
  87.   
  88. // 判断日志目录是否存在,不存在时创建日志目录  
  89. function checkAndCreateDir(dir){  
  90.     if(!fs.existsSync(dir)){  
  91.         fs.mkdirSync(dir);  
  92.     }  
  93. }  
  94.   
  95. // 指定的字符串是否绝对路径  
  96. function isAbsoluteDir(path){  
  97.     if(path == null)  
  98.         return false;  
  99.     var len = path.length;  
  100.   
  101.     var isWindows = process.platform === 'win32';  
  102.     if(isWindows){  
  103.         if(len <= 1)  
  104.             return false;  
  105.         return path[1] == ":";  
  106.     }else{  
  107.         if(len <= 0)  
  108.             return false;  
  109.         return path[0] == "/";  
  110.     }  
  111. }  

3、代码调用:
[javascript] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. var logger = require("./logHelper").helper;  
  2. logger.writeInfo("哈哈1开始记录日志");  
  3. logger.writeErr("出错了,你怎么搞的");  

4、跟express集成,可以输出客户端GET 或 POST的url(如果没用,或者不需要记录url,这段代码忽略):
[javascript] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //在app.js中添加以下代码, 以便在日志中输出url请求,由于加载顺序的原因,放在其他app.use前面  
  2. var app = express();  
  3. var log = require('./logHelper');  
  4. log.use(app); 
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zeroJustGG/article/details/72123167

智能推荐

2022黑龙江最新建筑八大员(材料员)模拟考试试题及答案_料账的试题-程序员宅基地

文章浏览阅读529次。百分百题库提供建筑八大员(材料员)考试试题、建筑八大员(材料员)考试预测题、建筑八大员(材料员)考试真题、建筑八大员(材料员)证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。310项目经理部应编制机械设备使用计划并报()审批。A监理单位B企业C建设单位D租赁单位答案:B311对技术开发、新技术和新工艺应用等情况进行的分析和评价属于()。A人力资源管理考核B材料管理考核C机械设备管理考核D技术管理考核答案:D312建筑垃圾和渣土._料账的试题

chatgpt赋能python:Python自动打开浏览器的技巧-程序员宅基地

文章浏览阅读614次。本文由chatgpt生成,文章没有在chatgpt生成的基础上进行任何的修改。以上只是chatgpt能力的冰山一角。作为通用的Aigc大模型,只是展现它原本的实力。对于颠覆工作方式的ChatGPT,应该选择拥抱而不是抗拒,未来属于“会用”AI的人。AI职场汇报智能办公文案写作效率提升教程 专注于AI+职场+办公方向。下图是课程的整体大纲下图是AI职场汇报智能办公文案写作效率提升教程中用到的ai工具。_python自动打开浏览器

Linux中安装JDK-RPM_linux 安装jdk rpm-程序员宅基地

文章浏览阅读545次。Linux中安装JDK-RPM方式_linux 安装jdk rpm

net高校志愿者管理系统-73371,计算机毕业设计(上万套实战教程,赠送源码)-程序员宅基地

文章浏览阅读25次。免费领取项目源码,请关注赞收藏并私信博主,谢谢-高校志愿者管理系统主要功能模块包括页、个人资料(个人信息。修改密码)、公共管理(轮播图、系统公告)、用户管理(管理员、志愿用户)、信息管理(志愿资讯、资讯分类)、活动分类、志愿活动、报名信息、活动心得、留言反馈,采取面对对象的开发模式进行软件的开发和硬体的架设,能很好的满足实际使用的需求,完善了对应的软体架设以及程序编码的工作,采取SQL Server 作为后台数据的主要存储单元,采用Asp.Net技术进行业务系统的编码及其开发,实现了本系统的全部功能。

小米宣布用鸿蒙了吗,小米OV对于是否采用鸿蒙保持沉默,原因是中国制造需要它们...-程序员宅基地

文章浏览阅读122次。原标题:小米OV对于是否采用鸿蒙保持沉默,原因是中国制造需要它们目前华为已开始对鸿蒙系统大规模宣传,不过中国手机四强中的另外三家小米、OPPO、vivo对于是否采用鸿蒙系统保持沉默,甚至OPPO还因此而闹出了一些风波,对此柏铭科技认为这是因为中国制造当下需要小米OV几家继续将手机出口至海外市场。 2020年中国制造支持中国经济渡过了艰难的一年,这一年中国进出口贸易额保持稳步增长的势头,成为全球唯一..._小米宣布用鸿蒙系统

Kafka Eagle_kafka eagle git-程序员宅基地

文章浏览阅读1.3k次。1.Kafka Eagle实现kafka消息监控的代码细节是什么?2.Kafka owner的组成规则是什么?3.怎样使用SQL进行kafka数据预览?4.Kafka Eagle是否支持多集群监控?1.概述在《Kafka 消息监控 - Kafka Eagle》一文中,简单的介绍了 Kafka Eagle这款监控工具的作用,截图预览,以及使用详情。今天_kafka eagle git

随便推点

Eva.js是什么(互动小游戏开发)-程序员宅基地

文章浏览阅读1.1k次,点赞29次,收藏19次。Eva.js 是一个专注于开发互动游戏项目的前端游戏引擎。:Eva.js 提供开箱即用的游戏组件供开发人员立即使用。是的,它简单而优雅!:Eva.js 由高效的运行时和渲染管道 (Pixi.JS) 提供支持,这使得释放设备的全部潜力成为可能。:得益于 ECS(实体-组件-系统)架构,你可以通过高度可定制的 API 扩展您的需求。唯一的限制是你的想象力!_eva.js

OC学习笔记-Objective-C概述和特点_objective-c特点及应用领域-程序员宅基地

文章浏览阅读1k次。Objective-C概述Objective-C是一种面向对象的计算机语言,1980年代初布莱德.考斯特在其公司Stepstone发明Objective-C,该语言是基于SmallTalk-80。1988年NeXT公司发布了OC,他的开发环境和类库叫NEXTSTEP, 1994年NExt与Sun公司发布了标准的NEXTSTEP系统,取名openStep。1996_objective-c特点及应用领域

STM32学习笔记6:TIM基本介绍_stm32 tim寄存器详解-程序员宅基地

文章浏览阅读955次,点赞20次,收藏16次。TIM(Timer)定时器定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断16位计数器、预分频器、自动重装寄存器的时基单元,在 72MHz 计数时钟下可以实现最大 59.65s 的定时,59.65s65536×65536×172MHz59.65s65536×65536×721​MHz不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能。_stm32 tim寄存器详解

前端基础语言HTML、CSS 和 JavaScript 学习指南_艾编程学习资料-程序员宅基地

文章浏览阅读1.5k次。对于任何有兴趣学习前端 Web 开发的人来说,了解 HTML、CSS 和JavaScript 之间的区别至关重要。这三种前端语言都是您访问过的每个网站的用户界面构建块。而且,虽然每种语言都有不同的功能重点,但它们都可以共同创建令人兴奋的交互式网站,让用户保持参与。因此,您会发现学习所有三种语言都很重要。如果您有兴趣从事前端开发工作,可以通过多种方式学习这些语言——在艾编程就可以参与到学习当中来。在本文中,我们将回顾每种语言的特征、它们如何协同工作以及您可以在哪里学习它们。HTML vs C._艾编程学习资料

三维重构(10):PCL点云配准_局部点云与全局点云配准-程序员宅基地

文章浏览阅读2.8k次。点云配准主要针对点云的:不完整、旋转错位、平移错位。因此要得到完整点云就需要对局部点云进行配准。为了得到被测物体的完整数据模型,需要确定一个合适的坐标系变换,将从各个视角得到的点集合并到一个统一的坐标系下形成一个完整的数据点云,然后就可以方便地进行可视化,这就是点云数据的配准。点云配准技术通过计算机技术和统计学规律,通过计算机计算两个点云之间的错位,也就是把在不同的坐标系下的得到的点云进行坐标变..._局部点云与全局点云配准

python零基础学习书-Python零基础到进阶必读的书藉:Python学习手册pdf免费下载-程序员宅基地

文章浏览阅读273次。提取码:0oorGoogle和YouTube由于Python的高可适应性、易于维护以及适合于快速开发而采用它。如果你想要编写高质量、高效的并且易于与其他语言和工具集成的代码,《Python学习手册:第4 版》将帮助你使用Python快速实现这一点,不管你是编程新手还是Python初学者。本书是易于掌握和自学的教程,根据作者Python专家Mark Lutz的著名培训课程编写而成。《Python学习..._零基础学pythonpdf电子书