Русский
Русский
English
Статистика
Реклама

Metrics

Перевод Как использовать grok exporter для создания метрик prometheus из неструктурированных журналов

30.06.2020 10:05:46 | Автор: admin

Здесь будет перевод 2 постов про grok exporter.


Первый перевод: Как использовать grok exporter для создания метрик prometheus из неструктурированных журналов


Поговорим о grok exporter. В этой статье я объясню, как можно использовать grok exporter для создания метрик prometheus из неструктурированных журналов.



Grok популярен для обработки журналов в массовом ELK стеке (ElasticSearch, Logstash, Kibana) и благодаря Fabian Stber для разработки grok exporter.


Вот официальная документация grok exporter => https://github.com/fstab/grok_exporter


Шаг 1: Установите Grok exporter


Давайте получим готовый zip файл grok exporter от https://github.com/fstab/grok_exporter/releases.


  1. Перейдите в раздел релизы (releases) и нажмите на последнюю версию (теперь это v0.2.7).
  2. Затем загрузите zip-файл, соответствующий вашей операционной системе. Моя операционная система это 64-битный Linux. Такова будет команда.

wget https://github.com/fstab/grok_exporter/releases/download/v0.2.7/grok_exporter-0.2.7.linux-amd64.zip

  1. Распакуйте файл и перейдите в извлеченный каталог.
  2. Затем выполните команду ниже, чтобы запустить grok exporter.

[root@localhost grok_exporter-0.2.7.linux-amd64]# ./grok_exporter -config ./config.ymlStarting server on http://localhost.localdomain:9144/metrics

Теперь вы можете посмотреть примеры метрик по адресу http://localhost.localdomain:9144/metrics.


Шаг 2: Давайте обработаем некоторые пользовательские журналы


Давайте исследуем некоторые примеры журналов с Grok exporter. Вот несколько случайных журналов, сделанных мной.


30.07.2016 04:33:03 10.3.4.1 user=Nijil message="logged in"30.07.2016 06:47:03 10.3.4.2 user=Alex message="logged failed"30.07.2016 06:55:03 10.3.4.2 user=Alex message="logged in"30.07.2016 07:03:03 10.3.4.3 user=Alan message="logged in"30.07.2016 07:37:03 10.3.4.1 user=Nijil message="logged out"30.07.2016 08:47:03 10.3.4.2 user=Alex message="logged out"30.07.2016 14:34:03 10.3.4.3 user=Alan message="logged out"

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


На Шаге 1 вы, возможно, заметили путь config.xml, который упоминается в стартовой команде grok exporter. Откройте конфигурационный файл и замените содержимое нижеприведенными данными.


global:    config_version: 2input:    type: file    path: ./example/nijil.log  # Specify the location of the your log    readall: true              # This should be True if you want to read whole log and False if you want to read only new lines.grok:    patterns_dir: ./patterns    metrics:    - type: counter      name: user_activity      help: Counter metric example with labels.      match: "%{DATE} %{TIME} %{HOSTNAME:instance} user=%{USER:user} message=\"%{GREEDYDATA:data}\""      labels:          user    : '{{.user}}'server:    port: 9144

Схема вышеприведенной конфигурации сделана внизу.


global:    # Config versioninput:    # How to read log lines (file or stdin).grok:    # Available Grok patterns.metrics:    # How to map Grok fields to Prometheus metrics.server:    # How to expose the metrics via HTTP(S).

Шаг 3: Настройка сердца Grok exporter


В приведенной выше конфигурации наиболее интересным разделом являются метрики, где мы указываем, как строки журнала должны быть сопоставлены с метриками Prometheus.


metrics:    - type: counter      name: user_activity      help: Counter metric example with labels.      match: "%{DATE} %{TIME} %{HOSTNAME:instance} user=%{USER:user} message=\"%{GREEDYDATA:data}\""      labels:          user    : '{{.user}}'

Синтаксис шаблона grok это %{SYNTAX:SEMANTIC}, где SYNTAX это имя шаблона, который будет соответствовать журналу, а SEMANTIC это имя поля для присвоения значения сопоставленному журналу. Возьмем в качестве примера %{HOSTNAME:instance}, HOSTNAME это шаблон grok, который только удаляет IP-часть из журнала, и эта IP-часть сохраняется в экземпляре (здесь вы можете дать любое имя), который вы можете использовать позже. Вы должны отметить, что каждый SYNTAX имеет свою собственную цель, это означает, что вы не можете отказаться от IP-адреса в журнале с синтаксисом даты. И как следует из названия, DATE, TIME, HOSTNAME, USER и GREEDYDATA обрывки даты, времени, имени хоста и "любого сообщения" соответственно.


Вы можете использовать метки, чтобы решить, какая метрика на основе параметров должна быть сгенерирована. Из приведенной выше конфигурации вы можете понять, что метрика основана на имени пользователя. Обратите внимание, что вам нужно использовать семантику синтаксиса (SEMANTIC of the SYNTAX) для метки. Для метрики должно быть по крайней мере два параметра. Здесь мы имеем имя пользователя в одной оси и количество вхождений пользователя в другую ось. Второй параметр определяется на основе счетчика метрического типа. Как и Счетчик (Counter), у grok exporter есть и другие метрические типы, узнайте о них из официальных документов.


А теперь займитесь grok exporter ./grok_exporter -config ./config.yml и откройте метрики в браузере. Вы увидите метрики, созданные с именем user_activity, как мы указали в конфигурационном файле.


# TYPE user_activity counteruser_activity{user="Alan"} 2user_activity{user="Alex"} 3user_activity{user="Nijil"} 2

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


Второй перевод по теме grok exporter


Второй перевод: Получение метрик из журналов Apache с помощью grok exporter


