diff --git a/libnavigation-base/src/main/java/com/mapbox/navigation/base/route/NavigationRoute.kt b/libnavigation-base/src/main/java/com/mapbox/navigation/base/route/NavigationRoute.kt index b0f2af9296b..69d0afd1ffe 100644 --- a/libnavigation-base/src/main/java/com/mapbox/navigation/base/route/NavigationRoute.kt +++ b/libnavigation-base/src/main/java/com/mapbox/navigation/base/route/NavigationRoute.kt @@ -184,10 +184,9 @@ class NavigationRoute internal constructor( } val deferredRouteOptionsParsing = async(ThreadController.DefaultDispatcher) { RouteOptions.fromUrl(URL(routeRequestUrl)).also { - logD( - "parsed request url to RouteOptions: ${it.toUrl("***")}", - LOG_CATEGORY - ) + logD(LOG_CATEGORY) { + "parsed request url to RouteOptions: ${it.toUrl("***")}" + } } } create( diff --git a/libnavigation-util/src/main/java/com/mapbox/common/NativeLoggerWrapper.kt b/libnavigation-util/src/main/java/com/mapbox/common/NativeLoggerWrapper.kt index 492b22d5d8d..125bbc0981c 100644 --- a/libnavigation-util/src/main/java/com/mapbox/common/NativeLoggerWrapper.kt +++ b/libnavigation-util/src/main/java/com/mapbox/common/NativeLoggerWrapper.kt @@ -20,4 +20,6 @@ internal object NativeLoggerWrapper { fun error(message: String, category: String?) { Log.error(message, category) } + + fun getLogLevel(category: String) = LogConfiguration.getLoggingLevel(category) } diff --git a/libnavigation-util/src/main/java/com/mapbox/navigation/utils/internal/LoggerFrontend.kt b/libnavigation-util/src/main/java/com/mapbox/navigation/utils/internal/LoggerFrontend.kt index 0b14d077621..133867ef4df 100644 --- a/libnavigation-util/src/main/java/com/mapbox/navigation/utils/internal/LoggerFrontend.kt +++ b/libnavigation-util/src/main/java/com/mapbox/navigation/utils/internal/LoggerFrontend.kt @@ -1,10 +1,12 @@ package com.mapbox.navigation.utils.internal +import com.mapbox.common.LoggingLevel import com.mapbox.common.NativeLoggerWrapper private const val NAV_SDK_CATEGORY = "nav-sdk" interface LoggerFrontend { + fun getLogLevel(): LoggingLevel? fun logV(msg: String, category: String? = null) fun logD(msg: String, category: String? = null) fun logI(msg: String, category: String? = null) @@ -13,6 +15,9 @@ interface LoggerFrontend { } internal class MapboxCommonLoggerFrontend : LoggerFrontend { + + override fun getLogLevel() = NativeLoggerWrapper.getLogLevel(NAV_SDK_CATEGORY) + override fun logV(msg: String, category: String?) { val message = createMessage(msg, category) // There's no com.mapbox.common.Log.verbose available - using Log.debug instead diff --git a/libnavigation-util/src/main/java/com/mapbox/navigation/utils/internal/LoggerProvider.kt b/libnavigation-util/src/main/java/com/mapbox/navigation/utils/internal/LoggerProvider.kt index 1b5e63d03ef..56532c648d9 100644 --- a/libnavigation-util/src/main/java/com/mapbox/navigation/utils/internal/LoggerProvider.kt +++ b/libnavigation-util/src/main/java/com/mapbox/navigation/utils/internal/LoggerProvider.kt @@ -2,6 +2,7 @@ package com.mapbox.navigation.utils.internal import androidx.annotation.VisibleForTesting import com.mapbox.base.common.logger.Logger +import com.mapbox.common.LoggingLevel /** * Singleton provider of [Logger]. @@ -39,6 +40,18 @@ fun logD(msg: String, category: String? = null) { LoggerProvider.frontend.logD(msg, category) } +/** + * @param category optional string to identify the source or category of the log message. + * @param lazyMsg is a lazy message to log. The lazy message isn't executed if current log level is less verbose than Debug. + * Noting that the category is appended to the log message to give extra context along with the `[nav-sdk]` parent category. + * As an example, this is how the logs would look like `D/Mapbox: [nav-sdk] [ConnectivityHandler] NetworkStatus=ReachableViaWiFi`. + */ +inline fun logD(category: String? = null, lazyMsg: () -> String) { + if (logLevel().atLeast(LoggingLevel.DEBUG)) { + logD(lazyMsg(), category) + } +} + /** * @param msg to log. * @param category optional string to identify the source or category of the log message. @@ -49,6 +62,18 @@ fun logI(msg: String, category: String? = null) { LoggerProvider.frontend.logI(msg, category) } +/** + * @param category optional string to identify the source or category of the log message. + * @param lazyMsg is a lazy message to log. The lazy message isn't executed if current log level is less verbose than Info. + * Noting that the category is appended to the log message to give extra context along with the `[nav-sdk]` parent category. + * As an example, this is how the logs would look like `I/Mapbox: [nav-sdk] [ConnectivityHandler] NetworkStatus=ReachableViaWiFi`. + */ +inline fun logI(category: String? = null, lazyMsg: () -> String) { + if (logLevel().atLeast(LoggingLevel.INFO)) { + logI(lazyMsg(), category) + } +} + /** * @param msg to log. * @param category optional string to identify the source or category of the log message. @@ -59,6 +84,18 @@ fun logW(msg: String, category: String? = null) { LoggerProvider.frontend.logW(msg, category) } +/** + * @param category optional string to identify the source or category of the log message. + * @param lazyMsg is a lazy message to log. The lazy message isn't executed if current log level is less verbose than Warning. + * Noting that the category is appended to the log message to give extra context along with the `[nav-sdk]` parent category. + * As an example, this is how the logs would look like `W/Mapbox: [nav-sdk] [ConnectivityHandler] NetworkStatus=ReachableViaWiFi`. + */ +inline fun logW(category: String? = null, lazyMsg: () -> String) { + if (logLevel().atLeast(LoggingLevel.WARNING)) { + logW(lazyMsg(), category) + } +} + /** * @param msg to log. * @param category optional string to identify the source or category of the log message. @@ -68,3 +105,21 @@ fun logW(msg: String, category: String? = null) { fun logE(msg: String, category: String? = null) { LoggerProvider.frontend.logE(msg, category) } + +/** + * @param category optional string to identify the source or category of the log message. + * @param lazyMsg is a lazy message to log. The lazy message isn't executed if current log level is less verbose than Error. + * Noting that the category is appended to the log message to give extra context along with the `[nav-sdk]` parent category. + * As an example, this is how the logs would look like `E/Mapbox: [nav-sdk] [ConnectivityHandler] NetworkStatus=ReachableViaWiFi`. + */ +inline fun logE(category: String? = null, lazyMsg: () -> String) { + if (logLevel().atLeast(LoggingLevel.ERROR)) { + logE(lazyMsg(), category) + } +} + +/** + * Should not be used directly. + * Added to support inline calls. Public inline functions can use only public API inside. + */ +fun logLevel() = LoggerProvider.frontend.getLogLevel() diff --git a/libnavigation-util/src/main/java/com/mapbox/navigation/utils/internal/LoggingLevelUtil.kt b/libnavigation-util/src/main/java/com/mapbox/navigation/utils/internal/LoggingLevelUtil.kt new file mode 100644 index 00000000000..baf5cbf3c3e --- /dev/null +++ b/libnavigation-util/src/main/java/com/mapbox/navigation/utils/internal/LoggingLevelUtil.kt @@ -0,0 +1,15 @@ +package com.mapbox.navigation.utils.internal + +import com.mapbox.common.LoggingLevel + +fun LoggingLevel?.atLeast(loggingLevel: LoggingLevel): Boolean { + return toPriority(this) >= toPriority(loggingLevel) +} + +private fun toPriority(loggingLevel: LoggingLevel?) = when (loggingLevel) { + null -> 0 + LoggingLevel.DEBUG -> 1 + LoggingLevel.INFO -> 2 + LoggingLevel.WARNING -> 3 + LoggingLevel.ERROR -> 4 +} diff --git a/libnavigation-util/src/test/java/com/mapbox/navigation/utils/internal/LoggingLevelUtilKtTest.kt b/libnavigation-util/src/test/java/com/mapbox/navigation/utils/internal/LoggingLevelUtilKtTest.kt new file mode 100644 index 00000000000..ab81b4c9d95 --- /dev/null +++ b/libnavigation-util/src/test/java/com/mapbox/navigation/utils/internal/LoggingLevelUtilKtTest.kt @@ -0,0 +1,135 @@ +package com.mapbox.navigation.utils.internal + +import com.mapbox.common.LoggingLevel +import org.junit.Assert.assertEquals +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.Parameterized + +@RunWith(Parameterized::class) +class LoggingLevelUtilKtTest(val parameter: LogLevelData) { + + companion object { + + @JvmStatic + @Parameterized.Parameters(name = "{0}") + fun parameters() = listOf( + LogLevelData( + what = null, + atLeast = LoggingLevel.ERROR, + expected = false + ), + LogLevelData( + what = null, + atLeast = LoggingLevel.WARNING, + expected = false + ), + LogLevelData( + what = null, + atLeast = LoggingLevel.INFO, + expected = false + ), + LogLevelData( + what = null, + atLeast = LoggingLevel.DEBUG, + expected = false + ), + + LogLevelData( + what = LoggingLevel.ERROR, + atLeast = LoggingLevel.ERROR, + expected = true + ), + LogLevelData( + what = LoggingLevel.ERROR, + atLeast = LoggingLevel.WARNING, + expected = true + ), + LogLevelData( + what = LoggingLevel.ERROR, + atLeast = LoggingLevel.INFO, + expected = true + ), + LogLevelData( + what = LoggingLevel.ERROR, + atLeast = LoggingLevel.DEBUG, + expected = true + ), + + LogLevelData( + what = LoggingLevel.WARNING, + atLeast = LoggingLevel.ERROR, + expected = false + ), + LogLevelData( + what = LoggingLevel.WARNING, + atLeast = LoggingLevel.WARNING, + expected = true + ), + LogLevelData( + what = LoggingLevel.WARNING, + atLeast = LoggingLevel.INFO, + expected = true + ), + LogLevelData( + what = LoggingLevel.WARNING, + atLeast = LoggingLevel.DEBUG, + expected = true + ), + + LogLevelData( + what = LoggingLevel.INFO, + atLeast = LoggingLevel.ERROR, + expected = false + ), + LogLevelData( + what = LoggingLevel.INFO, + atLeast = LoggingLevel.WARNING, + expected = false + ), + LogLevelData( + what = LoggingLevel.INFO, + atLeast = LoggingLevel.INFO, + expected = true + ), + LogLevelData( + what = LoggingLevel.INFO, + atLeast = LoggingLevel.DEBUG, + expected = true + ), + + LogLevelData( + what = LoggingLevel.DEBUG, + atLeast = LoggingLevel.ERROR, + expected = false + ), + LogLevelData( + what = LoggingLevel.DEBUG, + atLeast = LoggingLevel.WARNING, + expected = false + ), + LogLevelData( + what = LoggingLevel.DEBUG, + atLeast = LoggingLevel.INFO, + expected = false + ), + LogLevelData( + what = LoggingLevel.DEBUG, + atLeast = LoggingLevel.DEBUG, + expected = true + ), + ) + } + + @Test + fun `test atLeast`() { + val result = parameter.what.atLeast(parameter.atLeast) + assertEquals(parameter.expected, result) + } + + data class LogLevelData( + val what: LoggingLevel?, + val atLeast: LoggingLevel, + val expected: Boolean + ) +} diff --git a/libtesting-navigation-util/src/main/java/com/mapbox/navigation/testing/LoggingFrontendTestRule.kt b/libtesting-navigation-util/src/main/java/com/mapbox/navigation/testing/LoggingFrontendTestRule.kt index 87eeedc4ac2..f38860fc18a 100644 --- a/libtesting-navigation-util/src/main/java/com/mapbox/navigation/testing/LoggingFrontendTestRule.kt +++ b/libtesting-navigation-util/src/main/java/com/mapbox/navigation/testing/LoggingFrontendTestRule.kt @@ -1,6 +1,7 @@ package com.mapbox.navigation.testing import android.annotation.SuppressLint +import com.mapbox.common.LoggingLevel import com.mapbox.navigation.utils.internal.LoggerFrontend import com.mapbox.navigation.utils.internal.LoggerProvider import org.junit.rules.TestRule @@ -8,6 +9,9 @@ import org.junit.runner.Description import org.junit.runners.model.Statement private object NoLoggingFrontend : LoggerFrontend { + + override fun getLogLevel(): LoggingLevel = LoggingLevel.DEBUG + override fun logV(msg: String, category: String?) { }