Телеметрия

Полноценный мониторинг шлюза Meridian на основе Prometheus с кастомными метриками и метками. Автоматический сбор HTTP-метрик и метрик upstream-провайдеров без влияния на латентность запросов.

Обзор

Meridian предоставляет встроенную телеметрию и мониторинг через сбор метрик Prometheus. Система телеметрии отслеживает производительность на уровне HTTP и взаимодействие с upstream-провайдерами, давая полную видимость производительности и паттернов использования AI-шлюза.

Ключевые возможности:

  • Интеграция с Prometheus — нативный сбор метрик на эндпоинте /metrics;
  • Полное покрытие — успехи и ошибки, использование токенов, расходы и эффективность кэша;
  • Кастомные метки — настраиваемые измерения для детального анализа;
  • Динамические заголовки — внедрение значений меток в рантайме через заголовки x-bf-prom-*;
  • Контроль расходов — отслеживание стоимости в USD по AI-провайдерам в реальном времени;
  • Аналитика кэша — учёт прямых и семантических hit'ов кэша;
  • Асинхронный сбор — нулевое влияние на обработку запроса;
  • Многоуровневый учёт — метрики HTTP-транспорта + метрики upstream-провайдеров.

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


Метрики по умолчанию

HTTP-метрики транспорта

Эти метрики отслеживают все входящие HTTP-запросы к Meridian:

МетрикаТипОписание
http_requests_totalCounterОбщее число HTTP-запросов
http_request_duration_secondsHistogramДлительность HTTP-запросов
http_request_size_bytesHistogramРазмер входящего HTTP-запроса
http_response_size_bytesHistogramРазмер исходящего HTTP-ответа

Метки:

  • path — путь HTTP-эндпоинта;
  • method — HTTP-метод (GET, POST, PUT, DELETE);
  • status — HTTP-код ответа;
  • кастомные метки — настроенные в конфигурации Meridian.

Метрики upstream-провайдеров

Эти метрики отслеживают запросы, перенаправляемые AI-провайдерам:

МетрикаТипОписаниеМетки
meridian_upstream_requests_totalCounterОбщее число запросов, перенаправленных upstream-провайдерамбазовые метки, кастомные метки
meridian_success_requests_totalCounterОбщее число успешных запросов к upstream-провайдерамбазовые метки, кастомные метки
meridian_error_requests_totalCounterОбщее число неуспешных запросов к upstream-провайдерамбазовые метки, status_code, кастомные метки
meridian_upstream_latency_secondsHistogramЛатентность запросов к upstream-провайдерамбазовые метки, is_success, кастомные метки
meridian_input_tokens_totalCounterОбщее число input-токенов, отправленных upstream-провайдерамбазовые метки, кастомные метки
meridian_output_tokens_totalCounterОбщее число output-токенов от upstream-провайдеровбазовые метки, кастомные метки
meridian_cache_hits_totalCounterHit'ы кэша по типам (direct/semantic)базовые метки, cache_type, кастомные метки
meridian_cost_totalCounterОбщая стоимость запросов к upstream-провайдерам в USDбазовые метки, кастомные метки

Базовые метки:

  • provider — имя AI-провайдера (openai, anthropic, azure и т. д.);
  • model — имя модели (gpt-4o-mini, claude-3-sonnet и т. д.);
  • method — тип запроса (chat, text, embedding, speech, transcription);
  • virtual_key_id — ID виртуального ключа;
  • virtual_key_name — имя виртуального ключа;
  • routing_engines_used — список движков маршрутизации, через запятую (routing-rule, governance, loadbalancing);
  • routing_rule_id — ID правила маршрутизации, сматчившего запрос;
  • routing_rule_name — имя правила маршрутизации, сматчившего запрос;
  • selected_key_id — ID выбранного ключа;
  • selected_key_name — имя выбранного ключа;
  • number_of_retries — число повторов;
  • fallback_index — индекс fallback (0 — основная попытка, 1 — вторая и т. д.);
  • кастомные метки — настроенные в конфигурации Meridian.

Streaming-метрики

Эти метрики фиксируют латентность, специфичную для потоковых ответов:

МетрикаТипОписаниеМетки
meridian_stream_first_token_latency_secondsHistogramВремя от начала запроса до первого потокового токенабазовые метки
meridian_stream_inter_token_latency_secondsHistogramЛатентность между последовательными потоковыми токенамибазовые метки

Метрики кластерной топологии

В PostgreSQL-режимах (Enterprise) meta-группа топологии и per-shard degradation watch экспортируют собственное семейство метрик. Они отдаются на том же эндпоинте /metrics, что и остальные метрики.

