Метрики и мониторинг

Реализация OSA Proxy

Эта страница относится к текущей реализации OSA Proxy. Архивная Java/Spring-реализация доступна в разделе Архивная Java/Spring-реализация.

OSA Proxy отдает метрики в формате Prometheus по адресу:

GET /metrics

Например:

curl http://localhost:8080/metrics

В Go-версии нет Spring Boot actuator endpoints. Для сбора метрик используйте /metrics, а не /actuator/metrics или /actuator/prometheus.

Что предоставляет OSA Proxy

OSA Proxy предоставляет:

  • прикладные метрики OSA Proxy, а также стандартные Go- и process-метрики;
  • примеры конфигурации Prometheus, Alertmanager и Docker Compose в репозитории OSA Proxy.
Базовая конфигурация — это пример

Перед production-эксплуатацией настройте пороги, интервалы, маршрутизацию Alertmanager и receivers в recording rules и алертах под свою нагрузку, SLO и регламент реагирования. CodeScoring не может заранее выбрать универсальные пороги CPU, памяти, latency или отсутствия трафика для всех инсталляций.

Подключение к Prometheus

OSA Proxy не отправляет метрики самостоятельно. Система мониторинга должна опрашивать /metrics. Настройка хранения и доставки метрик находится вне зоны ответственности OSA Proxy.

Для запросов и правил используйте target labels service="osa-proxy" и environment. Label instance, который Prometheus добавляет для каждого target, разделяет реплики OSA Proxy.

OSA Proxy экспортирует постоянную метрику osa_proxy_info со значением 1. Она позволяет выбирать только OSA Proxy targets и не смешивать одноименные go_*, process_* и HTTP-метрики других сервисов.

Prometheus также автоматически добавляет технический label job. Его значение зависит от способа обнаружения targets и не входит в контракт OSA Proxy; запросы и правила не должны требовать конкретного значения job.

Статические targets

Если один Prometheus опрашивает несколько инстансов, достаточно одной группы targets. instance будет отличаться для каждого адреса:

scrape_configs:
  - job_name: osa-proxy
    metrics_path: /metrics
    scrape_interval: 30s
    scrape_timeout: 10s
    static_configs:
      - targets:
          - osa-proxy-1.example.com:8080
          - osa-proxy-2.example.com:8080
        labels:
          environment: production
          service: osa-proxy

В результате series будут различаться label instance:

instance="osa-proxy-1.example.com:8080"
instance="osa-proxy-2.example.com:8080"

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

Семантика HTTP outcomes

Пользовательский трафик и служебные probes разделены:

  • /healthz, /readyz и /metrics учитываются в http_operational_requests_total и не входят в пользовательские SLI;
  • outcome="success" означает успешный пользовательский запрос;
  • outcome="blocked" означает решение политики и не считается технической ошибкой сервиса;
  • outcome="client_error" означает некорректный запрос клиента;
  • outcome="error" означает техническую ошибку OSA Proxy или зависимости.

Для upstream registries ожидаемый HTTP 404 имеет outcome not_found, другие ответы 4xxclient_error, а transport errors и 5xxerror. Стройте error ratio по outcome="error", не по всем HTTP-кодам 4xx и 5xx вместе.

Контракт прикладных метрик

В таблицах ниже перечислены собственные метрики OSA Proxy. Отдельно регистрируемая promhttp_metric_handler_errors_total и стандартные семейства Go/process collectors описаны в разделе Runtime и metrics endpoint. Для histogram Prometheus автоматически создаёт series с суффиксами _bucket, _sum и _count; они являются частями одной метрики и отдельно в таблицах не перечисляются. Counter с именем, оканчивающимся на _total, публикуется под тем же именем.

HTTP, CodeScoring и upstream

МетрикаТипLabelsЧто показывает
osa_proxy_infoGaugeИдентификацию OSA Proxy target; всегда равна 1
http_server_requests_secondsHistogramroute, method, status, outcomeКоличество и latency пользовательских HTTP-запросов
http_operational_requests_totalCounterroute, method, status, outcomeВызовы /healthz, /readyz и /metrics
http_server_active_requestsGaugeКоличество запросов, которые реплика обрабатывает сейчас
gateway_route_requests_secondsHistogrampackage_type, operation, method, repository, status, outcomeКоличество и latency итоговых вызовов upstream registry
codescoring_api_requests_secondsHistogramendpoint, method, status, outcome, error_typeКоличество и полную latency вызовов CodeScoring API
codescoring_retry_attempts_totalCounterendpoint, attempt, outcomeRetry attempts CodeScoring API
codescoring_circuit_breaker_stateGaugegroup, stateТекущее one-hot состояние circuit breaker
codescoring_circuit_breaker_state_changes_totalCountergroup, from, toПереходы circuit breaker между состояниями
codescoring_circuit_breaker_requests_totalCountergroup, outcomeРезультаты операций, защищённых circuit breaker
codescoring_fallbacks_totalCounterendpoint, resultРешения allow или block после ошибок CodeScoring

