问题描述
当前,ktor client logging实现如下所示,并且可以按预期运行,但不符合我的期望。
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))
}
任何帮助都是有益的
解决方法
无法在非开放类中实际覆盖私有方法,但是如果您只是希望日志记录以不同的方式工作,那么最好使用管道中同一阶段的自定义拦截器:
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
,您将需要做一些额外的工作。