Открытый сборщик OpenTelemetry находится в центре архитектуры OpenTelemetry, но не связан с W3C Trace Context. В моем демо трассировки я использую Jaeger вместо Collector. Однако он всеобъемлющ, как в каждом посте, связанном с OpenTelemetry. Я хотел исследовать его дальше.
В этом посте я исследую различные аспекты Collector:
- Виды данных: журналы, метрики и трассировки
- Модели push и pull
- Операции: чтение, трансформация и запись
Первые шаги
A long time ago, observability as we know it didn’t exist; what we had instead was monitoring. Back then, monitoring was a bunch of people looking at screens displaying dashboards. Dashboards themselves consisted of metrics and only system metrics, mainly CPU, memory, and disk usage. For this reason, we will start with metrics.
Prometheus является одним из основных решений для мониторинга. Он работает по модели pull: Prometheus собирает совместимые конечные точки вашего приложения(ий) и хранит их внутри.
Мы будем использовать OTEL Collector для сбора данных с совместимой конечной точки Prometheus и вывода результата в консоль. Grafana Labs предлагает проект, который генерирует случайные метрики для работы. Для простоты я буду использовать Docker Compose; настройка выглядит следующим образом:
version: "3"
services:
fake-metrics:
build: ./fake-metrics-generator #1
collector:
image: otel/opentelemetry-collector:0.87.0 #2
environment: #3
- METRICS_HOST=fake-metrics
- METRICS_PORT=5000
volumes:
- ./config/collector/config.yml:/etc/otelcol/config.yaml:ro #4
- Для проекта со случайными метриками нет доступного образа Docker; следовательно, нам нужно его собрать
- Последняя версия OTEL Collector на момент написания этого текста
- Параметризация следующего конфигурационного файла
- Все происходит здесь
Как я упоминал выше, OTEL Collector может многое. Следовательно, конфигурация – это все.
receivers: #1
prometheus: #2
config:
scrape_configs: #3
- job_name: fake-metrics #4
scrape_interval: 3s
static_configs:
- targets: [ "${env.METRICS_HOST}:${env.METRICS_PORT}" ]
exporters: #5
logging: #6
loglevel: debug
service:
pipelines: #7
metrics: #8
receivers: [ "prometheus" ] #9
exporters: [ "logging" ] #10
- Список приемников. Приемник читает данные; он может быть основан на push или pull.
- Мы используем предопределенный приемник
prometheus
- Определение задач pull
- Конфигурация задачи
- Список экспортеров. В отличие от приемников, экспортер пишет данные.
- Простейший экспортер – это запись данных на стандартный вывод
- Конвейеры собирают приемники и экспортеры
- Определение конвейера, связанного с метриками
- Конвейер получает данные от ранее определенного приемника
prometheus
и отправляет их в экспортерlogging
, то есть, печатает их
Вот пример результата:
2023-11-11 08:28:54 otel-collector-collector-1 | StartTimestamp: 1970-01-01 00:00:00 +0000 UTC 2023-11-11 08:28:54 otel-collector-collector-1 | Timestamp: 2023-11-11 07:28:54.14 +0000 UTC 2023-11-11 08:28:54 otel-collector-collector-1 | Value: 83.090000 2023-11-11 08:28:54 otel-collector-collector-1 | NumberDataPoints #1 2023-11-11 08:28:54 otel-collector-collector-1 | Data point attributes: 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__embrace_world_class_systems: Str(concept) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__exploit_magnetic_applications: Str(concept) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__facilitate_wireless_architectures: Str(extranet) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__grow_magnetic_communities: Str(challenge) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__reinvent_revolutionary_applications: Str(support) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__strategize_strategic_initiatives: Str(internet_solution) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__target_customized_eyeballs: Str(concept) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__transform_turn_key_technologies: Str(framework) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__whiteboard_innovative_partnerships: Str(matrices) 2023-11-11 08:28:54 otel-collector-collector-1 | StartTimestamp: 1970-01-01 00:00:00 +0000 UTC 2023-11-11 08:28:54 otel-collector-collector-1 | Timestamp: 2023-11-11 07:28:54.14 +0000 UTC 2023-11-11 08:28:54 otel-collector-collector-1 | Value: 53.090000 2023-11-11 08:28:54 otel-collector-collector-1 | NumberDataPoints #2 2023-11-11 08:28:54 otel-collector-collector-1 | Data point attributes: 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__expedite_distributed_partnerships: Str(approach) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__facilitate_wireless_architectures: Str(graphical_user_interface) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__grow_magnetic_communities: Str(policy) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__reinvent_revolutionary_applications: Str(algorithm) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__transform_turn_key_technologies: Str(framework) 2023-11-11 08:28:54 otel-collector-collector-1 | StartTimestamp: 1970-01-01 00:00:00 +0000 UTC 2023-11-11 08:28:54 otel-collector-collector-1 | Timestamp: 2023-11-11 07:28:54.14 +0000 UTC 2023-11-11 08:28:54 otel-collector-collector-1 | Value: 16.440000 2023-11-11 08:28:54 otel-collector-collector-1 | NumberDataPoints #3 2023-11-11 08:28:54 otel-collector-collector-1 | Data point attributes: 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__exploit_magnetic_applications: Str(concept) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__grow_magnetic_communities: Str(graphical_user_interface) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__target_customized_eyeballs: Str(extranet)
Помимо печати
Вышеуказанное является отличным первым шагом, но есть и что-то большее, чем просто вывод на консоль. Мы будем предоставлять метрики для сбора регулярным экземпляром Prometheus; мы можем добавить панель Grafana для визуализации их. Хотя это может показаться бессмысленным, терпите, так как это лишь ступенька.
Для достижения вышеуказанного, мы изменяем конфигурацию OTEL Collector:
exporters:
prometheus: #1
endpoint: ":${env:PROMETHEUS_PORT}" #2
service:
pipelines:
metrics:
receivers: [ "prometheus" ]
exporters: [ "prometheus" ] #3
- Добавить экспортер
prometheus
- Обеспечить доступ к совместимому с Prometheus конечной точке
- Заменить печать на предоставление
Вот и все. OTEL Collector очень гибок.
Обратите внимание, что Collector поддерживает многовходовый, многовыходовый режим. Чтобы одновременно печатать данные и предоставлять их через конечную точку, мы добавляем их в конвейер:
exporters:
prometheus: #1
endpoint: ":${env:PROMETHEUS_PORT}"
logging: #2
loglevel: debug
service:
pipelines:
metrics:
receivers: [ "prometheus" ]
exporters: [ "prometheus", "logging" ] #3
- Предоставлять данные
- Печатать данные
- Трубопровод будет как выводить данные, так и предоставлять их
С настроенным экспортером Prometheus мы можем визуализировать метрики в Grafana.
Обратите внимание, что приемники и экспортеры указывают свой тип и каждый из них должен быть уникальным. Чтобы соответствовать последнему требованию, мы можем добавить квалификатор для различения их, например,, prometheus/foo
и prometheus/bar.
Обработка промежуточных данных
A valid question would be why the OTEL Collector is set between the source and Prometheus, as it makes the overall design more fragile. At this stage, we can leverage the true power of the OTEL Collector: data processing. So far, we have ingested raw metrics, but the source format may not be adapted to how we want to visualize data. For example, in our setup, metrics come from our fake generator, “business,” and the underlying NodeJS platform, “technical.” It is reflected in the metrics’ name. We could add a dedicated source label and remove the unnecessary prefix to filter more efficiently.
Обработчики данных объявляются в разделе processors
файла конфигурации. Коллектор выполняет их в порядке объявления. Давайте реализуем указанное преобразование.
Первым шагом к достижению нашей цели является понимание того, что коллектор имеет два варианта: “обычный” и contrib, который основан на нем. Обработчики, включенные в первый, ограничены как по количеству, так и по возможностям; следовательно, нам нужно перейти на версию contrib.
collector:
image: otel/opentelemetry-collector-contrib:0.87.0 #1
environment:
- METRICS_HOST=fake-metrics
- METRICS_PORT=5000
- PROMETHEUS_PORT=8889
volumes:
- ./config/collector/config.yml:/etc/otelcol-contrib/config.yaml:ro #2
- Используйте
contrib
аромат - Для дополнительного удовольствия, файл конфигурации находится в другом пути
На данном этапе мы можем добавить сам процессор:
processors:
metricstransform: #1
transforms: #2
- include: ^fake_(.*)$ #3
match_type: regexp #3
action: update
operations: #4
- action: add_label #5
new_label: origin
new_value: fake
- include: ^fake_(.*)$
match_type: regexp
action: update #6
new_name: $${1} #6-7
# Сделайте то же самое с метриками, генерируемыми NodeJS
- Вызовите процессор преобразования метрик
- Список применённых преобразований в порядке
- Сопоставляет все метрики с определенным регулярным выражением
- Список операций, примененных в порядке
- Добавьте метку
- Переименуйте метрику, удалив префикс группы регулярного выражения
- Забавные вещи: синтаксис
$${x}
Наконец, мы добавляем определенный процессор в пайплайн:
service:
pipelines:
metrics:
receivers: [ "prometheus" ]
processors: [ "metricstransform" ]
exporters: [ "prometheus" ]
Вот результаты:
Подключение приемников и экспортеров
A connector is both a receiver and an exporter and connects two pipelines. The example from the documentation receives the number of spans (tracing) and exports the count, which has a metric. I tried to achieve the same with 500 errors — spoiler: it doesn’t work as intended.
Сначала добавим лог-приемник:
receivers:
filelog:
include: [ "/var/logs/generated.log" ]
Затем добавим соединитель:
connectors:
count:
requests.errors:
description: Number of 500 errors
condition: [ "status == 500 " ]
В конце концов, соединим лог-приемник и экспортер метрик:
service:
pipelines:
logs:
receivers: [ "filelog" ]
exporters: [ "count" ]
metrics:
receivers: [ "prometheus", "count" ]
Метрика называется log_record_count_total
, но ее значение остается на 1.
Манипуляция логами
Процессоры позволяют манипулировать данными; операторы — это специализированные процессоры, работающие с логами. Если вы знакомы с стеком ELK, они эквивалентны Logstash.
Пока что временная метка лога — это время приема. Мы изменим ее на время создания.
receivers:
filelog:
include: [ "/var/logs/generated.log" ]
operators:
- type: json_parser #1
timestamp: #2
parse_from: attributes.datetime #3
layout: "%d/%b/%Y:%H:%M:%S %z" #4
severity: #2
parse_from: attributes.status #3
mapping: #5
error: 5xx #6
warn: 4xx
info: 3xx
debug: 2xx
- id: remove_body #7
type: remove
field: body
- id: remove_datetime #7
type: remove
field: attributes.datetime
- id: remove_status #7
type: remove
field: attributes.status
- Лог находится в формате JSON; мы можем использовать предоставленный парсер JSON
- Атрибуты метаданных для установки
- Поля для чтения
- Шаблон разбора
- Таблица сопоставления
- Принимать диапазон, например,
501-599
. Оператор имеет специальное интерпретируемое значение5xx
(и аналогичные) для HTTP-статусов. - Удаление дублирующихся данных
Логи
На данном этапе мы можем отправлять логи в любой компонент агрегации логов. Мы останемся в сфере Grafana Labs и будем использовать Loki.
exporters:
loki:
endpoint: "http://loki:3100/loki/api/v1/push"
Также можно использовать логи от самого коллектора:
service:
telemetry:
logs:
Наконец, добавим еще одну конвейерную линию:
service:
pipelines:
logs:
receivers: [ "filelog" ]
exporters: [ "loki" ]
Grafana также может визуализировать логи. Выберите Loki в качестве источника данных.
Заключение
В этом посте мы углубились в OpenTelemetry collector. Хотя он не является обязательной частью архитектуры OTEL, это универсальный швейцарский нож для всех ваших потребностей в обработке данных. Если вы не привязаны к конкретной стеке или не хотите этого делать, это огромная помощь.
Полный исходный код для этого поста можно найти на GitHub.
Дальше углубляться
Source:
https://dzone.com/articles/exploring-the-opentelemetry-collector