Skip to content

애플리케이션 모니터링

코드 예제: events

Ktor는 이벤트를 사용하여 서버 애플리케이션을 모니터링하는 기능을 제공합니다. 애플리케이션의 생명 주기(애플리케이션 시작, 중지 등)와 관련된 미리 정의된 이벤트를 처리하거나, 특정 케이스를 처리하기 위해 사용자 정의 이벤트를 사용할 수 있습니다. 또한 MonitoringEvent 훅을 사용하여 사용자 정의 플러그인에 대한 이벤트를 처리할 수도 있습니다.

이벤트 정의

각 이벤트는 EventDefinition 클래스 인스턴스로 표현됩니다. 이 클래스는 이벤트에 전달되는 값의 타입을 지정하는 T 타입 파라미터를 가집니다. 이 값은 이벤트 핸들러에서 람다 인자로 접근할 수 있습니다. 예를 들어, 대부분의 미리 정의된 이벤트는 이벤트 핸들러 내부에서 애플리케이션 프로퍼티에 접근할 수 있도록 Application을 파라미터로 받습니다.

사용자 정의 이벤트의 경우, 해당 이벤트에 필요한 타입 파라미터를 전달할 수 있습니다. 아래 코드 스니펫은 ApplicationCall 인스턴스를 받는 사용자 정의 NotFoundEvent를 생성하는 방법을 보여줍니다.

kotlin
val NotFoundEvent: EventDefinition<ApplicationCall> = EventDefinition()

사용자 정의 이벤트 섹션에서는 서버가 리소스에 대해 404 Not Found 상태 코드를 반환할 때 사용자 정의 플러그인에서 이 이벤트를 발생시키는 방법을 보여줍니다.

미리 정의된 애플리케이션 이벤트

Ktor는 애플리케이션의 생명 주기와 관련된 다음과 같은 미리 정의된 이벤트를 제공합니다.

예를 들어, 애플리케이션 리소스를 해제하기 위해 ApplicationStopped 이벤트를 구독할 수 있습니다.

애플리케이션에서 이벤트 처리

지정된 Application 인스턴스에 대한 이벤트를 처리하려면 monitor 프로퍼티를 사용합니다. 이 프로퍼티는 애플리케이션 이벤트를 처리할 수 있는 다음 함수들을 노출하는 Events 인스턴스에 대한 접근을 제공합니다.

  • subscribe: EventDefinition으로 지정된 이벤트를 구독합니다.
  • unsubscribe: EventDefinition으로 지정된 이벤트에 대한 구독을 해제합니다.
  • raise: 지정된 값을 사용하여 EventDefinition으로 지정된 이벤트를 발생시킵니다.

    사용자 정의 이벤트 섹션에서 사용자 정의 이벤트를 발생시키는 방법을 확인할 수 있습니다.

subscribe / unsubscribe 함수는 T 값을 람다 인자로 받는 EventDefinition 인스턴스를 허용합니다. 아래 예제는 ApplicationStarted 이벤트를 구독하고 이벤트 핸들러에서 메시지를 로그로 남기는 방법을 보여줍니다.

kotlin
fun Application.module() {
    monitor.subscribe(ApplicationStarted) { application ->
        application.environment.log.info("Server is started")
    }
}

이 예제에서는 ApplicationStopped 이벤트를 처리하는 방법을 볼 수 있습니다.

kotlin
fun Application.module() {
    monitor.subscribe(ApplicationStopped) { application ->
        application.environment.log.info("Server is stopped")
        // 리소스 해제 및 이벤트 구독 해제
        monitor.unsubscribe(ApplicationStarted) {}
        monitor.unsubscribe(ApplicationStopped) {}
    }
}

전체 예제는 events를 참조하세요.

사용자 정의 플러그인에서 이벤트 처리

MonitoringEvent 훅을 사용하여 사용자 정의 플러그인에서 이벤트를 처리할 수 있습니다. 아래 예제는 ApplicationMonitoringPlugin 플러그인을 생성하고 ApplicationStartedApplicationStopped 이벤트를 처리하는 방법을 보여줍니다.

kotlin
import io.ktor.events.EventDefinition
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.application.hooks.*

val ApplicationMonitoringPlugin = createApplicationPlugin(name = "ApplicationMonitoringPlugin") {
    on(MonitoringEvent(ApplicationStarted)) { application ->
        application.log.info("Server is started")
    }
    on(MonitoringEvent(ApplicationStopped)) { application ->
        application.log.info("Server is stopped")
        // 리소스 해제 및 이벤트 구독 해제
        application.monitor.unsubscribe(ApplicationStarted) {}
        application.monitor.unsubscribe(ApplicationStopped) {}
    }
}

전체 예제는 여기에서 찾을 수 있습니다: events.

사용자 정의 이벤트

이 섹션에서는 서버가 리소스에 대해 404 Not Found 상태 코드를 반환할 때 발생하는 사용자 정의 이벤트를 만드는 방법을 살펴보겠습니다.

  1. 먼저 이벤트 정의를 생성해야 합니다. 아래 코드 스니펫은 ApplicationCall을 파라미터로 받는 사용자 정의 NotFoundEvent 이벤트를 생성하는 방법을 보여줍니다.

    kotlin
    val NotFoundEvent: EventDefinition<ApplicationCall> = EventDefinition()
  2. 이벤트를 발생시키려면 Events.raise 함수를 호출합니다. 아래 샘플은 호출에 대한 상태 코드가 404인 경우 새로 생성된 이벤트를 발생시키기 위해 ResponseSent 을 처리하는 방법을 보여줍니다.

    kotlin
    import io.ktor.events.EventDefinition
    import io.ktor.http.*
    import io.ktor.server.application.*
    import io.ktor.server.application.hooks.*
    
    val ApplicationMonitoringPlugin = createApplicationPlugin(name = "ApplicationMonitoringPlugin") {
        on(ResponseSent) { call ->
            if (call.response.status() == HttpStatusCode.NotFound) {
                this@createApplicationPlugin.application.monitor.raise(NotFoundEvent, call)
            }
        }
    }
  3. 생성된 이벤트를 애플리케이션에서 처리하려면 플러그인을 설치(install)합니다.

    kotlin
    fun Application.module() {
        install(ApplicationMonitoringPlugin)
    }
  4. 그런 다음 Events.subscribe를 사용하여 이벤트를 구독합니다.

    kotlin
    fun Application.module() {
        install(ApplicationMonitoringPlugin)
        monitor.subscribe(NotFoundEvent) { call ->
            log.info("No page was found for the URI: ${call.request.uri}")
        }
    }

전체 예제는 events를 참조하세요.