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中Buffer模块详解
Jan 07 NodeJs
nodejs事件的监听与触发的理解分析
Feb 12 NodeJs
nodejs中使用多线程编程的方法实例
Mar 24 NodeJs
详解nodejs微信公众号开发——4.自动回复各种消息
Apr 11 NodeJs
Nodejs读取文件时相对路径的正确写法(使用fs模块)
Apr 27 NodeJs
nodejs结合socket.io实现websocket通信功能的方法
Jan 12 NodeJs
解决Nodejs全局安装模块后找不到命令的问题
May 15 NodeJs
Nodejs把接收图片base64格式保存为文件存储到服务器上
Sep 26 NodeJs
nodejs同步调用获取mysql数据时遇到的大坑
Mar 02 NodeJs
nodejs npm错误Error:UNKNOWN:unknown error,mkdir 'D:\Develop\nodejs\node_global'at Error
Mar 02 NodeJs
独立部署小程序基于nodejs的服务器过程详解
Jun 24 NodeJs
nodejs实现百度舆情接口应用示例
Feb 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 7的一些引人注目的新特性简单介绍
2015/11/08 PHP
PHP二进制与字符串之间的相互转换教程
2016/10/14 PHP
PHP hebrev()函数用法讲解
2019/02/21 PHP
PHP的静态方法与普通方法用法实例分析
2019/09/26 PHP
laravel5.6框架操作数据curd写法(查询构建器)实例分析
2020/01/26 PHP
javascript生成/解析dom的CDATA类型的字段的代码
2007/04/22 Javascript
用javascript实现的支持lrc歌词的播放器
2007/05/17 Javascript
javascript 对象定义方法 简单易学
2009/03/22 Javascript
Jquery之Ajax运用 学习运用篇
2011/09/26 Javascript
javascript 星级评分效果(手写)
2012/12/24 Javascript
用JQuery 判断某个属性是否存在hasAttr的解决方法
2013/04/26 Javascript
全面解析Bootstrap布局组件应用
2016/02/22 Javascript
微信小程序实现点击按钮移动view标签的位置功能示例【附demo源码下载】
2017/12/06 Javascript
在vue项目中优雅的使用SVG的方法实例详解
2018/12/03 Javascript
微信小程序简单的canvas裁剪图片功能详解
2019/07/12 Javascript
Vue项目实现简单的权限控制管理功能
2019/07/17 Javascript
layui 表格操作列按钮动态显示的实现方法
2019/09/06 Javascript
js实现适配移动端的拖动效果
2020/01/13 Javascript
windows如何把已安装的nodejs高版本降级为低版本(图文教程)
2020/12/14 NodeJs
简单说明Python中的装饰器的用法
2015/04/24 Python
关于python pyqt5安装失败问题的解决方法
2017/08/08 Python
python实现12306抢票及自动邮件发送提醒付款功能
2018/03/08 Python
Python之list对应元素求和的方法
2018/06/28 Python
python爬虫基础教程:requests库(二)代码实例
2019/04/09 Python
基于python框架Scrapy爬取自己的博客内容过程详解
2019/08/05 Python
CSS3的calc()做响应模式布局的实现方法
2017/09/06 HTML / CSS
amazeui页面分析之登录页面的示例代码
2020/08/25 HTML / CSS
中国专业的综合网上购物商城:京东
2016/08/02 全球购物
美国的Eastbay旗下的运动款子品牌:Final-Score
2018/01/01 全球购物
《鱼游到了纸上》教学反思
2014/02/20 职场文书
清明节扫墓活动总结
2015/02/09 职场文书
企业员工辞职信范文
2015/05/12 职场文书
水知道答案观后感
2015/06/08 职场文书
张思德观后感
2015/06/09 职场文书
六五普法学习心得体会
2016/01/21 职场文书
Python 数据结构之十大经典排序算法一文通关
2021/10/16 Python