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的前后端分离的思考与实践(一)全栈式开发
Sep 26 NodeJs
nodejs初步体验篇
Nov 23 NodeJs
详解nodejs 文本操作模块-fs模块(二)
Dec 22 NodeJs
nodejs基础应用
Feb 03 NodeJs
NodeJS测试框架mocha入门教程
Mar 28 NodeJs
NodeJS基础API搭建服务器详细过程记录
Apr 01 NodeJs
nodejs 终端打印进度条实例代码
Apr 22 NodeJs
nodejs npm错误Error:UNKNOWN:unknown error,mkdir 'D:\Develop\nodejs\node_global'at Error
Mar 02 NodeJs
typescript nodejs 依赖注入实现方法代码详解
Jul 21 NodeJs
NodeJS http模块用法示例【创建web服务器/客户端】
Nov 05 NodeJs
NodeJS实现一个聊天室功能
Nov 25 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
PHP4实际应用经验篇(6)
2006/10/09 PHP
php urlencode()与urldecode()函数字符编码原理详解
2011/12/06 PHP
深入浅析yii2-gii自定义模板的方法
2016/04/26 PHP
探讨js字符串数组拼接的性能问题
2014/10/11 Javascript
js操作css属性实现div层展开关闭效果的方法
2015/05/11 Javascript
javascript+HTML5的canvas实现七夕情人节3D玫瑰花效果代码
2015/08/04 Javascript
实例详解jQuery结合GridView控件的使用方法
2016/01/04 Javascript
jquery实现的判断倒计时是否结束代码
2016/02/05 Javascript
JavaScript面试题(指针、帽子和女朋友)
2016/11/23 Javascript
jQuery实现鼠标悬停3d菜单展开动画效果
2017/01/19 Javascript
Vuex提升学习篇
2018/01/11 Javascript
使用Vue生成动态表单
2019/11/26 Javascript
vue中后端做Excel导出功能返回数据流前端的处理操作
2020/09/08 Javascript
[04:16]DOTA2英雄梦之声_第09期_斧王
2014/06/21 DOTA
python实现dnspod自动更新dns解析的方法
2014/02/14 Python
用python 制作图片转pdf工具
2015/01/30 Python
Python实现批量更换指定目录下文件扩展名的方法
2016/09/19 Python
Python学习小技巧之列表项的推导式与过滤操作
2017/05/20 Python
解决Pycharm无法import自己安装的第三方module问题
2018/05/18 Python
详解Python装饰器
2019/03/25 Python
python实现windows倒计时锁屏功能
2019/07/30 Python
python FTP批量下载/删除/上传实例
2019/12/22 Python
python pyqtgraph 保存图片到本地的实例
2020/03/14 Python
Python try except finally资源回收的实现
2021/01/25 Python
详解HTML5中垂直上下居中的解决方案
2017/12/20 HTML / CSS
SHEIN美国:购买时髦的女性服装
2020/12/02 全球购物
教师年终个人自我评价
2013/10/04 职场文书
万年牢教学反思
2014/02/15 职场文书
安康杯竞赛活动总结
2014/05/05 职场文书
抗震救灾标语
2014/06/26 职场文书
人事局接收函
2015/01/30 职场文书
2015年前台文员工作总结
2015/05/18 职场文书
2019个人工作总结
2019/06/21 职场文书
2019年销售部季度工作计划3篇
2019/10/09 职场文书
MySQL EXPLAIN输出列的详细解释
2021/05/12 MySQL
教你怎么用Python实现GIF动图的提取及合成
2021/06/15 Python