33 KiB
module-09. Наблюдаемость production-like контура
Статус: целевая спецификация наблюдаемости MVP для ВМ1/ВМ2 и отдельного private SigNoz.
Источники:README.md,arch-00-glossary.md,arch-01-system-architecture.md,arch-02-api-contracts.md,arch-03-docker-compose-blueprint.md,arch-04-settings-and-content.md,arch-05-agent-development-process.md,module-01-api-backend.md–module-08-keycloak.md.
1. Цели и границы
Наблюдаемость должна позволять:
- найти пользовательский запрос по
request_id,trace_idилиux_session_id; - восстановить путь «frontend → nginx → API → Safety → S3/Open Lines»;
- измерять доступность, задержку, ошибки и насыщение каждого сервиса;
- обнаруживать backlog, DLQ, circuit open, потерю telemetry и истечение TLS;
- расследовать security/audit события без записи PII и секретов;
- проверять SLO по данным, независимым от бизнес-логов.
Telemetry не является источником бизнес-истины и не влияет на auth, safety verdict или доставку сообщений. Недоступность Collector не должна блокировать запросы. Audit в han_app — отдельный durable контур.
2. Production-like решение MVP
2.1. Обязательный минимум в основном Compose
Каждый root Compose (ВМ1 и ВМ2) обязан содержать локальный otel-collector. Prometheus/Grafana/Loki/Tempo не обязаны размещаться на application VM.
Предпочтительный operable-вариант после выбора backend:
- приложения на каждой VM экспортируют OTLP gRPC только в свой local
otel-collector:4317; - Collector отправляет telemetry в выбранный удалённый управляемый OTLP backend провайдера;
- JSON stdout остаётся аварийным локальным журналом Docker с rotation;
- пока удалённый backend не выбран, допустим архитектурный минимум из arch-03: bounded JSON stdout/platform logs и Collector
debugexporter с sampling в acceptance; такой режим не считается полноценным production-хранением и не закрывает alerting/SLO.
Требуемые возможности удалённого backend: OTLP ingest, поиск traces, PromQL-совместимые или эквивалентные metrics, поиск структурированных logs, alerting, RBAC, retention и TLS.
2.2. Самостоятельно размещаемая опция
Опциональный Compose profile observability-local может включать:
- Prometheus — scrape метрик Collector/Redis/Keycloak/nginx exporters;
- Grafana — dashboards и alerts;
- Loki — логи;
- Tempo — traces.
Он не включается по умолчанию на малой VM: стек требует дополнительной RAM/диска и сам становится объектом backup/monitoring. Для operable local-варианта нужны отдельный volume каждому backend, retention limits, compaction, auth через ops/VPN и отсутствие host ports. Grafana доступна только через отдельный защищённый ops route/VPN, не через публичный /.
Рекомендуемый минимум VM при local profile: дополнительно 4 vCPU, 8 ГБ RAM и 100+ ГБ SSD сверх приложения; точный размер — после измерения ingest.
3. Архитектура Collector
3.1. Компоненты
backend services ─OTLP gRPC/HTTP─┐
nginx/Redis/Keycloak exporters ──┼─> otel-collector
Docker JSON stdout ─filelog───────┘ ├─ OTLP/TLS remote backend
├─ Prometheus endpoint (optional)
└─ debug exporter (acceptance only)
Collector запускается одним сервисом MVP. При росте разделяется на agent/gateway: локальный agent принимает и буферизует, remote gateway выполняет policy/export.
3.2. Receivers
otlpgRPC0.0.0.0:4317— основной internal receiver;otlpHTTP0.0.0.0:4318— совместимость SDK;prometheus— scrape самого Collector, Keycloak metrics, Redis exporter, nginx exporter и сервисных/metrics, если они не идут OTLP;filelog— только если Docker logging driver предоставляет read-only каталог/volume; парсит JSON stdout без чтения secret-файлов;hostmetrics— CPU, memory, filesystem, network VM/container host, если Collector получает только необходимые read-only mounts.
Порты 4317, 4318, 8888, 8889 используют expose, не ports. Receiver доступен только в сети observability.
3.3. Processors и порядок
Во всех pipelines первым стоит защита памяти, последним — batch:
memory_limiter: check interval 1s, soft/hard limit относительно container memory;resource: нормализуетservice.namespace=han-chat,deployment.environment,service.version;attributes: удаляет/маскирует sensitive attributes;transform: нормализует route/status/error semantic conventions;filter: исключает health noise, debug events и запрещённые поля;probabilistic_samplerили tail sampling для traces;batch: bounded batch/timeout;- при remote export —
queued_retry/sending queue иfile_storageextension.
memory_limiter не заменяется Docker OOM limit. При pressure Collector отбрасывает telemetry контролируемо и увеличивает otelcol_processor_refused_*.
3.4. Exporters
otlp/remote: TLS verify, endpoint и auth header из secret env/mount;prometheus: optional pull endpoint только internal;debug: толькоAPP_ENV=test|acceptance, verbosity normal; production debug exporter по умолчанию выключен;loki/otlphttp— только если выбран backend и его контракт закреплён.
Секрет exporter-а не должен появляться в rendered config, логах или /debug/configz. Config монтируется read-only; secret подставляется env.
3.5. Extensions
health_check— internal endpoint, используется Compose;pprof/zpages— только при явном ops profile, internal network;file_storage— persistent sending queue на volumeotel-queue;basicauth/oauth2client— если требует remote backend.
3.6. Принципиальная конфигурация
receivers:
otlp:
protocols:
grpc: {endpoint: 0.0.0.0:4317}
http: {endpoint: 0.0.0.0:4318}
prometheus:
config:
scrape_configs:
- job_name: otel-collector
static_configs: [{targets: ["127.0.0.1:8888"]}]
processors:
memory_limiter:
check_interval: 1s
limit_mib: 384
spike_limit_mib: 96
resource/common:
attributes:
- {key: service.namespace, value: han-chat, action: upsert}
- {key: deployment.environment, value: "${env:APP_ENV}", action: upsert}
attributes/redact:
actions:
- {key: http.request.header.authorization, action: delete}
- {key: http.request.header.cookie, action: delete}
- {key: url.query, action: delete}
- {key: db.statement, action: delete}
filter/noise:
error_mode: ignore
traces:
span:
- 'attributes["http.route"] == "/health/live"'
batch:
send_batch_size: 1024
timeout: 5s
exporters:
otlp/remote:
endpoint: "${env:OTEL_REMOTE_ENDPOINT}"
tls: {insecure: false}
headers: {authorization: "${env:OTEL_REMOTE_AUTH_HEADER}"}
extensions:
health_check: {endpoint: 0.0.0.0:13133}
file_storage: {directory: /var/lib/otelcol/queue}
service:
extensions: [health_check, file_storage]
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, resource/common, attributes/redact, filter/noise, batch]
exporters: [otlp/remote]
metrics:
receivers: [otlp, prometheus]
processors: [memory_limiter, resource/common, attributes/redact, batch]
exporters: [otlp/remote]
logs:
receivers: [otlp]
processors: [memory_limiter, resource/common, attributes/redact, filter/noise, batch]
exporters: [otlp/remote]
telemetry:
metrics: {address: 0.0.0.0:8888}
Конкретная версия schema проверяется командой Collector validate; image закрепляется по digest. Значения memory/batch/queue — стартовые, не SLO.
4. Resource attributes и корреляция
Обязательные resource attributes:
service.name:nginx,api-backend,message-safety,bitrix-local-app,bitrix-sync,keycloak,redis,otel-collector;service.namespace=han-chat;service.version=<release-or-git-sha>;deployment.environment=production-like|production;host.name/service.instance.idбез публичного IP.
Обязательные поля request-события:
request_id;trace_id,span_id;ux_session_id— nullable, только когда передан;service.name;environmentлибо canonicaldeployment.environment.
request_id формирует/валидирует nginx; сервис возвращает его клиенту и передаёт downstream. trace_id берётся из active span. ux_session_id не является auth и не должен использоваться как metric label.
5. W3C propagation
- принимаются только валидные
traceparentи опциональныйtracestate; - nginx передаёт context в API; при edge instrumentation создаёт server span;
- API создаёт child spans для PostgreSQL, Redis, S3, Safety, Open Lines и JWKS;
- internal calls передают
traceparent,tracestate,X-Request-ID; baggageпо умолчанию не принимается от внешнего клиента; если включён, allow-list исключает PII;- Bitrix24/S3 могут не вернуть context: внешний client span всё равно закрывается результатом;
- async outbox/inbox связывается span link с исходным trace; новый worker trace не притворяется продолжением спустя долгий срок.
Frontend может отправлять валидный traceparent, но backend не доверяет его sampling/security атрибутам.
6. JSON stdout contract
Одна JSON-запись на строку UTF-8:
{
"timestamp": "2026-07-10T09:00:00.123Z",
"level": "INFO",
"service.name": "api-backend",
"service.version": "git-abcdef0",
"environment": "production-like",
"module": "message_service",
"event": "message.delivery.completed",
"message": "Message delivery completed",
"request_id": "01J...",
"trace_id": "32hex",
"span_id": "16hex",
"ux_session_id": "uuid-or-null",
"route": "/api/v1/dialogs/{dialog_id}/messages",
"method": "POST",
"status_code": 201,
"duration_ms": 742,
"dependency": "bitrix-local-app",
"outcome": "success",
"error_code": null
}
Правила:
event— стабильная mnemonic,message— безопасное описание;- route — template, никогда raw URI с id/query;
- stack trace допускается только в internal error log после redaction;
- message text, callback body, SQL values и file content запрещены;
- Docker driver ограничен
50m × 5, но это buffer, не retention backend; - multiline stack trace сериализуется полем JSON, не отдельными строками.
7. Redaction и data minimization
Удаляются или маскируются:
Authorization, Cookie, Set-Cookie, JWT, OAuth/code/refresh/access tokens;- raw OTP/mock code, Keycloak admin/client password;
- phone/email/full name, device id, IP по policy (допустим HMAC/truncated);
- message text, filenames с PII, document/file contents;
- DSN/password, Redis URL, S3 keys;
- presigned URL и любая query string;
- Bitrix raw payload/download URL/application token;
db.statementс literals; предпочтительно operation/table, не SQL.
Redaction выполняется в SDK/logger до stdout, затем повторяется Collector processor. Collector не может считаться единственной защитой. Автотесты отправляют canary secrets/PII и требуют отсутствие во всех трёх сигналах.
8. Instrumentation по компонентам
8.1. FastAPI-сервисы
- OpenTelemetry ASGI/FastAPI server spans с route template;
- HTTPX client spans с sanitized host/method/status;
- SQLAlchemy/asyncpg spans без параметров и raw statement;
- Redis instrumentation с command name и DB index, без key/value;
- boto/S3 spans: operation/bucket logical name, без object key/query;
- background workers: span на claim/process/finalize, links на origin;
- исключить
/health/liveиз traces; readiness оставить в metrics и sampled logs.
8.2. PostgreSQL
Собираются pool wait/checked-out, transaction duration, error class, migrations revision, managed PG provider metrics (CPU, storage, connections, locks, replication/PITR state). user_id, SQL text и row data не labels.
8.3. Redis
redis_exporter подключается отдельным ACL user только на INFO, PING, безопасные latency/keyspace metrics. Нужны memory ratio, evictions, expirations, blocked/rejected clients, command latency, AOF status/rewrite, Pub/Sub buffers, key count/TTL агрегаты. Keys/values не экспортируются.
8.4. Keycloak
Включаются management metrics/JVM/HTTP/DB pool. Custom OTP provider публикует counters send/verify/limit/settings-cache без phone labels. Login events идут в JSON/audit с masked/HMAC destination. Public OIDC synthetic проверяется отдельно.
8.5. nginx
JSON access log содержит request_id, извлечённый trace_id, route class, method, normalized path, status, bytes, request/upstream duration/status, TLS version, cache status. $request с query не используется.
Collector filelog parser:
- разбирает JSON, timestamp и severity;
- переносит
service.name=nginx; - превращает пустые/
-в null; - route class нормализует в bounded set;
- отбрасывает ACME/health success noise;
- не парсит raw URI в labels.
Native nginx OTEL module предпочтителен, если image/version закреплены. Без него nginx только передаёт W3C context и коррелирует access log; первый server span создаёт API.
8.6. Host/Docker
CPU, load, memory/swap, disk usage/inodes/IO, network, container restarts/OOM, Docker daemon health и clock sync. Container name/version — bounded labels; container id не хранится как долгосрочный high-cardinality label.
9. Метрики бизнес-потоков
API и auth
han_http_requests_total{service,route,method,status_class};han_http_request_duration_seconds;han_auth_bootstrap_total{outcome};han_ux_session_start_total{reason};han_jwks_refresh_total{outcome};han_rate_limit_decisions_total{scope,outcome}.
Message Safety
- checks/verdicts по
allow|deny|pending|error; processing_mode, active/usedconfig_version, config activation result,message_safety_mock_enabledи forced outcomes поtext|file/allow|deny;- poll duration/count buckets, timeout и recovery backlog age;
- stub mode info и terminal
400отдельно, пока действует test-only контракт; - cache hit, Redis latency, task expired/not-found.
Open Lines/Bitrix
- message submitted → delivered end-to-end latency;
- local app outbound result/retry/ambiguous/DLQ;
- inbox depth/oldest age/forward retries/duplicate;
- OAuth time-to-expiry/refresh result;
- connector desired/observed state;
- Bitrix 429, circuit state, setup failure.
Files/S3
- init/complete/promote/delete;
- quarantine object age/orphans;
- checksum/MIME/size reject;
- presigned download issued;
- S3 dependency latency/error by operation and logical bucket.
Frontend synthetic
- public config/content;
- OIDC discovery/authorization page;
- WS handshake;
- test-user end-to-end flow в отдельной тестовой identity без реального PII.
Никакие UUID/user/session/dialog/task/message id не labels. Они допустимы только в sampled logs/traces при принятой retention.
10. Dashboards
- Executive/SLO: availability, error budget burn, p50/p95/p99, message delivery, auth, active incidents.
- nginx ingress по VM: отдельные панели/filters ВМ1 и ВМ2; RPS, 4xx/5xx, upstream latency/status, 429, WS, TLS, cache, CRM webhook на ВМ2.
- api-backend: routes, DB/Redis pools, JWKS, circuits, outbox/safety backlog, S3.
- message-safety: capabilities, verdicts,
202poll, PG queue age/leases/fencing, ClamAV/signature age, file/link cache и DNS dependency. - bitrix-local-app: install/OAuth, connector, outbound/inbox/DLQ, API/Bitrix latency.
- bitrix-sync: mode/readiness, queue depth/oldest age, workflow/command transitions, CRM batch latency/subcommand outcome, limiter/throttle, retry/DLQ, webhook/reconciliation lag, mapping invariants и business-alert SLA.
- Keycloak: login/OTP/lockout, sessions/tokens, provider settings cache, JVM/DB.
- Redis: memory/evictions/AOF/latency/clients/keyspace.
- PostgreSQL/S3: provider metrics, storage, connections, backup/PITR, object errors.
- Business flow: guest config → OTP → bootstrap → session → dialog → safety → Open Lines → operator reply.
- Collector health: accepted/sent/refused/dropped, queue, retry, exporter errors, memory/CPU.
Каждая панель содержит release annotation, environment filter и links trace→logs по trace_id.
11. SLI, SLO и alerts
Значения — начальная production-like политика до load/product review:
| SLI | Initial SLO, 30 дней |
|---|---|
| HTTPS edge availability | 99.9% |
| public config/content successful requests | 99.9% |
| protected read API successful requests | 99.5% |
| Keycloak login flow availability | 99.5% |
| text message accepted и доставлен в Open Lines | 99.0% |
| operator inbox applied без permanent loss | 99.5% |
| p95 protected read API | < 750 ms |
| p95 text send без внешнего rate limit | < 5 s |
| telemetry Collector ingest availability | 99.0%, не входит в business availability |
Файловый send измеряется отдельно: p95 не должен превышать configured safety poll budget; user-cancel, safety deny, 4xx validation и edge abuse 429 не считаются server failure. 503/504 и unexpected 5xx считаются.
Paging alerts
- multi-window burn: 14.4× за 5m/1h или 6× за 30m/6h;
- edge/API 5xx >5% 5 минут;
- text delivery failure >5% 10 минут;
- oldest outbox/inbox/safety task >5 минут либо DLQ >0;
- Keycloak login failures infrastructure class >10% 5 минут;
- PostgreSQL unavailable/connection saturation >90%;
- Redis unavailable, AOF error или sustained evictions;
- Collector exporter queue >80%, dropped/refused telemetry >0 sustained;
- TLS expiry <14 дней warning, <7 дней page;
- disk >85% warning, >92% page; OOM/restart loop;
- managed PG backup/PITR failure.
- Message Safety active config missing/invalid, referenced artifact unavailable или config refresh stale >5 с.
message_safety_mock_enabled=1— active page/high-severity alert без auto-resolve по времени; закрывается только после возврата в standard.- bitrix-sync invalid/revoked credential или обязательная configuration/grant missing;
- bitrix-sync technical DLQ >0, mapping invariant violation или worker/limiter heartbeat stale;
- bitrix-sync queue oldest age >30 с при healthy CRM либо sustained рост;
- Contact webhook/reconciliation cursor lag выше двух configured intervals.
Ticket/warning alerts
- p95 regression 20% release-over-release;
- settings/JWKS cache stale;
- bitrix-sync CRM last success stale, rate-limit errors выше baseline или business alert SLA overdue;
- OAuth expires <24h без успешного refresh;
- quarantine orphan growth;
- cardinality/ingest growth >2× baseline.
Alert содержит service, environment, symptom, dashboard, runbook, release и безопасный query; не содержит PII.
12. Sampling, cardinality и retention
Traces
- errors/5xx, circuit, timeout, DLQ, safety final deny и slow requests — 100%;
- обычные успешные requests — 5–10%;
- health/ACME success — 0%;
- tail sampling предпочтителен в Collector, но head sample SDK должен оставлять достаточно данных;
- sampling decision передаётся W3C.
Metrics
Allow-list labels; route template вместо raw path; status class/known code; dependency enum. Cardinality budget: целевой <10 000 active series на MVP environment. CI проверяет запрещённые labels.
Retention initial
- metrics: 30 дней high resolution, 13 месяцев downsampled при доступности backend;
- traces: 7 дней, errors 14 дней;
- technical logs: 14 дней, security/auth logs 30 дней;
- audit
han_app: 365 дней только как временное допущение до legal policy; - raw Bitrix callback не хранится в telemetry;
- local Docker logs: не более 250 МБ/container и 5 файлов.
Legal retention/erasure имеет приоритет; изменение требует обновления policy и backup lifecycle.
13. Collector health и отказоустойчивость
Контролируются:
/healthextension;- process CPU/RSS/restarts;
- accepted/refused/sent/failed spans, points, records;
- batch send size/latency;
- exporter queue capacity/size, enqueue failures, retry age;
- file storage usage/corruption;
- scrape failures;
- config reload/validation.
При remote outage queue хранится на otel-queue с bounded size/age. При заполнении отбрасываются сначала low-priority success traces/logs; приложение продолжает работу. Нельзя позволять queue заполнить системный диск.
14. Docker Compose
otel-collector:
- pinned contrib image;
- networks: только
observability, а для scrape internal targets — минимально необходимаяbackend; expose: 4317, 4318, 13133, 8888/8889;- без host ports;
- config read-only,
otel-queuevolume rw; - non-root, read-only rootfs, tmpfs
/tmp, drop capabilities, no-new-privileges; - перед collector запускается idempotent
otel-queue-init: one-shot без сети и secrets, сuser: 0:0,cap_drop: ALLи толькоCHOWN/FOWNER, выставляет mount root10001:10001 0700; collector зависит отservice_completed_successfully; - initial limit: 0.5 CPU/512 MiB, queue disk 5–10 ГБ; уточнить load test;
- healthcheck extension;
- restart policy с backoff;
- приложения имеют bounded non-blocking OTLP exporter queue.
Collector существует отдельным экземпляром на ВМ1 и ВМ2. Каждый имеет собственный otel-queue volume/limits и экспортирует в private SigNoz 192.168.0.5:4317; ВМ2 никогда не использует Docker hostname collector ВМ1. Telemetry outage/overflow fail-open для business и Safety readiness, но создаёт alert.
Новый named volume считается потенциально root:root; основной collector не
запускается от root и volume не получает 0777. Ownership init проверяется
после первого create и повторного recreate.
Доступ к Docker socket запрещён. Для container metrics используется безопасный exporter/hostmetrics, а не unrestricted socket mount.
15. Security
- OTLP receiver internal-only; при переходе между hosts — mTLS;
- remote exporter только TLS verify, credentials least privilege;
- Grafana/Prometheus/Loki/Tempo не публичны;
- RBAC: viewer/operator/admin; audit доступа к logs/traces;
- dashboards не показывают PII;
- config/secret permissions 0400/0600;
- dependency/image scan и SBOM;
- защита от log injection: JSON encoding, control chars, bounded field lengths;
- telemetry input не исполняет expressions из пользовательских значений;
- регулярная secret-canary проверка и incident deletion procedure.
16. Runbooks
Collector not-ready
docker compose ps otel-collectorи bounded logs.- Проверить config validation, memory/OOM, queue volume.
- Проверить DNS/TLS/auth remote exporter.
- Не рестартовать бесконечно при полной queue; сначала освободить/расширить безопасно.
- Бизнес-сервисы оставить работающими; подтвердить local JSON logs.
- После восстановления проверить drain и gap.
Telemetry отсутствует у одного сервиса
- Проверить
service.name, endpoint/protocol и сетьobservability. - Проверить SDK queue/drop counters и clock.
- Отправить synthetic request с
X-Request-ID. - Найти его в stdout, Collector accepted и backend.
- Проверить sampling/filter/redaction rules.
Remote backend outage
- Подтвердить exporter errors, а не application outage.
- Оценить queue fill rate/time-to-full.
- Ограничить debug exporter; не включать verbose.
- При длительном outage увеличить sampling только через reviewed config.
- После восстановления подтвердить drain и создать incident note о потере данных.
Cardinality/ingest spike
- Найти новое metric/log attribute по release annotation.
- Отключить offending instrument/filter в Collector.
- Проверить raw path/id/user/session labels.
- Rollback instrumentation при риске стоимости/доступности.
- Добавить CI regression test.
Высокая latency сообщения
- Открыть trace по request id.
- Разделить API, Safety poll, S3, local app, Bitrix.
- Проверить circuit, queue age, DB pool и Redis.
- Не повторять ambiguous message без исходного idempotency key.
- Следовать runbook зависимого модуля.
Логи содержат секрет/PII
- Ограничить доступ и остановить offending export.
- Сохранить только incident metadata, не копировать значение.
- Ротировать скомпрометированный secret.
- Удалить данные по процедуре backend/provider.
- Исправить source redaction + Collector defense; добавить canary test.
17. Проверки и Definition of Done
- Collector config проходит validate и запускается в root Compose каждой VM;
- OTLP gRPC и HTTP принимают три сигнала;
- все сервисы имеют правильные resource attributes;
- request проходит nginx/API/Safety/Open Lines с одним
request_idи связанным trace; ux_session_idесть только где передан и не является label;- FastAPI/HTTPX/PG/Redis/S3 workers instrumented;
- nginx JSON parsing и trace correlation проверены;
- Redis/Keycloak/host/Collector metrics доступны;
- dashboards и alerts provisioned из versioned files для выбранного telemetry backend; до его выбора это остаётся acceptance/TBD, а не выполненный production DoD;
- remote outage, queue full, Collector restart и backend recovery rehearsed;
- local profile, если включён, имеет volumes/retention/auth и не публикует порты;
- secret/PII canary отсутствует в logs/traces/metrics;
- cardinality и sampling tests проходят;
- SLO queries воспроизводимы и исключения документированы;
- runbooks связаны с alerts.
18. Допущения, TBD и конфликты
Решения
- O1: обязательный архитектурный минимум — local Collector на каждой application VM; выбран self-hosted SigNoz
на отдельной VM
192.168.0.5, доступный по приватному OTLP gRPC. - O2: Prometheus/Grafana/Loki/Tempo — отдельный operable profile, не скрытая обязательная нагрузка основной VM.
- O3: JSON stdout — аварийный локальный buffer; audit App DB — durable.
- O4: telemetry fail-open для business path, но потеря telemetry alertится.
- O5: ID/PII не labels; source redaction обязательна до Collector.
TBD
- O-TBD1 закрыт: self-hosted SigNoz,
192.168.0.5:4317, plaintext только внутри доверенной приватной сети; UI через SSH jump host. - O-TBD2: утвердить SLO/RPS/error-budget с product owner.
- O-TBD3: legal retention/erasure и допустимость IP/user-agent.
- O-TBD4: точные sampling и resource limits после load test.
- O-TBD5: поддерживаемый nginx OTEL module и Keycloak native tracing по pinned versions.
- O-TBD6: нужен ли local observability profile в первой VM.
Обнаруженные архитектурные конфликты
arch-03разрешает stdout/platform exporter как минимум, но production-like расследования и alerts без backend ограничены. Здесь remote OTLP backend рекомендован, но не объявлен выбранным: провайдер остаётся TBD.module-05использует test-only terminal400и non-sticky verdict вместо canonical403/sticky production verdict. Dashboards обязаны маркировать сервисstub; production SLO Safety на нём недостоверен.module-07задаёт full sync target; до code/portal cutover dashboard обязан показыватьsync_disabled, а не синтетический CRM success. Queue/CRM SLI включаются только после module-07 preflight.- Retention, RPO/RTO и production SLO открыты в module-01/04/06/08; значения этого документа являются initial ops policy, не закрывают legal/product TBD.
- Observability env (
OTEL_REMOTE_*, service names, sampling/queue limits) добавлены в arch-04 и.env.example; sampling/queue limits уточняются после load test.
19. Ссылки на прототип и исходные документы
- VM/Docker logging и firewall:
../../HAN_chat/deploy/setup-vm-han-chat.sh. - Прототипный nginx stdout/access log:
../../HAN_chat/bitrix-local-app/deploy/nginx/nginx.conf. - Архитектурный observability contract:
arch-02-api-contracts.md. - Compose topology:
arch-03-docker-compose-blueprint.md.