Мониторинг GitLab с помощью Proto Observability

Сбор метрик и логов GitLab Omnibus: Sidekiq, Ruby/GC, БД, Redis, CI-пайплайны, transaction events.

На этой странице:

Сбор метрик GitLab

Интеграция gitlab собирает метрики через Prometheus exporter’ы, встроенные в GitLab Omnibus. Каждый компонент GitLab имеет свой exporter и слушает по умолчанию на 127.0.0.1:

ExporterПорт по умолчаниюЧто отдаёт
sidekiq_exporter8082Sidekiq jobs, Ruby/GC, DB/Redis client, CI-pipeline events
puma_exporter8083 (off by default)Puma (web), HTTP-метрики Rails-приложения
gitlab-exporter9168Health-проверки Sidekiq + статистика PostgreSQL и Redis
gitlab-workhorse9229Метрики Workhorse
gitaly9236gRPC-метрики Gitaly
node_exporter9100Метрики хоста (CPU, RAM, диск, сеть)

В этом гайде описана базовая интеграция с Sidekiq Exporter — это рекомендуемый минимум, покрывающий ~80 % полезных метрик GitLab (Sidekiq, Ruby/GC, доступ к БД и Redis, события CI). Добавление остальных exporter’ов делается отдельным instances:-блоком в той же конфигурации либо через универсальную интеграцию openmetrics.

Конфигурация GitLab

В стандартной установке GitLab Omnibus sidekiq_exporter включён и слушает на 127.0.0.1:8082. Проверить:

sudo gitlab-ctl status | grep -E "exporter|prometheus"
sudo ss -ltnp | grep -E ":(8082|9090|9100|9168|9229|9236)"

Если порт 8082 не слушает — включите в /etc/gitlab/gitlab.rb:

sidekiq['metrics_enabled']   = true
sidekiq['exporter_enabled']  = true
sidekiq['exporter_address']  = '127.0.0.1'
sidekiq['exporter_port']     = 8082

И примените: sudo gitlab-ctl reconfigure.

Конфигурация ProtoOBP агента

Если агент запускается в виде службы на хосте

  1. Создайте файл /etc/protoobp-agent/conf.d/gitlab.d/conf.yaml:

    init_config:
    
    instances:
      - prometheus_url: http://127.0.0.1:8082/metrics
        send_monotonic_counter: true
        send_distribution_counts_as_monotonic: true
        tags:
          - service:gitlab
          - host:<имя_сервера>     # например, gitlab-01
    
  2. Перезапустите агента: sudo systemctl restart protoobp-agent.

Если агент запускается в виде Docker контейнера

Добавьте autodiscovery-лейблы к контейнеру GitLab. В docker-compose.yaml:

services:
  gitlab:
    image: gitlab/gitlab-ee:17.5.1-ee.0
    labels:
      com.protoobp.ad.check_names: '["gitlab"]'
      com.protoobp.ad.init_configs: '[{}]'
      com.protoobp.ad.instances: '[{"prometheus_url": "http://%%host%%:8082/metrics", "send_monotonic_counter": true, "send_distribution_counts_as_monotonic": true, "tags": ["service:gitlab"]}]'

Проверка

sudo /usr/bin/protoobp-agent check gitlab | tail -25

Ожидаемый вывод — Instance ID: gitlab:... [OK] и непустое Metric Samples:

gitlab (5.3.1)
--------------
  Instance ID: gitlab:cbc1102a61e0cac4 [OK]
  Configuration Source: file:/etc/protoobp-agent/conf.d/gitlab.d/conf.yaml
  Total Runs: 1
  Metric Samples: Last Run: 11,590, Total: 11,590
  Service Checks: Last Run: 1, Total: 1
  Last Successful Execution Date: 2026-05-07 12:36:17 UTC

Собираемые метрики

Префикс — gitlab_*. Counter-метрики (с суффиксами _total, _count, _sum) при включенных send_monotonic_counter: true и send_distribution_counts_as_monotonic: true отправляются как монотонные счётчики — для расчёта скорости используйте rate(...) / increase(...).

Histogram-метрики Prometheus (*_seconds_bucket / _count / _sum) интеграция передаёт как пары _count + _sum; распределение по ведрам не сохраняется. Среднее latency считается как rate(_sum[5m]) / rate(_count[5m]).

Лейблы

