Skip to content
Server Plugin

在 Ktor Server 中跟踪请求

所需依赖项io.ktor:ktor-server-call-id

代码示例 call-id

原生服务器
Ktor 支持 Kotlin/Native,允许您在没有额外运行时或虚拟机的情况下运行服务器。
支持:✅

CallId 插件允许您通过使用唯一的请求 ID 或调用 ID 端到端地跟踪客户端请求。通常,在 Ktor 中使用调用 ID 的流程如下:

  1. 首先,您需要通过以下方式之一获取特定请求的调用 ID:
    • 反向代理(如 Nginx)或云提供商(如 Heroku)可能会在特定的标头中添加调用 ID,例如 X-Request-Id。在这种情况下,Ktor 允许您获取调用 ID。
    • 否则,如果请求未携带调用 ID,您可以在 Ktor 服务器上生成它。
  2. 接下来,Ktor 使用预定义字典验证获取/生成的调用 ID。您也可以提供自己的条件来验证调用 ID。
  3. 最后,您可以将调用 ID 在特定的标头(例如 X-Request-Id)中发送给客户端。

CallIdCallLogging 结合使用,通过将调用 ID 放入 MDC 上下文并配置日志记录器以显示每个请求的调用 ID,可以帮助您对调用进行故障排除。

在客户端,Ktor 提供了 CallId 插件用于跟踪客户端请求。

添加依赖项

要使用 CallId,您需要在构建脚本中包含 ktor-server-call-id 构件:

Kotlin
Groovy
XML

安装 CallId

要将 CallId 插件安装到应用程序,请将其传递给指定的

模块
模块允许您通过对路由进行分组来构建应用程序结构。
中的 install 函数。 下面的代码片段显示了如何安装 CallId ...

  • ... 在 embeddedServer 函数调用内部。
  • ... 在显式定义的 module 内部,该模块是 Application 类的一个扩展函数。
kotlin
kotlin

配置 CallId

获取调用 ID

CallId 提供了几种获取调用 ID 的方法:

  • 要从指定的标头中获取调用 ID,请使用 retrieveFromHeader 函数,例如:

    kotlin
    install(CallId) {
        retrieveFromHeader(HttpHeaders.XRequestId)
    }

    您还可以使用 header 函数在同一个标头中获取并发送调用 ID

  • 如果需要,您可以从 ApplicationCall 中获取调用 ID:

    kotlin
    install(CallId) {
        retrieve { call ->
            call.request.header(HttpHeaders.XRequestId)
        }
    }

请注意,所有获取的调用 ID 都会使用默认字典进行验证

生成调用 ID

如果传入的请求不包含调用 ID,您可以使用 generate 函数生成它:

  • 下面的示例显示了如何从预定义字典生成指定长度的调用 ID:
    kotlin
    install(CallId) {
        generate(10, "abcde12345")
    }
  • 在下面的示例中,generate 函数接受一个用于生成调用 ID 的代码块:
    kotlin
    install(CallId) {
        val counter = atomic(0)
        generate {
            "generated-call-id-${counter.getAndIncrement()}"
        }
    }

验证调用 ID

所有获取/生成的调用 ID 都会使用默认字典进行验证,如下所示:

kotlin
CALL_ID_DEFAULT_DICTIONARY: String = "abcdefghijklmnopqrstuvwxyz0123456789+/=-"

这意味着包含大写字母的调用 ID 将无法通过验证。如果需要,您可以使用 verify 函数应用不太严格的规则:

kotlin
install(CallId) {
    verify { callId: String ->
        callId.isNotEmpty()
    }
}

您可以在此处找到完整示例:call-id

将调用 ID 发送到客户端

获取/生成调用 ID 后,您可以将其发送给客户端:

  • header 函数可用于获取调用 ID并在同一个标头中发送它:

    kotlin
    install(CallId) {
        header(HttpHeaders.XRequestId)
    }

    您可以在此处 find 完整示例:call-id

  • replyToHeader 函数在指定的标头中发送调用 ID:

    kotlin
    install(CallId) {
        replyToHeader(HttpHeaders.XRequestId)
    }
  • If required, you can use ApplicationCall to send a call ID in a response:

    kotlin
    reply { call, callId ->
        call.response.header(HttpHeaders.XRequestId, callId)
    }

将调用 ID 放入 MDC

CallIdCallLogging 结合使用,通过将调用 ID 放入 MDC 上下文并配置日志记录器以显示每个请求的调用 ID,可以帮助您对调用进行故障排除。为此,请在 CallLogging 配置块内调用 callIdMdc 函数,并指定要放入 MDC 上下文的所需键:

kotlin
install(CallLogging) {
    callIdMdc("call-id")
}

此键可以传递给日志记录器配置以在日志中显示调用 ID。例如,logback.xml 文件可能如下所示:

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %X{call-id} %-5level %logger{36} - %msg%n</pattern>
    </encoder>
</appender>

您可以在此处找到完整示例:call-id