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 Post请求报socket hang up错误的解决办法
Sep 25 NodeJs
基于NodeJS的前后端分离的思考与实践(一)全栈式开发
Sep 26 NodeJs
轻松创建nodejs服务器(1):一个简单nodejs服务器例子
Dec 18 NodeJs
使用 NodeJS+Express 开发服务端的简单介绍
Apr 07 NodeJs
详解nodejs微信公众号开发——5.素材管理接口
Apr 11 NodeJs
浅谈nodejs中的类定义和继承的套路
Jul 26 NodeJs
详解nodejs通过响应回写的方式渲染页面资源
Apr 07 NodeJs
对mac下nodejs 更新到最新版本的最新方法(推荐)
May 17 NodeJs
nodejs 生成和导出 word的实例代码
Jul 31 NodeJs
NodeJs实现简单的爬虫功能案例分析
Dec 05 NodeJs
浅谈使用nodejs搭建web服务器的过程
Jul 20 NodeJs
使用 Koa + TS + ESLlint 搭建node服务器的过程详解
May 30 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
ajax实现无刷新分页(php)
2010/07/18 PHP
深入PHP许愿墙模块功能分析
2013/06/25 PHP
php计算数组不为空元素个数的方法
2014/01/27 PHP
PHP分页类集锦
2014/11/18 PHP
基于PHP微信红包的算法探讨
2016/07/21 PHP
PHP并发查询MySQL的实例代码
2017/08/09 PHP
JS HTML5 音乐天气播放器(Ajax获取天气信息)
2013/05/26 Javascript
浅谈JavaScript中Date(日期对象),Math对象
2015/02/05 Javascript
javascript数组去重方法汇总
2015/04/23 Javascript
原生js页面滚动延迟加载图片
2015/12/20 Javascript
响应式表格之固定表头的简单实现
2016/08/26 Javascript
微信小程序 开发之全局配置
2017/05/05 Javascript
ES6入门教程之let和const命令详解
2017/05/17 Javascript
Javascript 之封装(Package)
2018/09/14 Javascript
图文讲解用vue-cli脚手架创建vue项目步骤
2019/02/12 Javascript
微信小程序保持session会话的方法
2020/03/20 Javascript
JavaScript本地储存:localStorage、sessionStorage、cookie的使用
2020/10/13 Javascript
[01:30]2016国际邀请赛中国区预选赛神秘商店火爆开启
2016/06/26 DOTA
Tensorflow之构建自己的图片数据集TFrecords的方法
2018/02/07 Python
Python实现使用卷积提取图片轮廓功能示例
2018/05/12 Python
Python 中 function(#) (X)格式 和 (#)在Python3.*中的注意事项
2018/11/30 Python
python分割一个文本为多个文本的方法
2019/07/22 Python
Jupyter加载文件的实现方法
2020/04/14 Python
实例讲解CSS3中Transform的perspective属性的用法
2016/04/22 HTML / CSS
详解HTML5 LocalStorage 本地存储
2016/12/23 HTML / CSS
WoolOvers澳洲官方网站:英国针织服装公司
2018/05/13 全球购物
中级会计职业生涯规划范文
2014/01/16 职场文书
普通简短的个人自我评价
2014/02/15 职场文书
《我要的是葫芦》教学反思
2014/02/23 职场文书
道路交通事故人身损害赔偿协议书
2014/11/19 职场文书
会计工作总结范文2014
2014/12/23 职场文书
西安导游词
2015/02/12 职场文书
消防演习通知
2015/04/25 职场文书
政协常委会议主持词
2015/07/03 职场文书
Appium中scroll和drag_and_drop根据元素位置滑动
2022/02/15 Python
科学家研发出新型速效酶,可在 24 小时内降解塑料制品
2022/04/29 数码科技