Hi all, I am trying to develop a client plugin to ...
# ktor
a
Hi all, I am trying to develop a client plugin to log request bodies and response bodies. I am currently using the transformRequestBody and transformResponseBody functions to get access to the bodies. This is not exactly optimal, but when I try to extract the body from onRequest and onResponse functions, I end up with DoubleReceive exception. Is there a better way?
Copy code
createClientPlugin("SensibleClientLogging", ::SensibleClientLoggingConfig) {
    val config = pluginConfig

    if (config.requestConfig.logBody) {
        transformRequestBody { request, content, type ->
            request.attributes.put(traceIdKey, UUID.randomUUID().toString())
            if (type?.type == String::class) {
                val jsonBody = content as String
                logRequest(config, request, jsonBody)
                null
            } else {
                logRequest(config, request)
                null
            }
        }
    } else {
        onRequest { request, _ ->
            request.attributes.put(traceIdKey, UUID.randomUUID().toString())
            logRequest(config, request)
        }
    }

    if (config.responseConfig.logBodyOnError) {
        transformResponseBody { response, content, type ->
            if (type.type == String::class) {
                val body = content.readUTF8Line()
                logResponse(config, response, body.takeIf { !response.status.isSuccess() })
                body
            } else {
                content
            }
        }
    } else {
        onResponse { response ->
            logResponse(config, response)
        }
    }
}
👀 1
c
Why are you making your own plugin instead of using Logging?
a
because the standard logging plugin logs everything on separate lines, which makes it very hard to analyze
check out this one as well: https://github.com/zezutom/ktor-client-logging i am basically doing the same thing, just with some tweaks and for ktor 2.x
a
Do you have the problem with your current implementation or when a request and response are logged in the
onRequest
and
onResponse
?
a
When I try to process the content parameter passed to onRequest and onResponse. Then I run into the problem of DoubleReceive. The current implementation posted above works, but it only works if the requested type is a string. So when you call .body<String>(). Otherwise with any other type, it will just log the method and url, but does not try to extract the body, because I have no idea how to do that in a generic way
I've found a way 🙂 I'll publish it as a library on Github and will share the link then