将python web app指标发送到InfluxDB

时间:2016-06-19 16:14:07

标签: python monitoring metrics influxdb statsd

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

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

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

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

1 个答案:

答案 0 :(得分:4)

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

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

线路协议似乎比其他选项更容易使用,而telegraf可以直接接受线路协议。一个潜在的缺点是你以这种方式发送的任何东西都会在分配给telegraf统计数据的数据库中结束。直接进入InfluxDB,你可以选择你的数据最终会进入哪个数据库,虽然这意味着如果你想使用行protcol格式,可以绕过python模块。

要使用Influxdb-python并直接发送到InfluxDB,您可以选择JSON格式或使用SeriesHelper的子类

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

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

SeriesHelper

该模块可以通过使用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看到,一旦设置它就会让生活变得简单,但客户端的配置需要在全局范围内设置(这对模块不利)或者类定义。这不适合从配置文件或服务发现中获取配置,因此您最终会在配置解析函数中执行以下操作:

# 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类。这不是最复杂的事情,但指标背后的想法并不是一个有知识的人会加上所有这些,而是​​它是所有人在每个人编写代码的生活方式的一部分。链中的一部分。从这个角度来看,易用性是让人们采用工具的关键。