МетрикаТипОписаниеМетки
meridian_meta_raft_stateGaugeRaft-состояние этой ноды в meta-группе (0=follower, 1=candidate, 2=leader)—
meridian_meta_raft_leaderGaugeЯвляется ли эта нода лидером meta-группы (1=лидер, 0=нет)—
meridian_meta_raft_termGaugeТекущий raft-терм meta-группы—
meridian_meta_membersGaugeНоды кластера, объявленные текущим документом топологии, по административному состояниюstate
meridian_meta_topology_versionGaugeВерсия текущего применённого документа топологии—
meridian_meta_proposals_totalCounterПрименённые proposals meta state machine, по типу и результатуtype, result
meridian_meta_apply_duration_secondsHistogramЛатентность Apply meta state machine для одной committed-записи—
meridian_meta_fsync_duration_secondsHistogramЛатентность персиста raft Ready (хвост лога + HardState) в meta bbolt-store, включая fsync—
meridian_meta_snapshots_totalCounterВсего raft-снапшотов meta-группы, созданных на этой ноде—
meridian_meta_snapshot_bytesGaugeРазмер (в байтах) последнего снапшота meta-группы, созданного на этой ноде—
meridian_topology_plan_steps_totalCounterШаги плана, выполненные topology executor'ом, по виду и результатуkind, result
meridian_topology_execution_stateGaugeСостояние жизненного цикла выполнения плана для версии документа (0=running, 1=succeeded, 2=failed)version
meridian_raft_group_health_stateGaugeOne-hot наблюдаемое состояние доступности raft-группы (включая _meta): активна ровно одна пара state со значением 1group, state
meridian_raft_group_declared_votersGaugeОбъявленное число voter-реплик группы (устойчивый факт топологии)group
meridian_raft_group_quorumGaugeРазмер кворума для объявленного набора voter'овgroup
meridian_raft_group_healthy_votersGaugeVoter-реплики группы на gossip-alive нодах; сэмпл отсутствует, пока состояние unknowngroup
meridian_raft_group_failure_toleranceGaugemax(healthy_voters - quorum, 0); сэмпл отсутствует, пока состояние unknowngroup
meridian_raft_replica_parkedGauge1, пока нода отказывается запускать объявленную бюджетную реплику: её локальный store пропал или принадлежит другому replica idnode_id, shard_id, reason
meridian_raft_store_op_duration_secondsHistogramЛатентность одной операции raft-хранилища бюджетных шардовbackend, op
meridian_raft_store_bytesGaugeРазмер локального store шарда на диске (сэмплируется раз в 15 с)node_id, shard_id, kind
meridian_raft_budget_quarantine_dirsGaugeЧисло каталогов *.quarantine-<ts> под <data_dir>/raft/budget, ожидающих истечения срока храненияnode_id
meridian_shard_below_min_replicasGauge1, когда у шарда меньше здоровых voter'ов, чем min_replicas (WARNING), иначе 0shard
meridian_reconcile_enabledGaugeВключён ли авто-ремонт (reconciler) на этой ноде (1=да, 0=нет)—
meridian_reconcile_stateGaugeТекущее состояние reconciler'а: активна ровно одна пара state/reason со значением 1state, reason
meridian_reconcile_actions_totalCounterДействия авто-ремонта, по виду, результату и причинеaction, result, reason
meridian_orphan_virtual_keysGaugeВиртуальные ключи, чей customer удалён: они никуда не маршрутизируются и обслуживаются без customer-level потолкаshard_id
Семейство rb_* переименовано в meridian_raft_budget_* без алиасов — дашборды и алерты нужно переписать один раз. Таблица соответствия старых и новых имён лежит в framework/cluster/raftbudget/metrics/README.md.

Алертинг: pager-worthy сигналы — meridian_raft_group_health_state{state="quorum_lost"} == 1 (группа потеряла кворум, записи невозможны), meridian_shard_below_min_replicas > 0 (шард ниже min_replicas, деградация отказоустойчивости) и meridian_raft_replica_parked > 0 (реплика припаркована; само не рассосётся — нужен reseat, см. Кластеризация). Метрики meridian_raft_group_health_state покрывают и _meta, и data-группы одинаково. Ненулевой meridian_orphan_virtual_keys означает запись, обошедшую штатное удаление customer'а, — ключи обслуживаются без customer-level потолка. Остальные метрики семейства — диагностические.


Примеры мониторинга

Мониторинг success rate

Отслеживание доли успехов по разным провайдерам:

# Доля успехов по провайдерам
rate(meridian_success_requests_total[5m]) /
rate(meridian_upstream_requests_total[5m]) * 100

Анализ использования токенов

Мониторинг расхода токенов по моделям:

# Input-токены в минуту по моделям
increase(meridian_input_tokens_total[1m])

# Output-токены в минуту по моделям
increase(meridian_output_tokens_total[1m])

# Эффективность токенов (output/input)
rate(meridian_output_tokens_total[5m]) /
rate(meridian_input_tokens_total[5m])

Учёт расходов

Мониторинг расходов по провайдерам и моделям:

# Стоимость в секунду по провайдерам
sum by (provider) (rate(meridian_cost_total[1m]))

# Оценка дневных расходов
sum by (provider) (increase(meridian_cost_total[1d]))

