Сборщик OpenTelemetry находится в центре архитектуры OpenTelemetry, но не связан с контекстом трассировки W3C. В своей демонстрации трассировки я использую Jaeger вместо Collector. Тем не менее, это повсеместно, как и в каждом сообщении, связанном с OpenTelemetry. Я хотел изучить это дальше.
В этом посте я рассматриваю различные аспекты Collector:
Давным-давно наблюдаемости в том виде, в котором мы ее знаем, не существовало; вместо этого у нас был мониторинг . В то время мониторинг представлял собой группу людей, смотрящих на экраны с информационными панелями. Сами дашборды состояли из метрик и только системных показателей: в основном использования ЦП, памяти и диска. По этой причине мы начнем с показателей.
Prometheus — одно из основных решений для мониторинга. Он работает по модели извлечения: 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
Как я уже упоминал выше, 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" ] #9
prometheus
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
Вот и все. OTEL 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.
Правильный вопрос: почему OTEL Collector устанавливается между исходником и Prometheus, поскольку это делает общую конструкцию более хрупкой. На этом этапе мы можем использовать истинную мощь OTEL Collector: обработку данных. На данный момент мы получили необработанные метрики, но исходный формат может быть не адаптирован к тому, как мы хотим визуализировать данные. Например, в нашей настройке метрики берутся из нашего поддельного генератора «бизнес» и базовой платформы NodeJS «технические». Это отражено в названии метрики. Мы могли бы добавить специальную метку источника и удалить ненужный префикс, чтобы фильтровать более эффективно.
Обработчики данных объявляются в разделе processors
файла конфигурации. Сборщик выполняет их в том порядке, в котором они объявлены. Давайте реализуем вышеуказанное преобразование.
Первый шаг на пути к нашей цели — понять, что у сборщика есть два варианта: «голый» и вклад, основанный на нем. Процессоры, входящие в первую группу, ограничены как по количеству, так и по возможностям; следовательно, нам нужно переключить версию 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 # Do the same with metrics generated by NodeJS
$${x}
Наконец, мы добавляем определенный процессор в конвейер:
service: pipelines: metrics: receivers: [ "prometheus" ] processors: [ "metricstransform" ] exporters: [ "prometheus" ]
Вот результаты:
Соединитель является одновременно приемником и экспортером и соединяет два трубопровода. Пример из документации получает количество пролетов (трассировку) и экспортирует счетчик, имеющий метрику. Пытался добиться того же с 500 ошибками - спойлер: работает не так, как задумано.
Давайте сначала добавим получатель журнала:
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.
Процессоры позволяют манипулировать данными; операторы — это специализированные процессоры, работающие с журналами. Если вы знакомы со стеком Elasticsearch Logstash Kibana, они являются эквивалентом 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
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 также может визуализировать журналы. Выберите Локи в качестве источника данных.
В этом посте мы углубились в сборщик OpenTelemetry. Хотя это не является обязательной частью архитектуры OTEL, это полезный швейцарский нож для всех ваших потребностей в обработке данных. Если вы не привязаны к определенному стеку или не хотите, это огромная помощь.
Полный исходный код этого поста можно найти на GitHub .
Чтобы пойти дальше:
Первоначально опубликовано на сайте A Java Geek 12 ноября 2023 г.