Перейти к основному содержимому

Панель Наблюдаемости: news-overview (эксплуатация)

Operational-борд контекста news (лента новостей PIN): здоровье лент, публикаций, комментариев, консюмеров identity, embed-интеграции selections и outbox/детач-механик. Не dev-stats: метрики — OTel-инструменты приложения + PostgreSQL-counters (ClickHouse не используется, ADR-0056/0057). Дом полей — ../domain/post.md, ../domain/comment.md; контракты событий — ../events/post-published.md, ../events/comment-added.md.

Назначение

Отвечает на operational-вопрос: держит ли news свои SLO и не деградируют ли асинхронные механики (консюмеры pin.identity.*, outbox pin.news.*, детач snapshot-ов, reconcile CommentsCount) и синхронная зависимость selections (embed-блоки). Owning team — PIN Engagement; аудитория — engineering + support. Регистрируется в observability-dashboard-catalog как service-борд контекста (RED + доменные бизнес-метрики).

Область Действия

ПолеЗначение
ИнструментGrafana
Folderpin/news
Сервисыnews (owner); upstream identity (события), selections (internal API embed)
Аудиторияengineering / support
Primary SLOЛента global/subscription p99 < 300 мс; FTS p99 < 400 мс
Статусdraft

Переменные

Метрики — платформенного уровня (опубликованная лента публична, ADR-0052); tenantId применяется как drill-down по логам/трейсам для authoring/company-scope, не как высококардинальный label метрик (AuthorCompanyId не выносится в labels — bounded-требование каталога).

ПеременнаяТипИсточникЗначение по умолчаниюБезопасность
environmentstring (enum)resource attribute deployment.environmentproductionОбязательный фильтр
servicestringresource attribute service.namenewsФиксирован
feedKindstring (enum global/subscription/fts)label feed_kind*Bounded (3 значения)
authorTypestring (enum PostAuthorType)label author_type*Bounded (5 значений)
topicstring (enum pin.news.*/pin.identity.*)label topic*Bounded
tenantIdTenantId (= AuthorCompanyId, nullable)correlationId/tenant_id в логах/трейсах*Только drill-down authoring/company scope

Панели

PanelMetric/QueryАгрегацияПорогRunbook
feed-rpsnews_feed_query_requests_total{feed_kind}rate() by feed_kindinfo
feed-latencynews_feed_query_duration_ms{feed_kind}p50/p99 by feed_kindp99: global/subscription 300 мс, fts 400 мсfeed-latency
publish-ratenews_posts_published_total{category_slug,author_type,publish_kind}increase(1d) by category/author/kindinfo
comment-ratenews_comments_added_total{is_reply}rate()info
identity-consumer-lagnews_consumer_group_lag_seconds{topic}max by topicwarn 30 с / crit 60 сreplay-identity-dlq
consumer-dlqnews_consumer_dlq_total{topic,consumer,reason}increase(5m) + depthcrit > 0replay-identity-dlq
selections-client-errorsnews_selections_client_requests_total{operation,status}5xx-доля by operationwarn/crit по порогуselections-degraded
detach-outbox-pendingnews_snapshot_detach_outbox_pendinglast / deriv(30m)warn: растёт устойчивоstuck-snapshot-detach
comments-count-driftnews_comments_count_drift_postslast (из reconcile-job)warn > 0recompute-comments-count
news-outbox-lagnews_outbox_publish_delay_seconds{topic=~"pin.news..*"}p95 / max agecrit > 300 сstuck-news-outbox
posts-by-statusnews_posts_by_status{status}last by statusinfo

feed_kind=fts — глобальная лента с searchTerm (полнотекстовый поиск — Elasticsearch-проекция news-posts, ADR-0059); publish_kindfirst/republish (из IsFirstPublish, post-published.md); statusPostStatus (Draft/Published/Unpublished/Archived, post.md).

Метрики

Источник — OTel-инструменты приложения (RED) и PostgreSQL-gauges (периодический scrape counter-запросов). Все labels bounded, enum — строкой; PII/секретов/unbounded-id в labels нет.

МетрикаТипLabelsВладелецСмысл
news_feed_query_requests_totalcounterfeed_kind, statusnews (OTel)RPS лент global/subscription/fts; status = ok/error.
news_feed_query_duration_mshistogramfeed_kindnews (OTel)Latency лент; p50/p99 против SLO 300/400 мс.
news_posts_published_totalcountercategory_slug, author_type, publish_kindnews (OTel)Публикации/републикации по категориям и типам авторов.
news_comments_added_totalcounteris_replynews (OTel)Темп комментариев (корневые/ответы).
news_consumer_group_lag_secondsgaugetopic, consumernews (Kafka/OTel)Лаг консюмеров по pin.identity.users.v1/pin.identity.companies.v1.
news_consumer_dlq_totalcountertopic, consumer, reasonnews (OTel)Dead-letter консюмеров; reason = unknown_version/handler_error.
news_selections_client_requests_totalcounteroperation, statusnews (OTel)Вызовы internal API selections; operation = create/detach/get, status = ok/4xx/5xx/timeout; 5xx create/detach блокируют embed-публикацию.
news_snapshot_detach_outbox_pendinggaugenews (PostgreSQL)Число неотвязанных snapshot-ов (news.snapshot_detach_outbox, статус Pending).
news_comments_count_drift_postsgaugenews (reconcile-job)Число постов с расхождением Post.CommentsCount ↔ факт (INV-CMT-005), из comment-count-reconcile.
news_outbox_publish_delay_secondsgaugetopicnews (PostgreSQL)Возраст старейшего неопубликованного сообщения outbox для pin.news.post-published.v1/comment-added.v1.
news_posts_by_statusgaugestatusnews (PostgreSQL)Размеры Draft/Published/Unpublished/Archived.

