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