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的前后端分离的思考与实践(二)模版探索
Sep 26 NodeJs
nodejs教程之环境安装及运行
Nov 21 NodeJs
NodeJS学习笔记之Connect中间件模块(一)
Jan 27 NodeJs
Nodejs学习笔记之入门篇
Apr 16 NodeJs
Nodejs如何搭建Web服务器
Mar 28 NodeJs
Nodejs 发送Post请求功能(发短信验证码例子)
Feb 09 NodeJs
nodejs搭建本地http服务器教程
Mar 13 NodeJs
Nodejs 和Session 原理及实战技巧小结
Aug 25 NodeJs
Nodejs中crypto模块的安全知识讲解
Jan 03 NodeJs
NodeJS实现不可逆加密与密码密文保存的方法
Mar 16 NodeJs
原生nodejs使用websocket代码分享
Apr 07 NodeJs
NodeJs入门教程之定时器和队列
Mar 08 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中实现Bloom Filter算法
2015/03/30 PHP
搜索附近的人PHP实现代码
2018/02/11 PHP
Yii2框架加载css和js文件的方法分析
2019/05/25 PHP
ExtJS 设置级联菜单的默认值
2010/06/13 Javascript
javascript继承之为什么要继承
2012/11/10 Javascript
一个简单的jquery的多选下拉框(自写)
2014/05/05 Javascript
jQuery中:only-child选择器用法实例
2015/01/03 Javascript
js实现jquery的offset()方法实例
2015/01/10 Javascript
Javascript显示和隐藏ul列表的方法
2015/07/15 Javascript
全面解析Bootstrap表单使用方法(表单按钮)
2015/11/24 Javascript
郁闷!ionic中获取ng-model绑定的值为undefined如何解决
2016/08/27 Javascript
微信小程序 Canvas增强组件实例详解及源码分享
2017/01/04 Javascript
JavaScript门面模式详解
2017/10/19 Javascript
jQuery实现动态添加和删除input框代码实例
2019/03/29 jQuery
Node.js中package.json中库的版本号(~和^)
2019/04/02 Javascript
Vue解析剪切板图片并实现发送功能
2020/02/04 Javascript
详解Vue中的MVVM原理和实现方法
2020/07/15 Javascript
react ant Design手动设置表单的值操作
2020/10/31 Javascript
进一步探究Python中的正则表达式
2015/04/28 Python
详解django三种文件下载方式
2018/04/06 Python
bluepy 一款python封装的BLE利器简单介绍
2019/06/25 Python
python实现的Iou与Giou代码
2020/01/18 Python
记一次django内存异常排查及解决方法
2020/08/07 Python
英国奢侈品网站:MatchesFashion
2016/12/16 全球购物
荷兰时尚精品店:Labels Fashion
2020/03/22 全球购物
Bloomingdale’s阿联酋:选购奢华时尚、美容及更多
2020/09/22 全球购物
小学信息技术教学反思
2014/02/10 职场文书
公职人员索取回扣检举信
2014/04/04 职场文书
奉献演讲稿范文
2014/05/21 职场文书
大学生自我评价200字(4篇)
2014/09/17 职场文书
计算机实训心得体会
2016/01/14 职场文书
python实现ROA算子边缘检测算法
2021/04/05 Python
教你使用Python获取QQ音乐某个歌手的歌单
2022/04/03 Python
一行Python命令实现批量加水印
2022/04/07 Python
vue+elementUI实现表格列的显示与隐藏
2022/04/13 Vue.js
Apache POI操作批量导入MySQL数据库
2022/06/21 Servers