Не все приложения создают полезные метрики, но некоторые из них создают журналы.


Существует класс приложений, которые практически не имеют полезных метрик, однако информацию, которую вы хотели бы иметь, можно найти в журналах. Одним из вариантов решения этой проблемы является экспортер grok. Допустим, вы работали с Apache, вот несколько примеров журналов из типичного access.log:


x.x.x.x - - [20/Jan/2020:06:25:24 +0000] "GET / HTTP/1.1" 200 62316 "http://178.62.121.216" "Go-http-client/1.1"x.x.x.x - - [20/Jan/2020:06:25:25 +0000] "GET / HTTP/1.1" 200 16061 "-" "Go-http-client/1.1"x.x.x.x - - [20/Jan/2020:06:25:25 +0000] "GET / HTTP/1.1" 200 16064 "-" "Go-http-client/1.1"x.x.x.x - - [20/Jan/2020:06:25:25 +0000] "GET /blog/rss HTTP/1.1" 301 3478 "-" "Tiny Tiny RSS/19.2 (adc2a51) (http://personeltest.ru/away/tt-rss.org/)"x.x.x.x - - [20/Jan/2020:06:25:26 +0000] "GET / HTTP/1.1" 200 16065 "-" "Go-http-client/1.1"x.x.x.x - - [20/Jan/2020:06:25:26 +0000] "GET /blog/feed HTTP/1.1" 200 3413 "-" "Tiny Tiny RSS/19.2 (adc2a51) (http://personeltest.ru/away/tt-rss.org/)"x.x.x.x - - [20/Jan/2020:06:25:27 +0000] "GET /feed HTTP/1.1" 200 6496 "-" "Emacs Elfeed 3.2.0"x.x.x.x - - [20/Jan/2020:06:25:27 +0000] "GET / HTTP/1.1" 200 62316 "http://178.62.121.216" "Go-http-client/1.1"

Для начала загрузите:


wget https://github.com/fstab/grok_exporter/releases/download/v1.0.0.RC2/grok_exporter-1.0.0.RC2.linux-amd64.zip

распакуйте


unzip grok_exporter-*.zipcd grok_exporter*amd64

настройке:


cat << 'EOF' > config.ymlglobal:    config_version: 2input:    type: file    path: access.log    readall: truegrok:    patterns_dir: ./patternsmetrics:    - type: counter      name: apache_http_response_codes_total      help: HTTP requests to Apache      match: '%{COMBINEDAPACHELOG}'      labels:          method: '{{.verb}}'          path: '{{.request}}'          code: '{{.response}}'server:    port: 9144EOF

и запустите grok exporter:


./grok_exporter -config config.yml

Если вы посетите нас http://localhost:9144/metrics вы увидите метрику:


# HELP apache_http_response_codes_total HTTP requests to Apache# TYPE apache_http_response_codes_total counterapache_http_response_codes_total{code="200",method="GET",path="/"} 5apache_http_response_codes_total{code="200",method="GET",path="/blog/feed"} 1apache_http_response_codes_total{code="200",method="GET",path="/feed"} 1apache_http_response_codes_total{code="301",method="GET",path="/blog/rss"} 1

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


Чтобы сделать небольшую резервную копию, Grok это способ, которым вы можете анализировать строки журнала в Logstash (Logstash это L в стеке ELK). Соответственно, паттерны были написаны для многих распространенных приложений, включая Apache. Экспортер Grok позволяет вам строить на существующем корпусе шаблонов, а также добавлять свои собственные, чтобы извлекать метрики из журналов. COMMMONAPACHELOG наверху, например, определяется как


COMMONAPACHELOG %{IPORHOST:clientip} %{HTTPDUSER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response} (?:%{NUMBER:bytes}|-)

что само по себе опирается на множество других паттернов. Так что вы должны быть рады, что вам не придется писать это самому с нуля. Поля меток предоставляют вам шаблон Go (как показано в шаблонах Prometheus alerting и notification) для доступа к этим значениям.


Помимо подсчета строк журнала, экспортер Grok может позволить вам наблюдать размеры событий, такие как количество байтов в ответах:


    - type: summary      name: apache_http_response_bytes      help: Size of HTTP responses      match: '%{COMMONAPACHELOG}'      value: '{{.bytes}}'

Или датчики, например, когда был последний запрос:


    - type: gauge       name: apache_http_last_request_seconds      help: Timestamp of the last HTTP request      match: '%{COMMONAPACHELOG}'      value: '{{timestamp "02/Jan/2006:15:04:05 -0700" .timestamp}}'

Это происходит с помощью функции метки времени (timestamp) grok exporter, которая в основном является time.Parse из Golang. Разбор. Есть также функция деления (divide), если вам нужно преобразовать миллисекунды в секунды.


Это небольшая проба того, что вы можете сделать с экспортером Grok. Как вы можете видеть, синтаксический анализ журналов требует некоторой конфигурации, поэтому вы должны использовать такой экспортер только в том случае, если у вас нет возможности заставить само приложение создавать хорошие показатели.


Телеграм чат по метрикам https://t.me/metrics_ru

Подробнее..

Обзор возможностей Kubespray Отличие оригинальной версии и нашего форка

20.09.2020 14:22:27 | Автор: admin

23 сентября 20.00 МСК Сергей Бондарев проведёт бесплатный вебинар Обзор возможностей Kubespray, где расскажет, как готовят kubespray, чтобы получилось быстро, эффективно и отказоустойчиво.


Сергей Бондарев расскажет отличие оригинальной версии и нашего форка:



Отличие оригинальной версии и нашего форка.


