Skip to content

Commit

Permalink
KTOR-1219 Make Android logger log to Logcat on Android if the SLF4J b… (
Browse files Browse the repository at this point in the history
#4009)

* KTOR-1219 Make Android logger log to Logcat on Android if the SLF4J binding isn't found
  • Loading branch information
Stexxe committed Apr 3, 2024
1 parent 0837f12 commit e789b01
Showing 1 changed file with 44 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package io.ktor.client.plugins.logging

import io.ktor.client.*
import org.slf4j.*
import org.slf4j.helpers.NOPLoggerFactory

public actual val Logger.Companion.DEFAULT: Logger
get() = object : Logger {
Expand All @@ -16,11 +17,50 @@ public actual val Logger.Companion.DEFAULT: Logger
}

/**
* Android [Logger]: breaks up long log messages that would be truncated by Android's max log
* length of 4068 characters
* Android [Logger]: Logs to the Logcat on Android if the SLF4J provider isn't found.
* Otherwise, uses the [Logger.Companion.DEFAULT].
* Breaks up long log messages that would be truncated by Android's max log
* length of 4068 characters.
*/
public val Logger.Companion.ANDROID: Logger
get() = MessageLengthLimitingLogger()
public val Logger.Companion.ANDROID: Logger by lazy { getAndroidLogger() }

private fun getAndroidLogger(): Logger {
val logger = Logger.DEFAULT

val logClass = try {
Class.forName("android.util.Log")
} catch (_: ClassNotFoundException) {
return MessageLengthLimitingLogger(delegate = logger)
}

if (LoggerFactory.getILoggerFactory() !is NOPLoggerFactory) {
return MessageLengthLimitingLogger(delegate = logger)
}

return MessageLengthLimitingLogger(delegate = LogcatLogger(logClass, logger))
}

private class LogcatLogger(logClass: Class<*>, private val fallback: Logger) : Logger {
private val tag = "Ktor Client"

private val method = try {
logClass.getDeclaredMethod("i", String::class.java, String::class.java)
} catch (_: Throwable) {
null
}
override fun log(message: String) {
if (method == null) {
fallback.log(message)
return
}

try {
method.invoke(null, tag, message)
} catch (_: Throwable) {
fallback.log(message)
}
}
}

/**
* A [Logger] that breaks up log messages into multiple logs no longer than [maxLength]
Expand Down

0 comments on commit e789b01

Please sign in to comment.