Сигналы Logs И Traces

СигналQueryCorrelation
Logs (selections 5xx)service=news component=selections-client level=Error operation IN (create,detach)correlationId, tenantId, postId
Logs (consumer DLQ)service=news consumer=~"identity-.*" outcome=dead-letteredcorrelationId, messageId, aggregateId (= PostId)
Logs (detach retry)service=news job=snapshot-detach-retry outcome=failedcorrelationId, snapshotId, postId
Traces (publish)service=news span=публикация-поста (child: selections.create, запись outbox)correlationId, causationId

Trace публикации связывает переход Post → Published, запись PostVersion и outbox post-published в одном согласованном изменении (INV-NWS-005).

Оповещения Alerts

AlertУсловиеSeverityNotificationRunbook
news_selections_client_5xx_spike5xx-доля create/detach > порога 5 мин (блокирует embed)High#pin-news-oncallselections-degraded
news_consumer_dlq_presentincrease(news_consumer_dlq_total[5m]) > 0High#pin-news-oncallreplay-identity-dlq
news_identity_consumer_lag_breachnews_consumer_group_lag_seconds > 60 5 минHigh#pin-news-oncallreplay-identity-dlq
news_outbox_publish_delay_breachnews_outbox_publish_delay_seconds{topic=~"pin.news..*"} > 300 5 минHigh#pin-news-oncallstuck-news-outbox
news_snapshot_detach_backlog_growingnews_snapshot_detach_outbox_pending растёт (deriv > 0) 30 мин ∧ > базового уровняMedium#pin-news-oncallstuck-snapshot-detach
news_fts_latency_slo_breachfeed-latency p99 feed_kind=fts > 400 мс 10 минMedium#pin-news-oncallfeed-latency
news_comments_count_driftnews_comments_count_drift_posts > 0 после reconcile-runLow#pin-news-oncallrecompute-comments-count

SLO, Бюджет Ошибок И Эскалация

SLOЦельОкноИндикатор (панель)Действие при нарушении
Латентность ленты global/subscriptionp99 < 300 мс30 днейfeed-latencynews_fts_latency_slo_breach не покрывает — деградация ленты расследуется по feed-latency
Латентность поиска (fts)p99 < 400 мс30 днейfeed-latency{feed_kind=fts}Medium-alert 10 мин → feed-latency
Свежесть реплик identityлаг < 60 сrollingidentity-consumer-lagHigh-alert 5 мин → replay-identity-dlq
Доставка pin.news.* (outbox)возраст < 300 сrollingnews-outbox-lagHigh-alert 5 мин → stuck-news-outbox
Целостность консюмеровDLQ = 0rollingconsumer-dlqHigh-alert при любом росте → replay
  • Бюджет ошибок латентности тратится на минутах вне SLO; устойчивое превышение p99 (10+ мин) поднимает приоритет расследования до High даже без формального alert (борд — ранний сигнал деградации до брейча).
  • Приоритеты алертов. High (лаг реплик, outbox, DLQ, selections 5xx) — немедленная реакция oncall; Medium (fts-латентность, растущий backlog детача) — в течение смены; Low (CommentsCount drift) — плановый reconcile. Все ведут на greenfield-runbook.
  • Корреляция инцидента. При High-алерте по identity-consumer-lag/consumer-dlq подписи авторов/ компаний устаревают (эффекты Blocked/Suspended применяются query-слоем на выдаче) — деградация видна пользователю как «старая подпись/статус», не как отказ ленты; это ожидаемое eventual-поведение до replay.

Маскирование Sensitive Data

  • Борд не отображает Comment.Body (UGC/PII), тела блоков PostContentDocument, содержимое SelectionSnapshot, secrets и токены — только счётчики/латентности/лаги.
  • AuthorUserId/AuthorCompanyId/PostId/CommentId в labels не выносятся (unbounded); доступны только как correlation в логах/трейсах для drill-down.
  • Screenshots для инцидентов маскируют tenantId и любые id в аннотациях.

Проверка

ПроверкаОжидаемый Результат
Empty stateПри отсутствии трафика панели показывают 0/нет данных без ошибок запроса.
Tenant drill-downЛоги/трейсы authoring фильтруются по выбранному tenantId (= AuthorCompanyId).
Alert linksКаждый alert ведёт на действующий (планируемый greenfield) runbook.
Time rangeПанели корректны на 15m (инцидент) и 7d (тренды публикаций/детача).
SLO-панельfeed-latency показывает пороговые линии 300/400 мс по feed_kind.

Топология сигналов

Ограничения И Допущения

  • Метрики outbox/detach/status/drift — PostgreSQL-gauges через периодический scrape (задержка ≤ интервала scrape); мгновенные всплески между scrape-ами не видны — источник истины остаётся в БД.
  • news_comments_count_drift_posts обновляется ночным comment-count-reconcile (не realtime): алерт сигнализирует накопленный дрейф, не текущий.
  • FTS отделяется от global по наличию searchTerm (label feed_kind=fts), а не по отдельному endpoint.
  • Runbook-файлы — greenfield (пути целевые, по runbook-template).
  • Ранжирование (recommended) отложено (решение №10) — панели по ranking-сигналам отсутствуют.

Обратные ссылки

Автоссылки: где используется этот документ.

Связанные Документы