我得到了这样的东西:
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
}
}
但是我需要检查请求和响应正文,有什么办法可以做到吗?在控制台/文件中?
您可以使用
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()
}
我也遇到过这个。我转而使用 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)
}
}
无论您使用哪个客户端或使用哪个框架,您都可以像这样实现自己的记录器:
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 接口的更多信息
可以使用
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
}
}
}
看来我们应该处理
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:我们可以为请求实现相同的方案。
对于 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
}
查看 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" }
这将在控制台上打印消息。