Required dependencies: io.ktor:%artifact_name%
The %plugin_name% plugin allows you to trace client requests end-to-end by using unique request IDs or call IDs. Typically, working with a call ID in Ktor might look as follows:
- First, you need to obtain a call ID for a specific request in one of the following ways:
- Next, Ktor verifies a retrieved/generated call ID using a predefined dictionary. You can also provide your own condition to verify a call ID.
- Finally, you can send a call ID to the client in a specific header, for example,
X-Request-Id
.
Using %plugin_name%
along with CallLogging helps you troubleshoot calls by putting a call ID in the MDC context and configuring a logger to show a call ID for each request.
%plugin_name%
provides several ways to retrieve a call ID:
-
To retrieve a call ID from the specified header, use the
retrieveFromHeader
function, for example:install(CallId) { retrieveFromHeader(HttpHeaders.XRequestId) }
You can also use the
header
function to retrieve and send a call ID in the same header. -
If required, you can retrieve a call ID from the
ApplicationCall
:install(CallId) { retrieve { call -> call.request.header(HttpHeaders.XRequestId) } }
Note that all retrieved call IDs are verified using a default dictionary.
If an incoming request doesn't include a call ID, you can generate it using the generate
function:
- The example below shows how to generate a call ID with a specific length from the predefined dictionary:
install(CallId) { generate(10, "abcde12345") }
- In the example below, the
generate
function accepts a block for generating a call ID:install(CallId) { val counter = atomic(0) generate { "generated-call-id-${counter.getAndIncrement()}" } }
All retrieved/generated call IDs are verified using a default dictionary, which looks as follows:
CALL_ID_DEFAULT_DICTIONARY: String = "abcdefghijklmnopqrstuvwxyz0123456789+/=-"
This means that call IDs containing capital letters won't pass verification. If required, you can apply less strict rules by using the verify
function:
{src="snippets/call-id/src/main/kotlin/com/example/Application.kt" lines="13,15-18"}
You can find the full example here: call-id.
After retrieving/generating a call ID, you can send it to the client:
-
The
header
function can be used to retrieve a call ID and send it in the same header:{src="snippets/call-id/src/main/kotlin/com/example/Application.kt" lines="13-14,18"}
You can find the full example here: call-id.
-
The
replyToHeader
function sends a call ID in the specified header:install(CallId) { replyToHeader(HttpHeaders.XRequestId) }
-
If required, you can use
ApplicationCall
to send a call ID in a response:reply { call, callId -> call.response.header(HttpHeaders.XRequestId, callId) }
Using %plugin_name%
along with CallLogging helps you troubleshoot calls by putting a call ID in the MDC context and configuring a logger to show a call ID for each request. To do this, call the callIdMdc
function inside the CallLogging
configuration block and specify the desired key to be put in the MDC context:
{src="snippets/call-id/src/main/kotlin/com/example/Application.kt" lines="19-21"}
This key can be passed to a logger configuration to show call IDs in the log. For instance, the logback.xml
file might look as follows:
{style="block" src="snippets/call-id/src/main/resources/logback.xml" lines="2-6"}
You can find the full example here: call-id.