Те, кто с кубспреем уже сталкивался, наверное сейчас недоумевают, почему я kubeadm противопоставляю кубспрею, ведь кубспрей для создания кластера, как раз и вызывает кубадм и на первый взгляд выглядит, как скрипт установки пакетов и автоматизированного запуска.


Но так было не всегда, изначально кубспрей устанавливал все компоненты самостоятельно:


  • собирал кластер etcd;
  • устанавливал кублеты, генерил сертификаты, конфиги и токены доступа для статик подов контролплейна и прочих служебных компонентов;
  • создавал сервис аккаунты для рабочих узлов и подключал их в кластер.

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


В итоге разница между кластерами, созданными моим форком и оригинальным это kube-proxy и сроки действия сертификатов.


В моем форке все осталось, как было раньше куб-прокси запускается, как статик под, сертификаты выписываются на 100 лет.


В Kubeadm куб-прокси запускается, как daemonset, а сертификаты выписываются на 1 год, и их надо периодически продлевать. kubeadm наконец-то научился это делать одной командой.


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


Особенности (недостатки) при промышленной эксплуатации:


Сценарий универсальный, поэтому не очень быстрый. Собственный можно значительно ускорить, выкинув проверки, запускаясь из готового образа.


Сценарий сложный, есть нелогичные места, тяжелое наследие legacy. Установка доп. контроллеров и софта через кубспрей хороша для обучения и тестов. В пром. эксплуатации зависеть от кубспрея не очень здравая идея, плюс обновление софта реализовано методом "убил-сделал новый" значит перерыв в обслуживании.


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


Например у меня была проблема с кубадмом, когда он падал в момент добавления второго и третьего мастера, и после этого кубспрей делал kubeadm reset на узле, и пробовал добавить мастер еще раз.


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


Opensource как он есть.


Всё это и многое другое на бесплатном вебинаре Обзор возможностей Kubespray 23 сентября 20.00 МСК.


Присоединяйтесь!

Подробнее..

Собираем логи с Loki

25.06.2020 16:23:50 | Автор: admin


Мы в Badoo постоянно мониторим свежие технологии и оцениваем, стоит ли использовать их в нашей системе. Одним из таких исследований и хотим поделиться с сообществом. Оно посвящено Loki системе агрегирования логов.


Loki это решение для хранения и просмотра логов, также этот стек предоставляет гибкую систему для их анализа и отправки данных в Prometheus. В мае вышло очередное обновление, которое активно продвигают создатели. Нас заинтересовало, что умеет Loki, какие возможности предоставляет и в какой степени может выступать в качестве альтернативы ELK стека, который мы используем сейчас.


Что такое Loki


Grafana Loki это набор компонентов для полноценной системы работы с логами. В отличие от других подобных систем Loki основан на идее индексировать только метаданные логов labels (так же, как и в Prometheus), a сами логи сжимать рядом в отдельные чанки.


Домашняя страница, GitHub


Прежде чем перейти к описанию того, что можно делать при помощи Loki, хочу пояснить, что подразумевается под идеей индексировать только метаданные. Сравним подход Loki и подход к индексированию в традиционных решениях, таких как Elasticsearch, на примере строки из лога nginx:


172.19.0.4 - - [01/Jun/2020:12:05:03 +0000] "GET /purchase?user_id=75146478&amp;item_id=34234 HTTP/1.1" 500 8102 "-" "Stub_Bot/3.0" "0.001"

Традиционные системы парсят строку целиком, включая поля с большим количеством уникальных значений user_id и item_id, и сохраняют всё в большие индексы. Преимуществом данного подхода является то, что можно выполнять сложные запросы быстро, так как почти все данные в индексе. Но за это приходится платить тем, что индекс становится большим, что выливается в требования к памяти. В итоге полнотекстовый индекс логов сопоставим по размеру с самими логами. Для того чтобы по нему быстро искать, индекс должен быть загружен в память. И чем больше логов, тем быстрее индекс увеличивается и тем больше памяти он потребляет.


Подход Loki требует, чтобы из строки были извлечены только необходимые данные, количество значений которых невелико. Таким образом, мы получаем небольшой индекс и можем искать данные, фильтруя их по времени и по проиндексированным полям, а затем сканируя оставшееся регулярными выражениями или поиском подстроки. Процесс кажется не самым быстрым, но Loki разделяет запрос на несколько частей и выполняет их параллельно, обрабатывая большое количество данных за короткое время. Количество шардов и параллельных запросов в них конфигурируется; таким образом, количество данных, которое можно обработать за единицу времени, линейно зависит от количества предоставленных ресурсов.


Этот компромисс между большим быстрым индексом и маленьким индексом с параллельным полным перебором позволяет Loki контролировать стоимость системы. Её можно гибко настраивать и расширять в соответствии с потребностями.


Loki-стек состоит из трёх компонентов: Promtail, Loki, Grafana. Promtail собирает логи, обрабатывает их и отправляет в Loki. Loki их хранит. А Grafana умеет запрашивать данные из Loki и показывать их. Вообще Loki можно использовать не только для хранения логов и поиска по ним. Весь стек даёт большие возможности по обработке и анализу поступающих данных, используя Prometheus way.
Описание процесса установки можно найти здесь.


Поиск по логам


Искать по логам можно в специальном интерфейсе Grafana Explorer. Для запросов используется язык LogQL, очень похожий на PromQL, использующийся в Prometheus. В принципе, его можно рассматривать как распределённый grep.


Интерфейс поиска выглядит так:



Сам запрос состоит из двух частей: selector и filter. Selector это поиск по индексированным метаданным (лейблам), которые присвоены логам, а filter поисковая строка или регэксп, с помощью которого отфильтровываются записи, определённые селектором. В приведенном примере: В фигурных скобках селектор, все что после фильтр.


{image_name="nginx.promtail.test"} |= "index"

