如何覆盖 logRequest/logResponse 以在 Ktor 客户端日志记录中记录自定义消息?
Posted
技术标签:
【中文标题】如何覆盖 logRequest/logResponse 以在 Ktor 客户端日志记录中记录自定义消息?【英文标题】:How can I override logRequest/logResponse to log custom message in Ktor client logging? 【发布时间】:2021-01-24 21:33:58 【问题描述】:目前,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))
任何帮助将不胜感激
【问题讨论】:
【参考方案1】:没有办法真正覆盖非开放类中的私有方法,但如果您只是希望日志以不同的方式工作,最好使用管道中同一阶段的自定义拦截器:
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
,您需要做一些额外的工作。
【讨论】:
以上是关于如何覆盖 logRequest/logResponse 以在 Ktor 客户端日志记录中记录自定义消息?的主要内容,如果未能解决你的问题,请参考以下文章