在 Ktor 服务器中跟踪请求
所需依赖项: io.ktor:ktor-server-call-id
代码示例: call-id
CallId 插件允许您使用唯一的请求 ID 或调用 ID 端到端地跟踪客户端请求。通常,在 Ktor 中使用调用 ID 的流程如下:
- 首先,您需要通过以下方式之一为特定请求获取一个调用 ID:
- 接下来,Ktor 使用预定义字典验证检索/生成的调用 ID。您也可以提供自己的条件来验证调用 ID。
- 最后,您可以将调用 ID 在特定请求头中发送给客户端,例如
X-Request-Id。
将 CallId 与 CallLogging 结合使用,有助于您通过将调用 ID 放入 MDC 上下文并配置日志记录器以显示每个请求的调用 ID 来排查调用问题。
在客户端,Ktor 提供了 CallId 插件来跟踪客户端请求。
添加依赖项
要使用 CallId,您需要在构建脚本中包含 ktor-server-call-id 构件:
安装 CallId
要将 安装 CallId 插件到应用程序, 请在指定的
install 函数。 以下代码片段展示了如何安装 CallId ... - ... 在
embeddedServer函数调用内部。 - ... 在显式定义的
module内部,它是Application类的一个扩展函数。
配置 CallId
检索调用 ID
CallId 提供了几种检索调用 ID 的方法:
要从指定请求头中检索调用 ID,请使用
retrieveFromHeader函数,例如:kotlininstall(CallId) { retrieveFromHeader(HttpHeaders.XRequestId) }您还可以使用
header函数在同一个请求头中检索并发送调用 ID。如果需要,您可以从
ApplicationCall中检索调用 ID:kotlininstall(CallId) { retrieve { call -> call.request.header(HttpHeaders.XRequestId) } }
请注意,所有检索到的调用 ID 都将使用默认字典进行验证。
生成调用 ID
如果传入请求不包含调用 ID,您可以使用 generate 函数生成它:
- 以下示例展示了如何从预定义字典中生成具有特定长度的调用 ID:kotlin
install(CallId) { generate(10, "abcde12345") } - 在以下示例中,
generate函数接受一个用于生成调用 ID 的代码块:kotlininstall(CallId) { val counter = atomic(0) generate { "generated-call-id-${counter.getAndIncrement()}" } }
验证调用 ID
所有检索/生成的调用 ID 都将使用默认字典进行验证,其内容如下:
CALL_ID_DEFAULT_DICTIONARY: String = "abcdefghijklmnopqrstuvwxyz0123456789+/=-"这意味着包含大写字母的调用 ID 将无法通过验证。如果需要,您可以通过使用 verify 函数来应用更宽松的规则:
install(CallId) {
verify { callId: String ->
callId.isNotEmpty()
}
}您可以在此处找到完整示例:call-id。
将调用 ID 发送给客户端
使用
header函数可以在同一个请求头中检索并发送调用 ID:kotlininstall(CallId) { header(HttpHeaders.XRequestId) }您可以在此处找到完整示例:call-id。
replyToHeader函数将在指定请求头中发送调用 ID:kotlininstall(CallId) { replyToHeader(HttpHeaders.XRequestId) }如果需要,您可以使用
ApplicationCall在响应中发送调用 ID:kotlinreply { call, callId -> call.response.header(HttpHeaders.XRequestId, callId) }
将调用 ID 放入 MDC
将 CallId 与 CallLogging 结合使用,有助于您通过将调用 ID 放入 MDC 上下文并配置日志记录器以显示每个请求的调用 ID 来排查调用问题。为此,请在 CallLogging 配置代码块内部调用 callIdMdc 函数,并指定要放入 MDC 上下文中的所需键:
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。