Scanner, manifest и cache

МетрикаТипLabelsЧто показывает
scanner_evaluations_totalCounteroperation, outcome, resultБизнес-результаты проверок package, image и manifest
verdict_cache_lookup_purls_totalCounterpackage_type, resultCache hit, miss и stale на уровне PURL
verdict_cache_operations_secondsHistogramoperation, package_type, outcomeКоличество и latency операций Redis verdict cache
manifest_processing_secondsHistogramphase, outcome, resultДлительность фаз обработки manifest
manifest_packages_totalCounterresultPackage-level результаты обработки manifest
cache_proactive_refresh_secondsHistogramscope, outcomeДлительность proactive refresh cycle и group
cache_proactive_refresh_groups_totalCounteroutcomeКоличество refresh groups по outcome
cache_proactive_refresh_entries_totalCounterКоличество успешно обновлённых cache entries

Artifactory и Nexus discovery

Для каждого provider экспортируются одинаковые группы:

МетрикиТипLabelsЧто показывают
artifactory_discovery_syncs_total, nexus_discovery_syncs_totalCounterresultРезультаты synchronization attempts
artifactory_discovery_sync_duration_seconds, nexus_discovery_sync_duration_secondsHistogramresultДлительность sync
artifactory_discovery_last_success_timestamp_seconds, nexus_discovery_last_success_timestamp_secondsGaugeВремя последнего успешного snapshot
artifactory_discovery_active_repositories, nexus_discovery_active_repositoriesGaugepackage_typeАктивные динамические репозитории по package type
artifactory_discovery_repository_changes_total, nexus_discovery_repository_changes_totalCounterchangeAdd, update, remove и skip при reconciliation

Управляемая конфигурация

МетрикаТипLabelsОписание
managed_configuration_desired_revisionGaugeЖелаемая ревизия конфигурации
managed_configuration_active_revisionGaugeРевизия, активная на этой реплике
managed_configuration_convergence_lagGaugeРазница между желаемой и активной ревизиями
managed_configuration_activation_duration_secondsHistogramstage, result, failureДлительность сборки и активации
managed_configuration_activation_failures_totalCounterfailureОшибки активации по безопасной категории
managed_configuration_store_stateGaugestateOne-hot состояние Configuration Store
managed_configuration_store_durability_stateGaugestateOne-hot результат проверки надёжности при старте
managed_configuration_readinessGaugeДоступность корректной runtime generation
managed_configuration_lease_healthyGaugeСостояние heartbeat lease реплики
managed_configuration_discovery_healthyGaugeproviderСостояние discovery Artifactory и Nexus

Revision gauges показывают, активировала ли реплика желаемое состояние; managed_configuration_convergence_lag должен возвращаться к 0. Readiness и health gauges используют 1 для исправного/доступного состояния и 0 в остальных случаях. Store state — one-hot enum со значениями disabled, healthy, degraded, never_loaded. Durability state — one-hot enum со значениями disabled, verified, unverified, unsafe_accepted. Labels активации принимают stage="build|activation", result="success|failure" и failure="none|build|start|activation". Для discovery используется provider="artifactory|nexus".

Lease и managed-discovery health имеют смысл только при включённом Configuration Store. Готовые базовые правила пока не содержат алертов для этих managed-configuration series; при необходимости добавьте правила с порогами, соответствующими эксплуатационной политике конкретного deployment.

Runtime и metrics endpoint

Стандартные collectors Go предоставляют go_* и process_*, включая CPU, RSS, heap, GC, goroutines и file descriptors. Метрика promhttp_metric_handler_errors_total{cause} — стандартный counter ошибок сбора или кодирования ответа /metrics.

OSA Proxy не экспортирует количество сетевых байтов и загрузку сетевого интерфейса. В Kubernetes используйте kubelet/cAdvisor, например container_network_receive_bytes_total и container_network_transmit_bytes_total, с фильтрацией по namespace и pod.

Когда series могут отсутствовать

