Collectd -> Elasticsearch, если удаленный хост не может подключиться к центральному elasticsearch

Цель

Центральное хранилище и способ анализа показателей производительности:

  • загрузка процессора
  • использование оперативной памяти
  • ...

Текущая стратегия

Я хотел бы реализовать такая настройка:

  1. collectd
  2. logstash
  3. elasticsearch
  4. kibana

Как описано здесь: https://mtalavera.wordpress.com/2015/02/16/monitoring-with-collectd-and-kibana/

Проблема: удаленный хост не может отправить данные

Ограничения:

  • У нас есть только ssh от центрального сервера к удаленному хосту.
  • ssh от удаленных хостов к центральному серверу не работает из-за настройки сети (кое-что я, к сожалению, не могу изменить
  • сетевой трафик проходит через несколько непубличных сетей. Дважды в месяц к хосту невозможно подключиться, потому что администратор играет с правилами брандмауэра. Я не хочу потерять ни единой строчки. Вот почему я хочу хранить журналы на удаленном хосте и получать (сжатые) данные.

Решение?

Как я могу получать данные каждый час?

0
задан 25 April 2016 в 17:38
2 ответа

A fent felsorolt ​​problémákkal pufferolnia kell a statisztikákat a távoli végén, hogy semmi ne vesszen el.

Ennek számos módja van, de egyik sem túlságosan egyszerű, és sok tesztet fog igénybe venni annak biztosítására, hogy életképesek legyenek. Ezek mindegyike magában foglalja az collectd kimenetének helyi megírását, majd valamilyen módszer használatával a központi szerverre.

Az alábbiak egyikét sem teszteltem, így előfordulhat, hogy egyesek egyáltalán nem működnek.

A könnyebbség és a bonyolultság különösebb sorrendjében:

  1. Socket / hálózati kimenet szkriptbe
    Írja Collectd kimenetét egy foglalatba vagy IP / portba, ahol egy PHP / Perl / Python / A Bash szkript hallgatja a parancsok fájlba írását.

    Ezeket a fájlokat ezután a központi szerverre lehet tolni / meghúzni, és a Logstash beviheti őket. Előnyök : Egyszerű szkript a kimenet rögzítésére; szokásos Linux parancsok
    Hátrányok : Nem méretezhető, ha sok statisztikát húz; a szkript fenntartásának szükségessége; nem biztos abban, hogy az LS kezeli-e a sima protokollt

  2. Redis / AMQP / Kafka / MongoDB Írja be az Collectd kimenetét a lehetséges "pufferek" egyikébe. Mindegyikük kicsit másképp működik, és különböző telepítési lehetőségeik vannak, ezért rátok bízom, hogy kitaláljuk, melyik a legjobb, mivel ez nem tartozik erre a kérdésre. Ez azt jelenti, hogy bármelyiküknek működnie kell.

    Ezután szüksége van egy módszerre, amellyel a pufferoldat adatai visszakerülnek a központi szerverre. Az alkalmazás natív replikációja / tükrözése / fürtözése, vagy egy szkript, amely minden X intervallumot futtat az adatok elküldéséhez (mindkét végén fut), két lehetőség.

    Előnyök : Nagyon rugalmas telepítési lehetőségek; nagyon jól kell méreteznie; jól ismert eszközöket / programokat használ
    Hátrányok : A pufferprogramhoz sok erőforrásra lehet szükség, vagy sok csomagra van szükség

  3. Socket / Network Output to Logstash Ez majdnem megegyezik az 1. opcióval, de ahelyett, hogy collectd kimenetet adna egy szkriptnek / progarmnak, írnia kell egy helyi Logstash példányba minden távoli hoszton.

    A Logstash ezután helyben ír a CSV / JSON-ra, és bármilyen eszközzel visszaállíthatja ezeket a fájlokat a központi szerverre, beleértve magát az LS-t is.

    Előnyök : Egyetlen eszközkészlet a teljes megoldáshoz; lehetőséget nyújt az adatok szélén történő átalakítására, majd csak központilag történő bevitelre; nagyon kevés mozgó alkatrész Hátrányok : Java / LS szükséges minden távoli gazdagépen

Az egyes opciók mellett / ellen, az egyetlen közös hátrány mindannyiuk számára az, hogy meg kell találni a módszert az állandó konfigurációk fenntartására az összes szerveren. Ha sok távoli csomópont van (vagy általában csak sok csomópont van), akkor lehet, hogy már van egy Konfigurációkezelő rendszer, és ez triviális lesz.

1
ответ дан 4 December 2019 в 16:38

редактирование: Achtung! Внимание!

Пожалуйста, используйте этот docker-составьте вместо того, который я связал (это действительно требует docker и составьте и, возможно, машина , но он сделал больше для вас, и вам придется бороться меньше.

CELK: https://github.com/codenamekt/celk-docker-compose/blob/master/logstash/logstash.conf

Также

Так что начните здесь, чтобы получить хорошее представление о рабочей системе. Они проделали часть работы за вас, так что вам придется беспокоиться только о своем вопросе, который касается настройки и установки.

Даже если вы не используете Docker, это все равно приведет вас на путь к успеху и имеет дополнительное преимущество, показывая вам, как она подходит друг другу.

Сначала возьмите Vagrant и создайте образ Vagrant

Если вы не знаете, что такое Vagrant, то это замечательно. Это программа, которая позволяет людям совместно использовать весь набор виртуальных машин и провайдеров, так что вы можете определить только ВМ и ее конфигурацию, а не совместно использовать всю ВМ, и это "просто работает". Это волшебное ощущение, но на самом деле это просто солидная работа систем

Чтобы использовать это, нужно установить Vagrant. Просто сделайте это! Тогда вам не придется устанавливать docker, потому что он будет работать на Vagrant VM.

У вас есть четыре варианта, как вы хотите его использовать, но сначала подготовьте Vagrant с помощью команды, выделенной жирным шрифтом.....

бродяга вверх


Решите, какие программы вам нужно запустить

Вашими опциями являются:

  • полный набор или ELK (эластичный поиск, логсташ, кибана)
  • только агент (коллектор логсташей)
  • только кибана

Доступны другие конфигурации, но только для тестирования.


Showtime

Теперь пришло время настроить Logstash, который на самом деле является единственной частью, имеющей сложное поведение.

Конфигурационные файлы Logstash - это обычные текстовые файлы, которые заканчиваются на conf и в качестве опции могут быть сгруппированы с помощью tar или gunzipgz.

Конфигурационные файлы можно получить одним из двух способов:

  • вы загружаете их из Интернета, используя переменную окружения LOGSTASH_CONFIG_URL, чтобы указать на url вашего конфигурационного файла, и **если вы получите url неправильно или есть какая-то проблема, и он не может получить конфигурацию из url, он возвращается к knonw url или
  • считывает их с диска, вроде как - так как это docker, вы фактически будете создавать том один раз (сейчас), и вы будете монтировать том каждый раз, когда вы запускаете контейнер.

Вот как это выглядит, когда вы запускаете, используя конфигурацию из Интернета:

$ docker run -d \
  -e LOGSTASH_CONFIG_URL=https://secretlogstashesstash.com/myconfig.tar.gz \
  -p 9292:9292 \
  -p 9200:9200 \
  pblittle/docker-logstash

Автор docker предупреждает вас:

По умолчанию logstash.conf слушает только stdin и файловые входы. Если вы хотите настроить ввод tcp и/или udp, используйте свой собственный логсташ. конфигурационные файлы и откройте сами порты. См. лог-файл документация по синтаксису конфигурации и более подробная информация.

Примечание: Что такое default logstash conf?

Вспомните, что это файл, который вы получаете, когда вы не вставляете в правильный URL для требуемой переменной окружения LOGSTASH_CONFIG_URL

Это раздел ввода:

// As the author warned, this is all you get. StdIn and Syslog file inputs.

input {
  stdin {
    type => "stdin-type"
  }

  file {
    type => "syslog"
    path => [ "/var/log/*.log", "/var/log/messages", "/var/log/syslog" ]
  }

  file {
    type => "logstash"
    path => [ "/var/log/logstash/logstash.log" ]
    start_position => "beginning"
  }
}

За пределами стандартных

Подробнее о logstash на веб-сайте.

Теперь logstash имеет плагины, которые вставляют данные в input. Плагины различаются в точности так, как вы ожидаете; вот несколько:

  • s3 от amazon (события файловой системы)
  • stdin от logstash (по умолчанию, читает буфер stdin)
  • http от logstash (ваше предположение)
  • ...и т.д...

Пример: UDP sockets

UDP - протокол без соединения и быстрый, который работает внизу L4 (транспорт) и поддерживает мультиплексирование, обрабатывает сбои, и в целом является хорошим выбором для протоколирования передачи данных.

Вы выбираете нужный порт; другие опции зависят от того, что вы делаете.

TCP работает таким же образом.

udp { порт => 9999 кодек => Джсон buffer_size => 1452 }

Пример 2: UDP-сокеты из collectd отфильтрованы и выводят

This is stolen from https://github.com/codenamekt/celk-docker-compose/blob/master/logstash/logstash.conf

input {
  udp {
    port => 25826         # 25826 matches port specified in collectd.conf
    buffer_size => 1452   # 1452 is the default buffer size for Collectd
    codec => collectd { } # specific Collectd codec to invoke
    type => collectd
  }
}
output {
  elasticsearch {
    host => elasticsearch
    cluster  => logstash
    protocol => http
  }
}

А фильтрация - отличный пример:. То есть, это очень долго, и я думаю, что это делает вещи

filter {
  # TEST implementation of parse for collectd
  if [type] == "collectd" {
    if [plugin] {
      mutate {
        rename => { "plugin" => "collectd_plugin" }
      }
    }
    if [plugin_instance] {
      mutate {
        rename => { "plugin_instance" => "collectd_plugin_instance" }
      }
    }
    if [type_instance] {
      mutate {
        rename => { "type_instance" => "collectd_type_instance" }
      }
    }
    if [value] {
      mutate {
        rename => { "value" => "collectd_value" }
      }
      mutate {
        convert => { "collectd_value" => "float" }
      }
    }
    if [collectd_plugin] == "interface" {
      mutate {
        add_field => {
          "collectd_value_instance" => "rx"
          "collectd_value" => "%{rx}"
        }
      }
      mutate {
        convert => {
          "tx" => "float"
          "collectd_value" => "float"
        }
      }
      # force clone for kibana3
      clone {
        clones => [ "tx" ]
      }
      ##### BUG EXISTS : AFTER clone 'if [type] == "foo"' NOT WORKING : ruby code is working #####
      ruby {
        code => "
          if event['type'] == 'tx'
            event['collectd_value_instance'] = 'tx'
            event['collectd_value'] = event['tx']
          end
        "
      }
      mutate {
        replace => { "_type" => "collectd" }
        replace => { "type" => "collectd" }
        remove_field => [ "rx", "tx" ]
      }
    }
    if [collectd_plugin] == "disk" {
      mutate {
        add_field => {
          "collectd_value_instance" => "read"
          "collectd_value" => "%{read}"
        }
      }
      mutate {
        convert => {
          "write" => "float"
          "collectd_value" => "float"
        }
      }
      # force clone for kibana3
      clone {
        clones => [ "write" ]
      }
      ##### BUG EXISTS : AFTER clone 'if [type] == "foo"' NOT WORKING : ruby code is working #####
      ruby {
        code => "
          if event['type'] == 'write'
             event['collectd_value_instance'] = 'write'
             event['collectd_value'] = event['write']
          end
        "
      }
      mutate {
        replace => { "_type" => "collectd" }
        replace => { "type" => "collectd" }
        remove_field => [ "read", "write" ]
      }
    }
    if [collectd_plugin] == "df" {
      mutate {
        add_field => {
          "collectd_value_instance" => "free"
          "collectd_value" => "%{free}"
        }
      }
      mutate {
        convert => {
          "used" => "float"
          "collectd_value" => "float"
        }
      }
      # force clone for kibana3
      clone {
        clones => [ "used" ]
      }
      ##### BUG EXISTS : AFTER clone 'if [type] == "foo"' NOT WORKING : ruby code is working  #####
      ruby {
        code => "
          if event['type'] == 'used'
            event['collectd_value_instance'] = 'used'
            event['collectd_value'] = event['used']
          end
        "
      }
      mutate {
        replace => { "_type" => "collectd" }
        replace => { "type" => "collectd" }
        remove_field => [ "used", "free" ]
      }
    }
    if [collectd_plugin] == "load" {
      mutate {
        add_field => {
          "collectd_value_instance" => "shortterm"
          "collectd_value" => "%{shortterm}"
        }
      }
      mutate {
        convert => {
          "longterm" => "float"
          "midterm" => "float"
          "collectd_value" => "float"
        }
      }
      # force clone for kibana3
      clone {
        clones => [ "longterm", "midterm" ]
      }
      ##### BUG EXISTS : AFTER clone 'if [type] == "foo"' NOT WORKING : ruby code is working #####
      ruby {
        code => "
          if event['type'] != 'collectd'
            event['collectd_value_instance'] = event['type']
            event['collectd_value'] = event[event['type']]
          end
        "
      }
      mutate {
        replace => { "_type" => "collectd" }
        replace => { "type" => "collectd" }
        remove_field => [ "longterm", "midterm", "shortterm" ]
      }
    }
  }
}

edit 3: Я, вероятно, не должен делать вашу работу за вас, но это нормально.

collectd как любая хорошая программа ENCAPSULTAES некоторые аспекты, которые уродливы или трудны для пользователей, и пытается сделать это легче для вас в том, что это выглядит так, как будто вы посылаете данные (кортеж в данном случае), вместо того, чтобы обманывать с сериализацией.

Ваш пример:

(date_time, current_cpu_load), например ('2016-0-04-24 11:09:12', 12.3)

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

Тем не менее, подумайте об этом... чуть-чуть, это не повредит.

Вы видите, что плагин для процессора загружен внизу.

Вы видите, что интерфейс для collectd в файле conf слишком мал, чтобы указывать поля.

Так что если вы просто сделаете это, то это сработает, но вы получите гораздо больше данных, чем просто загрузку процессора.

Вот где вы можете использовать фильтр. Но вы также можете сделать это в Кибане, я думаю. Так что я бы не хотел тратить время на написание фильтра, который вам a) не нужен и b) мог бы легко написать, если бы вы потратили некоторое время.

