콘텐츠로 이동
Bluetape4k 문서1.11

Async channel과 수명주기

최신 안정판 Bluetape4k 1.11.0 릴리스 기준

KLoggingChannel은 log event를 caller coroutine에서 바로 backend로 보내지 않고 MutableSharedFlow를 거쳐 background collector가 SLF4J에 전달합니다. caller latency와 emission lifecycle을 분리하는 대신 buffer와 shutdown 계약이 추가됩니다.

KLoggingChannel send, collect, close, post-close 흐름

  • replay는 0입니다.
  • extra buffer capacity는 64입니다.
  • overflow policy는 SUSPEND입니다.
  • 기본 instance들은 Dispatchers.IO + SupervisorJob + CoroutineName("logchannel") shared scope를 사용합니다.
  • JVM shutdown hook 하나가 shared job을 취소합니다.

SUSPEND는 “무제한 비동기”가 아닙니다. collector가 느리고 buffer가 가득 차면 sendemit이 suspend합니다.

class ImportWorker : AutoCloseable {
private val logger = object : KLoggingChannel() {}
suspend fun run(id: String) {
logger.info { "Import started id=$id" }
}
override fun close() = logger.close()
}

close()는 idempotent하고 이 instance의 collector job만 cancel합니다. injected CoroutineScope는 caller 소유이므로 취소하지 않습니다. deterministic test나 suspend lifecycle callback은 closeAndJoin()으로 collector 종료까지 기다립니다.

현재 구현의 close는 drain이 아니라 cancel입니다. close 직전 buffer에 있던 event가 모두 backend에 기록된다고 보장하지 않습니다. close 뒤 send는 block하지 않고 event를 버립니다. 따라서 audit 또는 반드시 기록해야 하는 event transport로 사용하면 안 됩니다.

collector는 개별 log emission exception을 catch하고 error log를 시도합니다. CancellationException은 다시 던져 정상적인 취소를 유지합니다.

조건선택
일반 request/service logKLogging
appender latency가 측정된 병목이며 suspend backpressure 허용KLoggingChannel 검토
shutdown 때 모든 event 보장 필요durable queue/explicit drain 설계
audit/security eventlogging channel이 아닌 보존 가능한 event pipeline

설정과 장애 진단은 Operations & recipes에서 마무리합니다.