Sensu 和 InfluxDB:存储来自指标收集检查的数据
作者:Noah Crowley / 产品, 开发者, 用例
2018 年 1 月 19 日
导航到
Sensu 是一种流行的应用程序和基础设施监控解决方案,旨在满足现代云计算环境的需求。
Sensu 框架由客户端和服务器应用程序组成,这些应用程序通过消息总线进行通信——默认情况下为 RabbitMQ,尽管可以使用其他传输方式。配置完全使用 JSON 文件完成,使其易于与 Ansible 或 Chef 等自动化工具集成,并且客户端可以注册和注销,而无需重启服务器。
客户端的副本驻留在您基础设施中的每台主机上。客户端从传输拉取健康检查请求,执行它们,并将结果作为“事件”推回消息总线。Sensu 检查遵循与 Nagios 插件相同的格式,这使开发人员可以利用 Nagios 生态系统中的大量插件以及 Sensu 社区提供的插件。检查可以是任何将数据写入 STDOUT
或 STDERR
并返回与给定状态相对应的错误代码的程序或脚本:0 OK
、1 警告
、2 严重
以及 3
或更高版本,用于未知或自定义状态。
一旦检查结果被推送到消息总线,一个或多个 Sensu 服务器会从总线拉取事件并处理它们,处理结果、触发警报或将指标转发到长期存储。
Sensu 开箱即用,不对在检查期间可能收集的数据执行任何操作,但提供了配置处理程序的功能,这些处理程序将处理数据并将其转发到外部存储——在我们的例子中,是 InfluxDB。
通过存储指标数据,开发团队可以在以后使用这些数据进行分析;查看性能数据以推动工程路线图,或作为事件响应或事后处理过程的一部分。此外,通过在 时间序列数据库 中查询指标,Sensu 可以针对多个数据点执行检查,从而减少噪音和抖动警报。
那么我们如何保存这些数据呢?
设置
本文假设您已经在您的基础设施中运行 Sensu,客户端上运行指标收集检查,并且您已经设置了 InfluxDB 实例。如果您没有,您可以在此处找到安装说明
对于本示例,我们将使用来自 Sensu CPU 检查插件 的 CPU 百分比检查,以收集有关处理器使用率的指标。
我已经配置了两台运行 Ubuntu 16.04 的主机:Sensu 服务器本身,它运行 Sensu、Redis、RabbitMQ 和 Uchiwa,以及第二台服务器用于 InfluxDB。Sensu 服务器除了两台主机共有的 dev
和 ubuntu-servers
订阅外,还配置了 legacy-servers
订阅。订阅允许您确定哪些检查由各种客户端运行;在本例中,我们将假设我们现有的基础设施配置为通过 Sensu 收集资源指标,而 InfluxDB 服务器使用 Telegraf 收集这些指标。我们将使用 legacy-servers
订阅来确保我们仅在未安装 Telegraf 的服务器上运行指标收集检查。
Sensu InfluxDB 插件
Sensu 有大量社区贡献的插件,这些插件提供了 Sensu 和从 Apache 到 Zookeeper 的第三方应用程序之间的易于使用的集成,这些插件可以在 GitHub 上的 Sensu 社区插件 组织下找到。
我们将使用 InfluxDB Sensu 插件,它提供了 InfluxDB 和 Sensu 之间的许多集成
- check-influxdb.rb — 通过
/ping
端点对 InfluxDB 进行监控检查 - metrics-influxdb.rb — 使用 InfluxDB 查询的指标检查
- mutator-influxdb-line-protocol.rb — 将检查结果发送到 InfluxDB 的处理程序
- check-influxdb-query.rb — 将检查输出转换为 InfluxDB 行协议的 mutator
我们可以使用以下命令将 InfluxDB 插件安装到 Sensu 的嵌入式 Ruby 环境 /opt/sensu/embedded/
中
$ sudo sensu-install influxdb
我们已经在“legacy”主机上运行指标检查,因此我们希望设置 InfluxDB 处理程序来处理 Sensu 服务器接收到的事件。首先,我们将处理程序添加到 /etc/sensu/conf.d/handlers.json
以启用它
{
"handlers": {
"influx-tcp": {
"type": "pipe",
"command": "/opt/sensu/embedded/bin/metrics-influxdb.rb"
}
}
}
并在 /etc/sensu/conf.d/influx.json
中添加配置
{
"influxdb": {
"host" : "192.168.227.134",
"port" : "8086",
"database" : "sensumetrics"
}
}
本例中的 InfluxDB 实例未使用任何类型的身份验证或 SSL,因此我们使用了非常简单的配置,但是有 许多其他配置选项 可以指定。
现在我们已经配置了处理程序,我们希望在每次收到 CPU 百分比检查的结果时调用它,方法是将处理程序添加到检查配置中,在本例中为 /etc/sensu/conf.d/cpu_percentage.json
{
"checks": {
"cpu_metrics": {
"type": "metric",
"command": "metrics-cpu-pcnt-usage.rb",
"subscribers": [
"legacy-hosts"
],
"interval": 10,
"handlers": [
"debug",
"influxdb-tcp"
]
}
}
}
如您所见,我们已将订阅者配置为仅包含 legacy-hosts
。较新的主机将使用 Telegraf 设置,因此我们无需在这些主机上运行这些检查。
现在让我们重启 Sensu 服务以获取任何配置更改
$ sudo systemctl restart sensu-server sensu-api sensu-client
收集指标
此时,我们应该在 InfluxDB 中看到数据。Sensu 的默认指标格式是 Graphite 明文;每个指标表示为一个句点分隔的路径、值和时间戳。对于我们正在使用的 CPU 百分比检查,我们返回九个指标,如下所示
sensu.cpu.user 0.50 1515534170
sensu.cpu.nice 0.00 1515534170
sensu.cpu.system 0.00 1515534170
sensu.cpu.idle 99.50 1515534170
sensu.cpu.iowait 0.00 1515534170
sensu.cpu.irq 0.00 1515534170
sensu.cpu.softirq 0.00 1515534170
sensu.cpu.steal 0.00 1515534170
sensu.cpu.guest 0.00 1515534170
另一方面,InfluxDB 使用标签和字段的概念来提高效率。InfluxDB “measurement” 可以包含存储在字段中的多个值,以及索引标签,这些标签可用于在以后执行更复杂的查询。
以上所有指标都可以作为单个 measurement 存储在 InfluxDB 中,主机由标签表示,每个指标由字段表示。InfluxDB 行协议中的相同指标可能如下所示
cpu,host=sensu user=0.50,nice=0.00,system=0.00,idle=99.50,iowait=0.00,softirq=0.00,steal=0.00,guest=0.00 1515534170
但是,Sensu 的 InfluxDB 插件旨在与检查可能生成的所有指标一起使用,因此它没有太多地解析 Graphite 值到标签和字段中。该插件为每个 Graphite 指标创建一个 measurement,从 Graphite 路径的开头提取主机名,并从事件数据中提取指标名称以用作标签。所以
sensu.cpu.user 0.50 1515534170
变为
cpu_user,host=sensu,metric=cpu_percentage 0.50 1515534170
这不是一个理想的解决方案;它未能充分利用标签和字段提供的效率,但这可能是将指标快速导入 InfluxDB 并显示在仪表板上的一种快速方法,并且很可能是许多 InfluxDB 用户将尝试的第一件事。
我们可以使用 InfluxDB CLI 验证是否正在接收 InfluxDB 的数据。登录到 InfluxDB 主机并在提示符下键入 influx
$ influx
Connected to http://localhost:8086 version 1.4.2
InfluxDB shell version: 1.4.2
>
使用 SHOW MEASUREMENTS
命令验证是否已创建所有指标
>SHOW MEASUREMENTS
name: measurements
name
----
cpu_guest
cpu_idle
cpu_iowait
cpu_irq
cpu_nice
cpu_softirq
cpu_steal
cpu_system
cpu_user
最后,我们可以查询其中一个 measurement 以查看各个数据点
SELECT * from cpu_idle WHERE time > now() - 1m
name: cpu_idle
time host metric value
---- ---- ------ -----
1515534170000000000 sensu cpu_percentage 99.5
1515534270000000000 sensu cpu_percentage 100
1515534370000000000 sensu cpu_percentage 100
1515534470000000000 sensu cpu_percentage 100
1515534570000000000 sensu cpu_percentage 100
1515534670000000000 sensu cpu_percentage 100
替代方法:将 Graphite 明文发送到 Telegraf
通过为每个指标创建一个 measurement,我们已经没有充分利用 InfluxDB,此外,Sensu InfluxDB 插件的工作方式效率不高。
Sensu 的 Graphite 处理程序带有以下警告
但是请注意,将此 mutator 用作 mutator 命令可能非常昂贵,因为 Sensu 必须为每个指标检查结果生成一个新的 Ruby 进程来启动此脚本。请考虑从您的插件生成正确的指标名称,并通过套接字处理程序直接将它们发送到 Graphite。有关更多信息,请参见 https://groups.google.com/d/msg/sensu-users/1hkRSvL48ck/8Dhl98lR24kJ。
我们正在使用的处理程序 check-influxdb-query.rb
也存在同样的问题,因为需要为每个结果运行脚本。链接线程中的讨论建议使用 only_check_output
,这是一个内置的 Sensu mutator 扩展,不需要 Sensu 生成新进程。它从事件数据中提取 Graphite 明文,然后可以使用套接字处理程序转发。
幸运的是,InfluxDB 和 Telegraf 都可以 Graphite 明文格式摄取指标,因此这是一个可行的选择。InfluxDB 或 Telegraf 可以负责在指标进入时转换指标,而 Sensu 可以继续执行 Sensu 操作。
注意:在撰写这篇文章时,我遇到了 Telegraf 中的一个错误,该错误导致它拒绝包含换行符的数据包,这意味着它拒绝了 Sensu 发送的数据。幸运的是,这是一个简单的修复(拉取请求在此处:#3684),并且该更改已在 GitHub 的 master 分支中!它将出现在 Telegraf 的下一个版本中,或者您可以下载 repo 中链接的 夜间构建之一以立即开始使用。
默认情况下,以 Graphite 明文形式发送到 Telegraf 或 InfluxDB 的指标将使用完整的 Graphite 路径作为 measurement 名称存储,类似于 Sensu InfluxDB 插件所做的那样,但是这两个应用程序也提供模板功能,该功能告诉 InfluxDB 或 Telegraf 如何将指标转换为 InfluxDB 格式。
可以为您配置的每个侦听器定义模板,并且模板的格式与 Graphite 路径类似,具有句点分隔的值。模板中值的位置决定了 Graphite 路径中相同部分的处理方式,作为标签、measurement 或字段。您可以在 模板文档 中找到更多信息。
让我们再次看一下我们的 CPU 百分比指标
sensu.cpu.user 0.50 1515534170
sensu.cpu.nice 0.00 1515534170
sensu.cpu.system 0.00 1515534170
...
每个指标都具有相同的格式,因此我们可以使用单个模板来解析它们。它们在路径中都有三个部分,第一个部分用于主机,第二个部分用于指标。我们希望将每个指标分解为一个 measurement 和一个字段,以便我们可以有一个单独的 cpu
measurement,其中包含 user
、nice
、system
等字段。为了实现这一点,我们可以使用以下模板
host.measurement.field
注意:许多 Sensu 指标收集检查都包含一个参数--scheme
,该参数可用于自定义指标输出。对于 CPU 百分比检查,方案默认为#{Socket.gethostname}.cpu
,这对我们来说足够了。
由于 InfluxDB 和 Telegraf 都可以处理 Graphite 明文,因此您决定在哪里完成工作取决于您的工作负载、基础设施和工具。如果您只收集几种类型的指标,则可以使用几个模板轻松处理它们,并且 InfluxDB 盒上有可用资源,您可能希望将指标直接发送到那里。
但是,如果您尝试从许多不同的服务收集指标,您可能会发现创建模板时遇到冲突,或者您在 InfluxDB 服务器上施加了不合理的负载。在这种情况下,在您的应用程序旁边放置一个 Telegraf 实例可能更有意义,这样您就可以分配处理负载并最大限度地减少每个侦听器所需的模板数量。这种方法更易于扩展,但需要额外的配置开销。
对于本示例,我们将在 Sensu 旁边安装 Telegraf,并通过套接字将 Graphite 明文发送到它。
Telegraf 设置
首先,在您的 Sensu 主机上安装 Telegraf。您可以在此处找到适用于各种平台的 Telegraf 安装说明
接下来,我们将禁用 Telegraf 默认执行的 CPU 统计信息收集,因为它们与 Sensu 的指标收集检查是冗余的。确保注释掉默认配置中的 [[inputs.cpu]]
、[[inputs.disk]]
、[[inputs.mem]]
、[[inputs.network]]
部分。
我们还需要为 Sensu 配置一个输入以发送指标。我们将定义一个 socket_listener
,为其指定一个端口和一个数据格式,并指定我们的模板以解析 Graphite 明文。
将此部分添加到 /etc/telegraf/telegraf.conf
中的 Telegraf 配置中
[[inputs.socket_listener]]
service_address = "udp://:8094"
data_format = "graphite"
templates = [
"host.measurement.field"
]
重启 Telegraf 以使用 sudo systemctl restart telegraf
获取新配置。
Sensu 设置
在 Sensu 中使用 only_check_output
mutator 配置 UDP 处理程序,方法是将此添加到您的 /etc/sensu/conf.d/handlers.json
中
{
"handlers": {
"telegraf-graphite-handler": {
"type": "udp",
"socket": {
"host": "127.0.0.1",
"port": 8094
},
"mutator": "only_check_output"
}
}
}
通过编辑 /etc/sensu/conf.d/cpu_percentage.json
来更新检查,使其使用新的处理程序
{
"checks": {
"cpu_metrics": {
"type": "metric",
"command": "metrics-cpu-pcnt-usage.rb",
"subscribers": [
"legacy-hosts"
],
"interval": 10,
"handlers": [
"debug",
"telegraf-grafphite-handler"
]
}
}
}
最后,重启 Sensu 服务
$ sudo systemctl restart sensu-server sensu-api sensu-client
验证其是否有效
我们的指标以这种格式从 Sensu 中出来
sensu.cpu.user 0.50 1515534170
sensu.cpu.nice 0.00 1515534170
sensu.cpu.system 0.00 1515534170
sensu.cpu.idle 99.50 1515534170
sensu.cpu.iowait 0.00 1515534170
sensu.cpu.irq 0.00 1515534170
sensu.cpu.softirq 0.00 1515534170
sensu.cpu.steal 0.00 1515534170
sensu.cpu.guest 0.00 1515534170
通过此模板运行
host.measurement.field
并生成一个 measurement,cpu
,其中包含多个字段。让我们检查一下这是否是我们在数据库中看到的内容。打开 InfluxDB CLI,选择 sensumetrics
数据库,显示 measurement,然后选择最后一分钟的数据,就像我们之前做的那样
> USE sensumetrics
Using database sensumetrics
> SHOW MEASUREMENTS
name
----
cpu
> SELECT * FROM cpu WHERE time < now() - 1m
name: cpu
time guest host idle iowait irq nice softirq steal system user
---- ----- ---- ---- ------ --- ---- ------- ----- ------ ----
2018-01-09T20:32:09Z 0 sensu 98.51 0 0 0 0 0 0.5 1
2018-01-09T20:32:19Z 0 sensu 98.51 0 0 0 0 0 0.5 1
2018-01-09T20:32:29Z 0 sensu 98.51 0 0 0 0 0 0.5 1
2018-01-09T20:32:39Z 0 sensu 98.51 0 0 0 0 0 0.5 1
2018-01-09T20:32:49Z 0 sensu 98.51 0 0 0 0 0 0.5 1
下一步
通过转换 Graphite 明文中的指标,我们仍然在做一些不必要的工作;在某个时候,将我们的检查更新为以 InfluxDB 行协议输出数据,或者使用 Telegraf 直接从我们的应用程序收集和发送指标可能更有意义。
下周,我们将继续探索 Sensu 和 InfluxDB 的集成,方法是基于我们捕获的数据创建指标检查。