Nodejs中获取当前函数被调用的行数及文件名详解


Posted in NodeJs onDecember 12, 2018

背景

在自定义Egg.js的请求级别日志这篇文章中,我们实现了自定义请求级别的日志模块。看上去功能是完整了,但好像还缺点什么。

大家在根据日志追查问题的过程中,很多时候看到了某条log信息想去找出处,但是实际上代码里面打相同类型的log地方可能不止一处,这时你就比较难去定位这行log到底是哪里打的。

举个最极端的例子

//home.js
class AppController extends app.Controller {
 async first() {
 this.ctx.swLog.info('in controller');
 await this.ctx.render('first.html');
 }
 
 async second(){
 this.ctx.swLog.info('in controller')
 await this.ctx.render('second.html');
 }
}

上面的例子虽然比较极端,但是我们在代码中难免会碰到类似的情况。两个route对于的controller中都打印了相同的log,你在查日志的时候,是无法区分log到底是first里面打的还是second里面打的。
这个时候,我们就需要在日志打印的时候,同时也将调用日志时的文件名和代码行数记录下来一并打印,效果如下

[2018-11-02 19:25:09.665][22896][home.js:4][/] in controller

开始动手

查了很久的Nodejs文档,发现Nodejs的api中并没有直接提供我们想到的信息,所以只能另找出路。
回忆我们以往的开发,这类的信息好像只有在Nodejs抛出异常的时候看到过。每当Nodejs抛出异常时,我们都能看到一堆异常调用的堆栈,里面就有我们想要的信息,我们从这开始入手。
我们先手动创造一个异常对象,并打印出来

function getException() {
 try {
 throw Error('');
 } catch (err) {
 return err;
 }
}
 
let err = getException();
console.log(err);

console的信息如下图:

Nodejs中获取当前函数被调用的行数及文件名详解

在图上我们可以看到,我们想要的信息

Nodejs中获取当前函数被调用的行数及文件名详解

err对象在console的时候,会直接输出err对象中的stack属性,该属性是个字符串,我们可以通过一系列的字符串操作,拿到我们想要的文件名和行数。

接下来我们开始对日志模块代码进行改造,新增一个getCallerFileNameAndLine方法,如下:

getCallerFileNameAndLine(){
 function getException() {
  try {
  throw Error('');
  } catch (err) {
  return err;
  }
 }
 
 const err = getException();

 const stack = err.stack;
 const stackArr = stack.split('\n');
 let callerLogIndex = 0;
 for (let i = 0; i < stackArr.length; i++) {
 if (stackArr[i].indexOf('Map.Logger') > 0 && i + 1 < stackArr.length) {
  callerLogIndex = i + 1;
  break;
 }
 }

 if (callerLogIndex !== 0) {
 const callerStackLine = stackArr[callerLogIndex];
 return `[${callerStackLine.substring(callerStackLine.lastIndexOf(path.sep) + 1, callerStackLine.lastIndexOf(':'))}]`;
 } else {
 return '[-]';
 }
}

最终结果

最后我们每条打印的日志后面,都会跟上文件名和行数

Nodejs中获取当前函数被调用的行数及文件名详解

有的同学可能担心,每次打log都抛一个异常,会不会对性能造成影响。
我在getCallerFileNameAndLine方法前后进行打点统计,平均执行时间在2ms左右,所以是可以忽略不计的。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

NodeJs 相关文章推荐
用nodejs实现PHP的print_r函数代码
Mar 14 NodeJs
使用DNode实现php和nodejs之间通信的简单实例
Jul 06 NodeJs
Nodejs下使用gm圆形裁剪并合成图片的示例
Feb 22 NodeJs
nodejs多版本管理总结
Apr 03 NodeJs
nodejs(officegen)+vue(axios)在客户端导出word文档的方法
Jul 31 NodeJs
NodeJS 将文件夹按照存放路径变成一个对应的JSON的方法
Oct 17 NodeJs
nodejs图片处理工具gm用法小结
Dec 12 NodeJs
Nodejs中怎么实现函数的串行执行
Mar 02 NodeJs
nodejs中实现用户注册路由功能
May 20 NodeJs
Nodejs监听日志文件的变化的过程解析
Aug 04 NodeJs
nodejs+koa2 实现模仿springMVC框架
Oct 21 NodeJs
分享五个Node.js开发的优秀实践 
Apr 07 NodeJs
nodejs图片处理工具gm用法小结
Dec 12 #NodeJs
详解nodejs解压版安装和配置(带有搭建前端项目脚手架)
Dec 06 #NodeJs
NodeJs实现简单的爬虫功能案例分析
Dec 05 #NodeJs
nodejs 使用 js 模块的方法实例详解
Dec 04 #NodeJs
使用koa-log4管理nodeJs日志笔记的使用方法
Nov 30 #NodeJs
nodejs 使用nodejs-websocket模块实现点对点实时通讯
Nov 28 #NodeJs
NodeJs 文件系统操作模块fs使用方法详解
Nov 26 #NodeJs
You might like
PHP+MySQL 制作简单的留言本
2009/11/02 PHP
用PHP的超级变量$_POST获取HTML表单(HTML Form) 数据
2011/05/07 PHP
使用图灵api创建微信聊天机器人
2015/07/23 PHP
用js代码改变单选框选中状态的简单实例
2013/12/18 Javascript
JavaScript中实现PHP的打乱数组函数shuffle实例
2014/10/11 Javascript
JavaScript 学习笔记之操作符(续)
2015/01/14 Javascript
jquery插件corner实现圆角边框的方法
2015/03/09 Javascript
js鼠标点击图片切换效果代码分享
2015/08/26 Javascript
node.js连接mongoDB数据库 快速搭建自己的web服务
2016/04/17 Javascript
深入理解jquery中的事件与动画
2016/05/24 Javascript
Vue.js实现微信过渡动画左右切换效果
2017/06/13 Javascript
微信小程序多列选择器range-key使用详解
2020/03/30 Javascript
Vue.js通用应用框架-Nuxt.js的上手教程
2017/12/25 Javascript
浅谈Python中的闭包
2015/07/08 Python
cmd运行python文件时对结果进行保存的方法
2018/05/16 Python
python的pytest框架之命令行参数详解(下)
2019/06/27 Python
检测python爬虫时是否代理ip伪装成功的方法
2019/07/12 Python
python 实现return返回多个值
2019/11/19 Python
Python Tkinter模块 GUI 可视化实例
2019/11/20 Python
python re模块匹配贪婪和非贪婪模式详解
2020/02/11 Python
澳大利亚领先的运动鞋商店:Hype DC
2018/03/31 全球购物
美国最大的在线寄售和旧货店:Swap.com
2018/08/27 全球购物
牵手50香港:专为黄金岁月的单身人士而设的交友网站
2020/08/14 全球购物
个人自我鉴定怎么写
2013/10/28 职场文书
法律进学校实施方案
2014/03/15 职场文书
共产党员公开承诺书范文
2014/03/28 职场文书
学习之星事迹材料
2014/05/17 职场文书
关于奉献的演讲稿
2014/05/21 职场文书
羽毛球比赛策划方案
2014/06/13 职场文书
学校四风问题对照检查材料思想汇报
2014/09/26 职场文书
学年个人总结范文
2015/03/05 职场文书
2015年创先争优工作总结
2015/05/23 职场文书
科普 | 业余无线电知识-波段篇
2022/02/18 无线电
Python正则表达式中flags参数的实例详解
2022/04/01 Python
动作冒险《Hell Is Us》将采用虚幻5 消灭怪物探索王国
2022/04/13 其他游戏
Win11查看设备管理器
2022/04/19 数码科技