Общие (на всех метриках)
ЛейблЗначение
hostХост, на котором работает агент (например, gitlab-01.ru-central1.internal)
exported_hostИмя хоста из тега host: (например, gitlab-01)
serviceТег service (например, gitlab)
gitlab_host, gitlab_portВнутренние поля интеграции (берутся из gitlab_url)
service_id_hostИдентификатор сервиса, проставляемый ProtoOBP backend’ом
Специфичные для Sidekiq / Ruby
ЛейблЗначениеПример
pidИдентификатор процессаsidekiq_0
workerКласс воркера SidekiqMergeRequests::UpdateHeadPipelineWorker
queueИмя очереди Sidekiqdefault
feature_categoryКатегория фичи в GitLabcode_review_workflow
urgencyПриоритет джобаhigh / low / throttled
boundaryТип ресурсного лимитаcpu / memory / ""
external_dependenciesЗависит ли джоб от внешних сервисовyes / no
destination_shard_redisШард Redis, в который ушёл запросmain / cache / queues
job_statusСтатус завершения джобаdone / fail / retry
upper_boundВерхняя граница ведра histogram’а0.1 / 1.0 / 10.0

Метрики Sidekiq

Имя метрикиТипОписание
gitlab_sidekiq_concurrencygaugeConcurrency-лимит процесса Sidekiq
gitlab_sidekiq_running_jobsgaugeКоличество выполняющихся в моменте джобов
gitlab_sidekiq_jobs_completion_seconds_countcounterКоличество завершённых джобов (rate → throughput per worker/queue)
gitlab_sidekiq_jobs_completion_seconds_sumcounterСуммарное wall-clock-время выполнения джобов (для среднего latency)
gitlab_sidekiq_jobs_cpu_seconds_countcounterКоличество завершённых джобов (для CPU-метрики)
gitlab_sidekiq_jobs_cpu_seconds_sumcounterСуммарное CPU-время Sidekiq джобов
gitlab_sidekiq_jobs_db_seconds_countcounterКоличество завершённых джобов (для DB-метрики)
gitlab_sidekiq_jobs_db_seconds_sumcounterСуммарное время в БД на стороне джобов
gitlab_sidekiq_jobs_gitaly_seconds_countcounterКоличество завершённых джобов (для Gitaly-метрики)
gitlab_sidekiq_jobs_gitaly_seconds_sumcounterСуммарное время вызовов Gitaly из джобов
gitlab_sidekiq_jobs_queue_duration_seconds_countcounterКоличество подхваченных из очереди джобов
gitlab_sidekiq_jobs_queue_duration_seconds_sumcounterСуммарное время ожидания джобов в очереди до старта (раннее предупреждение)
gitlab_sidekiq_jobs_failed_totalcounterСкорость неуспешных джобов
gitlab_sidekiq_jobs_retried_totalcounterСкорость повторных запусков джобов
gitlab_sidekiq_redis_requests_totalcounterОбщее число запросов к Redis из Sidekiq
gitlab_sidekiq_redis_requests_duration_seconds_countcounterКоличество запросов к Redis (для среднего latency)
gitlab_sidekiq_redis_requests_duration_seconds_sumcounterСуммарное время запросов к Redis
gitlab_sidekiq_elasticsearch_requests_totalcounterОбщее число запросов к Elasticsearch
gitlab_sidekiq_elasticsearch_requests_duration_seconds_countcounterКоличество запросов к Elasticsearch (для среднего latency)
gitlab_sidekiq_elasticsearch_requests_duration_seconds_sumcounterСуммарное время запросов к Elasticsearch

Метрики Ruby процесса и GC

Несут лейбл pid — позволяют разрезать по конкретному воркеру. RSS / CPU / GC-метрики полезны для диагностики утечек и пика нагрузки.

