Skip to content

应用程序监控

代码示例: events

Ktor 提供了通过使用事件来监控服务器应用程序的能力。您可以处理与应用程序生命周期相关的预定义事件(例如应用程序启动、停止等),也可以使用自定义事件来处理特定情况。您还可以使用 MonitoringEvent 钩子来处理自定义插件的事件。

事件定义

每个事件都由 EventDefinition 类实例表示。此类别带有一个 T 类型形参,用于指定传递给事件的值的类型。此值可在事件处理程序中作为 lambda 实参访问。例如,大多数预定义事件接受 Application 作为形参,允许您在事件处理程序中访问应用程序属性。

对于自定义事件,您可以传入此事件所需的类型形参。以下代码片段展示了如何创建一个接受 ApplicationCall 实例的自定义 NotFoundEvent

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

自定义事件 一节展示了当服务器针对某个资源返回 404 Not Found 状态码时,如何在自定义插件中触发此事件。

预定义应用程序事件

Ktor 提供以下与应用程序生命周期相关的预定义事件:

例如,您可以订阅 ApplicationStopped 事件以释放应用程序资源。

在应用程序中处理事件

要处理指定 Application 实例的事件,请使用 monitor 属性。此属性提供对 Events 实例的访问,该实例暴露以下函数,允许您处理应用程序事件:

subscribe / unsubscribe 函数接受 EventDefinition 实例,其中 T 值作为 lambda 实参。以下示例展示了如何订阅 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 函数。以下示例展示了如何处理 ResponseSent 钩子,以便在调用的状态码为 404 时触发新创建的事件。

    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. 要在应用程序中处理所创建的事件,请安装该插件:

    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