【问题标题】:Send python web app metrics to InfluxDB将 python web 应用程序指标发送到 InfluxDB
【发布时间】:2016-06-19 16:14:06
【问题描述】:

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

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 前面的聚合部分,还是直接将指标发送到InfluxDB 实例?

【问题讨论】:

    标签: python monitoring metrics influxdb statsd


    【解决方案1】:

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

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

    线路协议对我来说似乎比其他选项更容易使用,并且电报可以直接接受线路协议。一个潜在的缺点是,您以这种方式发送的任何内容最终都会出现在分配给电报统计信息的数据库中。直接进入 InfluxDB,你可以选择你的数据最终存放在哪个数据库中,尽管如果你想使用 line 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,这可能很难设置,但易于使用。

    他们给出的例子是:

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

    【讨论】:

    • 好的,非常感谢!但是,我还有两个问题。如果在 InfluxDB 端使用 UDP 侦听器,为什么您提到直接向 InfluxDB 发送指标会阻止应用程序代码的执行?第二个 - InfluxDB 是否经过优化以接收大量指标而无需在电报中即时聚合?
    • 我写了关于阻塞执行的部分,同时只考虑了常规的 http POST 方法,对于那里的混乱表示歉意。对于第二部分,0.9 以后的较新的数据库引擎(我认为它被称为 tsm1)应该能够在不聚合的情况下接收大量指标。我们的 LDAP 指标初稿每个查询存储 1 个数据点,每天大约 3000 万个,InfluxDB 应对了。 (我们现在只是针对我们自己的存储大小进行了汇总)
    • 嗯,恐怕我还有问题。我已经开始使用batch-size = 1000batch-timeout = "1s" 设置通过UDP 将我的指标直接发送到InfluxDB 实例。但是,现在我每秒只存储一个值(我猜是最后一个),用于标签集和字段集的唯一组合。但我想准确计算所有指标。看起来我必须切换到通过 HTTP 发送的批量指标,但我必须以某种方式消除应用程序代码中的延迟。也许使用电报可以帮助它?
    • 我还没有使用 telegraf 发送指标,所以我对此无能为力,抱歉。从文档看来,UDP 的最低分辨率为 1 秒,这很尴尬。
    • 没错。我将尝试通过某种“代理”代理进行批量 HTTP 插入。与statsd 类似,但在代理端没有任何聚合。仅将传入的指标保存一段时间,然后将它们一次全部转储到 InfluxDB。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多