Имя метрикиТипОписание
gitlab_ruby_process_resident_memory_bytesgaugeRSS процесса (байт)
gitlab_ruby_process_proportional_memory_bytesgaugePSS процесса (с долей от shared-страниц)
gitlab_ruby_process_unique_memory_bytesgaugeUSS процесса (только private-страницы)
gitlab_ruby_process_cpu_seconds_totalcounterСуммарное CPU-время процесса (rate → CPU usage)
gitlab_ruby_process_max_fdsgaugeЛимит открытых файловых дескрипторов
gitlab_ruby_process_start_time_secondsgaugeUnix-время старта процесса
gitlab_ruby_file_descriptorsgaugeТекущее количество открытых FD
gitlab_ruby_threads_running_threadsgaugeТекущее число потоков
gitlab_ruby_threads_max_expected_threadsgaugeОжидаемый лимит потоков
gitlab_ruby_sampler_duration_seconds_totalcounterСуммарное время на сбор метрик внутри процесса
gitlab_ruby_gc_stat_countcounterОбщее число запусков GC
gitlab_ruby_gc_stat_minor_gc_countcounterМинорные циклы GC
gitlab_ruby_gc_stat_major_gc_countcounterМажорные циклы GC
gitlab_ruby_gc_duration_seconds_countcounterКоличество измерений длительности GC
gitlab_ruby_gc_duration_seconds_sumcounterСуммарная длительность GC
gitlab_ruby_gc_stat_heap_allocatable_pagesgaugeHeap-страниц, которые можно аллоцировать
gitlab_ruby_gc_stat_heap_allocated_pagesgaugeТекущее количество аллоцированных heap-страниц
gitlab_ruby_gc_stat_heap_available_slotsgaugeСвободные слоты в heap’е
gitlab_ruby_gc_stat_heap_eden_pagesgaugeEden-страницы (где живут “новые” объекты)
gitlab_ruby_gc_stat_heap_tomb_pagesgaugeTomb-страницы (полностью пустые, готовые к освобождению)
gitlab_ruby_gc_stat_heap_free_slotsgaugeСвободные слоты на используемых страницах
gitlab_ruby_gc_stat_heap_live_slotsgaugeЖивые объекты в heap’е
gitlab_ruby_gc_stat_heap_marked_slotsgaugeОбъекты, помеченные последним GC
gitlab_ruby_gc_stat_heap_final_slotsgaugeСлоты с финализаторами
gitlab_ruby_gc_stat_heap_sorted_lengthgaugeДлина отсортированного списка страниц heap’а
gitlab_ruby_gc_stat_total_allocated_objectscounterАллоцированные объекты с момента старта
gitlab_ruby_gc_stat_total_freed_objectscounterОсвобождённые объекты с момента старта
gitlab_ruby_gc_stat_total_allocated_pagescounterАллоцированные страницы heap’а с момента старта
gitlab_ruby_gc_stat_total_freed_pagescounterОсвобождённые страницы heap’а с момента старта
gitlab_ruby_gc_stat_old_objectsgaugeOld-generation объекты
gitlab_ruby_gc_stat_old_objects_limitgaugeЛимит на old-generation, после которого запускается major GC
gitlab_ruby_gc_stat_malloc_increase_bytesgaugeТекущий прирост malloc после последнего GC
gitlab_ruby_gc_stat_malloc_increase_bytes_limitgaugeЛимит прироста malloc, после которого запускается GC
gitlab_ruby_gc_stat_oldmalloc_increase_bytesgaugeТо же для old-generation
gitlab_ruby_gc_stat_oldmalloc_increase_bytes_limitgaugeЛимит для old-generation
gitlab_ruby_gc_stat_remembered_wb_unprotected_objectsgaugeWB-unprotected объекты в remembered set
gitlab_ruby_gc_stat_remembered_wb_unprotected_objects_limitgaugeЛимит на WB-unprotected объекты

Метрики БД и Redis

Со стороны клиента (Sidekiq-процессов).

Имя метрикиТипОписание
gitlab_sql_duration_seconds_countcounterКоличество SQL-запросов
gitlab_sql_duration_seconds_sumcounterСуммарное время SQL-запросов (для среднего latency)
gitlab_database_transaction_seconds_countcounterКоличество DB-транзакций
gitlab_database_transaction_seconds_sumcounterСуммарное время DB-транзакций
gitlab_db_load_balancing_hostsgaugeАктивные реплики PostgreSQL для load balancing
gitlab_db_partitions_presentgaugeСуществующие партиции в партиционированных таблицах
gitlab_db_partitions_missinggaugeПартиции, которых не хватает (планировщик пытается создать)
gitlab_redis_client_requests_totalcounterОбщее число запросов к Redis
gitlab_redis_client_requests_duration_seconds_countcounterКоличество запросов к Redis (для среднего latency)
gitlab_redis_client_requests_duration_seconds_sumcounterСуммарное время запросов к Redis
gitlab_transaction_new_redis_connections_totalcounterСкорость открытия новых соединений с Redis

