Мониторинг GitLab с помощью Proto Observability
На этой странице:
- Сбор метрик GitLab
- Сбор логов GitLab
Сбор метрик GitLab
Интеграция gitlab собирает метрики через Prometheus exporter’ы, встроенные
в GitLab Omnibus. Каждый компонент GitLab имеет свой exporter и слушает по
умолчанию на 127.0.0.1:
| Exporter | Порт по умолчанию | Что отдаёт |
|---|---|---|
sidekiq_exporter | 8082 | Sidekiq jobs, Ruby/GC, DB/Redis client, CI-pipeline events |
puma_exporter | 8083 (off by default) | Puma (web), HTTP-метрики Rails-приложения |
gitlab-exporter | 9168 | Health-проверки Sidekiq + статистика PostgreSQL и Redis |
gitlab-workhorse | 9229 | Метрики Workhorse |
gitaly | 9236 | gRPC-метрики Gitaly |
node_exporter | 9100 | Метрики хоста (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 агент запущен не на том же хосте, что и GitLab, добавьте
его IP в whitelist в /etc/gitlab/gitlab.rb:
gitlab_rails['monitoring_whitelist'] = ['127.0.0.0/8', '<IP_агента>/32']
И примените sudo gitlab-ctl reconfigure. Без этого exporter’ы вернут
403 Forbidden для запросов с внешних адресов.
Конфигурация ProtoOBP агента
Если агент запускается в виде службы на хосте
Создайте файл
/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Перезапустите агента:
sudo systemctl restart protoobp-agent.
Service check `gitlab.readiness`
Параметрgitlab_url в instances: опционален и используется только для
проверки сервиса gitlab.readiness на эндпоинте /-/readiness. GitLab отдаёт
этот эндпоинт только при наличии токена, поэтому без явной настройки токена
проще не указывать gitlab_url совсем — readiness-probe просто пропускается,
а основная проверка gitlab.prometheus_endpoint_up (по prometheus_url) продолжает
работать. Если хотите включить readiness-probe, найдите токен в
/etc/gitlab/gitlab.rb (gitlab_rails['health_check_access_token']) и
укажите gitlab_url: https://gitlab.example.com/?token=<HEALTH_CHECK_TOKEN>.Если агент запускается в виде 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"]}]'
Контейнер агента
Контейнер агента должен находиться в той же docker network, что и GitLab. Также агенту нужен смонтированный/var/run/docker.sock:/var/run/docker.sock:ro
для autodiscovery.Проверка
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 | Класс воркера Sidekiq | MergeRequests::UpdateHeadPipelineWorker |
queue | Имя очереди Sidekiq | default |
feature_category | Категория фичи в GitLab | code_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_concurrency | gauge | Concurrency-лимит процесса Sidekiq |
gitlab_sidekiq_running_jobs | gauge | Количество выполняющихся в моменте джобов |
gitlab_sidekiq_jobs_completion_seconds_count | counter | Количество завершённых джобов (rate → throughput per worker/queue) |
gitlab_sidekiq_jobs_completion_seconds_sum | counter | Суммарное wall-clock-время выполнения джобов (для среднего latency) |
gitlab_sidekiq_jobs_cpu_seconds_count | counter | Количество завершённых джобов (для CPU-метрики) |
gitlab_sidekiq_jobs_cpu_seconds_sum | counter | Суммарное CPU-время Sidekiq джобов |
gitlab_sidekiq_jobs_db_seconds_count | counter | Количество завершённых джобов (для DB-метрики) |
gitlab_sidekiq_jobs_db_seconds_sum | counter | Суммарное время в БД на стороне джобов |
gitlab_sidekiq_jobs_gitaly_seconds_count | counter | Количество завершённых джобов (для Gitaly-метрики) |
gitlab_sidekiq_jobs_gitaly_seconds_sum | counter | Суммарное время вызовов Gitaly из джобов |
gitlab_sidekiq_jobs_queue_duration_seconds_count | counter | Количество подхваченных из очереди джобов |
gitlab_sidekiq_jobs_queue_duration_seconds_sum | counter | Суммарное время ожидания джобов в очереди до старта (раннее предупреждение) |
gitlab_sidekiq_jobs_failed_total | counter | Скорость неуспешных джобов |
gitlab_sidekiq_jobs_retried_total | counter | Скорость повторных запусков джобов |
gitlab_sidekiq_redis_requests_total | counter | Общее число запросов к Redis из Sidekiq |
gitlab_sidekiq_redis_requests_duration_seconds_count | counter | Количество запросов к Redis (для среднего latency) |
gitlab_sidekiq_redis_requests_duration_seconds_sum | counter | Суммарное время запросов к Redis |
gitlab_sidekiq_elasticsearch_requests_total | counter | Общее число запросов к Elasticsearch |
gitlab_sidekiq_elasticsearch_requests_duration_seconds_count | counter | Количество запросов к Elasticsearch (для среднего latency) |
gitlab_sidekiq_elasticsearch_requests_duration_seconds_sum | counter | Суммарное время запросов к Elasticsearch |
Метрики Ruby процесса и GC
Несут лейбл pid — позволяют разрезать по конкретному воркеру. RSS / CPU /
GC-метрики полезны для диагностики утечек и пика нагрузки.
| Имя метрики | Тип | Описание |
|---|---|---|
gitlab_ruby_process_resident_memory_bytes | gauge | RSS процесса (байт) |
gitlab_ruby_process_proportional_memory_bytes | gauge | PSS процесса (с долей от shared-страниц) |
gitlab_ruby_process_unique_memory_bytes | gauge | USS процесса (только private-страницы) |
gitlab_ruby_process_cpu_seconds_total | counter | Суммарное CPU-время процесса (rate → CPU usage) |
gitlab_ruby_process_max_fds | gauge | Лимит открытых файловых дескрипторов |
gitlab_ruby_process_start_time_seconds | gauge | Unix-время старта процесса |
gitlab_ruby_file_descriptors | gauge | Текущее количество открытых FD |
gitlab_ruby_threads_running_threads | gauge | Текущее число потоков |
gitlab_ruby_threads_max_expected_threads | gauge | Ожидаемый лимит потоков |
gitlab_ruby_sampler_duration_seconds_total | counter | Суммарное время на сбор метрик внутри процесса |
gitlab_ruby_gc_stat_count | counter | Общее число запусков GC |
gitlab_ruby_gc_stat_minor_gc_count | counter | Минорные циклы GC |
gitlab_ruby_gc_stat_major_gc_count | counter | Мажорные циклы GC |
gitlab_ruby_gc_duration_seconds_count | counter | Количество измерений длительности GC |
gitlab_ruby_gc_duration_seconds_sum | counter | Суммарная длительность GC |
gitlab_ruby_gc_stat_heap_allocatable_pages | gauge | Heap-страниц, которые можно аллоцировать |
gitlab_ruby_gc_stat_heap_allocated_pages | gauge | Текущее количество аллоцированных heap-страниц |
gitlab_ruby_gc_stat_heap_available_slots | gauge | Свободные слоты в heap’е |
gitlab_ruby_gc_stat_heap_eden_pages | gauge | Eden-страницы (где живут “новые” объекты) |
gitlab_ruby_gc_stat_heap_tomb_pages | gauge | Tomb-страницы (полностью пустые, готовые к освобождению) |
gitlab_ruby_gc_stat_heap_free_slots | gauge | Свободные слоты на используемых страницах |
gitlab_ruby_gc_stat_heap_live_slots | gauge | Живые объекты в heap’е |
gitlab_ruby_gc_stat_heap_marked_slots | gauge | Объекты, помеченные последним GC |
gitlab_ruby_gc_stat_heap_final_slots | gauge | Слоты с финализаторами |
gitlab_ruby_gc_stat_heap_sorted_length | gauge | Длина отсортированного списка страниц heap’а |
gitlab_ruby_gc_stat_total_allocated_objects | counter | Аллоцированные объекты с момента старта |
gitlab_ruby_gc_stat_total_freed_objects | counter | Освобождённые объекты с момента старта |
gitlab_ruby_gc_stat_total_allocated_pages | counter | Аллоцированные страницы heap’а с момента старта |
gitlab_ruby_gc_stat_total_freed_pages | counter | Освобождённые страницы heap’а с момента старта |
gitlab_ruby_gc_stat_old_objects | gauge | Old-generation объекты |
gitlab_ruby_gc_stat_old_objects_limit | gauge | Лимит на old-generation, после которого запускается major GC |
gitlab_ruby_gc_stat_malloc_increase_bytes | gauge | Текущий прирост malloc после последнего GC |
gitlab_ruby_gc_stat_malloc_increase_bytes_limit | gauge | Лимит прироста malloc, после которого запускается GC |
gitlab_ruby_gc_stat_oldmalloc_increase_bytes | gauge | То же для old-generation |
gitlab_ruby_gc_stat_oldmalloc_increase_bytes_limit | gauge | Лимит для old-generation |
gitlab_ruby_gc_stat_remembered_wb_unprotected_objects | gauge | WB-unprotected объекты в remembered set |
gitlab_ruby_gc_stat_remembered_wb_unprotected_objects_limit | gauge | Лимит на WB-unprotected объекты |
Метрики БД и Redis
Со стороны клиента (Sidekiq-процессов).
| Имя метрики | Тип | Описание |
|---|---|---|
gitlab_sql_duration_seconds_count | counter | Количество SQL-запросов |
gitlab_sql_duration_seconds_sum | counter | Суммарное время SQL-запросов (для среднего latency) |
gitlab_database_transaction_seconds_count | counter | Количество DB-транзакций |
gitlab_database_transaction_seconds_sum | counter | Суммарное время DB-транзакций |
gitlab_db_load_balancing_hosts | gauge | Активные реплики PostgreSQL для load balancing |
gitlab_db_partitions_present | gauge | Существующие партиции в партиционированных таблицах |
gitlab_db_partitions_missing | gauge | Партиции, которых не хватает (планировщик пытается создать) |
gitlab_redis_client_requests_total | counter | Общее число запросов к Redis |
gitlab_redis_client_requests_duration_seconds_count | counter | Количество запросов к Redis (для среднего latency) |
gitlab_redis_client_requests_duration_seconds_sum | counter | Суммарное время запросов к Redis |
gitlab_transaction_new_redis_connections_total | counter | Скорость открытия новых соединений с Redis |
Метрики CI / Pipelines
| Имя метрики | Тип | Описание |
|---|---|---|
gitlab_pipelines_created_total | counter | Скорость создания CI-пайплайнов |
gitlab_ci_pipeline_creation_duration_seconds_count | counter | Количество измерений времени создания пайплайна |
gitlab_ci_pipeline_creation_duration_seconds_sum | counter | Суммарное время создания пайплайнов |
gitlab_ci_pipeline_size_builds_count | counter | Количество измерений размера пайплайнов |
gitlab_ci_pipeline_size_builds_sum | counter | Суммарное число джобов в созданных пайплайнах |
Транзакционные события
Каждая метрика — счётчик; для дашбордов и алертов используйте rate(...).
| Имя метрики | Описание |
|---|---|
gitlab_transaction_event_push_commit_total | Push коммитов |
gitlab_transaction_event_push_branch_total | Push веток |
gitlab_transaction_event_push_tag_total | Push тегов |
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_up | 0 (OK) если prometheus_url отвечает 200, иначе 2 (CRITICAL) |
gitlab_readiness | 0 если доступен /-/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_bytesperpid— рост = утечка либо крупный dataset; алерт по абсолютному порогу или росту > N MiB / час.rate(gitlab_ruby_process_cpu_seconds_total[5m])perpid— 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) описано в
Получение данных логов.
Без `logs_config.logs_pobp_url` логи не уйдут
Если в agent status видно Status: OK на tailer’ах и
BytesRead > 0, но в UI логов нет, а в секции Logs Agent —
BytesSent: 0 и предупреждение Connection to the log intake cannot be established: dial tcp: lookup agent-intake.logs.proto.group: no such host,
значит в /etc/protoobp-agent/protoobp.yaml не задан блок logs_config:.
ProtoOBP-агент не наследует pobp_url для логов и по умолчанию идёт
в облачный intake. Минимальный рабочий шаблон (см. также
Получение данных логов):
logs_enabled: true
logs_config:
logs_pobp_url: <protoobp-backend>:443
logs_no_ssl: false
Для backend’а без HTTPS используйте :80 + logs_no_ssl: true.
Права на каталоги логов
Это не правит конфигурацию GitLab
Шаги ниже не меняют настройки самого GitLab и не требуютgitlab-ctl reconfigure. Они только корректируют права на каталоги логов
так, чтобы их мог читать пользователь ProtoOBP агента.Добавьте пользователя агента в группу
git:sudo usermod -a -G git pobp-agentВыставьте групповое чтение на каталоги логов и интересующие файлы:
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
Logrotate и долговечность прав
GitLab logrotate используетcopytruncate + su git git
(см. /var/opt/gitlab/logrotate/logrotate.d/gitlab-rails), поэтому права
0640 на файлах сохраняются после ротации. После полного
sudo gitlab-ctl reconfigure Chef может пересоздать каталоги с правами
0700 git:root — в этом случае повторите шаг 2.Конфигурация ProtoOBP агента
Если агент запускается в виде службы на хосте
Включите сбор логов в
/etc/protoobp-agent/protoobp.yaml:logs_enabled: trueДополните уже существующий
/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Перезапустите агента:
sudo systemctl restart protoobp-agent.
JSON vs текстовый
production_json.log и api_json.log — JSON-структурированные, ProtoOBP
backend парсит поля автоматически (без log_processing_rules).
production.log — текстовый и пишется в одну строку на запись, поэтому
multi_line тоже не нужен.Если агент запускается в виде 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