第六十八期:聊一聊Node程序调试(一)

2022-07-15 10:43:09 浏览数 (1)

也许我们并不懂得如何调试Node

有很多Node模块都依赖于第三方的调试模块,一些比较有名的代码库,比如express ,Koa 等等,同样也使用调试模块儿。

在许多代码库中,有大量的调试日志相关的内容,我们可以通过他们来理解我们的应用程序是怎样的一个行为。

启动调试日志

我们还是从简单的创建一个项目开始。

代码语言:javascript复制
mkdir app
cd app
npm init -y
npm install --save express
touch index.js

index.js中内容如下:

我这里沿用了上期的内容

代码语言:javascript复制
// require('cute-stack')()
const express = require('express')
const routes = require('./routes')
const app = express()
const stylus = require('stylus')

// if (process.env.NODE_ENV !== 'production') {
// Error.stackTraceLimit = Infinity
// require('longjohn')
// }

// app.use(routes)
app.get('/some.css', (req, res) => {
  const css = stylus(`
    body
      color:red
  `).render(css)
  res.send(css)
})

app.listen(3000)

然后我们开启(debug logging)调试日志:

代码语言:javascript复制
DEBUG=* node index.js

记得需要先安装下stylus依赖包,不然会报错。

然后我们可以看到如下内容:

我们可以看到类似:

代码语言:javascript复制
express:application set "x-powered-by" to true  1ms

这样的信息。这条信息告诉我们当前的服务器运行的是哪款软件,当然不公开这些信息,安全性相对来说会高一点。

这些调试日志可以帮助我们理解我们的应用是如何运行的,同时也可以让我们监控到一些我们不希望看到的内容。

我们发起一个请求:

代码语言:javascript复制
curl http://localhost:3000/some.css

然后终端上会输出下面的内容:

如果你仔细看的话,可以发现,其实它是stylus的解析器解析的一个过程,当然,我们可以过虑掉stylus,只看express的日志。

只需要执行:

代码语言:javascript复制
DEBUG=express:* node index.js

这时候重新发送请求,就直接将stylus相关的日志过虑掉了。

DEBUG=express:* 命令是如何工作的

刚开始的时候,我们将DEBUG设置为星号,表示启用所有日志。当我们想看express相关的日志时,我们设置成了DEBUG=express:* 表示以express:开头的日志。

按照惯例,模块儿和框架一般使用冒号分割子命名空间。

在调试模块内部代码中,它们从process.env.DEBUG中读取数据,按空格,逗号进行分割,然后转换为正则表达式。

当一个模块需要使用debug模块的时候,它需要一个能够代表自身的命名空间来创建一个方法,这个方法可以在模块启用调试日志的时候,将日志信息进行输出。

每次模块向调试模块进行注册时,都会根据命名空间踢动的正则表达式进行校验。

如果匹配不到,则生成的方日志方法就是noop空函数,这样,调试日志在生产中的成本最低。

如果存在匹配项,返回的日志函数将接受输入,用ANSI代码装饰它,并在每次调用Logger时创建一个时间戳。

如何调试代码

我们可以使用debug模块对代码进行调试。

安装debug模块

代码语言:javascript复制
npm install --save debug

在需要调试的位置加入代码:

代码语言:javascript复制
// require('cute-stack')()
const express = require('express')
const routes = require('./routes')
const app = express()
const stylus = require('stylus')
const debug = require('debug')('terrence')

// if (process.env.NODE_ENV !== 'production') {
// Error.stackTraceLimit = Infinity
// require('longjohn')
// }

// app.use(routes)
app.get('/some.css', (req, res) => {
  debug('style requested')
  const css = stylus(`
    body
      color:red
  `).render()
  res.send(css)
})

app.listen(3000)

然后启动程序

代码语言:javascript复制
DEBUG=terrence node index.js

发起请求后就可以看到结果

生产环境中使用

默认的调试日志并不适用于生成环境。因为默认的日志是为了方便人们阅读,而不是机器阅读。终端支持的带有颜色的ANSI代码存到数据库或保存到文件时会产生额外的污染。

所以,生产环境中,假如我们需要开启日志,我们可以这样做:

代码语言:javascript复制
DEBUG_COLORS=no DEBUG=* node index.js

JSON格式的日志

我们可以使用pino-debug 模块创建json格式的日志。

安装pino-debug:

代码语言:javascript复制
npm install --save pino-debug

写个配置文件:

代码语言:javascript复制
{
  "main": "index.js",
  "scripts": {
    "dev": "node index.js",
    "prod": "node -r pino-debug index.js"
  }
}

运行一下:

代码语言:javascript复制
DEBUG=* npm run --silent prod

出来的就是JSON格式的日志:

0 人点赞