## In `collectd`:
# For each instance where collectd is running, we define 
# hostname proper to that instance. When metrics from
# multiple instances are aggregated, hostname will tell 
# us were they came from.
Hostname "**YOUR_HOSTNAME**"


    # Fully qualified domain name, false for our little lab
    FQDNLookup false

    # Plugins we are going to use with their configurations,
    # if needed
    LoadPlugin cpu

    LoadPlugin df
    <Plugin df>
            Device "/dev/sda1"
            MountPoint "/"
            FSType "ext4"
            ReportReserved "true"
    </Plugin>

    LoadPlugin interface
    <Plugin interface>
            Interface "eth0"
            IgnoreSelected false
    </Plugin>

    LoadPlugin network
    <Plugin network>
            Server "**YOUR.HOST.IP.ADDR**" "**PORTNUMBER**"
    </Plugin>

    LoadPlugin memory

    LoadPlugin syslog
    <Plugin syslog>
            LogLevel info
    </Plugin>

    LoadPlugin swap

    <Include "/etc/collectd/collectd.conf.d">
            Filter ".conf"
    </Include>

Your logstash config

    input {
      udp {
        port => **PORTNUMBER**         # 25826 matches port specified in collectd.conf
        buffer_size => **1452**   **# 1452 is the default buffer size for Collectd**
        codec => collectd { } # specific Collectd codec to invoke
        type => collectd 
      }
    }
    output {
      elasticsearch {
        cluster  => **ELASTICSEARCH_CLUSTER_NAME** # this matches out elasticsearch cluster.name
        protocol => http
      }
    }

