telegraf - плагин exec - aws ec2 ebs Volumen Info - ошибка анализа метрики, причина: [пропущенные поля] или обнаруженные ошибки: [неверный номер]

Машина - CentOS 7.2 или Ubuntu 14.04/16.xx

Телеграф версия: 1.0.1

Версия Python: 2.7.5

Telegraf поддерживает плагин INPUT с именем: exec. Сначала, пожалуйста, посмотрите ПРИМЕР 2 в документе README. Я не могу использовать формат JSON, так как он использует только числовые значения для метрик. Согласно документам:

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

Итак, идея проста: вы указываете скрипт в разделе плагина exec, который должен выплевывать некоторую значимую информацию (в моем случае - либо в формате данных JSON -или- приток, в моем случае, так как у меня есть некоторые метрики, которые содержат нечисловые значения), которые вы бы хочу поймать / показать где-нибудь на крутой панели, как, например, Wavefront Dashboard, показанный здесь: Wavefront:

По сути, можно использовать эти метрики, теги, источники, откуда эти метрики, чтобы находить различную информацию о памяти, процессоре, диске, сети, другую значимую информацию, а также создавать оповещения, используя их, если происходит что-то нежелательное.

Хорошо, я придумал этот скрипт на 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 все время (ограничения API AWS / фактор стоимости).

Итак, после создания файла.csv я создал этот небольшой сценарий оболочки, который я установлю в разделе exec плагина Telegraf.

Сценарий оболочки /tmp/aws-vol-info.sh установить в Telegraf exec плагин:

#!/bin/bash

cat /tmp/aws-vol-info.csv

Файл конфигурации Telegraf, созданный с помощью плагина exec (/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), и хотел проверить, как telegraf будет обрабатывать эти данные, прежде чем я включу файл конфигурации (/ 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 дает мне следующую ошибку.

Команда: $ 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, чтобы телеграф мог использовать его в формате данных притока),

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

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

1 ответ

Решение

Кажется, что правила очень строгие, я должен был присмотреться.

НЕОБХОДИМО, чтобы синтаксис вывода любой программы, которую вы можете использовать, ДОЛЖЕН соответствовать или следовать формату 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) Линия протокола обрабатывает смайлики без проблем:)

6) TAG / TAG (теги, разделенные запятыми) в OPTIONAL

7) FIELD / FIELD set (поля, разделенные запятыми) - для каждой строки требуется как минимум ОДИН.

8) TIMESTAMP (последнее значение, показанное в формате) является необязательным.



9) очень важные правила котировки ниже:

а) Никогда не ставьте двойную или одинарную кавычку с отметкой времени Это не действующий протокол линии. "123123131312313" или "1231313213131" не будут работать, если этот # допустим.

б) Никогда не заключайте в кавычки значения полей (даже если они строки!). Это также не действующий протокол линии. то есть fieldname='giga' не будет работать.

c) Не используйте двойные или одинарные кавычки для имен измерений, ключей тегов, значений тегов и ключей полей. ПРИМЕЧАНИЕ: это говорит!!! значения тегов!!!! так осторожно

d) Не заключайте в двойные кавычки значения полей ТОЛЬКО в формате с плавающей запятой, целыми числами или логическим форматом, в противном случае InfluxDB будет считать эти значения строками.

e) Делать двойные кавычки значения полей, которые являются строками.

е) И САМОЕ ВАЖНОЕ (что избавит вас от получения BALD): если значение FIELD установлено без двойных кавычек / т.е. вы думаете, что это целочисленное значение или число с плавающей запятой в одной строке (например, любой скажет размер поля или iops) и в некоторых других строках (в любом месте файла, который телеграф будет читать / анализировать с помощью плагина exec), если у вас установлено нецелое значение (например, строка), вы получите следующее сообщение об ошибке: Обнаружены ошибки: [недопустимо ошибка числа

Таким образом, чтобы исправить это, ПРАВИЛО, если любое возможное значение ПОЛЯ для ключа ПОЛЯ является строкой, то вы ДОЛЖНЫ убедиться, что используете " чтобы обернуть его (в каждой строке), не имеет значения, имеет ли оно значение 1, 200 или 1,5 в некоторых строках (например, iops может быть 1, 5) и в некоторых других строках это значение (iops может быть 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) /" (примечание: пробел перед закрытием сед / характер), а затем вы можете иметь " вокруг любой пары ключ = значение. Я изменил.py файл, чтобы не использовать " за size а также iops поля.

В любом случае, если результат будет примерно таким:

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"

В приведенном выше окончательном рабочем решении я создал измерение с именем awsec2ebs затем дал , между этим измерением и ключом метки 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
Другие вопросы по тегам