Hi guys, I'm trying to create a simple logging Fea...
# ktor
l
Hi guys, I'm trying to create a simple logging Feature around client calls (using Apache as engine) I looked into JsonFeature and HttpPlainText as inspiration, and managed to log output requests bodies (if present) and input responses. But, logging the responses consumes the stream, and I have no clue about how to write again the raw content to the response, for the following features (such as Json serialization..) as the HttpResponse.content is a ByteReadChannel (so readonly..)
e
You could try to intercept replace response
ByteReadChannel
with new one from:
reader(...) { ... }
or
writer(...) { ... }
and perform piping and logging inside the block
JsonFeature
expects specific body content type.
l
Yes, that is what I used to do when in Java and dealing with CXF interceptors : logging consumed the stream, so I had to pipe it to another writer
But I don't know how to write it back
You could take a look at the reverse-proxy sample.
l
huhhh I might be dumb be which one would it be ?
j
inside other/reverse-proxy
l
Thanks !
I can't quite understand what needs to be done... In order to get my response marshalled from Json to Object, I need to do something like
Copy code
proceedWith(HttpResponseContainer(info, message))
right ?
But I can't figure out what the type of message should be in this case
e
Something like this:
Copy code
proceedWith(HttpResponseContainer(info, channel))
l
with channel being a WriteChannelContent ? because I just tried passing an anonymous WriteChannelContent with an overriden writeTo() like in the example
e
ByteReadChannel
l
but I still get No transformation found: class com.xxx.yyy.LoggingFeature$Feature$install$2$res$1 -> class com.xxx.yyy.MyModel
I can't make it work with the
ByteReadChannel
either : even without consuming the stream :
No transformation found: class kotlinx.coroutines.io.ByteBufferChannel -> class com.xxx.yyy.MyModel
Doing just:
Copy code
val byteReadChannel = response.content
                proceedWith(HttpResponseContainer(info, byteReadChannel))
e
Ok, let me check. I’ll try to make test interceptor for you :)
l
Ah ! You're so nice, maybe I just haven't found the good documentation page, but I found it a bit hard to understand how the custom features work (apart from the simple "adding a header" example)
e
It looks like there is a problem with intercepting content for now. Could you file an issue?
l
Hi @e5l, I sure could, but I'm not sure what to report... I am able to read the content, is the problem the fact that the proceedWith() fails ?
e
Nope. It looks like content intercept problem. You have to
proceedWith(HttpClientCall(typeInfo, response))
for now. And there is no obvious way to observe the data in the response channel.