将 python 个网络应用指标发送到 InfluxDB

Send python web app metrics to InfluxDB

目前我配置了这样一个监控系统:

web_app (via python statsd client) -> statsd -> ...
    ... -> carbon-relay-ng -> carbon-cache -> whisper

我使用 Grafana 而不是 Graphite 作为绘图工具。

由于查询性能太差,我决定将此堆栈更改为 InfluxDB + Grafana 包。所以,我的问题是如何将应用指标发送到 InfluxDB?我更喜欢让这个包非常简单,所以如果可能的话我想跳过 statsd。我应该将 python statsd client 替换为 influxdb-python and use telegraf UDP 服务作为 InfluxDB 前面的聚合部分,还是直接将指标发送到 InfluxDB实例?

我会使用线路协议将数据发送到 telegraf。

我经常使用 influxdb-python 将统计数据直接提交给 InfluxDB。将结果本地发送到 telegraf 可能会更快,这取决于您的 InfluxDB 安装响应的速度和可靠性——如果有延迟,这将阻止您的应用程序。

线路协议对我来说似乎比其他选项更容易使用,telegraf 可以直接接受线路协议。一个潜在的缺点是,您以这种方式发送的任何内容最终都会出现在分配给 telegraf stats 的数据库中。直接转到 InfluxDB,你可以选择你的数据最终将在哪个数据库中,尽管如果你想使用 line protcol 格式,这意味着绕过 python 模块。

要使用 influxdb-python 并直接发送到 InfluxDB,您可以选择 JSON 格式或使用 SeriesHelper[=22= 的子class ]

JSON

创建 write_points/write 使用的 JSON 结构真的很笨拙。它只会将其转换为行格式。

比较JSON:

json_body = [
    {
        "measurement": "cpu_load_short",
        "tags": {
            "host": "server01",
            "region": "us-west"
        },
        "time": "2009-11-10T23:00:00Z",
        "fields": {
            "value": 0.64
        }
    }
]

转行格式:

# measurement,tag1=tag1value,tag2=tag2value column1=... 
cpu_load_short,host=server01,region=us-west value=0.64 1465290833288375000

我知道我认为哪个更容易制作(而且我知道时间戳不匹配,我只是在使用示例)。行格式可以使用 requests 库直接 POSTed 到 InfluxDB,或者如果已经配置了监听器则通过 UDP 发送。

系列助手

该模块有一种方法可以通过使用 SeriesHelper 来接受值和标签,这可能很难设置,但易于使用。

他们举的例子是:

from influxdb import InfluxDBClient, SeriesHelper

myclient = InfluxDBClient(host, port, user, password, dbname)

class MySeriesHelper(SeriesHelper):
    # Meta class stores time series helper configuration.
    class Meta:
        client = myclient
        series_name = 'events.stats.{server_name}'
        fields = ['some_stat', 'other_stat']
        tags = ['server_name']
        bulk_size = 5
        autocommit = True


MySeriesHelper(server_name='us.east-1', some_stat=159, other_stat=10)
MySeriesHelper(server_name='us.east-1', some_stat=158, other_stat=20)

所以你可以从调用 MySeriesHelper 中看到,一旦它设置起来就很容易,但是客户端的配置要么需要在全局范围内设置(这对模块不利),要么在 class定义。这不利于从配置文件或服务发现中获取配置,所以你最终会在你的配置解析函数中做这样的事情:

# Read host, port, user password, dbname from config file, then:
MySeriesHelper.Meta.client = InfluxDBClient(host, port, user, password, dbname)
# Now it is safe to call MySeriesHelper

我没有遇到过 influxdb-python 的可靠性问题,大多数时候我们使用 SeriesHelper classes。这不是最复杂的事情,但指标背后的想法并不是一个拥有知识的人把它全部加起来,而是它是在链的每个部分编写代码的所有人的生活方式的一部分。从这个角度来看,易用性是让人们采用工具的关键。