1

机器- CentOS 7.2Ubuntu 14.04/16.xx

电报版本:1.0.1

Python版本:2.7.5

Telegraf 支持一个名为:exec的 INPUT 插件。首先请参阅那里的README文档中的示例 2 。我不能使用 JSON 格式,因为它只使用数值作为指标。根据文档:

If using JSON, only numeric values are parsed and turned into floats. Booleans and strings will be ignored.

所以,这个想法很简单,你在 exec 插件部分指定一个脚本,它应该吐出一些有意义的信息(在我的例子中是JSON - 或- influx数据格式,因为我有一些包含非数字值的指标)你会想要在一个很酷的仪表板中的某个地方捕捉/显示,例如此处显示 的Wavefront 仪表板::波前

基本上,人们可以使用这些指标、标签、这些指标的来源来找出有关内存、cpu、磁盘、网络、其他有意义的信息的各种信息,并在发生意外情况时使用这些信息创建警报。

好的,我想出了这个可用的 python 脚本:

#!/usr/bin/python

# sudo pip install boto3 if you don't have it on your machine.
import boto3


def generate(key, value):
    """
    Creates a nicely formatted Key(Value) item for output
    """
    return '{}="{}"'.format(key, value)
    #return '{}={}'.format(key, value)


def main():
    ec2 = boto3.resource('ec2', region_name="us-west-2")
    volumes = ec2.volumes.all()

    for vol in volumes:
        # You don't need to wrap everything in `str` unless it is not a string
        # By default most things will come back as a string 
        # unless they are very obviously not (complex, date time, etc)
        # but since we are printing these (and formatting them into strings)
        # the cast to string will be implicit and we don't need to make it 
        # explicit


        # vol is already a fully returned volume you are essentially DOUBLING
        # your API calls when you do this
        #iv = ec2.Volume(vol.id)
        output_parts = [
            # Volume level details
            generate('create_time', vol.create_time),
            generate('availability_zone', vol.availability_zone),
            generate('volume_id', vol.volume_id),
            generate('volume_type', vol.volume_type),
            generate('state', vol.state),
            generate('size', vol.size),
            generate('iops', vol.iops),
            generate('encrypted', vol.encrypted),
            generate('snapshot_id', vol.snapshot_id),
            generate('kms_key_id', vol.kms_key_id),
        ]

        for _ in vol.attachments:
            # Will get any attachments and since it is a list
            # we should write this to handle MULTIPLE attachments
            output_parts.extend([
                generate('InstanceId', _.get('InstanceId')),
                generate('InstanceVolumeState', _.get('State')),
                generate('DeleteOnTermination', _.get('DeleteOnTermination')),
                generate('Device', _.get('Device')),
            ])

        # only process when there are tags to process        
        if vol.tags:
            for _ in vol.tags:
                # Get all of the tags
                output_parts.extend([
                    generate(_.get('Key'), _.get('Value')),
                ])

        # output everything at once.. 
        print ','.join(output_parts)


if __name__ == '__main__':
    main()

此脚本将与 AWS EC2 EBS 卷对话并输出它可以找到的所有值(通常是您在 AWS EC2 EBS 卷控制台中看到的)并将该信息格式化为有意义的 CSV 格式,我将其重定向到 .csv 日志文件。 我们不想一直运行 python 脚本(AWS API 限制/成本因素)。

因此,一旦创建了 .csv 文件,我就创建了这个小的 shell 脚本,我将在Telegraf 的 exec 插件部分中设置它。

/tmp/aws-vol-info.shTelegraf exec 插件中设置的Shell 脚本为:

#!/bin/bash

cat /tmp/aws-vol-info.csv

使用 exec 插件 ( ) 创建的 Telegraf 配置文件/etc/telegraf/telegraf.d/exec-plugin-aws-info.conf

#--- https://github.com/influxdata/telegraf/tree/master/plugins/inputs/exec

[[inputs.exec]]
  commands = ["/tmp/aws-vol-info.sh"]

  ## Timeout for each command to complete.
  timeout = "5s"

  # Data format to consume.
  # NOTE json only reads numerical measurements, strings and booleans are ignored.
  data_format = "influx"

  name_suffix = "_telegraf_execplugin"

