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 相关文章推荐
14款NodeJS Web框架推荐
Jul 11 NodeJs
使用nodejs、Python写的一个简易HTTP静态文件服务器
Jul 18 NodeJs
nodejs下打包模块archiver详解
Dec 03 NodeJs
nodejs中的fiber(纤程)库详解
Mar 24 NodeJs
浅析Nodejs npm常用命令
Jun 14 NodeJs
nodeJs内存泄漏问题详解
Sep 05 NodeJs
Ajax异步文件上传与NodeJS express服务端处理
Apr 01 NodeJs
NodeJS基础API搭建服务器详细过程记录
Apr 01 NodeJs
详解nodeJS之二进制buffer对象
Jun 03 NodeJs
nodejs 日志模块winston的使用方法
May 02 NodeJs
NodeJs 文件系统操作模块fs使用方法详解
Nov 26 NodeJs
nodejs+koa2 实现模仿springMVC框架
Oct 21 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自动更新新闻DIY
2006/10/09 PHP
PHP 配置文件中open_basedir选项作用
2009/07/19 PHP
PHP 5.3.0 安装分析心得
2009/08/07 PHP
php循环table实现一行两列显示的方法
2015/06/04 PHP
简单介绍win7下搭建apache+php+mysql开发环境
2015/08/06 PHP
PHP正则匹配操作简单示例【preg_match_all应用】
2017/07/10 PHP
js+FSO遍历文件夹下文件并显示
2007/03/07 Javascript
Javascript 学习书 推荐
2009/06/13 Javascript
网页下载文件期间如何防止用户对网页进行其他操作
2014/06/27 Javascript
jQuery实现HTML表格单元格的合并功能
2016/04/06 Javascript
详解JavaScript中|单竖杠运算符的使用方法
2016/05/23 Javascript
JavaScript正则表达式简单实用实例
2017/06/23 Javascript
Vue2.0 组件传值通讯的示例代码
2017/08/01 Javascript
JS实现中文汉字按拼音排序的方法
2017/10/09 Javascript
javascript 判断用户有没有操作页面
2017/10/17 Javascript
Angular实现的日程表功能【可添加及隐藏显示内容】
2017/12/27 Javascript
vue-cli项目根据线上环境分别打出测试包和生产包
2018/05/23 Javascript
JavaScript类的继承方法小结【组合继承分析】
2018/07/11 Javascript
Vue封装Axios请求和拦截器的步骤
2020/09/16 Javascript
tornado框架blog模块分析与使用
2013/11/21 Python
在树莓派2或树莓派B+上安装Python和OpenCV的教程
2015/03/30 Python
Python实现获取域名所用服务器的真实IP
2015/10/25 Python
Python实现字符串逆序输出功能示例
2017/06/24 Python
django 将model转换为字典的方法示例
2018/10/16 Python
详解python列表(list)的使用技巧及高级操作
2019/08/15 Python
关于python3中setup.py小概念解析
2019/08/22 Python
Python如何根据时间序列数据作图
2020/05/12 Python
python如何保存文本文件
2020/06/07 Python
Python进行特征提取的示例代码
2020/10/15 Python
python BeautifulSoup库的安装与使用
2020/12/17 Python
css3 transform及原生js实现鼠标拖动3D立方体旋转
2016/06/20 HTML / CSS
动物学专业毕业生求职信
2013/10/11 职场文书
早会主持词
2014/03/17 职场文书
煤矿安全协议书
2014/08/20 职场文书
六年级作文之预言作文
2019/10/25 职场文书
三种方式清除vue路由跳转router-link的历史记录
2022/04/10 Vue.js