Одной из важнейших задач при проектировании систем является организация мониторинга состояния всех узлов, в том числе большого числа сервисов. В условиях, когда дополнительных сил и средств на это не выделяется, приходится максимально использовать готовые решения.
Думаю, у многих картина в проекте примерно такая:
Что-то куда-то пересылается, как-то обрабатывается и держится на одном гвозде. Задача была собрать со всех точек статистику обработки данных и сложить в одном месте, чтобы потом строить графики и писать отчеты.
Благодаря статье выбор пал на связку Telegraf-Elasticsearch-Grafana. Telegraf отлично вписался в проект для организации мониторинга состояния как железа, так и общедоступного стороннего софта, но я отдельно освещу вопрос измерения нагрузки на собственные сервисы. В данном случае речь идет о .NET сервисах, запущенных в docker контейнерах под Linux. Все сервисы образуют несколько этапов обработки входящей информации, и мне необходимо было измерять количество успешно обработанных и отбракованных пакетов с дополнительными метками этапа обработки, источника и др. для возможности последующей статистической обработки.
Опущу процесс установки и перейду сразу к настройке. Итак, Telegraf умеет принимать сообщения с метриками по каналам tcp, udp, а также через unixsocket:
[[inputs.socket_listener]] #service_address = "unixgram:///tmp/telegraf.sock" service_address = "udp4://:14230" data_format = "json" json_name_key = "name" namepass = ["query_pass"] tag_keys = ["appname","fromip"]
Сервисы будут отправлять сообщения каждый раз, когда обработается очередной пакет, поэтому дополнительно настроим агрегирование. Интервала в 10 секунд вполне достаточно, зависит от нагрузки конкретной системы.
[[aggregators.basicstats]] period = "10s" drop_original = true stats = ["sum"] namepass = ["query_pass"] fieldpass = ["pass","fail"]
Пройдемся по параметрам: query_pass — название метрики, объединяющее будущие измерения, pass — успешная обработка, fail — нет. Дополнительно метрики будут помечаться тегами appname и fromip.
Теперь немного кода. Мне нравится отправлять метрики через udp и unixsocket, хотя вам могут подойти и другие варианты.
UdpClient udpClient = new UdpClient("127.0.0.1", 14230); byte[] datagramBytes= Encoding.UTF8.GetBytes("{\"name\":\"query_pass\",\"pass\":1,\"fromip\":\"127.0.0.1\",\"appname\":\"application\"}"); udpClient.Send(datagramBytes, datagramBytes.Length); datagramBytes= Encoding.UTF8.GetBytes("{\"name\":\"query_pass\",\"fail\":1,\"fromip\":\"127.0.0.1\",\"appname\":\"application\"}"); udpClient.Send(datagramBytes, datagramBytes.Length);
Все это отлично суммируется и складывается в базу, в моем случае это elasticsearch (скриншот).
[[outputs.elasticsearch]] urls = [ "http://localhost:9200" ] # required. timeout = "5s" health_check_interval = "5s" index_name = "telegraf-%Y.%m.%d" # required. manage_template = true template_name = "tp_telegraf" overwrite_template = true
Всем котов.
P.S.: тут итоговый проект для отправки метрик под net.core