Из-за принципа работы Loki нельзя делать запросы без селектора, но лейблы можно делать сколь угодно общими.


Селектор это key-value значения в фигурных скобках. Можно комбинировать селекторы и задавать разные условия поиска, используя операторы =, != или регулярные выражения:


{instance=~"kafka-[23]",name!="kafka-dev"} // Найдёт логи с лейблом instance, имеющие значение kafka-2, kafka-3, и исключит dev 

Фильтр это текст или регэксп, который отфильтрует все данные, полученные селектором.


Есть возможность получения ad-hoc-графиков по полученным данным в режиме metrics. Например, можно узнать частоту появления в логах nginx записи, содержащей строку index:



Полное описание возможностей можно найти в документации LogQL.


Парсинг логов


Есть несколько способов собрать логи:


  • С помощью Promtail, стандартного компонента стека для сбора логов.
  • Напрямую с докер-контейнера при помощи Loki Docker Logging Driver.
  • Использовать Fluentd или Fluent Bit, которые умеют отправлять данные в Loki. В отличие от Promtail они имеют готовые парсеры практически для любого вида лога и справляются в том числе с multiline-логами.

Обычно для парсинга используют Promtail. Он делает три вещи:


  • Находит источники данных.
  • Прикрепляет к ним лейблы.
  • Отправляет данные в Loki.

В настоящий момент Promtail может читать логи с локальных файлов и с systemd journal. Он должен быть установлен на каждую машину, с которой собираются логи.


Есть интеграция с Kubernetes: Promtail автоматически через Kubernetes REST API узнаёт состояние кластера и собирает логи с ноды, сервиса или пода, сразу развешивая лейблы на основе метаданных из Kubernetes (имя пода, имя файла и т. д.).


Также можно развешивать лейблы на основе данных из лога при помощи Pipeline. Pipeline Promtail может состоять из четырёх типов стадий. Более подробно в официальной документации, тут же отмечу некоторые нюансы.


  1. Parsing stages. Это стадия RegEx и JSON. На этом этапе мы извлекаем данные из логов в так называемую extracted map. Извлекать можно из JSON, просто копируя нужные нам поля в extracted map, или через регулярные выражения (RegEx), где в extracted map мапятся named groups. Extracted map представляет собой key-value хранилище, где key имя поля, а value его значение из логов.
  2. Transform stages. У этой стадии есть две опции: transform, где мы задаем правила трансформации, и source источник данных для трансформации из extracted map. Если в extracted map такого поля нет, то оно будет создано. Таким образом, можно создавать лейблы, которые не основаны на extracted map. На этом этапе мы можем манипулировать данными в extracted map, используя достаточно мощный Golang Template. Кроме того, надо помнить, что extracted map целиком загружается при парсинге, что даёт возможность, например, проверять значение в ней: {{if .tag}tag value exists{end}}. Template поддерживает условия, циклы и некоторые строковые функции, такие как Replace и Trim.
  3. Action stages. На этом этапе можно сделать что-нибудь с извлечённым:
    • Создать лейбл из extracted data, который проиндексируется Loki.
    • Изменить или установить время события из лога.
    • Изменить данные (текст лога), которые уйдут в Loki.
    • Создать метрики.
  4. Filtering stages. Стадия match, на которой можно либо отправить в /dev/null записи, которые нам не нужны, либо направить их на дальнейшую обработку.

Покажу на примере обработки обычных nginx-логов, как можно парсить логи при помощи Promtail.


Для теста возьмём в качестве nginx-proxy модифицированный образ nginx jwilder/nginx-proxy:alpine и небольшой демон, который умеет спрашивать сам себя по HTTP. У демона задано несколько эндпоинтов, на которые он может давать ответы разного размера, с разными HTTP-статусами и с разной задержкой.


Собирать логи будем с докер-контейнеров, которые можно найти по пути /var/lib/docker/containers/<container_id>/<container_id>-json.log


В docker-compose.yml настраиваем Promtail и указываем путь до конфига:


promtail:  image: grafana/promtail:1.4.1 // ... volumes:   - /var/lib/docker/containers:/var/lib/docker/containers:ro   - promtail-data:/var/lib/promtail/positions   - ${PWD}/promtail/docker.yml:/etc/promtail/promtail.yml command:   - '-config.file=/etc/promtail/promtail.yml' // ...

Добавляем в promtail.yml путь до логов (в конфиге есть опция "docker", которая делает то же самое одной строчкой, но это было бы не так наглядно):


