# req-093: DLQ 가시성/경보 + emit 실패 경보 (trex.events.dlq 관측성) - Status: Approved - Type: Exception - Priority: High - Owner: project maintainers ## Intent - `trex.events.dlq`(unroutable + 발행 실패 양쪽)는 현재 durable 큐로 보존되지만 소비/알림 주체가 없어 운영에서 조용히 누적된다. 또한 `_make_event_emitter`의 발행 실패는 warning 로그로 삼켜져 운영자가 인지하지 못한다. DLQ 유입/깊이를 관측 가능하게 만들고, 최종 실패 시 식별 가능한 경보 레벨 로그를 남겨 운영 피드백 루프를 닫는다. ## Requirement - `trex.events.dlq` 유입(unroutable + 발행 실패 양쪽)과 깊이(queue depth)를 운영에서 관측·경보 가능하게 한다. 구현 방식(메트릭 노출 / 로그 기반 / 소비자 데몬)은 draft-batch-design에서 OQ-3 기준으로 결정한다. - unroutable 이벤트: `mandatory=True` → `UnroutableError` → `_publish_dlq`로 `trex.events.dlq`에 보존하는 기존 경로는 유지하되, DLQ 유입이 관측 가능해야 한다. - 발행 실패 이벤트: REQ-091의 재시도까지 실패한 경우 `TransportUnavailableError`가 올라오면, 해당 실패를 DLQ(또는 별도 실패 경보 채널)에 추적 가능한 형태로 기록하거나 메트릭을 카운트한다. 구체 경로는 OQ-3 결정에 따른다. - `_make_event_emitter`(`runtime/daemon.py`)의 발행 실패 처리를 보강한다: REQ-091 재시도 후에도 실패 시 단순 `WARNING` 삼킴이 아니라 `ERROR` 또는 그에 준하는 경보 레벨 로그를 남긴다. 로그에는 routing key, 슬롯 ID(또는 correlation 정보), 실패 사유가 포함되어 식별 가능해야 한다. - `_publish_dlq`의 best-effort 실패(DLQ 자체 발행 실패)도 `ERROR` 수준 로그를 남긴다. - 이 변경은 `adapters/messaging/rabbitmq.py`(`_publish_dlq`)와 `runtime/daemon.py`(`_make_event_emitter`) 및 관측성 메커니즘 추가 범위에 국소화한다. wire 계약·consume/RPC 경로·슬롯 도메인 불변(NFR-1·NFR-3 흡수). ## Acceptance Criteria 1. Given unroutable 이벤트가 `trex.events.dlq`에 유입될 때, When 관측 지표(로그/메트릭/소비자)를 확인하면, Then DLQ 유입이 운영자가 인지 가능한 형태로 노출된다(S-3 연결). 2. Given `trex.events.dlq` 큐의 깊이(depth)를 확인할 때, When 유입 이벤트가 누적되면, Then 운영자가 접근 가능한 지표(로그/메트릭/RabbitMQ 관리 API 등)로 깊이를 파악할 수 있다(S-3 연결). 3. Given REQ-091 재시도 후에도 발행이 실패한 경우, When `_make_event_emitter`에서 `TransportUnavailableError`를 처리할 때, Then `WARNING` 수준이 아닌 `ERROR`(또는 이상) 수준 로그가 남고, routing key와 슬롯 식별 정보가 포함된다(FR-4 연결). 4. Given `_publish_dlq`의 DLQ 재발행 자체가 실패한 경우, When 예외가 발생하면, Then `ERROR` 수준 로그가 남고 메시지 유실이 silent하게 처리되지 않는다. 5. Given DLQ 가시성 구현 방식이 설계 단계에서 확정된 후, When batch design 문서를 확인하면, Then OQ-3(DLQ 가시성 구현 방식 — 메트릭/로그/소비자 데몬 중 택1)이 명시적으로 결정되어 있다(OQ-3 종료 조건 추적). 6. Given DLQ 유입/경보 메커니즘이 추가된 상태에서, When consumer 경로(intent/slots/control RPC)를 확인하면, Then 해당 경로의 동작·큐 바인딩·토폴로지에 변화가 없다(consume/RPC 무회귀, NFR-1). ## Impacted Area - Docs: docs/operations.md(DLQ 가시성/경보 운영 절차 신규 기재, REQ-094에서 함께 갱신 검토). docs/runtime-flows.md(`슬롯 이벤트 발행/구독` DLQ 경로 설명 보강, REQ-094에서 갱신). - Modules: `trex_core/adapters/messaging/rabbitmq.py`(`_publish_dlq` L199-216 — DLQ best-effort 실패 ERROR 로그 + 가시성 훅). `trex_core/runtime/daemon.py`(`_make_event_emitter` L238-248 — 발행 실패 ERROR 경보). 관측성 구현(OQ-3 결정 후 추가). wire 계약·consume/RPC 경로·슬롯 도메인 불변. - Tests: `tests/adapters/messaging/` — DLQ 유입 관측 지표 확인(AC-1), DLQ 깊이 노출(AC-2), emit 실패 ERROR 로그(AC-3), DLQ 재발행 실패 ERROR(AC-4), consume 경로 회귀(AC-6). `tests/application/test_messaging_event_publisher.py` 기존 회귀 유지. ## Notes - 출처: dcy-031 FR-3(D), FR-4, A-3(dcy-029 관측성 자산 재사용 여부 검토), S-3. - OQ-3(DLQ 가시성 구현 방식 — 메트릭/로그/소비자 중 택1): 설계 단계 결정. AC-5에서 추적. 종료 조건: batch design에 명시되면 Answered. dcy-029(REQ-084~090) 관측성 자산(구조화 로깅 인프라) 재사용 가능성을 설계 단계에서 검토한다. - FR-4(emit 실패 경보)는 독립 REQ로 승격하지 않고 본 REQ에 흡수한다 — FR-3(DLQ 가시성)과 같은 코드 경로(`_make_event_emitter`, `_publish_dlq`)를 공유하며 독립 구현·검증 시 오버헤드 대비 가치가 낮다. - `_publish_dlq` best-effort 정책(실패 시 silent log → ERROR로 강화)은 기존 wire 계약 변경 없이 로그 레벨 조정만으로 구현 가능해 설계 결정 없이도 확정 가능하다. - 본 변경은 DLQ 소비자 데몬(별도 상시 프로세스)을 강제하지 않는다 — 관측 방식은 OQ-3에서 결정. ## Change Log ### CHG-20260619-01 - Date: 2026-06-19 - Author: trex-core-dev #### Change Summary - dcy-031 FR-3(D) + FR-4로부터 최초 생성(Proposed). NFR-1·NFR-3 흡수. FR-4를 본 REQ에 흡수. OQ-3 설계 인계. A-3(dcy-029 자산 재사용) 인계. S-3 연결. #### Intent - DLQ 가시성/경보 + emit 실패 경보 정책을 backlog에 정규화하고, OQ-3 설계 결정 추적을 AC-5로 고정한다. #### Acceptance Criteria Delta - Added: - AC-1: DLQ 유입 관측 가능 - AC-2: DLQ 깊이 파악 가능 - AC-3: emit 실패 ERROR 수준 경보 - AC-4: DLQ 재발행 실패 ERROR - AC-5: OQ-3 종료 조건 추적 - AC-6: consume/RPC 경로 무회귀 - Updated: 없음 - Removed: 없음 #### Impacted Area Delta - Docs: - docs/operations.md, docs/runtime-flows.md - Modules: - trex_core/adapters/messaging/rabbitmq.py, trex_core/runtime/daemon.py - Tests: - tests/adapters/messaging/ (DLQ/emit 경보/회귀) #### Delivery Trace Delta - Batches: - none (draft-req 단계, batch 미편성) - Releases: - none #### Revalidation Impact - Reverification Needed: no - Existing Implementation Invalidated: no - Status Recommendation: keep-current - Follow-up Action: confirm-req 후 REQ-091·092와 함께 단일 batch 편성 예정 #### Validation Plan - 로그 캡처 기반으로 DLQ 유입 로그/ERROR 레벨 확인. mock `_publish_dlq` 실패 시나리오로 AC-4 검증. OQ-3 결정 후 구현 방식에 맞는 통합 검증 추가. ### CHG-20260619-02 - Date: 2026-06-19 - Author: 팀장 (confirm-req) #### Change Summary - Proposed → **Approved**. 필수 필드 충족, AC 구체, source dcy-031(confirmed, Open OQ 0) 정합. FR-4 흡수 승인(동일 emit 경로). OQ-3(DLQ 가시성 구현 방식)은 AC-5에서 design 인계 추적 — 승인 비차단. #### Intent - delivery input 승인. DLQ 가시성 구현 방식(메트릭/로그/소비자)은 draft-batch-design에서 dcy-029 관측성 자산 재사용성과 함께 확정. #### Acceptance Criteria Delta - Added: 없음 - Updated: 없음 - Removed: 없음 #### Revalidation Impact - Reverification Needed: no - Existing Implementation Invalidated: no - Status Recommendation: keep-current - Follow-up Action: REQ-091·092와 함께 단일 batch 편성 예정