Панель Наблюдаемости: support-overview (эксплуатация)
Operational-борд контекста support («Служба заботы»): здоровье приёма/жизненного цикла обращений, SLA
первого ответа/решения, очередей, арбитражных дел, консюмера identity, SLA-worker и outbox. Не
dev-stats: метрики — OTel-инструменты приложения + PostgreSQL-counters (ClickHouse не используется,
ADR-0056/ADR-0057).
Дом полей — ticket.md, arbitrage-case.md; контракты
событий — ticket-created.md, ticket-status-changed.md,
arbitrage-resolved.md.
Назначение
Отвечает на operational-вопрос: держит ли support свои SLA поддержки и не деградируют ли асинхронные
механики (SLA-worker ticket-sla-monitor, консюмер pin.identity.users.v1, outbox pin.support.*).
Продуктовый разрез тематик/нагрузки операторов (8.1/8.4) отдаёт SQL-ручка
get-support-dashboard — здесь только RED + доменные бизнес-метрики
надёжности. Owning team — PIN Platform (Care squad); аудитория — engineering + support. Регистрируется в
observability-dashboard-catalog как service-борд.
Область Действия
| Поле | Значение |
|---|
| Инструмент | Grafana |
| Folder | pin/support |
| Сервисы | support (owner); upstream identity (события/lookup); downstream notifications (консюмер событий) |
| Аудитория | engineering / support |
| Primary SLO | команды p95 < 500 мс; списки/поиск p95 < 1 с; SLA-worker — точность цикла ≤ 1 мин |
| Статус | draft |
Переменные
support — single-tenant platform-tool (TenantId = PIN CompanyId, ADR-0052):
tenantId фиксирован и используется как санити-фильтр, не как высококардинальный label. Разрезы — по
bounded-enum (category/queue_code/status/priority/channel), id заявителей/операторов в labels не
выносятся.
| Переменная | Тип | Источник | Значение по умолчанию | Безопасность |
|---|
environment | string (enum) | resource attribute deployment.environment | production | Обязательный фильтр |
service | string | resource attribute service.name | support | Фиксирован |
tenantId | TenantId (= PIN CompanyId) | resource attribute tenant_id | PIN | Санити-фильтр single-tenant |
category | string (enum TicketCategory) | label category | * | Bounded (8 значений) |
queueCode | string (enum Queue.Code) | label queue_code | * | Bounded (SEED-очереди) |
status | string (enum TicketStatus) | label status | * | Bounded (4 значения) |
priority | string (enum TicketPriority) | label priority | * | Bounded (4 значения) |
topic | string (enum pin.support.*/pin.identity.*) | label topic | * | Bounded |
Панели
| Panel | Metric/Query | Агрегация | Порог | Runbook |
|---|
intake-rate | support_tickets_created_total{category,queue_code,channel} | rate() by category/queue | info | — |
command-latency | support_command_duration_ms{operation} | p50/p95 by operation | p95 500 мс | command-latency |
list-search-latency | support_query_duration_ms{query_kind} | p95 by query_kind | p95 1 с | command-latency |
tickets-by-status | support_tickets_by_status{status} | last by status | info | — |
queue-depth | support_open_tickets{queue_code} | last (New+InWork) by queue | warn: рост устойчиво | queue-backlog |
first-response-latency | support_first_response_seconds{priority} | p50/p95 by priority | против FirstResponseDueAt | sla-breach |
sla-breaches | support_tickets_sla_breached{priority,kind} | last/increase(1h) | crit: рост | sla-breach |
reopen-rate | support_ticket_reopened_total | rate() | info | — |
sla-worker-cycle | support_sla_monitor_cycle_seconds | p95 / max | crit > 60 с | sla-worker-stalled |
arbitrage-by-status | support_arbitrage_by_status{status,type} | last by status/type | info | — |
arbitrage-outcomes | support_arbitrage_resolved_total{outcome,escalated} | increase(1d) | info | — |
identity-consumer-lag | support_consumer_group_lag_seconds{topic} | max by topic | warn 60 с / crit 300 с | replay-identity-dlq |
consumer-dlq | support_consumer_dlq_total{topic,reason} | increase(5m) + depth | crit > 0 | replay-identity-dlq |
outbox-lag | support_outbox_publish_delay_seconds{topic=~"pin.support..*"} | p95 / max age | crit > 300 с; backlog > 1000 | stuck-support-outbox |
query_kind — list-tickets/kb-search/arbitrage-list; kind (sla-breaches) — first-response/resolution
(из FirstResponseDueAt/ResolutionDueAt); status/priority/outcome — enum ticket.md/
arbitrage-case.md.
Метрики
Источник — OTel-инструменты приложения (RED) и PostgreSQL-gauges (периодический scrape counter-запросов).
Все labels bounded, enum — строкой;
PII/секретов/unbounded-id (заявитель/оператор) в labels нет.
| Метрика | Тип | Labels | Владелец | Смысл |
|---|
support_tickets_created_total | counter | category, queue_code, channel | support (OTel) | Приём обращений по категориям/очередям/каналам (WebForm/Operator). |
support_command_duration_ms | histogram | operation | support (OTel) | Latency команд (take/assign/reply/status/escalate) против SLO 500 мс. |
support_query_duration_ms | histogram | query_kind | support (OTel) | Latency списков/поиска против SLO 1 с. |
support_tickets_by_status | gauge | status | support (PostgreSQL) | Размеры New/InWork/Resolved/Closed. |
support_open_tickets | gauge | queue_code | support (PostgreSQL) | Глубина очереди — открытые (New+InWork) по очереди. |
support_first_response_seconds | histogram | priority | support (OTel) | Время до первого публичного ответа (INV-TKT-5) по приоритету. |
support_tickets_sla_breached | gauge | priority, kind | support (SLA-worker) | Тикеты с SlaBreached=true (первый ответ/решение), из ticket-sla-monitor. |
support_ticket_reopened_total | counter | — | support (OTel) | Темп реопенов (ReopenedCount++). |
support_sla_monitor_cycle_seconds | gauge | — | support (worker) | Длительность цикла SLA-worker (точность ≤ 1 мин, ADR-0056). |
support_arbitrage_by_status | gauge | status, type | support (PostgreSQL) | Дела по статусам/типам (Registered..Closed). |
support_arbitrage_resolved_total | counter | outcome, escalated | support (OTel) | Решения/эскалации арбитража (ArbitrageOutcome). |
support_consumer_group_lag_seconds | gauge | topic, consumer | support (Kafka/OTel) | Лаг SupportUserUpsertedConsumer по pin.identity.users.v1. |
support_consumer_dlq_total | counter | topic, reason | support (OTel) | Dead-letter консюмера; reason = unknown_version/handler_error. |
support_outbox_publish_delay_seconds | gauge | topic | support (PostgreSQL) | Возраст старейшего неопубликованного события (Pending) для pin.support.*. |
Сигналы Logs И Traces
| Сигнал | Query | Correlation |
|---|
| Logs (SLA breach) | service=support job=ticket-sla-monitor outcome=breached | correlationId, ticketId, number |
| Logs (consumer DLQ) | service=support consumer=identity-user-upserted outcome=dead-lettered | correlationId, messageId, aggregateId (= TicketId/CaseId) |
| Logs (escalation) | service=support operation IN (escalate-ticket,escalate-arbitrage-case) | correlationId, ticketId/caseId, escalatedByUserId |
| Traces (create) | service=support operation=create-ticket (child: identity.lookup, публикация события) | correlationId, causationId |
| Traces (resolve) | service=support operation=resolve-arbitrage-case (событие arbitrage-resolved) | correlationId, causationId |
Trace создания связывает создание тикета, первое сообщение переписки и публикацию события ticket-created в
одном согласованном изменении; PII заявителя (ФИО/тел/email/Body) в трейсах маскируется.
Оповещения Alerts
| Alert | Условие | Severity | Notification | Runbook |
|---|
support_identity_consumer_lag_breach | support_consumer_group_lag_seconds > 300 5 мин | High | #pin-support-oncall | replay-identity-dlq |
support_consumer_dlq_present | increase(support_consumer_dlq_total[5m]) > 0 | High | #pin-support-oncall | replay-identity-dlq |
support_outbox_backlog | outbox Pending > 1000 или outbox_publish_delay > 300 5 мин | High | #pin-support-oncall | stuck-support-outbox |
support_sla_worker_stalled | support_sla_monitor_cycle_seconds > 60 или отсутствие цикла 5 мин | High | #pin-support-oncall | sla-worker-stalled |
support_sla_breach_spike | рост support_tickets_sla_breached (increase(1h) > базового) | Medium | #pin-support-oncall | sla-breach |
support_command_latency_slo_breach | command-latency p95 > 500 мс 10 мин | Medium | #pin-support-oncall | command-latency |
support_queue_backlog_growing | support_open_tickets растёт (deriv > 0) 30 мин ∧ > базового | Low | #pin-support-oncall | queue-backlog |
Маскирование Sensitive Data
- Борд не отображает
TicketMessage.Body/ArbitrageNote.Body, ФИО/телефон/email заявителя, тексты решений
(Decision.Rationale), secrets и токены — только счётчики/латентности/лаги.
RequesterUserId/AssigneeUserId/TicketId/CaseId в labels не выносятся (unbounded); доступны только
как correlation в логах/трейсах для drill-down.
- Внутренние заметки (
Visibility=Internal) не проецируются на борд; screenshots для инцидентов маскируют
tenantId и любые id в аннотациях.
Проверка
| Проверка | Ожидаемый Результат |
|---|
| Empty state | При отсутствии трафика панели показывают 0/нет данных без ошибок запроса. |
| Tenant filter | Данные относятся только к TenantId = PIN CompanyId (single-tenant санити). |
| Alert links | Каждый alert ведёт на действующий (планируемый greenfield) runbook. |
| Time range | Панели корректны на 15m (инцидент) и 7d (тренды приёма/SLA/арбитража). |
| SLO-панель | command-latency/list-search-latency показывают пороговые линии 500 мс / 1 с. |
Топология сигналов
Диагностика По Сочетаниям Сигналов (triage)
Панели читаются вместе: одна и та же деградация проявляется в нескольких сигналах, а их сочетание
локализует корень и ведёт к нужному runbook.
| Наблюдаемое сочетание | Вероятный корень | Бизнес-эффект | Runbook |
|---|
outbox-lag растёт ∧ identity-consumer-lag растёт одновременно | Kafka/брокер недоступен или деградирует (общая шина) | И исходящие pin.support.*, и синк заявителя отстают; уведомления/реплика eventual, команды работают | stuck-support-outbox |
outbox-lag растёт, а identity-consumer-lag в норме | Застрял диспетчер outbox support (не общий брокер) | Уведомления по тикетам/арбитражу запаздывают; входящий синк не затронут | stuck-support-outbox |
consumer-dlq > 0 ∧ reason=unknown_version | Рассинхрон контракта pin.identity.user-upserted | Часть событий в DLQ, реплика ФИО/телефона заявителя устаревает | replay-identity-dlq |
consumer-dlq > 0 ∧ reason=handler_error (напр. невалидный телефон) | Аномалия данных producer-а identity | Отдельные карточки заявителей не обновляются | replay-identity-dlq |
sla-worker-cycle > 60 с ИЛИ нет цикла 5 мин ∧ sla-breaches не растёт | Worker ticket-sla-monitor не крутится/тормозит | Просрочки первого ответа/решения детектятся с опозданием, эскалации супервизору запаздывают | sla-worker-stalled |
sla-breaches растёт ∧ queue-depth растёт ∧ command-latency в норме | Нехватка операторов / всплеск приёма (не техсбой) | Реальная деградация SLA поддержки; нужна балансировка нагрузки | queue-backlog / sla-breach |
command-latency p95 > 500 мс ∧ list-search-latency p95 > 1 с одновременно | PostgreSQL/инфраструктура под нагрузкой | Замедлены и команды, и списки/поиск | command-latency |
Ограничения И Допущения
- Метрики status/queue/arbitrage/outbox — PostgreSQL-gauges через периодический scrape (задержка ≤ интервала
scrape); мгновенные всплески между scrape-ами не видны — источник истины остаётся в БД.
support_tickets_sla_breached обновляется циклом ticket-sla-monitor (1 мин, ADR-0056): алерт сигнализирует
накопленную просрочку с точностью цикла, не мгновенно.
- Продуктовый разрез тематик/операторов (8.1/8.4) — вне борда: SQL-ручка
get-support-dashboard; ClickHouse
не используется (объём мал, ADR-0056).
- Runbook-файлы — greenfield (пути целевые, по runbook-template).
Связанные Документы
- Сервис: README (Runtime И Эксплуатация — SLO/Dashboard/Alerts/Background jobs); домены
ticket.md, ticket-queue.md, arbitrage-case.md.
- События:
ticket-created.md, ticket-status-changed.md,
arbitrage-resolved.md (ContractVersion = 1, топики pin.support.*.v1);
consumed pin.identity.users.v1.
- Операции:
create-ticket, change-ticket-status,
escalate-ticket, get-support-dashboard.
- Use-cases: UC-SUP-001, UC-SUP-002,
UC-SUP-003, UC-SUP-005.
- Каталог бордов: observability-dashboard-catalog.
- ADR: ADR-0052 (tenancy),
ADR-0053 (admin),
ADR-0056 (PostgreSQL-only, без ClickHouse).