教你在Nodejs中如何获取当前函数被调用的行数及文件名
- 苏格团队
- 作者:MaxPan
- 交流QQ群:855833773
背景
在自定义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的信息如下图:
在图上我们可以看到,我们想要的信息
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 '[-]';}
}复制代码
最终结果
最后我们每条打印的日志后面,都会跟上文件名和行数
有的同学可能担心,每次打log都抛一个异常,会不会对性能造成影响。
我在getCallerFileNameAndLine
方法前后进行打点统计,平均执行时间在2ms
左右,所以是可以忽略不计的。
教你在Nodejs中如何获取当前函数被调用的行数及文件名相关推荐
- html文本框容纳行数和列数,html中怎么获取多行文本框的行数
2010-05-28 回答 你直接把这个拷贝到一个html文件中,打开就可以看效果,我建议你在生成table的时候可以把text的框加一个id,id中包含它属于的行和列,这样在点击text的时候可以很 ...
- linux c++ 等待函数,JavaScript在nodejs中实现sleep休眠函数wait等待的方法
参考文档: JavaScript在nodejs中实现sleep休眠函数wait等待的方法: https://www.bas369.com/more/l... js的休眠实现---sleep(): ht ...
- mysql+影响的行数+获取_CI中获取读操作的结果集行数+获取写操作的影响行数
本质:读操作,用mysql_num_rows函数,写操作用mysql_affected_rows函数 mysql_num_rows() 返回结果集中行的数目.此命令仅对 SELECT 语句有效.要取得 ...
- java1.8中javassist获取接口函数参数名称
前提条件 在java8中要获取类函数参数名称必须在编译时增加参数 编译器时加上-parameters参数 具体内容详见 java1.8获取类和接口函数参数名称 尝试使用javassist获取接口函数名 ...
- dojo——AMD(二、AMD中class内部成员函数相互调用实现)
一.引言 这两天写arcgis javascript代码的时候,自己以为对dojo的amd规范掌握了,可是后来碰到了一个问题,在每个module中成员函数调用另外一个成员函数必须使用this调用(这点 ...
- mysql group by 行数_mysql获取group by的总记录行数另类方法
mysql获取group by内部可以获取到某字段的记录分组统计总数,而无法统计出分组的记录数. mysql的SQL_CALC_FOUND_ROWS 使用 获取查询的行数 在很多分页的程序中都这样写: ...
- node.js超过php,在nodejs中如何解决超出最大的调用栈错误
这篇文章主要介绍了nodejs超出最大的调用栈错误问题,需要的朋友可以参考下 今天早上老大和我说之前项目里面的那个数据要改动,要对 mongodb 中每条记录进行 update 操作,你写个脚本跑一下 ...
- 替代GDA中的获取rpc函数poDataset->GetMetadata(“RPC“)
使用gdal获取经纬度可以通过API this->poDataset->GetMetadata("RPC")来自动实现定位rpc文件,并且将内容读入到char** pa ...
- 神经网络模型中class的forward函数何时调用_总结深度学习PyTorch神经网络箱使用...
↑ 点击蓝字 关注极市平台来源丨计算机视觉联盟编辑丨极市平台 极市导读 本文介绍了Pytorch神经网络箱的使用,包括核心组件.神经网络实例.构建方法.优化器比较等内容,非常全面.>>加入 ...
最新文章
- Windows 8.1 重复数据删除
- kali怎么新建文本_甘特图怎么画?零基础快速绘制甘特图的软件
- Spring MVC文件上传示例教程 - 单个和多个文件
- 跨部门不配合工作_同事不配合工作,划水甚至推诿,该怎么体现你的手腕
- 使用JWT保护你的Spring Boot应用 - Spring Security实战
- LitePal(版本1.5.0,写此博客时是最新版本)
- Moore型状态机和Mealy型状态机的区别以及各自Verilog的实现细节:为什么Moore型状态机需要多一个状态?怎么选择用哪一种状态机?
- 世界名牌大学课件下载地址
- 机器人风马_泰迦奥特曼介绍了三个超兽,其中一个克制风马奥特曼
- 利用群体遗传数据估计基因组上重组率
- python判断按键是否按下_python – 如何检查键修饰符是否被按下(shift,ctrl,alt)?
- matlab毕业答辩会问什么,论文答辩必备:自述模板和注意问题
- 数据结构更新中...
- P1796 汤姆斯的天堂梦_NOI导刊2010提高(05)
- 如何用多台机器产生agent到A上。
- 进出口海运货物保险条款及做法
- Badusb 攻击之MacOSX系统实战
- CnOpenData中国发明公布专利事务表
- FLEX 4.6 Spark DataGrid 一些的用法
- android自定义下拉筛选,android自定义Spinner下拉菜单(下拉列表框)样式