Zhiqiang Bian
10/20/2021, 11:06 AMlogging
feature. Does anyone know how to match an HTTP request to the corresponding response in the logs?
Assuming I send 10 http requests to the backend immediately. And then, I should receive 10 responses. But I cannot tell which response belongs to which request from the logs. Is it possible to assign a UUID to each request and its corresponding responses, then we can match them in the logs easily?
Or it must involve some changes on the backend too? For example, the frontend generates a UUID in the header, and backend use the same one in the response header?
-----------------------------------------------------------
I assume that in the responsePipeline receives each response in the same order of the requestPipeline. But I am not sure if it is correct. So my temporal solution is to modify the Logging
class (since it does not allow extends). I added two Int variables requestSequenceId
and responseSequenceId
. Every time the logRequest
and logResponse
get called, I just plus 1 for each sequenceId.
private var requestSequenceId: Int = 0
private var responseSequenceId: Int = 0
...
private suspend fun logRequest(request: HttpRequestBuilder): OutgoingContent? {
if (<http://level.info|level.info>) {
logger.log("REQUEST SEQUENCE ID: ${requestSequenceId++}")
...
private fun logResponse(response: HttpResponse) {
if (<http://level.info|level.info>) {
logger.log("RESPONSE SEQUENCE ID: ${responseSequenceId++}")
Ivan Pavlov
10/20/2021, 12:24 PMAleksei Tirman [JB]
10/20/2021, 12:25 PMLogging
feature identify request/response pairs but here is an example of how you can use attributes to achieve this:
suspend fun main(): Unit = coroutineScope {
val client = HttpClient(CIO)
val key = AttributeKey<String>("Request id")
client.sendPipeline.intercept(HttpSendPipeline.Monitoring) {
val uuid = UUID.randomUUID().toString()
context.attributes.put(key, uuid)
println("[$uuid] REQUEST: ${Url(context.url)}")
}
client.receivePipeline.intercept(HttpReceivePipeline.State) {
try {
val uuid = context.attributes[key]
println("[$uuid] RESPONSE: ${context.response.status}")
proceedWith(subject)
} catch (cause: Throwable) {
throw cause
}
}
(1..10).map {
async {
client.get<String>("<https://httpbin.org/get>")
}
}.awaitAll()
}
Zhiqiang Bian
10/20/2021, 1:05 PMsend1=>receive1=>send2 =>receive2
should be expected order. But if send1=>send2=>receive1=>receive2
, then will the UUID of receive1
to be overwritten by send2
?CallId
thing seems to be server-side only? I cannot find a similar one on the ktor client.Aleksei Tirman [JB]
10/20/2021, 1:26 PMZhiqiang Bian
10/20/2021, 1:32 PM