# Стоимость на запрос по провайдеру и модели
sum by (provider, model) (rate(meridian_cost_total[5m])) /
sum by (provider, model) (rate(meridian_upstream_requests_total[5m]))

Эффективность кэша

Контроль эффективности кэша:

# Hit rate кэша по типам
rate(meridian_cache_hits_total[5m]) /
rate(meridian_upstream_requests_total[5m]) * 100

# Прямые против семантических hit'ов
sum by (cache_type) (rate(meridian_cache_hits_total[5m]))

Анализ ошибок

Мониторинг паттернов ошибок:

# Доля ошибок по провайдерам
rate(meridian_error_requests_total[5m]) /
rate(meridian_upstream_requests_total[5m]) * 100

# Ошибки по моделям
sum by (model) (rate(meridian_error_requests_total[5m]))

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

Настройте кастомные метки Prometheus, чтобы добавить измерения для фильтрации и анализа:

Метки Prometheus
  1. Перейдите в конфигурацию:

    • откройте UI Meridian по адресу http://localhost:8080;
    • перейдите на вкладку Config.
  2. Метки Prometheus:

    Custom Labels: team, environment, organization, project
# Обновить метки Prometheus через API
curl -X PATCH http://localhost:8080/config \
  -H "Content-Type: application/json" \
  -d '{
    "client": {
      "prometheus_labels": ["team", "environment", "organization", "project"]
    }
  }'
{
  "client": {
    "prometheus_labels": ["team", "environment", "organization", "project"],
    "drop_excess_requests": false,
    "initial_pool_size": 300
  }
}

Динамическое внедрение меток

Добавляйте значения кастомных меток в рантайме через заголовки x-bf-prom-*:

# Добавить кастомные метки к конкретному запросу
curl -X POST http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "x-bf-prom-team: engineering" \
  -H "x-bf-prom-environment: production" \
  -H "x-bf-prom-organization: my-org" \
  -H "x-bf-prom-project: my-project" \
  -d '{
    "model": "gpt-4o-mini",
    "messages": [{"role": "user", "content": "Hello!"}]
  }'

Формат заголовка:

  • Префикс — x-bf-prom-;
  • Имя метки — любая строка после префикса;
  • Значение — строковое значение метки.

Настройка инфраструктуры

Разработка и тестирование

Для локальной разработки и тестирования используйте готовый Docker Compose:

# Запустить Prometheus и Grafana
docker-compose up -d

# Доступные эндпоинты:
# Prometheus: http://localhost:9090
# Grafana:    http://localhost:3000 (admin/admin)
# Метрики Meridian: http://localhost:8080/metrics

Только для разработки. Готовый Docker Compose рассчитан только на тестирование. Не используйте его в production без правильной настройки безопасности, масштабирования и persistence.

Production-развёртывание

Для production-окружений:

  1. Разверните Prometheus с правильным persistence, retention и безопасностью.
  2. Настройте scrape на ваши инстансы Meridian, путь — /metrics.
  3. Поднимите Grafana с аутентификацией и дашбордами.
  4. Настройте алерты под ваши SLA.

Пример конфигурации scrape Prometheus:

scrape_configs:
  - job_name: "meridian-gateway"
    static_configs:
      - targets: ["meridian-instance-1:8080", "meridian-instance-2:8080"]
    scrape_interval: 30s
    metrics_path: /metrics
    # Если у Meridian включена аутентификация, добавьте:
    # basic_auth:
    #   username: '<admin_username>'
    #   password: '<admin_password>'

Если у Meridian включена аутентификация (auth_config), в scrape-конфигурации обязательно укажите basic_auth с admin_username и admin_password.

Примеры production-алертов

Настройте алерты для критичных сценариев на основе метрик:

Алерт на высокую долю ошибок:

- alert: MeridianHighErrorRate
  expr: sum by (provider) (rate(meridian_error_requests_total[5m])) / sum by (provider) (rate(meridian_upstream_requests_total[5m])) > 0.05
  for: 2m
  labels:
    severity: warning
  annotations:
    summary: "High error rate detected for provider {{ $labels.provider }} ({{ $value | humanizePercentage }})"

Алерт на высокие расходы:

- alert: MeridianHighCosts
  expr: sum by (provider) (increase(meridian_cost_total[1d])) > 100  # порог $100/день
  for: 10m
  labels:
    severity: warning
  annotations:
    summary: "Daily cost for provider {{ $labels.provider }} exceeds $100 ({{ $value | printf \"%.2f\" }})"

Алерт на низкую эффективность кэша:

- alert: MeridianLowCacheHitRate
  expr: sum by (provider) (rate(meridian_cache_hits_total[15m])) / sum by (provider) (rate(meridian_upstream_requests_total[15m])) < 0.1
  for: 5m
  labels:
    severity: info
  annotations:
    summary: "Cache hit rate for provider {{ $labels.provider }} below 10% ({{ $value | humanizePercentage }})"

Содержание