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 模块开发及发布详解分享
Mar 07 NodeJs
nodejs获取本机内网和外网ip地址的实现代码
Jun 01 NodeJs
轻松创建nodejs服务器(10):处理POST请求
Dec 18 NodeJs
NodeJS学习笔记之Connect中间件应用实例
Jan 27 NodeJs
nodejs中全局变量的实例解析
Mar 07 NodeJs
详解nodejs微信公众号开发——1.接入微信公众号
Apr 10 NodeJs
浅析 NodeJs 的几种文件路径
Jun 07 NodeJs
基于nodejs res.end和res.send的区别
May 14 NodeJs
nodejs之koa2请求示例(GET,POST)
Aug 07 NodeJs
nodejs使用node-xlsx生成excel的方法示例
Aug 22 NodeJs
linux 下以二进制的方式安装 nodejs
Feb 12 NodeJs
ubuntu系统下使用pm2设置nodejs开机自启动的方法
May 12 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
火影忍者:这才是千手柱间和扉间的真正死因,角都就比较搞笑了!
2020/03/10 日漫
php安全开发 添加随机字符串验证,防止伪造跨站请求
2013/02/14 PHP
JavaScript面向对象设计二 构造函数模式
2011/12/20 Javascript
当自定义数据属性为json格式字符串时jQuery的data api问题探讨
2013/02/18 Javascript
浅谈JavaScript之事件绑定
2013/07/08 Javascript
JavaScript极简入门教程(三):数组
2014/10/25 Javascript
JavaScript使用Math.Min返回两个数中较小数的方法
2015/04/06 Javascript
浅谈JavaScript中setInterval和setTimeout的使用问题
2015/08/01 Javascript
JavaScript设计模式经典之命令模式
2016/02/24 Javascript
AngularJS入门教程之ng-class 指令用法
2016/08/01 Javascript
canvas实现弧形可拖动进度条效果
2017/05/11 Javascript
web前端vue filter 过滤器
2018/01/12 Javascript
Bootstrap 中data-[*] 属性的整理
2018/03/13 Javascript
JavaScript设计模式之单例模式简单实例教程
2018/07/02 Javascript
微信打开网址添加在浏览器中打开提示的办法
2019/05/20 Javascript
Vue CLI3移动端适配(px2rem或postcss-plugin-px2rem)
2020/04/27 Javascript
JavaScript构造函数原理及实现流程解析
2020/11/19 Javascript
py中的目录与文件判别代码
2008/07/16 Python
修改Python的pyxmpp2中的主循环使其提高性能
2015/04/24 Python
python文件操作之目录遍历实例分析
2015/05/20 Python
Python常用小技巧总结
2015/06/01 Python
Python中生成Epoch的方法
2017/04/26 Python
对Python中type打开文件的方式介绍
2018/04/28 Python
Python3爬虫学习之将爬取的信息保存到本地的方法详解
2018/12/12 Python
Pytorch卷积层手动初始化权值的实例
2019/08/17 Python
浅谈Python中的字符串
2020/06/10 Python
Python docutils文档编译过程方法解析
2020/06/23 Python
电子商务网站的创业计划书
2014/01/05 职场文书
施工班组长岗位职责
2014/01/05 职场文书
三年级评语大全
2014/04/23 职场文书
广告学专业毕业生自荐信
2014/05/28 职场文书
骨干教师事迹材料
2014/12/17 职场文书
开会迟到检讨书范文
2015/05/06 职场文书
优秀党员主要事迹范文
2015/11/05 职场文书
大队委员竞选演讲稿
2015/11/20 职场文书
让人瞬间清醒的句子,句句经典,字字如金
2019/07/08 职场文书