0

目前,ktor 客户端日志记录实现如下,它按预期工作,但不是我想要的。


public class Logging(
    public val logger: Logger,
    public var level: LogLevel,
    public var filters: List<(HttpRequestBuilder) -> Boolean> = emptyList()
)
....
   private suspend fun logRequest(request: HttpRequestBuilder): OutgoingContent? {
        if (level.info) {
            logger.log("REQUEST: ${Url(request.url)}")
            logger.log("METHOD: ${request.method}")
        }

        val content = request.body as OutgoingContent

        if (level.headers) {
            logger.log("COMMON HEADERS")
            logHeaders(request.headers.entries())

            logger.log("CONTENT HEADERS")
            logHeaders(content.headers.entries())
        }

        return if (level.body) {
            logRequestBody(content)
        } else null
    }

上面在查看日志时会产生一场噩梦,因为它正在记录每一行。由于我是 Kotlin 和 Ktor 的初学者,我很想知道如何改变这种行为。由于在 Kotlin 中,除非特别打开,否则所有类都是最终类,我不知道如何修改logRequest函数行为。我理想地想要实现的是下面的例子。

....
private suspend fun logRequest(request: HttpRequestBuilder): OutgoingContent? {

        ...
        if (level.body) {
            val content = request.body as OutgoingContent
        return logger.log(value("url", Url(request.url)),
                          value("method", request.method),
                          value("body", content))


    }

任何帮助将不胜感激

4

1 回答 1

0

无法在非开放类中实际覆盖私有方法,但如果您只是希望日志以不同的方式工作,最好使用管道中同一阶段的自定义拦截器:

       val client = HttpClient(CIO) {
            install("RequestLogging") {
                sendPipeline.intercept(HttpSendPipeline.Monitoring) {
                    logger.info(
                        "Request: {} {} {} {}",
                        context.method,
                        Url(context.url),
                        context.headers.entries(),
                        context.body
                    )
                }
            }
        }
        runBlocking {
            client.get<String>("https://google.com")
        }

这将产生您想要的日志记录。当然,要正确记录POST,您需要做一些额外的工作。

于 2020-10-21T12:29:00.137 回答