a update from aaron at collectd

In Logstash 1.3.x, мы ввели плагин для ввода данных collectd. Он был потрясающе! Мы могли бы обрабатывать метрики в Логсташе, хранить их в Упругое исследование и просмотр их с Кибаной. Единственным недостатком было то, что через плагин можно было получить только около 3100 событий в секунду. В Logstash 1.4.0 мы ввели новый обновлённый плагин UDP входа которая была многопоточной и имела очередь. Я восстановил коллекцию входной плагин, чтобы быть кодеком (с некоторой помощью моих сотрудников и сообщества), чтобы воспользоваться этим огромным увеличением производительности. Теперь только с 3 нитями на моем двухъядерном Macbook Air я могу получить более 45,000 событий в секунду с помощью кодека collectd!

Итак, я хотел бы предоставить несколько быстрых примеров, которые вы могли бы использовать для изменения ваша конфигурация плагина для использования кодека вместо него.

Старый способ: вход { collectd {} } Новый способ:

input {   udp {
port => 25826         # Must be specified. 25826 is the default for collectd
buffer_size => 1452   # Should be specified. 1452 is the default for recent versions of collectd
codec => collectd { } # This will invoke the default options for the codec
type => "collectd"   } } This new configuration will use 2 threads and a queue size of 2000 by default for the UDP input plugin. With
this you should easily be able to break 30,000 events per second!

я привел несколько других примеров конфигурации. Для больше информации, пожалуйста, ознакомьтесь с документацией Logstash для collectd codec.

Happy Logstashing!

0
ответ дан 4 December 2019 в 16:38

Теги

Похожие вопросы