CallId
The CallId 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 CallId
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.
Add dependencies
To use CallId
, you need to include the ktor-server-call-id
artifact in the build script:
Install CallId
To install the CallId
plugin to the application, pass it to the install
function in the specified module. The code snippets below show how to install CallId
...
... inside the
embeddedServer
function call.... inside the explicitly defined
module
, which is an extension function of theApplication
class.
Configure CallId
Retrieve a call ID
CallId
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.
Generate a call ID
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()}" } }
Verify a call ID
All retrieved/generated call IDs are verified using a default dictionary, which looks as follows:
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:
You can find the full example here: call-id.
Send a call ID to the client
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:install(CallId) { header(HttpHeaders.XRequestId) }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) }
Put a call ID into MDC
Using CallId
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:
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:
You can find the full example here: call-id.