https://kotlinlang.org logo
#ktor
Title
# ktor
m

mp

01/17/2022, 3:12 PM
hi there guys does ktor has the way (mode\interceptor arguments for configuration) how to join all logs related to request\response to one log record? or should I make it by myself as my own interceptor? not very convenient to log all(method, header, body) info separately in my case
a

Aleksei Tirman [JB]

01/18/2022, 7:53 AM
What do you mean by joining all logs related to a request/response to one log record?
r

Rescribet

01/18/2022, 10:44 AM
It is quite common to prefix all logs within a request with the
X-Request-Id
header, or generate one if it is not available Joining them into one line would require buffering all logs which doesn’t seem wise
m

mp

01/18/2022, 11:53 AM
@Aleksei Tirman [JB] e.g.
Copy code
log.debug("""
$method $url
$headers
$body
""")
@Rescribet you`re about something similar to trace_id id concept, aren’t you?! I’m about something much simpler 😃 In my case sending logs to some third party (elk sumologic) issue few problems • often footprint of messages much higher then actual messages • also simpler to consume info when all
meaningful
data in one place
a

Aleksei Tirman [JB]

01/18/2022, 1:03 PM
On a server or a client?
m

mp

01/19/2022, 10:52 AM
@Aleksei Tirman [JB] oh sorry - client. using ktor client for 3rd party services communications
a

Aleksei Tirman [JB]

01/26/2022, 11:12 AM
You can implement your own logger that will accumulate log lines and then put them into the log.
Copy code
suspend fun main(): Unit = coroutineScope {
    val client = HttpClient(Apache) {
        install(Logging) {
            level = LogLevel.ALL
            logger = OneLineLogger()
        }
    }

    client.get<String>("<https://httpbin.org/get>")
}

class OneLineLogger: Logger {
    private val lines = mutableListOf<String>()
    private val logger = Logger.DEFAULT

    override fun log(message: String) {
        lines.add(message)

        if (message.startsWith("BODY END")) {
            logger.log(lines.joinToString(separator = "\n"))
        }
    }
}
Unfortunately, this way two entries are logged for a request and response instead of one.
m

mp

02/03/2022, 8:07 PM
Copy code
logger = OneLineLogger()
tnx! very helpful
a

Alexander Weickmann

10/17/2022, 2:19 PM
I gather this solution depends on the LogLevel.ALL for request bodies to be logged, or otherwise nothing will be logged at all I am having a similar problem not for request body, but for multiple log lines for request and response It would be great if we could log a single line for a http request and it's response From monitoring perspective, I am just interested in the requests going out (method & url), and the status codes received from the response Having this on 2 lines means it is difficult to analyze the log for both automatic and manual processing 😞
m

mp

10/17/2022, 2:20 PM
@Alexander Weickmann In new version looks line it was fixed and request logs goes as single line
a

Alexander Weickmann

10/17/2022, 2:21 PM
really? thats good news
where to find details?
m

mp

10/17/2022, 2:21 PM
its not documented as far as I know just have realised it after update 😃 hope it will helps
a

Alexander Weickmann

10/17/2022, 2:22 PM
uh, so it just automatically changes the behavior under the hood without additional config required?
m

mp

10/17/2022, 2:24 PM
think so
a

Alexander Weickmann

10/17/2022, 2:28 PM
nup, just updated to the latest released versions. nothing changed
m

mp

10/17/2022, 2:30 PM
hm… sorry for confusing. I’m sure that I’ve remove OneLineLogger solution that was discussed above
a

Alexander Weickmann

10/17/2022, 2:30 PM
logs 3 lines INFO REQUEST ... METHOD: ... FROM: url totally horrible for monitoring purposes 😞
config i am using is this:
Copy code
install(Logging) {
            logger = Logger.DEFAULT
            level = <http://LogLevel.INFO|LogLevel.INFO>
        }
Copy code
implementation("io.ktor", "ktor-client-logging", "2.1.2")
found something that looks like very good work: https://github.com/zezutom/ktor-client-logging
m

mp

10/17/2022, 2:40 PM
looks interesting tnx
@Alexander Weickmann btw - only configuration of logging that I have is
Copy code
install(Logging) {
            level = LogLevel.ALL
}
and logs that I got comes as
Copy code
2022-10-24 18:59:46.218  INFO --- [             main @coroutine#5] i.k.c.HttpClient.log(14)                                     : REQUEST: <https://countrycode.org/api/countryCode/countryMenu>
METHOD: HttpMethod(value=GET)
COMMON HEADERS
-> Accept: application/json
-> Accept-Charset: UTF-8
CONTENT HEADERS
-> Content-Length: 0
BODY Content-Type: null
BODY START

BODY END
2022-10-24 18:59:47.828  INFO --- [-worker-4 @ktor-cio-context#24] i.k.c.HttpClient.log(14)                                     : RESPONSE: 200 
METHOD: HttpMethod(value=GET)
FROM: <https://countrycode.org/api/countryCode/countryMenu>
COMMON HEADERS
-> cache-control: public, max-age=2592000
-> content-type: application/json;charset=UTF-8
-> date: Mon, 24 Oct 2022 15:59:47 GMT
-> lc-cache: MISS
-> server: nginx/1.22.0
-> transfer-encoding: chunked
-> x-frame-options: SAMEORIGIN
-> x-upstream: lax-p14
BODY Content-Type: application/json; charset=UTF-8
BODY START

[
  {
    "code": "af",
    "name": "Afghanistan",
    "path": "afghanistan"
  },
ktor version 2.0.2 I don’t know how to explain this difference (one line logger as I’ve mentioned before - was removed) 🤯
one more btw 😃 😃 😃 did u try to configure truncation of single log message? (e.g. 500 symbols)
a

Alexander Weickmann

11/10/2022, 4:18 PM
noticed something else also the ktor-test framework does a proper logging in one line
Copy code
404 Not Found: GET - <urlPath>
so somehow different opinion what would be a good standard log between the devs of the main client and the test client
19 Views