scrape_configs: - job_name: containers   static_configs:       labels:         job: containerlogs         __path__: /var/lib/docker/containers/*/*log  # for linux only

При включении такой конфигурации в Loki будут попадать логи со всех контейнеров. Чтобы этого избежать, меняем настройки тестового nginx в docker-compose.yml добавляем логирование поле tag:


proxy: image: nginx.test.v3// logging:   driver: "json-file"   options:     tag: "{{.ImageName}}|{{.Name}}"

Правим promtail.yml и настраиваем Pipeline. На вход попадают логи следующего вида:


{"log":"\u001b[0;33;1mnginx.1    | \u001b[0mnginx.test 172.28.0.3 - - [13/Jun/2020:23:25:50 +0000] \"GET /api/index HTTP/1.1\" 200 0 \"-\" \"Stub_Bot/0.1\" \"0.096\"\n","stream":"stdout","attrs":{"tag":"nginx.promtail.test|proxy.prober"},"time":"2020-06-13T23:25:50.66740443Z"}{"log":"\u001b[0;33;1mnginx.1    | \u001b[0mnginx.test 172.28.0.3 - - [13/Jun/2020:23:25:50 +0000] \"GET /200 HTTP/1.1\" 200 0 \"-\" \"Stub_Bot/0.1\" \"0.000\"\n","stream":"stdout","attrs":{"tag":"nginx.promtail.test|proxy.prober"},"time":"2020-06-13T23:25:50.702925272Z"}

Pipeline stage:


 - json:     expressions:       stream: stream       attrs: attrs       tag: attrs.tag

Извлекаем из входящего JSON поля stream, attrs, attrs.tag (если они есть) и кладём их в extracted map.


 - regex:     expression: ^(?P<image_name>([^|]+))\|(?P<container_name>([^|]+))$     source: "tag"

Если удалось положить поле tag в extracted map, то при помощи регэкспа извлекаем имена образа и контейнера.


 - labels:     image_name:     container_name:

Назначаем лейблы. Если в extracted data будут обнаружены ключи image_name и container_name, то их значения будут присвоены соотвестующим лейблам.


 - match:     selector: '{job="docker",container_name="",image_name=""}'     action: drop

Отбрасываем все логи, у которых не обнаружены установленные labels image_name и container_name.


  - match:     selector: '{image_name="nginx.promtail.test"}'     stages:       - json:           expressions:             row: log

Для всех логов, у которых image_name равен nginx.promtail.test, извлекаем из исходного лога поле log и кладём его в extracted map с ключом row.


  - regex:         # suppress forego colors         expression: .+nginx.+\|.+\[0m(?P<virtual_host>[a-z_\.-]+) +(?P<nginxlog>.+)         source: logrow

Очищаем входную строку регулярными выражениями и вытаскиваем nginx virtual host и строку лога nginx.


     - regex:         source: nginxlog         expression: ^(?P<ip>[\w\.]+) - (?P<user>[^ ]*) \[(?P<timestamp>[^ ]+).*\] "(?P<method>[^ ]*) (?P<request_url>[^ ]*) (?P<request_http_protocol>[^ ]*)" (?P<status>[\d]+) (?P<bytes_out>[\d]+) "(?P<http_referer>[^"]*)" "(?P<user_agent>[^"]*)"( "(?P<response_time>[\d\.]+)")?

Парсим nginx-лог регулярными выражениями.


    - regex:           source: request_url           expression: ^.+\.(?P<static_type>jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm)$     - regex:           source: request_url           expression: ^/photo/(?P<photo>[^/\?\.]+).*$       - regex:           source: request_url           expression: ^/api/(?P<api_request>[^/\?\.]+).*$

Разбираем request_url. С помощью регэкспа определяем назначение запроса: к статике, к фоткам, к API и устанавливаем в extracted map соответствующий ключ.


       - template:           source: request_type           template: "{{if .photo}}photo{{else if .static_type}}static{{else if .api_request}}api{{else}}other{{end}}"

При помощи условных операторов в Template проверяем установленные поля в extracted map и устанавливаем для поля request_type нужные значения: photo, static, API. Назначаем other, если не удалось. Теперь request_type содержит тип запроса.


       - labels:           api_request:           virtual_host:           request_type:           status:

Устанавливаем лейблы api_request, virtual_host, request_type и статус (HTTP status) на основании того, что удалось положить в extracted map.


       - output:           source: nginx_log_row

Меняем output. Теперь в Loki уходит очищенный nginx-лог из extracted map.



После запуска приведённого конфига можно увидеть, что каждой записи присвоены метки на основе данных из лога.


Нужно иметь в виду, что извлечение меток с большим количеством значений (cardinality) может существенно замедлить работу Loki. То есть не стоит помещать в индекс, например, user_id. Подробнее об этом читайте в статье How labels in Loki can make log queries faster and easier. Но это не значит, что нельзя искать по user_id без индексов. Нужно использовать фильтры при поиске (грепать по данным), а индекс здесь выступает как идентификатор потока.


Визуализация логов



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


  • rate количество записей в секунду;
  • count over time количество записей в заданном диапазоне.

Ещё присутствуют агрегирующие функции Sum, Avg и другие. Можно строить достаточно сложные графики, например график количества HTTP-ошибок:



Стандартный data source Loki несколько урезан по функциональности по сравнению с data source Prometheus (например, нельзя изменить легенду), но Loki можно подключить как источник с типом Prometheus. Я не уверен, что это документированное поведение, но, судя по ответу разработчиков How to configure Loki as Prometheus datasource? Issue #1222 grafana/loki, например, это вполне законно, и Loki полностью совместим с PromQL.


Добавляем Loki как data source с типом Prometheus и дописываем URL /loki:



И можно делать графики, как в том случае, если бы мы работали с метриками из Prometheus:



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



Метрики


В Loki доступны возможность извлечения числовых метрик из логов и отправка их в Prometheus. Например, в логе nginx присутствует количество байтов на ответ, а также, при определённой модификации стандартного формата лога, и время в секундах, которое потребовалось на ответ. Эти данные можно извлечь и отправить в Prometheus.


Добавляем ещё одну секцию в promtail.yml:


- match:   selector: '{request_type="api"}'   stages:     - metrics:         http_nginx_response_time:           type: Histogram           description: "response time ms"           source: response_time           config:             buckets: [0.010,0.050,0.100,0.200,0.500,1.0]- match:   selector: '{request_type=~"static|photo"}'   stages:     - metrics:         http_nginx_response_bytes_sum:           type: Counter           description: "response bytes sum"           source: bytes_out           config:             action: add         http_nginx_response_bytes_count:           type: Counter           description: "response bytes count"           source: bytes_out           config:             action: inc

Опция позволяет определять и обновлять метрики на основе данных из extracted map. Эти метрики не отправляются в Loki они появляются в Promtail /metrics endpoint. Prometheus должен быть сконфигурирован таким образом, чтобы получить данные, полученные на этой стадии. В приведённом примере для request_type=api мы собираем метрику-гистограмму. С этим типом метрик удобно получать перцентили. Для статики и фото мы собираем сумму байтов и количество строк, в которых мы получили байты, чтобы вычислить среднее значение.


Более подробно о метриках читайте здесь.


Открываем порт на Promtail:


promtail:     image: grafana/promtail:1.4.1     container_name: monitoring.promtail     expose:       - 9080     ports:       - "9080:9080"

Убеждаемся, что метрики с префиксом promtail_custom появились:



Настраиваем Prometheus. Добавляем job promtail:


- job_name: 'promtail' scrape_interval: 10s static_configs:   - targets: ['promtail:9080']

И рисуем график:



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


Масштабирование


Loki может быть как в одиночном режиме (single binary mode), так и в шардируемом (horizontally-scalable mode). Во втором случае он может сохранять данные в облако, причём чанки и индекс хранятся отдельно. В версии 1.5 реализована возможность хранения в одном месте, но пока не рекомендуется использовать её в продакшене.



Чанки можно хранить в S3-совместимом хранилище, для хранения индексов использовать горизонтально масштабируемые базы данных: Cassandra, BigTable или DynamoDB. Другие части Loki Distributors (для записи) и Querier (для запросов) stateless и также масштабируются горизонтально.


На конференции DevOpsDays Vancouver 2019 один из участников Callum Styan озвучил, что с Loki его проект имеет петабайты логов с индексом меньше 1% от общего размера: How Loki Correlates Metrics and Logs And Saves You Money.


Сравнение Loki и ELK


Размер индекса
Для тестирования получаемого размера индекса я взял логи с контейнера nginx, для которого настраивался Pipeline, приведённый выше. Файл с логами содержал 406 624 строки суммарным объёмом 109 Мб. Генерировались логи в течение часа, примерно по 100 записей в секунду.


Пример двух строк из лога:



При индексации ELK это дало размер индекса 30,3 Мб:



В случае с Loki это дало примерно 128 Кб индекса и примерно 3,8 Мб данных в чанках. Стоит отметить, что лог был искусственно сгенерирован и не отличался большим разнообразием данных. Простой gzip на исходном докеровском JSON-логе с данными давал компрессию 95,4%, а с учётом того, что в сам Loki посылался только очищенный nginx-лог, то сжатие до 4 Мб объяснимо. Суммарное количество уникальных значений для лейблов Loki было 35, что объясняет небольшой размер индекса. Для ELK лог также очищался. Таким образом, Loki сжал исходные данные на 96%, а ELK на 70%.


Потребление памяти



Если сравнивать весь стек Prometheus и ELK, то Loki ест в несколько раз меньше. Понятно, что сервис на Go потребляет меньше, чем сервис на Java, и сравнение размера JVM Heap Elasticsearch и выделенной памяти для Loki некорректно, но тем не менее стоит отметить, что Loki использует гораздо меньше памяти. Его преимущество по CPU не так очевидно, но также присутствует.


Скорость


Loki быстрее пожирает логи. Скорость зависит от многих факторов что за логи, как изощрённо мы их парсим, сеть, диск и т. д. но она однозначно выше, чем у ELK (в моём тесте примерно в два раза). Объясняется это тем, что Loki кладёт гораздо меньше данных в индекс и, соответственно, меньше времени тратит на индексирование. Со скоростью поиска при этом ситуация обратная: Loki ощутимо притормаживает на данных размером более нескольких гигабайтов, у ELK же скорость поиска от размера данных не зависит.


Поиск по логам


Loki существенно уступает ELK по возможностям поиска по логам. Grep с регулярными выражениями это сильная вещь, но он уступает взрослой базе данных. Отсутствие range-запросов, агрегация только по лейблам, невозможность искать без лейблов всё это ограничивает нас в поисках интересующей информации в Loki. Это не подразумевает, что с помощью Loki ничего нельзя найти, но определяет флоу работы с логами, когда вы сначала находите проблему на графиках Prometheus, а потом по этим лейблам ищете, что случилось в логах.


Интерфейс


Во-первых, это красиво (извините, не мог удержаться). Grafana имеет приятный глазу интерфейс, но Kibana гораздо более функциональна.


Плюсы и минусы Loki


Из плюсов можно отметить, что Loki интегрируется с Prometheus, соответственно, метрики и алертинг мы получаем из коробки. Он удобен для сбора логов и их хранения с Kubernetes Pods, так как имеет унаследованный от Prometheus service discovery и автоматически навешивает лейблы.


Из минусов слабая документация. Некоторые вещи, например особенности и возможности Promtail, я обнаружил только в процессе изучения кода, благо open-source. Ещё один минус слабые возможности парсинга. Например, Loki не умеет парсить multiline-логи. Также к недостаткам можно отнести то, что Loki относительно молодая технология (релиз 1.0 был в ноябре 2019 года).


Заключение


Loki на 100% интересная технология, которая подходит для небольших и средних проектов, позволяя решать множество задач агрегирования логов, поиска по логам, мониторинга и анализа логов.


Мы не используем Loki в Badoo, так как имеем ELK-стек, который нас устраивает и который за много лет оброс различными кастомными решениями. Для нас камнем преткновения является поиск по логам. Имея почти 100 Гб логов в день, нам важно уметь находить всё и чуть-чуть больше и делать это быстро. Для построения графиков и мониторинга мы используем другие решения, которые заточены под наши нужды и интегрированы между собой. У стека Loki есть ощутимые плюсы, но он не даст нам больше, чем у нас есть, и его преимущества точно не перекроют стоимость миграции.


И хотя после исследования стало понятно, что мы Loki использовать не можем, надеемся, что данный пост поможет вам в выборе.


Репозиторий с кодом, использованным в статье, находится тут.

Подробнее..

Пушим метрики Prometheus с помощью pushgateway

06.12.2020 04:20:10 | Автор: admin

Всё тоже, только у pushgateway пламя голубенькое в favicon


Предисловие


Данная заметка в целом о пуше метрик в pushgateway, однако, предупрежу и признаюсь сразу, что в тексте будет пример анти-паттерна пуша метрик, так как использование pushgateway рекомендуется в случае, когда сервис работает не постоянно (или у сервиса/запускаемого задания вообще нет никакого интерфейса), а значит и prometheus'у лучше в закрытые двери постоянно не стучать и не заниматься лишней работой.


Введение


Итак, pushgateway это сервис куда можно скидывать метрики, когда стандартная pull-модель prometheus'а не применима (в предисловии, я в общем описал, как такая ситуация может возникнуть и выглядеть). После того, как метрики попали в pushgateway оттуда их уже забирает prometheus и из этого вытекает несколько ограничений, связанных с пушем метрик, например, отсутствие метрики up, так как она формируется самим prometheus для опрашиваемого инстанса, а в данном случае это только pushgateway.


p.s. Хотя, если говорить о up метрике, то она и не нужна, в случае, если вы используете pushgateway бестпрактайс-способом.


Готовим prometheus к опросу pushgateway


Допустим, у нас есть вот такой compose с prometheus и pushgateway:


# ....(тут какие-нибудь графаны и т.д.)   prometheus:      restart: always      image: bitnami/prometheus:latest      links:          - pushgateway      volumes:          - ./.prom.yml:/opt/bitnami/prometheus/conf/prometheus.yml  pushgateway:      restart: always      image: bitnami/pushgateway:latest      ports:          - 9091:9091  

В данном случае prom.yml должен выглядеть как-то так, чтобы собирать данные с pushgateway:


global: nullscrape_interval: 5sscrape_timeout: 2sevaluation_interval: 15sscrape_configs:  - job_name: pushgateway    honor_labels: true    static_configs:      - targets:          - 'pushgateway:9091'

Тут всё достаточно понятно, добавили только honor_lables, который, если вкратце разрешает конфликты имён лэйблов, то есть например, если у вашего сервиса есть метрика с лэблом "X" и у pushgateway, есть лэйбл "X", то при honor_lables=false у вас будет лэйбл "X" с pushgateway и "exported_X" с вашего сервиса, который запушил метрики в pushgateway, а при значении true будут отображаться только лэйблы вашего сервиса (опять же, если будет конфликт).


p.s. Незабываем о безопасности pushgateway дока по-умолчанию рекомендует, например, использовать basic_auth.


Пушим метрики


Я бы мог привести красивый пример, соответствующий нормальной практике, однако, я подумал и решил, что давно мне минусов не ставили, потому будет пример пуша метрик из-за того, что настройка service_discovery отсутствует (в прод, понятное дело, это низя).


Итак, допустим, у нас есть воркеры Faust их много и они не в кластере (нет ни swarm, ни куберов), так же нет consul и иных способов в которые умеет prometheus, они просто спокойно запускаются в docker compose и размножаются параметром scale.


Больший ужас и крамолу, помимо пуша метрик, можно сделать рэйджировав порты, например, так:


ports:  - "9100-9200:6066"  

И загонять в конфиг prometheus таргеты со всем множеством портов.


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


async def push_metrics():      def auth_handler(url, method, timeout, headers, data):          return basic_auth_handler(url, method, timeout, headers, data, PUSHGATEWAY_USERNAME, PUSHGATEWAY_PASSWORD)      push_to_gateway(PUSHGATEWAY_URI, job=f"{WORKERS_APP_NAME}-{ENV}", registry=registry_metrics, handler=auth_handler)  @app.timer(interval=PUSH_METRICS_INTERVAL)  async def push_metrics_cron():      await push_metrics()  

Как видите тут всё достаточно просто указываем job name (при пуле метрик это делается в конфиге prometheus'а), подставляем handler для аутентификации и указываем registry из которого будут пушиться метрики. Ну и собственно всё, запускаем и при открытии pushgateway веб-морды видим, что у нас через интервал загрузились метрики, далее оттуда их заберёт ранее настроенный prometheus.


Послесловие


Заметку я решил написать, так как столкнулся с подобным в работе, сразу скажу, что способ из примера в прод не пойдёт, однако, как применение pushgateway при отсутствии service discovery, для тестирования это сойти может.

Подробнее..
Категории: Python , Devops , Monitoring , Prometheus , Metrics , Faust , Pushgateway

Перевод Новые метрики объектных хранилищ

12.10.2020 18:16:09 | Автор: admin
Flying Fortress by Nele-Diel

Команда объектного S3-хранилища Mail.ru Cloud Storage перевела статью о том, какие критерии важны при выборе объектного хранилища. Далее текст от лица автора.

Когда заходит речь об объектном хранилище, как правило, люди думают только об одной характеристике цене за ТБ/ГБ. Конечно, эта метрика важна, но она делает подход однобоким и приравнивает объектное хранилище к инструменту для хранения архивов. Плюс такой подход уменьшает важность объектного хранилища для технологического стека предприятия.

Выбирая объектное хранилище, стоит обращать внимание на пять характеристик:

  • производительность;
  • масштабируемость;
  • совместимость с S3;
  • реакция на сбои;
  • целостность.

Эти пять характеристик новые метрики объектного хранилища, наравне со стоимостью. Рассмотрим их все.

Производительность


Традиционные объектные хранилища не отличаются производительностью. Поставщики услуг постоянно жертвовали ей в погоне за низкими ценами. Однако с современными объектными хранилищами всё иначе.

Скорость различных хранилищ приближается к Hadoop или даже превосходит ее. Современные требования к скорости чтения и записи: от 10 ГБ/с для жестких дисков, до 35 ГБ/с для NVMe.

Такой пропускной способности достаточно для Spark, Presto, Tensorflow, Teradata, Vertica, Splunk и других современных вычислительных фреймворков в стеке аналитики. Тот факт, что MPP-базы данных настраивают на объектные хранилища, говорит о том, что оно всё чаще используется как основное хранилище.

Если ваша система хранения не обеспечивает нужную скорость, вы не можете использовать данные и извлекать из них значения. Даже если вы извлекаете данные из объектного хранилища в структуру обработки в памяти, всё равно потребуется пропускная способность для передачи данных в память и из нее. У устаревших объектных хранилищ ее недостаточно.

Это ключевой момент: новый показатель производительности пропускная способность, а не задержка. Она требуется для масштабируемых данных, и это норма в современной инфраструктуре данных.

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

Масштабируемость


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

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

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

У мультиклиентности множество характеристик. Хотя параметр говорит о том, как организации предоставляют доступ к данным и приложениям, он также относится и к самим приложениям, и к логике их изоляции друг от друга.

Характеристики современного подхода к мультиклиентности:

  • За короткое время количество клиентов может вырасти с нескольких сотен до нескольких миллионов.
  • Клиенты полностью изолированы друг от друга. Это позволяет им запускать разные версии одного и того же ПО и хранить объекты с различными конфигурациями, разрешениями, функциями, уровнями безопасности и обслуживания. Это необходимо, когда масштабируются новые серверы, обновления и географические регионы.
  • Хранилище эластично масштабируется, ресурсы предоставляются по запросу.
  • Каждая операция управляется API и автоматизируется без участия человека.
  • ПО можно разместить в контейнерах и использовать стандартные системы оркестрации, например Kubernetes.

Совместимость с S3


Amazon S3 API фактически стандарт для объектных хранилищ. Каждый поставщик ПО для объектного хранилища заявляет о совместимости с ним. Совместимость с S3 двоичная: либо она реализована в полном объеме, либо ее нет.

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

Значительные преимущества у ПО с открытым исходным кодом. Оно покрывает большинство пограничных сценариев, учитывая размер и разнообразие приложений, операционных систем и аппаратной архитектуры.

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

Открытый исходный код означает: приложения не привязаны к поставщику и более прозрачны. Это обеспечивает долгий жизненный цикл приложения.

И еще несколько замечаний насчет открытого исходного кода и S3.

Если вы запускаете приложение для работы с большими данными, S3 SELECT на порядок повышает производительность и эффективность. Это происходит за счет использования SQL для извлечения из хранилища только тех объектов, которые вам необходимы.

Ключевой момент поддержка уведомлений бакетов. Бакетные уведомления упрощают бессерверные вычисления важный компонент любой микросервисной архитектуры, которая предоставляется как услуга. Учитывая, что объектное хранилище фактически облачное хранилище, эта возможность становится решающей, когда объектное хранилище используют облачные приложения.

Наконец, реализация S3 должна поддерживать Amazon S3 API-интерфейсы шифрования на стороне сервера: SSE-C, SSE-S3, SSE-KMS. Еще лучше, если S3 поддерживает защиту от несанкционированного доступа, которая действительно безопасна.

Реакция на сбои


Показатель, который, вероятно, часто упускают из виду, то, как система обрабатывает сбои. Неудачи случаются по разным причинам, и объектное хранилище должно обрабатывать их все.

Например, есть единственная точка отказа, метрика этого равна нулю.

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

Даже там, где предусмотрено несколько точек отказа, первостепенное значение имеет способность выдерживать катастрофические отказы. Диски выходят из строя, серверы выходят из строя. Ключевой момент создание программного обеспечения, предназначенного для обработки сбоев как нормального состояния. При выходе из строя диска или узла такое ПО продолжит работать без изменений.

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

Отказ редко проверяется под нагрузкой, но такая проверка обязательна. Моделирование сбоя под нагрузкой покажет совокупные затраты, понесенные после сбоя.

Консистентность


Показатель консистентности в 100% также называют строгой консистентностью. Консистентность ключевой компонент любой системы хранения, но строгая консистентность встречается довольно редко. Например, Amazon S3 ListObject не является строго консистентным, он консистентен только в конце.

Что подразумевается под строгой консистентностью? Для всех операций после подтвержденной операции PUT должно выполняться следующее:

  • Обновленное значение видно при чтении с любого узла.
  • Обновление защищено резервированием от сбоя узла.

Это означает: если выдернуть штекер в середине записи, то ничего не потеряется. Система никогда не возвращает поврежденные или устаревшие данные. Это высокая планка, которая имеет значение для многих сценариев: от транзакционных приложений до резервного копирования и восстановления.

Заключение


Это новые метрики объектного хранилища, которые отражают модели использования в современных организациях, где производительность, консистентность, масштабируемость, домены отказа и совместимость с S3 строительные блоки для облачных приложений и аналитики больших данных. Рекомендую использовать этот список в дополнение к цене при создании современных стеков данных.

Об объектном хранилище Mail.ru Cloud Solutions: Архитектура S3. 3 года эволюции Mail.ru Cloud Storage.

Что еще почитать:

  1. Пример event-driven приложения на основе вебхуков в объектном S3-хранилище Mail.ru Cloud Solutions.
  2. Больше чем Ceph: блочное хранилище облака MCS
  3. Работа с объектным S3-хранилищем Mail.ru Cloud Solutions как с файловой системой.
  4. Наш канал в Телеграме с новостями об обновлениях S3-хранилища и других продуктов.
Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru