为 Node/Express 应用程序添加监控

导航到

本文将指导您如何使用 Telegraf 为示例 nodeJS/Express 应用程序添加监控,并将指标存储在 InfluxDB 中。后续文章将涵盖数据探索和构建仪表板的过程,使用 Chronograf

为什么我们要添加监控

当我刚开始进入应用开发领域时,我很快学到的一点是,在开发环境中,应用程序似乎总是很完美,但在生产环境中,应用程序却经常出现问题。当您的应用程序面向整个世界时,您有理由相信,有时会发生错误。对您的应用程序进行监控可以为您提供关于应用程序健康状况的切实证据,使您能够就其长期发展做出更明智的决定,并有效地以更高效的方式处理出现的问题。

过程

那么,让我们来学习如何监控我们的应用程序并开始收集一些指标。我们首先需要一个要监控的示例应用程序。我慷慨地提供了一款看起来相当破旧但可以让我们玩玩的示例应用程序,这是我上学时制作的。当然,您也可以用您自己的 nodeJS 应用程序替换它。让我向您介绍 AmazonBay,一个仅销售一项商品的电子商务应用程序——冲浪板。

AmazonBay 应用程序图片<figcaption>是的,我知道冲浪板描述都是一团的乱七八糟的东西。</figcaption>

我们将打破它,修复它,然后再故意破坏它。但是,我保证在本文结束前(我希望如此)它会正常工作。如果您想跟随操作,可以在此处克隆仓库 here。您还需要安装 InfluxDBTelegraf——这些链接将带您进入安装指南,可以引导您完成所有这些有趣的事情。

市面上有很多指标库,各有优缺点,但为了节省时间和简化流程,我们将坚持使用IBM的Node应用程序指标库,可在GitHub上找到,主要因为我感觉他们的文档很详尽且易于理解。这个指标库可以与您的Node应用程序一起工作,无论您是否将其与其他库或框架(例如ExpressJS)集成。还有一些其他库,比如Coda Hale的指标库的NodeJS版本,或者这个express-node-metrics库,它被压缩成一个精巧的npm包,我强烈建议您尝试几个不同的库,以找到最适合您的。

首先,我们需要安装这个指标库

$ npm install appmetrics --save

导航到服务器文件(方便地命名为server.js),然后在服务器文件的前两行引入appmetrics库

const appmetrics = require('appmetrics');
const monitoring = appmetrics.monitor();

正如指标库的文档所述,您必须在任何其他npm模块(您希望监控的模块)的require语句之前先引入appmetrics模块。Appmetrics必须首先初始化,以便在模块加载时开始对其进行监控。第二行appmetrics.monitor()启动数据收集代理,从而使得数据可用于收集并发送到InfluxDB。

让我们在服务器文件中添加以下示例代码,以检查是否正常工作

monitoring.on('cpu', (cpu) => {
    console.log('[' + new Date(cpu.time) + '] CPU Process Percentage: ' + cpu.process + 'CPU System Percentage: ' + cpu.system);
});

一旦触发cpu事件,此函数将记录时间戳以及CPU进程百分比(应用程序使用的CPU百分比)和CPU系统百分比。通过以下命令启动服务器:

$ node server.js

您应该在终端中短暂看到一些输出。

CPU使用情况的终端输出图像<figcaption>这么多数字!</figcaption>

虽然看到应用程序确实被监控并获取了一些数据令人满意,但将所有数据收集并存储在一个地方会更有意义。这就是我们的开源数据收集代理Telegraf的用武之地。我们将通过HTTP监听服务输入插件将一些数据发送到InfluxDB(用于存储时间序列数据的数据库)。您可以在这里了解更多信息这里

在Telegraf配置文件中,在HTTP监听服务输入插件下,我已经编辑过它,以便Telegraf运行时将监听端口8186上的HTTP Post请求。重要的是要记住,通过的数据必须是Influx Line Protocol;这个特定的插件不接受任何其他格式。幸运的是,对于您,亲爱的读者,我们有许多Telegraf插件可用(您也可以自己编写!),可以接受其他数据格式,所以总有一款适合您。然而,为了我们的目的,我们将保持简单,并练习Line Protocol。

以下是我的配置文件

# # Influx HTTP write listener
  [[inputs.http_listener]]
#   ## Address and port to host HTTP listener on
    service_address = ":8186"
#
#   ## maximum duration before timing out read of the request
    read_timeout = "10s"
#   ## maximum duration before timing out write of the response
    write_timeout = "10s"
#
#   ## Maximum allowed http request body size in bytes.
#   ## 0 means to use the default of 536,870,912 bytes (500 mebibytes)
    max_body_size = 0
#
#   ## Maximum line size allowed to be sent in bytes.
#   ## 0 means to use the default of 65536 bytes (64 kibibytes)
    max_line_size = 0

您还可以进行其他编辑,例如,如果您想通过指定服务TLS证书和密钥的文件名来启用TLS,或者通过包括授权客户端连接列表来启用双向认证TLS,但我们留待另日再谈。

通过以下命令启动Telegraf:

$ telegraf -config /usr/local/etc/telegraf.conf

您应该看到它在运行的证据

终端输出图像<figcaption>事情正在发生。

现在我们已经成功配置并运行了Telegraf,是时候向InfluxDB发送一些指标了。回到我们的服务器文件中,我们将设置一个HTTP POST请求到本地Telegraf实例监听的端口,看看会发生什么。

monitoring.on('cpu', (cpu) => {
  const postData = `cpu_percentage,host=AmazonBay process=${cpu.process},system=${cpu.system} ${cpu.time}`;

  const options = {
    port: 8186,
    path: '/write?precision=ms',
    method: 'POST',
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
  };

  const req = http.request(options, (res) => {
    console.log(`STATUS: ${res.statusCode}`);
    console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
    res.setEncoding('utf8');
    res.on('data', (chunk) => {
      console.log(`BODY: ${chunk}`);
    });
    res.on('end', () => {
      console.log('No more data in response.');
    });
  });

  req.on('error', (e) => {
    console.error(`problem with request: ${e.message}`);
  });

  req.write(postData);
  req.end();
});

这里有很多事情在发生,让我来详细说明一下。当cpu事件被触发时,我们调用一个函数来执行HTTP POST请求。我们的变量postData包含了CPU进程、系统和时间戳值。在我们的options对象中,我们指定了portpath,并设置了额外的查询参数precision为毫秒,因为InfluxDB的时间戳默认为纳秒。主机默认为localhost,这对于我们的当前目的来说很合适。代码的其余部分处理我们的请求/响应功能以及错误路径。

让我们开始运行它吧!

显示日志的终端输出图像<figcaption> 日志 日志 日志</figcaption>

如果我们查询数据库,我们应该会看到一些存储在那里的数据。您可能需要调整查询的时间范围,以免终端被结果过载。

显示查询InfluxDB获取CPU百分比数据的终端输出<figcaption> 一些数据…</figcaption>

下一步

如您所见,我们的数据现在已成功存储在InfluxDB中。通过这个库还有许多其他指标可供添加并存储到InfluxDB中。我已经添加了几个,并将完成的应用程序推送到GitHub:[Instrumented-AmazonBay](https://github.com/mschae16/AmazonBay-Instrumented)。在下一篇文章中,我们将开始探索收集到的数据,并在Chronograf中构建仪表板。感谢阅读,请随时通过[联系方式](/cdn-cgi/l/email-protection#462b27342129062f28202a333e222732276825292b)[发送邮件](mailto:[email protected]),或者在Twitter上[联系我](https://twitter.com/mschae16) @mschae16提出任何问题和/或评论。