调整了 .py(用于生成函数的 Python 脚本)以生成以下三种类型的输出格式(.csv 文件),并想在启用配置文件( /etc/ telegraf /telegraf. d/catch-aws-ebs-info.conf)并重新启动telegraf服务。


格式 1:("每个值都用双引号括起来)

create_time="2017-01-09 23:24:29.428000+00:00",availability_zone="us-east-2b",volume_id="vol-058e1d47dgh721121",volume_type="gp2",state="in-use",size="8",iops="100",encrypted="False",snapshot_id="snap-06h1h1b91bh662avn",kms_key_id="None",InstanceId="i-0jjb1boop26f42f50",InstanceVolumeState="attached",DeleteOnTermination="True",Device="/dev/sda1",Name="[company-2b-app90] secondary",hostname="company-2b-app90-i-0jjb1boop26f42f50",high_availability="1",mirror="secondary",cluster="company",autoscale="true",role="app"

在电报目录上测试telegraf配置给了我以下错误。

命令$ telegraf --config-directory=/etc/telegraf --test --input-filter=exec

[vagrant@myvagrant ~] $ telegraf --config-directory=/etc/telegraf --test --input-filter=exec
2017/03/10 00:37:48 I! Using config file: /etc/telegraf/telegraf.conf
* Plugin: inputs.exec, Collection 1
2017-03-10T00:37:48Z E! Errors encountered: [ metric parsing error, reason: [invalid field format], buffer: [create_time="2017-01-09 23:24:29.428000+00:00",availability_zone="us-east-2b",volume_id="vol-058e1d47dgh721121",volume_type="gp2",state="in-use",size="8",iops="100",encrypted="False",snapshot_id="snap-06h1h1b91bh662avn",kms_key_id="None",InstanceId="i-0jjb1boop26f42f50",InstanceVolumeState="attached",DeleteOnTermination="True",Device="/dev/sda1",Name="[company-2b-app90] secondary",hostname="company-2b-app90-i-0jjb1boop26f42f50",high_availability="1",mirror="secondary",cluster="company",autoscale="true",role="app"], index: [372]]
[vagrant@myvagrant ~] $

格式 2:(不带任何"双引号)

create_time=2017-01-09 23:24:29.428000+00:00,availability_zone=us-east-2b,volume_id=vol-058e1d47dgh721121,volume_type=gp2,state=in-use,size=8,iops=100,encrypted=False,snapshot_id=snap-06h1h1b91bh662avn,kms_key_id=None,InstanceId=i-0jjb1boop26f42f50,InstanceVolumeState=attached,DeleteOnTermination=True,Device=/dev/sda1,Name=[company-2b-app90] secondary,hostname=company-2b-app90-i-0jjb1boop26f42f50,high_availability=1,mirror=secondary,cluster=company,autoscale=true,role=app

在测试 Telegraf 的 exec 插件配置时出现相同的错误:

2017/03/10 00:45:01 I! Using config file: /etc/telegraf/telegraf.conf
* Plugin: inputs.exec, Collection 1
2017-03-10T00:45:01Z E! Errors encountered: [ metric parsing error, reason: [invalid value], buffer: [create_time=2017-01-09 23:24:29.428000+00:00,availability_zone=us-east-2b,volume_id=vol-058e1d47dgh721121,volume_type=gp2,state=in-use,size=8,iops=100,encrypted=False,snapshot_id=snap-06h1h1b91bh662avn,kms_key_id=None,InstanceId=i-0jjb1boop26f42f50,InstanceVolumeState=attached,DeleteOnTermination=True,Device=/dev/sda1,Name=[company-2b-app90] secondary,hostname=company-2b-app90-i-0jjb1boop26f42f50,high_availability=1,mirror=secondary,cluster=company,autoscale=true,role=app], index: [63]]

格式 3:(此格式的值中没有任何"双引号和空格字符)。_用字符替换空格。

create_time=2017-01-09_23:24:29.428000+00:00,availability_zone=us-east-2b,volume_id=vol-058e1d47dgh721121,volume_type=gp2,state=in-use,size=8,iops=100,encrypted=False,snapshot_id=snap-06h1h1b91bh662avn,kms_key_id=None,InstanceId=i-0jjb1boop26f42f50,InstanceVolumeState=attached,DeleteOnTermination=True,Device=/dev/sda1,Name=[company-2b-app90]_secondary,hostname=company-2b-app90-i-0jjb1boop26f42f50,high_availability=1,mirror=secondary,cluster=company,autoscale=true,role=app

仍然没有工作,得到同样的错误:

[vagrant@myvagrant ~] $ telegraf --config-directory=/etc/telegraf --test --input-filter=exec
2017/03/10 00:50:30 I! Using config file: /etc/telegraf/telegraf.conf
* Plugin: inputs.exec, Collection 1
2017-03-10T00:50:30Z E! Errors encountered: [ metric parsing error, reason: [missing fields], buffer: [create_time=2017-01-09_23:24:29.428000+00:00,availability_zone=us-east-2b,volume_id=vol-058e1d47dgh721121,volume_type=gp2,state=in-use,size=8,iops=100,encrypted=False,snapshot_id=snap-06h1h1b91bh662avn,kms_key_id=None,InstanceId=i-0jjb1boop26f42f50,InstanceVolumeState=attached,DeleteOnTermination=True,Device=/dev/sda1,Name=[company-2b-app90]_secondary,hostname=company-2b-app90-i-0jjb1boop26f42f50,high_availability=1,mirror=secondary,cluster=company,autoscale=true,role=app], index: [476]]

格式 4:如果我按照此页面遵循流入线协议: https ://docs.influxdata.com/influxdb/v1.2/write_protocols/line_protocol_tutorial/

awsebs,Name=[company-2b-app90]_secondary,hostname=company-2b-app90-i-0jjb1boop26f42f50,high_availability=1,mirror=secondary,cluster=company,autoscale=true,role=app create_time=2017-01-09_23:24:29.428000+00:00,availability_zone=us-east-2b,volume_id=vol-058e1d47dgh721121,volume_type=gp2,state=in-use,size=8,iops=100,encrypted=False,snapshot_id=snap-06h1h1b91bh662avn,kms_key_id=None,InstanceId=i-0jjb1boop26f42f50,InstanceVolumeState=attached,DeleteOnTermination=True,Device=/dev/sda1

我收到此错误

[vagrant@myvagrant ~] $ telegraf --config-directory=/etc/telegraf --test --input-filter=exec
2017/03/10 02:34:30 I! Using config file: /etc/telegraf/telegraf.conf
* Plugin: inputs.exec, Collection 1
2017-03-10T02:34:30Z E! Errors encountered: [ invalid number]

我怎样才能摆脱这个错误并让 telegraf 与 exec 插件(运行 .sh 脚本)一起工作


其他信息

Python 脚本将每天运行一次/两次(通过 cron),而 telegraf 将每 1 分钟运行一次(运行 exec 插件 - 运行 .sh 脚本 - 它将对 .csv 文件进行分类,以便 telegraf 可以以流入数据格式使用它) .

https://galaxy.ansible.com/wavefrontHQ/wavefront-ansible/

https://github.com/influxdata/telegraf/issues/2525

4

1 回答 1

3

好像规矩很严格,我应该仔细看看。

您可以使用的任何程序的输出语法必须匹配或遵循如下所示的INFLUX LINE PROTOCOL格式以及随附的所有规则。

例如:

weather,location=us-midwest temperature=82 1465839830100400200
  |    -------------------- --------------  |
  |             |             |             |
  |             |             |             |
+-----------+--------+-+---------+-+---------+
|measurement|,tag_set| |field_set| |timestamp|
+-----------+--------+-+---------+-+---------+

您可以在此处阅读有关什么是度量、标签、字段和可选(时间戳)的更多信息:https ://docs.influxdata.com/influxdb/v1.2/write_protocols/line_protocol_tutorial/

重要的规则是

1)测量和标签集之间必须有一个,空格。

2)标签集和字段集之间必须有空格。

3) 对于标签键、标签值和字段键,如果要转义测量名称、标签或字段集名称及其值中的任何字符,请始终使用反斜杠字符 \ 转义!

