如何在 ktor http 客户端中记录请求?

问题描述 投票:0回答:7

我得到了这样的东西:

private val client = HttpClient {
    install(JsonFeature) {
        serializer = GsonSerializer()
    }
    install(ExpectSuccess)
}

并提出要求

  private fun HttpRequestBuilder.apiUrl(path: String, userId: String? = null) {
    header(HttpHeaders.CacheControl, "no-cache")
    url {
        takeFrom(endPoint)
        encodedPath = path
    }
}

但是我需要检查请求和响应正文,有什么办法可以做到吗?在控制台/文件中?

kotlin okhttp ktor
7个回答
16
投票

您可以使用

Logging
功能来实现此目的。

首先添加依赖:

implementation "io.ktor:ktor-client-logging-native:$ktor_version"

然后安装该功能:

private val client = HttpClient {
   install(Logging) {
      logger = Logger.DEFAULT
      level = LogLevel.ALL
   }
}

奖金:

如果您需要在整个应用程序中拥有多个

HttpClient
实例并且想要重用某些配置,那么您可以创建一个扩展函数并在其中添加通用逻辑。例如:

fun HttpClientConfig<*>.default() {
    install(Logging) {
        logger = Logger.DEFAULT
        level = LogLevel.ALL
    }

    // Add all the common configuration here.
}

然后像这样初始化你的

HttpClient

private val client = HttpClient {
   default()
}

11
投票

我也遇到过这个。我转而使用 Ktor OkHttp 客户端,因为我熟悉那里的日志机制。

更新您的

pom.xml
gradle.build
以包含该客户端(从 Ktor 站点复制/粘贴),并添加 OkHttp 日志拦截器(再次从该站点复制/粘贴)。当前版本是
3.12.0

现在配置客户端

val client = HttpClient(OkHttp) {
    engine {
        val loggingInterceptor = HttpLoggingInterceptor()
        loggingInterceptor.level = Level.BODY
        addInterceptor(loggingInterceptor)
    }
}

11
投票

无论您使用哪个客户端或使用哪个框架,您都可以像这样实现自己的记录器:

private val client = HttpClient {
    // Other configurations...
    install(Logging) {
        logger = CustomHttpLogger()
        level = LogLevel.BODY
    }
}

其中

CustomHttpLogger
是任何实现 ktor Logger 接口的类,如下所示:

import io.ktor.client.features.logging.Logger

class CustomHttpLogger(): Logger {
    override fun log(message: String) {
        Log.d("loggerTag", message) // Or whatever logging system you want here
    }
}

您可以在此处的文档或此处的源代码

中阅读有关 Logger 接口的更多信息

2
投票

可以使用

HttpSend
插件

创建自定义结构化日志

Ktor 2.x

client.plugin(HttpSend).intercept { request ->
    val call = execute(request)
    val response = call.response
    val durationMillis = response.responseTime.timestamp - response.requestTime.timestamp
    Log.i("NETWORK", "[${response.status.value}] ${request.url.build()} ($durationMillis ms)")
    call
}

Ktor 1.x:

client.config {
    install(HttpSend) {
        intercept { call, _ ->
            val request = call.request
            val response = call.response
            val durationMillis = response.responseTime.timestamp - response.requestTime.timestamp
            Log.i("NETWORK", "[${response.status.value}] ${request.url} ($durationMillis ms)")
            call
        }
    }
}

1
投票

看来我们应该处理

response
中的
HttpReceivePipeline
。我们可以克隆原始响应并将其用于记录目的:

scope.receivePipeline.intercept(HttpReceivePipeline.Before) { response ->
    val (loggingContent, responseContent) = response.content.split(scope)

    launch {
        val callForLog = DelegatedCall(loggingContent, context, scope, shouldClose = false)
        ....
    }
    ...
}

示例实现可以在这里找到:https://github.com/ktorio/ktor/blob/00369bf3e41e91d366279fce57b8f4c97f927fd4/ktor-client/ktor-client-core/src/io/ktor/client/features/observer/ResponseObserver。 kt 并将在下一个次要版本中作为客户端功能提供。

btw:我们可以为请求实现相同的方案。


0
投票

对于 Android 上的 Ktor 客户端登录,除了

implementation("io.ktor:ktor-client-logging:2.3.4")
依赖之外,您还需要添加 SLF4J
implementation("org.slf4j:slf4j-simple:2.0.9")

如果没有 SLF4J,您将不会在 Logcat 中看到任何 Ktor HTTP 日志(使用提供的

DEFAULT
ANDROID
Ktor 记录器)。只有这个警告:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

如果您使用 Timber(或类似),添加 SLF4J 后,您必须实现如下所示的自定义记录器:

install(Logging) {
    logger = object : Logger {
        override fun log(message: String) {
            if (BuildConfig.DEBUG) Timber.d(message) else Timber.i(message)
        }
    }
    level = if (BuildConfig.DEBUG) LogLevel.BODY else LogLevel.INFO
}

-6
投票

查看 Kotlin Logging,https://github.com/MicroUtils/kotlin-logging 它被许多开源框架使用并负责所有漂亮的打印。

您可以像这样简单地使用它:

 private val logger = KotlinLogging.logger {  }
 logger.info { "MYLOGGER INFO" }
 logger.warn { "MYLOGGER WARNING" }
 logger.error { "MYLOGGER ERROR" }

这将在控制台上打印消息。

© www.soinside.com 2019 - 2024. All rights reserved.