Метрики CI / Pipelines

Имя метрикиТипОписание
gitlab_pipelines_created_totalcounterСкорость создания CI-пайплайнов
gitlab_ci_pipeline_creation_duration_seconds_countcounterКоличество измерений времени создания пайплайна
gitlab_ci_pipeline_creation_duration_seconds_sumcounterСуммарное время создания пайплайнов
gitlab_ci_pipeline_size_builds_countcounterКоличество измерений размера пайплайнов
gitlab_ci_pipeline_size_builds_sumcounterСуммарное число джобов в созданных пайплайнах

Транзакционные события

Каждая метрика — счётчик; для дашбордов и алертов используйте rate(...).

Имя метрикиОписание
gitlab_transaction_event_push_commit_totalPush коммитов
gitlab_transaction_event_push_branch_totalPush веток
gitlab_transaction_event_push_tag_totalPush тегов
gitlab_transaction_event_remove_branch_totalУдаление веток
gitlab_transaction_event_remove_repository_totalУдаление репозиториев
gitlab_transaction_event_change_default_branch_totalСмена default branch
gitlab_transaction_event_import_repository_totalИмпорт репозиториев
gitlab_transaction_event_stuck_import_jobs_totalЗависшие импорт-джобы

Service checks

ИмяОписание
gitlab_prometheus_endpoint_up0 (OK) если prometheus_url отвечает 200, иначе 2 (CRITICAL)
gitlab_readiness0 если доступен /-/readiness на gitlab_url (нужен HEALTH_CHECK_TOKEN)

Ключевые метрики для дашбордов и алертов

Доступность

  • gitlab_prometheus_endpoint_up == 2 — алерт: GitLab metrics endpoint не отвечает.
  • Отсутствие свежих серий с service=gitlab за последнюю минуту — агент не достучался до GitLab или сам не работает.

Sidekiq throughput / latency

  • sum(rate(gitlab_sidekiq_jobs_completion_seconds_count[5m])) by (worker) — скорость завершения джобов в разрезе воркера.
  • rate(gitlab_sidekiq_jobs_completion_seconds_sum[5m]) / rate(gitlab_sidekiq_jobs_completion_seconds_count[5m]) — среднее wall-clock latency джоба.
  • rate(gitlab_sidekiq_jobs_queue_duration_seconds_sum[5m]) / rate(gitlab_sidekiq_jobs_queue_duration_seconds_count[5m]) — среднее время ожидания в очереди до старта джоба (раннее предупреждение о backlog).
  • gitlab_sidekiq_running_jobs / gitlab_sidekiq_concurrency — насыщение pool’а воркеров.

Качество выполнения джобов

  • rate(gitlab_sidekiq_jobs_failed_total[5m]) — скорость падений (ошибки воркеров).
  • rate(gitlab_sidekiq_jobs_retried_total[5m]) — скорость retry (косвенный признак нестабильности).

Доступ к зависимостям

  • rate(gitlab_redis_client_requests_duration_seconds_sum[5m]) / rate(gitlab_redis_client_requests_duration_seconds_count[5m]) — Redis latency.
  • rate(gitlab_sql_duration_seconds_sum[5m]) / rate(gitlab_sql_duration_seconds_count[5m]) — DB latency.
  • gitlab_db_partitions_missing > 0 — планировщик не успевает создавать партиции.
  • gitlab_db_load_balancing_hosts < ожидаемого — реплика PostgreSQL отвалилась.

CI / Pipelines

  • rate(gitlab_pipelines_created_total[5m]) — pipeline throughput.
  • rate(gitlab_ci_pipeline_creation_duration_seconds_sum[5m]) / rate(gitlab_ci_pipeline_creation_duration_seconds_count[5m]) — среднее время создания пайплайна.
  • rate(gitlab_ci_pipeline_size_builds_sum[5m]) / rate(gitlab_ci_pipeline_size_builds_count[5m]) — среднее число job’ов в пайплайне.

Здоровье Ruby-процессов

  • gitlab_ruby_process_resident_memory_bytes per pid — рост = утечка либо крупный dataset; алерт по абсолютному порогу или росту > N MiB / час.
  • rate(gitlab_ruby_process_cpu_seconds_total[5m]) per pid — CPU usage процесса.
  • gitlab_ruby_file_descriptors / gitlab_ruby_process_max_fds — приближение к лимиту FD.
  • rate(gitlab_ruby_gc_duration_seconds_sum[5m]) — давление GC; высокое значение = много времени на GC, ухудшает latency запросов.

