1
0
mirror of https://github.com/square/okhttp.git synced 2025-07-31 05:04:26 +03:00

Add a configurable AndroidLogging API (#7844)

This commit is contained in:
Yuri Schimke
2024-04-01 12:07:32 +01:00
committed by GitHub
parent 1ede680245
commit 3bed816c91
7 changed files with 158 additions and 0 deletions

View File

@ -10,3 +10,10 @@ public final class okhttp3/android/AndroidAsyncDns$Companion {
public final fun getIPv6 ()Lokhttp3/android/AndroidAsyncDns;
}
public final class okhttp3/android/AndroidLoggingKt {
public static final fun androidLogging (Lokhttp3/logging/HttpLoggingInterceptor$Companion;ILjava/lang/String;)Lokhttp3/logging/HttpLoggingInterceptor;
public static final fun androidLogging (Lokhttp3/logging/LoggingEventListener$Companion;ILjava/lang/String;)Lokhttp3/logging/LoggingEventListener$Factory;
public static synthetic fun androidLogging$default (Lokhttp3/logging/HttpLoggingInterceptor$Companion;ILjava/lang/String;ILjava/lang/Object;)Lokhttp3/logging/HttpLoggingInterceptor;
public static synthetic fun androidLogging$default (Lokhttp3/logging/LoggingEventListener$Companion;ILjava/lang/String;ILjava/lang/Object;)Lokhttp3/logging/LoggingEventListener$Factory;
}

View File

@ -48,6 +48,7 @@ android {
dependencies {
api(libs.squareup.okio)
api(projects.okhttp)
api(projects.loggingInterceptor)
compileOnly(libs.androidx.annotation)
compileOnly(libs.findbugs.jsr305)
debugImplementation(libs.androidx.annotation)

View File

@ -0,0 +1,36 @@
/*
* Copyright (C) 2022 Block, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okhttp3.android
import android.util.Log
import okhttp3.logging.HttpLoggingInterceptor
import okhttp3.logging.LoggingEventListener
/**
* An OkHttp [LoggingEventListener], with android Log as the target.
*/
fun LoggingEventListener.Companion.androidLogging(
priority: Int = Log.INFO,
tag: String = "OkHttp",
) = LoggingEventListener.Factory { Log.println(priority, tag, it) }
/**
* An OkHttp [HttpLoggingInterceptor], with android Log as the target.
*/
fun HttpLoggingInterceptor.Companion.androidLogging(
priority: Int = Log.INFO,
tag: String = "OkHttp",
) = HttpLoggingInterceptor { Log.println(priority, tag, it) }

View File

@ -0,0 +1,102 @@
/*
* Copyright (c) 2022 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package okhttp3.android
import android.util.Log
import assertk.assertThat
import assertk.assertions.containsExactly
import assertk.assertions.containsOnly
import assertk.assertions.isNull
import java.net.UnknownHostException
import okhttp3.ConnectionSpec
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.logging.HttpLoggingInterceptor
import okhttp3.logging.LoggingEventListener
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.shadows.ShadowLog
@RunWith(RobolectricTestRunner::class)
class AndroidLoggingTest {
val clientBuilder =
OkHttpClient.Builder()
.connectionSpecs(listOf(ConnectionSpec.CLEARTEXT))
.dns {
throw UnknownHostException("shortcircuit")
}
val request = Request("http://google.com/robots.txt".toHttpUrl())
@Test
fun testHttpLoggingInterceptor() {
val interceptor =
HttpLoggingInterceptor.androidLogging(tag = "testHttpLoggingInterceptor").apply {
level = HttpLoggingInterceptor.Level.BASIC
}
val client = clientBuilder.addInterceptor(interceptor).build()
try {
client.newCall(request).execute()
} catch (uhe: UnknownHostException) {
// expected
}
val logs = ShadowLog.getLogsForTag("testHttpLoggingInterceptor")
assertThat(logs.map { it.type }).containsOnly(Log.INFO)
assertThat(logs.map { it.msg }).containsExactly(
"--> GET http://google.com/robots.txt",
"<-- HTTP FAILED: java.net.UnknownHostException: shortcircuit",
)
// We should consider if these logs should retain Exceptions
assertThat(logs.last().throwable).isNull()
}
@Test
fun testLoggingEventListener() {
val client =
clientBuilder.eventListenerFactory(LoggingEventListener.androidLogging(tag = "testLoggingEventListener")).build()
try {
client.newCall(request).execute()
} catch (uhe: UnknownHostException) {
// expected
}
val logs = ShadowLog.getLogsForTag("testLoggingEventListener")
assertThat(logs.map { it.type }).containsOnly(Log.INFO)
assertThat(
logs.map {
it.msg.replace(
"\\[\\d+ ms] ".toRegex(),
"",
)
},
).containsExactly(
"callStart: Request{method=GET, url=http://google.com/robots.txt}",
"proxySelectStart: http://google.com/",
"proxySelectEnd: [DIRECT]",
"dnsStart: google.com",
"callFailed: java.net.UnknownHostException: shortcircuit",
)
// We should consider if these logs should retain Exceptions
assertThat(logs.last().throwable).isNull()
}
}

View File

@ -1,4 +1,5 @@
public final class okhttp3/logging/HttpLoggingInterceptor : okhttp3/Interceptor {
public static final field Companion Lokhttp3/logging/HttpLoggingInterceptor$Companion;
public final fun -deprecated_level ()Lokhttp3/logging/HttpLoggingInterceptor$Level;
public fun <init> ()V
public fun <init> (Lokhttp3/logging/HttpLoggingInterceptor$Logger;)V
@ -10,6 +11,9 @@ public final class okhttp3/logging/HttpLoggingInterceptor : okhttp3/Interceptor
public final fun setLevel (Lokhttp3/logging/HttpLoggingInterceptor$Level;)Lokhttp3/logging/HttpLoggingInterceptor;
}
public final class okhttp3/logging/HttpLoggingInterceptor$Companion {
}
public final class okhttp3/logging/HttpLoggingInterceptor$Level : java/lang/Enum {
public static final field BASIC Lokhttp3/logging/HttpLoggingInterceptor$Level;
public static final field BODY Lokhttp3/logging/HttpLoggingInterceptor$Level;
@ -30,6 +34,7 @@ public final class okhttp3/logging/HttpLoggingInterceptor$Logger$Companion {
}
public final class okhttp3/logging/LoggingEventListener : okhttp3/EventListener {
public static final field Companion Lokhttp3/logging/LoggingEventListener$Companion;
public synthetic fun <init> (Lokhttp3/logging/HttpLoggingInterceptor$Logger;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun cacheConditionalHit (Lokhttp3/Call;Lokhttp3/Response;)V
public fun cacheHit (Lokhttp3/Call;Lokhttp3/Response;)V
@ -62,6 +67,9 @@ public final class okhttp3/logging/LoggingEventListener : okhttp3/EventListener
public fun secureConnectStart (Lokhttp3/Call;)V
}
public final class okhttp3/logging/LoggingEventListener$Companion {
}
public class okhttp3/logging/LoggingEventListener$Factory : okhttp3/EventListener$Factory {
public fun <init> ()V
public fun <init> (Lokhttp3/logging/HttpLoggingInterceptor$Logger;)V

View File

@ -330,4 +330,6 @@ class HttpLoggingInterceptor
val contentType = response.body.contentType()
return contentType != null && contentType.type == "text" && contentType.subtype == "event-stream"
}
companion object
}

View File

@ -240,4 +240,6 @@ class LoggingEventListener private constructor(
) : EventListener.Factory {
override fun create(call: Call): EventListener = LoggingEventListener(logger)
}
companion object
}