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为什么选择javascript为载体语言
Jan 13 NodeJs
NodeJS实现客户端js加密
Jan 09 NodeJs
nodejs操作mysql实现增删改查的实例
May 28 NodeJs
nodejs集成sqlite使用示例
Jun 05 NodeJs
Nodejs之http的表单提交
Jul 07 NodeJs
基于nodejs+express4.X实现文件下载的实例代码
Jul 13 NodeJs
nodejs对express中next函数的一些理解
Sep 08 NodeJs
nodejs简单读写excel内容的方法示例
Mar 16 NodeJs
nodejs实现套接字服务功能详解
Jun 21 NodeJs
nodejs中方法和模块用法示例
Dec 24 NodeJs
Nodejs异步流程框架async的方法
Jun 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
乱谈我对耳机、音箱的感受
2021/03/02 无线电
set_include_path在win和linux下的区别
2008/01/10 PHP
PHP 获取客户端真实IP地址多种方法小结
2010/05/15 PHP
PHP 事件机制(2)
2011/03/23 PHP
ThinkPHP多表联合查询的常用方法
2020/03/24 PHP
分享下php5类中三种数据类型的区别
2015/01/26 PHP
php编写简单的文章发布程序
2015/06/18 PHP
thinkphp5.1 文件引入路径问题及注意事项
2018/06/13 PHP
jquery及原生js获取select下拉框选中的值示例
2013/10/25 Javascript
js动态设置div的值下例子
2013/10/29 Javascript
兼容IE、firefox以及chrome的js获取时间(getFullYear)
2014/07/04 Javascript
学习Bootstrap滚动监听 附调用方法
2016/07/02 Javascript
jQuery使用deferreds串行多个ajax请求
2016/08/22 Javascript
JavaScript-html标题滚动效果的简单实现
2016/09/08 Javascript
详解Js模板引擎(TrimPath)
2016/11/22 Javascript
js实现文字无缝向上滚动
2017/02/16 Javascript
浅析Angular2子模块以及异步加载
2017/04/24 Javascript
JavaScript变量作用域_动力节点Java学院整理
2017/06/27 Javascript
解决vue 表格table列求和的问题
2019/11/06 Javascript
antd Form组件方法getFieldsValue获取自定义组件的值操作
2020/10/29 Javascript
[01:11:21]DOTA2-DPC中国联赛 正赛 VG vs Elephant BO3 第一场 3月6日
2021/03/11 DOTA
Python使用pymysql小技巧
2017/06/04 Python
用python编写第一个IDA插件的实例
2018/05/29 Python
浅谈python在提示符下使用open打开文件失败的原因及解决方法
2018/11/30 Python
Django框架会话技术实例分析【Cookie与Session】
2019/05/24 Python
英国著名的化妆品折扣网站:Allbeauty.com
2016/07/21 全球购物
Fashion Eyewear美国:英国线上设计师眼镜和太阳镜的零售商
2016/08/15 全球购物
Zavvi西班牙:电子游戏、极客服装、Blu-ray、Funko Pop等
2019/05/03 全球购物
英国最大的独立玩具专卖店:The Entertainer
2019/09/06 全球购物
Linux如何修改文件和文件夹的权限
2012/06/27 面试题
软件测试题目
2013/02/27 面试题
优秀广告词大全
2014/03/19 职场文书
欢迎新生标语
2014/10/06 职场文书
综治维稳工作汇报
2014/10/27 职场文书
房产公证书格式
2015/01/26 职场文书
党性教育心得体会(共6篇)
2016/01/21 职场文书