Отсутствие метрики не всегда означает неисправность:

  • в whitelist-режиме нет вызовов CodeScoring API, retry, circuit breaker и fallback traffic;
  • cache metrics появляются при включенном Redis verdict cache и фактических операциях;
  • proactive refresh metrics появляются только при включенной фоновой задаче;
  • Artifactory и Nexus discovery metrics появляются только для включенного provider после первой попытки sync;
  • histogram series появляются после первого подходящего наблюдения.

Не заменяйте отсутствующую latency нулем: нулевая latency означала бы выполненный мгновенный запрос. Для error ratio возвращайте 0 только если за интервал был трафик, но не было ошибок.

Примеры PromQL

Частота пользовательских запросов по репликам и outcomes:

sum by (environment, instance, outcome) (
  rate(http_server_requests_seconds_count{service="osa-proxy"}[5m])
)

Доля технических ошибок входящих запросов:

sum by (environment, instance) (
  rate(http_server_requests_seconds_count{service="osa-proxy",outcome="error"}[5m])
)
/
clamp_min(
  sum by (environment, instance) (
    rate(http_server_requests_seconds_count{service="osa-proxy"}[5m])
  ),
  0.001
)

p95 latency успешных запросов:

histogram_quantile(
  0.95,
  sum by (le, environment, instance) (
    rate(http_server_requests_seconds_bucket{
      service="osa-proxy",
      outcome="success"
    }[5m])
  )
)

Возраст последнего успешного Artifactory discovery:

time() - artifactory_discovery_last_success_timestamp_seconds{service="osa-proxy"}

Метрики recording rules

После загрузки recording rules Prometheus вычисляет семь дополнительных series. Это не метрики приложения: их нет на /metrics, и они существуют только после загрузки recording rules.

SeriesРазрезЗначение
osa_proxy:http_request_rate:5menvironment, instance, outcomeЧастота пользовательских запросов за 5 минут
osa_proxy:http_error_ratio:5menvironment, instanceДоля технических ошибок входящих запросов
osa_proxy:http_latency_p95_seconds:5menvironment, instancep95 latency успешных входящих запросов
osa_proxy:codescoring_error_ratio:5menvironment, instanceДоля ошибок CodeScoring API
osa_proxy:codescoring_latency_p95_seconds:5menvironment, instancep95 latency CodeScoring API
osa_proxy:upstream_error_ratio:5menvironment, instanceДоля ошибок upstream registries
osa_proxy:upstream_latency_p95_seconds:5menvironment, instancep95 latency upstream registries

Базовые алерты

Recording rules и базовые алерты могут покрывать основные классы неисправностей:

ГруппаПримеры сигналов
ДоступностьTarget недоступен для scrape, ошибки /metrics, ошибки operational endpoints
Входящий трафикВысокий technical error ratio, высокая p95 latency, длительное отсутствие трафика, много active requests
CodeScoringОшибки и latency API, retry amplification, open circuit breaker, fallback allow или block
Upstream registriesВысокий error ratio/latency, persistent auth и rate-limit responses
Cache и manifestОшибки Redis cache, scanner, manifest processing и proactive refresh
DiscoveryОшибки sync и устаревший last-success snapshot Artifactory/Nexus
RuntimeВысокие CPU, RSS, GC rate, goroutines и использование file descriptors

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

Особое внимание уделите codescoring_fallbacks_total{result="allow"}: даже одиночное fail-open решение может быть значимым. Для такого события используйте increase(...[5m]) > 0, а не только длительный rate() > 0 с большим for.

Exemplars и трассировка

При включенной OpenTelemetry-трассировке histogram metrics могут содержать exemplars с trace_id. Если Prometheus и Grafana настроены на хранение и отображение exemplars, из точки на графике latency можно перейти к соответствующему trace.

Не добавляйте trace_id как обычный metric label: это создаст отдельную series на каждый запрос.

Проверка после установки

  1. Проверьте liveness и readiness:

    curl http://localhost:8080/healthz
    curl http://localhost:8080/readyz
  2. Проверьте endpoint метрик:

    curl http://localhost:8080/metrics
  3. Проверьте метрику идентификации:

    curl -s http://localhost:8080/metrics | grep '^osa_proxy_info'
  4. В Prometheus откройте страницу Targets и убедитесь, что OSA Proxy имеет состояние UP.

  5. Выполните запрос osa_proxy_info и проверьте labels service, environment и instance. Технический label job также будет, но его конкретное значение не входит в контракт конфигурации OSA Proxy.

  6. Убедитесь, что Prometheus загрузил recording/alerting rules без ошибок, а Alertmanager принимает тестовый алерт.

Страница была полезна?