4)你无法\逃脱\

5) Line Protocol 处理表情符号没有问题:)

6) TAG / TAG 设置(标签逗号分隔)在OPTIONAL

7) FIELD / FIELD set(字段,逗号分隔) -每行至少需要一个。

8) TIMESTAMP(格式中显示的最后一个值)是OPTIONAL



9)非常重要的报价规则如下:

a)切勿 双引号或单引号时间戳。它不是有效的线路协议。如果 # 有效,则“123123131312313”或“1231313213131”将不起作用。

b)永远不要 单引号 字段值(即使它们是字符串!)。它也不是有效的线路协议。即 fieldname='giga' 将不起作用。

c)不要 双引号或单引号 测量名称、标签键标签值字段键注意:这确实说!标记值!!!!这么小心。

d)不要 双引号仅以浮点数、整数或布尔格式的 字段值,否则 InfluxDB 将假定这些值是字符串。

e)对作为字符串的字段值进行双引号

f)和最重要的一个(这将使您免于 秃顶):如果在没有双引号的情况下设置了 FIELD 值/即您认为它是一个整数值或在一行中浮动(例如:任何人都会说字段大小iops ) 和其他一些行(telegraf 将使用exec 插件读取/解析的文件中的任何位置)如果您设置了非整数值(即 String),那么您将收到以下错误消息Errors遇到:[无效号码错误。

所以要修复它,规则是,如果 FIELD 键的任何可能 FIELD 值string,那么你必须确保使用"它来包装它(在每一行中),它​​是否具有值1, 200都没有关系或 1.5在某些行(例如: iops can be 1, 5)和在其他一些行中的值(iopscan be None)。

错误信息: Errors encountered: [ invalid number

[vagrant@myvagrant ~] $ telegraf --config-directory=/etc/telegraf --test --input-filter=exec
2017/03/10 11:13:18 I! Using config file: /etc/telegraf/telegraf.conf
* Plugin: inputs.exec, Collection 1
2017-03-10T11:13:18Z E! Errors encountered: [ invalid number metric parsing error, reason: [invalid field format], buffer: [awsebsvol,host=myvagrant ], index: [25]]

所以,在所有这些学习之后,很明显,首先我错过了 Influx Line 协议格式和规则

现在,我希望我的 python 脚本生成的输出应该是这样的(根据 INFLUX LINE PROTOCOL)。您可以只更改 .sh 文件并使用sed "s/^/awsec2ebs,/"或也这样做sed "s/^/awsec2ebs,sourcehost=$(hostname) /"(注意:结束 sed/字符之前的空格),然后您可以拥有"任何 key=value 对。我确实将 .py 文件更改为不使用"forsizeiops字段。

无论如何,如果输出是这样的:

awsec2ebs,volume_id=vol-058e1d47dgh721121 create_time="2017-01-09 23:24:29.428000+00:00",availability_zone="us-east-2b",volume_type="gp2",state="in-use",size="8",iops="100",encrypted="False",snapshot_id="snap-06h1h1b91bh662avn",kms_key_id="None",InstanceId="i-0jjb1boop26f42f50",InstanceVolumeState="attached",DeleteOnTermination="True",Device="/dev/sda1",Name="[company-2b-app90] secondary",hostname="company-2b-app90-i-0jjb1boop26f42f50",high_availability="1",mirror="secondary",cluster="company",autoscale="true",role="app"

在上面的最终工作解决方案中,我创建了一个名为awsec2ebsthen的度量,然后,在此度量和标签键之间给出volume_id,对于标签值,我没有使用任何'"引号,然后我给出了一个空格字符(因为我现在只想要一个标签,否则您可以使用命令分隔方式并遵循规则在标签集和字段集之间拥有更多标签。

最后运行命令

$ telegraf --config-directory=/etc/telegraf --test --input-filter=exec这就像一个神子!

2017/03/10 03:33:54 I! Using config file: /etc/telegraf/telegraf.conf
* Plugin: inputs.exec, Collection 1
> awsec2ebs_telegraf_execplugin,volume_id=vol-058e1d47dgh721121,host=myvagrant volume_type="gp2",iops="100",kms_key_id="None",role="app",size="8",encrypted="False",InstanceId="i-0jjb1boop26f42f50",InstanceVolumeState="attached",Name="[company-2b-app90] secondary",snapshot_id="snap-06h1h1b91bh662avn",DeleteOnTermination="True",mirror="secondary",cluster="company",autoscale="true",high_availability="1",create_time="2017-01-09 23:24:29.428000+00:00",availability_zone="us-east-2b",state="in-use",Device="/dev/sda1",hostname="company-2b-app90-i-0jjb1boop26f42f50" 1489116835000000000
[vagrant@myvagrant ~] $ echo $?
0

在上面的示例中,size是唯一一个始终为数字/数值的字段,因此我们不需要将其包装起来,"但这取决于您。回想一下上面最重要的规则......以及它产生的错误。

所以最终的python文件是:

#!/usr/bin/python

#Do `sudo pip install boto3` first
import boto3

def generate(key, value, qs, qe):
    """
    Creates a nicely formatted Key(Value) item for output
    """
    return '{}={}{}{}'.format(key, qs, value, qe)

def main():
    ec2 = boto3.resource('ec2', region_name="us-west-2")
    volumes = ec2.volumes.all()

    for vol in volumes:
        # You don't need to wrap everything in `str` unless it is not a string
        # By default most things will come back as a string
        # unless they are very obviously not (complex, date time, etc)
        # but since we are printing these (and formatting them into strings)
        # the cast to string will be implicit and we don't need to make it
        # explicit

        # vol is already a fully returned volume you are essentially DOUBLING
        # your API calls when you do this
        #iv = ec2.Volume(vol.id)
        output_parts = [
            # Volume level details
            generate('volume_id', vol.volume_id, '"', '"'),
            generate('create_time', vol.create_time, '"', '"'),
            generate('availability_zone', vol.availability_zone, '"', '"'),
            generate('volume_type', vol.volume_type, '"', '"'),
            generate('state', vol.state, '"', '"'),
            generate('size', vol.size, '', ''),
            #The following vol.iops variable can be a number or None so you must wrap it with double quotes otherwise "invalid number" error will come.
            generate('iops', vol.iops, '"', '"'),
            generate('encrypted', vol.encrypted, '"', '"'),
            generate('snapshot_id', vol.snapshot_id, '"', '"'),
            generate('kms_key_id', vol.kms_key_id, '"', '"'),
        ]

        for _ in vol.attachments:
            # Will get any attachments and since it is a list
            # we should write this to handle MULTIPLE attachments
            output_parts.extend([
                generate('InstanceId', _.get('InstanceId'), '"', '"'),
                generate('InstanceVolumeState', _.get('State'), '"', '"'),
                generate('DeleteOnTermination', _.get('DeleteOnTermination'), '"', '"'),
                generate('Device', _.get('Device'), '"', '"'),
            ])

        # only process when there are tags to process
        if vol.tags:
            for _ in vol.tags:
                # Get all of the tags
                output_parts.extend([
                    generate(_.get('Key'), _.get('Value'), '"', '"'),
                ])

        # output everything at once..
        print ','.join(output_parts)

if __name__ == '__main__':
    main()

最终的 aws-vol-info.sh 是:

#!/bin/bash

cat aws-vol-info.csv | sed "s/^/awsebsvol,host=`hostname|head -1|sed "s/[ \t][ \t]*/_/g"` /"

最终的 telegraf exec 插件配置文件是( /etc/telegraf/telegraf.d/exec-plugin-aws-info.conf) 使用 .conf 给出任何名称:

#--- https://github.com/influxdata/telegraf/tree/master/plugins/inputs/exec

[[inputs.exec]]
  commands = ["/some/valid/path/where/csvfileexists/aws-vol-info.sh"]

  ## Timeout for each command to complete.
  timeout = "5s"

  # Data format to consume.
  # NOTE json only reads numerical measurements, strings and booleans are ignored.
  data_format = "influx"

  name_suffix = "_telegraf_exec"

运行:现在一切正常!

$ telegraf --config-directory=/etc/telegraf --test --input-filter=exec
于 2017-03-10T03:39:27.110 回答