Nodejs中获取当前函数被调用的行数及文件名详解

  

  

在自定义鸡蛋。js的请求级别日志这篇文章中,我们实现了自定义请求级别的日志模块。看上去功能是完整了,但好像还缺点什么。
  

  

大家在根据日志追查问题的过程中,很多时候看到了某条日志信息想去找出处,但是实际上代码里面打相同类型的日志地方可能不止一处,这时你就比较难去定位这行日志到底是哪里打的。
  

  

<强>举个最极端的例子
  

     //home.js   类有一个扩展app.Controller {   异步第(){   this.ctx.swLog.info(“在控制器”);   等待this.ctx.render (“first.html”);   }      异步第二(){   this.ctx.swLog.info(“控制器”)   等待this.ctx.render (“second.html”);   }   }      

上面的例子虽然比较极端,但是我们在代码中难免会碰到类似的情况。两个路线对于的控制器中都打印了相同的日志,你在查日志的时候,是无法区分日志到底是第一里面打的还是第二里面打的。
  这个时候,我们就需要在日志打印的时候,同时也将调用日志时的文件名和代码行数记录下来一并打印,效果如下
  

  
  

[2018-11-02 19:25:09.665][22896][回家。js: 4][/]在控制器

     


  

  

查了很久的Nodejs文档,发现Nodejs的api中并没有直接提供我们想到的信息,所以只能另找出路。
  回忆我们以往的开发,这类的信息好像只有在Nodejs抛出异常的时候看到过。每当Nodejs抛出异常时,我们都能看到一堆异常调用的堆栈,里面就有我们想要的信息,我们从这开始入手。
  我们先手动创造一个异常对象,并打印出来
  

        函数getException () {   尝试{   把错误(”);   }捕捉(err) {   返回错误;   }   }      让犯错=getException ();    console.log(错);      

控制台的信息如下图:

  

 Nodejs中获取当前函数被调用的行数及文件名详解

  

在图上我们可以看的到,我们想要的信息

  

 Nodejs中获取当前函数被调用的行数及文件名详解

  

犯错对象在控制台的时候,会直接输出犯错对象中堆栈的属性,该属性是个字符串,我们可以通过一系列的字符串操作,拿到我们想要的文件名和行数。
  

  

接下来我们开始对日志模块代码进行改造,新增一个getCallerFileNameAndLine方法,如下:
  

        getCallerFileNameAndLine () {   函数getException () {   尝试{   把错误(”);   }捕捉(err) {   返回错误;   }   }      const呃=getException ();      const堆栈=err.stack;   const stackArr=stack.split (“\ n”);   让callerLogIndex=0;   (让我=0;我& lt;stackArr.length;我+ +){   如果(stackArr[我].indexOf (“Map.Logger”)比;0,,我+ 1 & lt;stackArr.length) {   callerLogIndex=i + 1;   打破;   }   }      如果(callerLogIndex !==0) {   const callerStackLine=stackArr [callerLogIndex];   返回的[$ {callerStackLine.substring (callerStackLine.lastIndexOf (path.sep) + 1, callerStackLine.lastIndexOf (': '))})”;   其他}{   返回“[-]”;   }   }      


  

  

最后我们每条打印的日志后面,都会跟上文件名和行数

  

 Nodejs中获取当前函数被调用的行数及文件名详解

  

有的同学可能担心,每次打日志都抛一个异常,会不会对性能造成影响。
  我在getCallerFileNameAndLine方法前后进行打点统计,平均执行时间在2女士左右,所以是可以忽略不计的。

  

  

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。

Nodejs中获取当前函数被调用的行数及文件名详解