Активность пользователей и push’ы

  • rate(gitlab_transaction_event_push_commit_total[5m]) — поток коммитов.
  • gitlab_transaction_event_stuck_import_jobs_total > 0 (или его рост) — алерт: зависают импорты репозиториев.

Сбор логов GitLab

GitLab Omnibus пишет логи в /var/log/gitlab/<service>/. По умолчанию каталоги имеют режим 0700 git:root, файлы — 0600 git:git, поэтому пользователю ProtoOBP агента нужно дать на них доступ. Здесь — только специфичные для GitLab настройки. Включение логов на стороне агента (logs_enabled, logs_config.logs_pobp_url) описано в Получение данных логов.

Права на каталоги логов

  1. Добавьте пользователя агента в группу git:

    sudo usermod -a -G git pobp-agent
    
  2. Выставьте групповое чтение на каталоги логов и интересующие файлы:

    for d in /var/log/gitlab/gitlab-rails \
             /var/log/gitlab/gitaly \
             /var/log/gitlab/gitlab-workhorse \
             /var/log/gitlab/sidekiq; do
      [ -d "$d" ] && sudo chgrp git "$d" && sudo chmod 0750 "$d"
    done
    
    for f in /var/log/gitlab/gitlab-rails/production_json.log \
             /var/log/gitlab/gitlab-rails/production.log \
             /var/log/gitlab/gitlab-rails/api_json.log; do
      sudo chgrp git "$f" && sudo chmod 0640 "$f"
    done
    

Конфигурация ProtoOBP агента

Если агент запускается в виде службы на хосте

  1. Включите сбор логов в /etc/protoobp-agent/protoobp.yaml:

    logs_enabled: true
    
  2. Дополните уже существующий /etc/protoobp-agent/conf.d/gitlab.d/conf.yaml (тот же файл, в котором лежит instances: для метрик) блоком logs::

    logs:
      - type: file
        path: /var/log/gitlab/gitlab-rails/production_json.log
        service: gitlab
        source: gitlab
      - type: file
        path: /var/log/gitlab/gitlab-rails/production.log
        service: gitlab
        source: gitlab
      - type: file
        path: /var/log/gitlab/gitlab-rails/api_json.log
        service: gitlab
        source: gitlab
    
  3. Перезапустите агента: sudo systemctl restart protoobp-agent.

Если агент запускается в виде Docker контейнера

GitLab Omnibus в Docker пишет логи в /var/log/gitlab/... внутри своего контейнера. Простейший способ собрать их — пробросить общий volume в контейнер агента и тейлить файлы напрямую:

services:
  protoobp-agent:
    environment:
      POBP_LOGS_ENABLED: "true"
      POBP_LOGS_CONFIG_LOGS_POBP_URL: <protoobp-backend>:443
      POBP_LOGS_CONFIG_LOGS_NO_SSL: "false"     # "true" если используется порт 80
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - gitlab-logs:/var/log/gitlab:ro

  gitlab:
    image: gitlab/gitlab-ee:17.5.1-ee.0
    volumes:
      - gitlab-logs:/var/log/gitlab
    labels:
      com.protoobp.ad.logs: '[{"source": "gitlab", "service": "gitlab", "path": "/var/log/gitlab/gitlab-rails/production_json.log"}, {"source": "gitlab", "service": "gitlab", "path": "/var/log/gitlab/gitlab-rails/production.log"}, {"source": "gitlab", "service": "gitlab", "path": "/var/log/gitlab/gitlab-rails/api_json.log"}]'

volumes:
  gitlab-logs:

Проверка

В выводе agent status должна появиться секция gitlab со статусом Status: OK и ненулевым BytesRead хотя бы на одном пути:

sudo /usr/bin/protoobp-agent status \
  | sed -n '/Logs Agent/,/^=====/p' | head -60

Ожидаемый вывод:

gitlab
------
  - Type: file
    Path: /var/log/gitlab/gitlab-rails/production_json.log
    Service: gitlab
    Source: gitlab
    Status: OK
    BytesRead: 9874
  - Type: file
    Path: /var/log/gitlab/gitlab-rails/production.log
    Status: OK
  - Type: file
    Path: /var/log/gitlab/gitlab-rails/api_json.log
    Status: OK