[BE-04] Async 스레드풀 메트릭 + OTLP 로그 appender

작업 내용 (설계 의도)

근거 TDD: ../TDD.md “클래스/파일 역할 정의”, FR-5·FR-3·FR-11.

변경 사항

FR-5의 “Async 스레드풀 active/max” 노출과 FR-3의 “log→Loki” 경로를 완성한다. Tomcat·JVM·GC·Heap 메트릭은 Micrometer가 registry 교체(BE-01/02)만으로 자동 노출되지만, 커스텀 executor mcpAuditExecutor(AsyncConfig.kt:12)는 자동 바인딩 대상이 아니라 명시 바인딩이 필요하다.

  • AsyncConfig.kt(또는 신규 ThreadPoolMetricsConfig.kt): mcpAuditExecutor를 Micrometer ExecutorServiceMetrics로 바인딩 → executor_active_threads{name="mcp-audit"}·executor_pool_max_threads 노출
  • 신규 logback-spring.xml: 기존 콘솔 출력 유지 + OpenTelemetry logback appender 추가 + 로그 패턴에 trace_id/span_id(MDC) 포함 → 로그가 OTLP로 Collector→Loki 전달, trace_id로 exemplar 상호 연결(FR-11)

파일 소유: AsyncConfig.kt(또는 신규 metrics config) + 신규 logback-spring.xml — BE-02(yml)·BE-03(kafka config)와 교집합 없음. 롤백: logback-spring.xml 삭제 시 Spring 기본 로깅 복귀, executor 바인딩 revert.

의존

  • BE-01 (micrometer-core·logback-appender 클래스패스 필요)

다이어그램

처리 흐름

sequenceDiagram
    participant E as mcpAuditExecutor
    participant M as Micrometer
    participant L as logback
    participant C as OTel Collector
    E->>M: ExecutorServiceMetrics 바인딩
    M->>M: executor_active_threads 노출
    L->>C: OTLP log (trace_id MDC)
    C->>C: Loki 라우팅

클래스 의존

flowchart LR
    AC["AsyncConfig / ThreadPoolMetricsConfig"] --> ESM["ExecutorServiceMetrics"]
    LB["logback-spring.xml"] --> APP["OTLP appender"]
    LB --> MDC["trace_id/span_id 패턴"]

테스트 케이스

  • /actuator/prometheusexecutor_active_threads{name="mcp-audit"}·executor_pool_max_threads가 노출된다.
  • /actuator/prometheustomcat_threads_busy_threads·jvm_gc_pause_seconds가 노출된다(registry 교체로 자동).
  • API 요청 처리 로그에 비어 있지 않은 trace_id가 MDC로 출력된다.
  • OTLP 엔드포인트 미설정 시에도 콘솔 로그는 정상 출력된다(로그 appender 실패가 앱을 막지 않음).