From 18bb176208b6ee8f6793510dfa3a8b9849722851 Mon Sep 17 00:00:00 2001 From: Raman Lebiadzinski Date: Tue, 14 Jan 2020 12:46:33 +0300 Subject: [PATCH] Add common Logger module implementation --- .circleci/config.yml | 4 +- Makefile | 10 +- annotations-processor/gradle.properties | 1 + annotations/gradle.properties | 1 + common/gradle.properties | 1 + .../com/mapbox/base/common/logger/Logger.kt | 59 ++++ .../base/common/logger/model/Message.kt | 8 + .../mapbox/base/common/logger/model/Tag.kt | 9 + gradle/artifact-settings.gradle | 2 +- gradle/bintray-publish.gradle | 2 +- liblogger/.gitignore | 1 + liblogger/build.gradle.kts | 39 +++ liblogger/gradle.properties | 5 + liblogger/src/main/AndroidManifest.xml | 1 + .../java/com/mapbox/common/logger/LogEntry.kt | 15 + .../com/mapbox/common/logger/LogPriority.kt | 49 +++ .../mapbox/common/logger/LoggerObserver.kt | 17 + .../com/mapbox/common/logger/MapboxLogger.kt | 294 ++++++++++++++++++ .../common/logger/annotations/LogLevel.kt | 16 + .../mapbox/common/logger/MapboxLoggerTest.kt | 151 +++++++++ settings.gradle.kts | 2 +- 21 files changed, 679 insertions(+), 8 deletions(-) create mode 100644 common/src/main/java/com/mapbox/base/common/logger/Logger.kt create mode 100644 common/src/main/java/com/mapbox/base/common/logger/model/Message.kt create mode 100644 common/src/main/java/com/mapbox/base/common/logger/model/Tag.kt create mode 100644 liblogger/.gitignore create mode 100644 liblogger/build.gradle.kts create mode 100644 liblogger/gradle.properties create mode 100644 liblogger/src/main/AndroidManifest.xml create mode 100644 liblogger/src/main/java/com/mapbox/common/logger/LogEntry.kt create mode 100644 liblogger/src/main/java/com/mapbox/common/logger/LogPriority.kt create mode 100644 liblogger/src/main/java/com/mapbox/common/logger/LoggerObserver.kt create mode 100644 liblogger/src/main/java/com/mapbox/common/logger/MapboxLogger.kt create mode 100644 liblogger/src/main/java/com/mapbox/common/logger/annotations/LogLevel.kt create mode 100644 liblogger/src/test/java/com/mapbox/common/logger/MapboxLoggerTest.kt diff --git a/.circleci/config.yml b/.circleci/config.yml index 22c2c9f..8881b36 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -4,7 +4,7 @@ commands: steps: - restore_cache: keys: - - v1-dependencies-{{ checksum "build.gradle.kts" }}-{{ checksum "annotations/build.gradle.kts" }}-{{ checksum "annotations-processor/build.gradle.kts" }}-{{ checksum "common/build.gradle.kts" }} + - v1-dependencies-{{ checksum "build.gradle.kts" }}-{{ checksum "annotations/build.gradle.kts" }}-{{ checksum "annotations-processor/build.gradle.kts" }}-{{ checksum "common/build.gradle.kts" }}-{{ checksum "liblogger/build.gradle.kts" }} - v1-dependencies- - run: name: Download dependencies @@ -12,7 +12,7 @@ commands: - save_cache: paths: - ~/.gradle - key: v1-dependencies-{{ checksum "build.gradle.kts" }}-{{ checksum "annotations/build.gradle.kts" }}-{{ checksum "annotations-processor/build.gradle.kts" }}-{{ checksum "common/build.gradle.kts" }} + key: v1-dependencies-{{ checksum "build.gradle.kts" }}-{{ checksum "annotations/build.gradle.kts" }}-{{ checksum "annotations-processor/build.gradle.kts" }}-{{ checksum "common/build.gradle.kts" }}-{{ checksum "liblogger/build.gradle.kts" }} run-unit-tests: steps: diff --git a/Makefile b/Makefile index 940fb31..716faf9 100644 --- a/Makefile +++ b/Makefile @@ -8,26 +8,30 @@ check: buildDebug: ./gradlew annotations:assemble && \ ./gradlew annotations-processor:assemble && \ - ./gradlew common:assembleDebug + ./gradlew common:assembleDebug && \ + ./gradlew liblogger:assembleDebug .PHONY: buildRelease buildRelease: ./gradlew annotations:assemble && \ ./gradlew annotations-processor:assemble && \ - ./gradlew common:assembleRelease + ./gradlew common:assembleRelease && \ + ./gradlew liblogger:assembleRelease .PHONY: bintrayPublish bintrayPublish: ./gradlew :annotations:bintrayUpload ; \ ./gradlew :annotations-processor:bintrayUpload ; \ ./gradlew :common:bintrayUpload ; \ + ./gradlew :liblogger:bintrayUpload ; \ .PHONY: artifactoryPublish artifactoryPublish: ./gradlew :annotations:artifactoryPublish ; \ ./gradlew :annotations-processor:artifactoryPublish ; \ ./gradlew :common:artifactoryPublish ; \ + ./gradlew :liblogger:artifactoryPublish ; \ .PHONY: runUnitTests runUnitTests: - ./gradlew examples:test \ No newline at end of file + ./gradlew test \ No newline at end of file diff --git a/annotations-processor/gradle.properties b/annotations-processor/gradle.properties index 88b07ae..b7f3857 100644 --- a/annotations-processor/gradle.properties +++ b/annotations-processor/gradle.properties @@ -1,4 +1,5 @@ IS_ANDROID_PROJECT=false POM_ARTIFACT_ID=annotations-processor +POM_ARTIFACT_GROUP_ID=com.mapbox.base POM_ARTIFACT_TITLE=Mapbox Annotations Processor POM_DESCRIPTION=Artifact that provides Mapbox module and plugin generators \ No newline at end of file diff --git a/annotations/gradle.properties b/annotations/gradle.properties index 08879e2..7d6b885 100644 --- a/annotations/gradle.properties +++ b/annotations/gradle.properties @@ -1,4 +1,5 @@ IS_ANDROID_PROJECT=false POM_ARTIFACT_ID=annotations +POM_ARTIFACT_GROUP_ID=com.mapbox.base POM_ARTIFACT_TITLE=Mapbox Annotations POM_DESCRIPTION=Artifact that provides Mapbox module and plugin annotations \ No newline at end of file diff --git a/common/gradle.properties b/common/gradle.properties index 6a25434..030215c 100644 --- a/common/gradle.properties +++ b/common/gradle.properties @@ -1,4 +1,5 @@ IS_ANDROID_PROJECT=true POM_ARTIFACT_ID=common +POM_ARTIFACT_GROUP_ID=com.mapbox.base POM_ARTIFACT_TITLE=Mapbox Common POM_DESCRIPTION=Artifact that provides Mapbox module and plugin contracts \ No newline at end of file diff --git a/common/src/main/java/com/mapbox/base/common/logger/Logger.kt b/common/src/main/java/com/mapbox/base/common/logger/Logger.kt new file mode 100644 index 0000000..3fe9590 --- /dev/null +++ b/common/src/main/java/com/mapbox/base/common/logger/Logger.kt @@ -0,0 +1,59 @@ +package com.mapbox.base.common.logger + +import com.mapbox.base.common.logger.model.Message +import com.mapbox.base.common.logger.model.Tag + +/** + * Logger definition + */ +interface Logger { + /** + * Send a verbose log message and log the exception. + * + * @param tag is [Tag] used to identify the source of a log message. It usually identifies + * the class or activity where the log call occurs. + * @param msg is [Message] you would like logged. + * @param tr An exception to log + */ + fun v(tag: Tag? = null, msg: Message, tr: Throwable? = null) + + /** + * Send a debug log message and log the exception. + * + * @param tag is [Tag] used to identify the source of a log message. It usually identifies + * the class or activity where the log call occurs. + * @param msg is [Message] you would like logged. + * @param tr An exception to log + */ + fun d(tag: Tag? = null, msg: Message, tr: Throwable? = null) + + /** + * Send an info log message and log the exception. + * + * @param tag is [Tag] used to identify the source of a log message. It usually identifies + * the class or activity where the log call occurs. + * @param msg is [Message] you would like logged. + * @param tr An exception to log + */ + fun i(tag: Tag? = null, msg: Message, tr: Throwable? = null) + + /** + * Send a warning log message and log the exception. + * + * @param tag is [Tag] used to identify the source of a log message. It usually identifies + * the class or activity where the log call occurs. + * @param msg is [Message] you would like logged. + * @param tr An exception to log + */ + fun w(tag: Tag? = null, msg: Message, tr: Throwable? = null) + + /** + * Send an error log message and log the exception. + * + * @param tag is [Tag] used to identify the source of a log message. It usually identifies + * the class or activity where the log call occurs. + * @param msg is [Message] you would like logged. + * @param tr An exception to log + */ + fun e(tag: Tag? = null, msg: Message, tr: Throwable? = null) +} \ No newline at end of file diff --git a/common/src/main/java/com/mapbox/base/common/logger/model/Message.kt b/common/src/main/java/com/mapbox/base/common/logger/model/Message.kt new file mode 100644 index 0000000..21509f2 --- /dev/null +++ b/common/src/main/java/com/mapbox/base/common/logger/model/Message.kt @@ -0,0 +1,8 @@ +package com.mapbox.base.common.logger.model + +/** + * Wrapper class for loggers message. + * + * @param message The message you would like logged. + */ +data class Message(val message: String) \ No newline at end of file diff --git a/common/src/main/java/com/mapbox/base/common/logger/model/Tag.kt b/common/src/main/java/com/mapbox/base/common/logger/model/Tag.kt new file mode 100644 index 0000000..441bd62 --- /dev/null +++ b/common/src/main/java/com/mapbox/base/common/logger/model/Tag.kt @@ -0,0 +1,9 @@ +package com.mapbox.base.common.logger.model + +/** + * Wrapper class for loggers tag. + * + * @param tag used to identify the source of a log message. It usually identifies + * the class or activity where the log call occurs. + */ +data class Tag(val tag: String) \ No newline at end of file diff --git a/gradle/artifact-settings.gradle b/gradle/artifact-settings.gradle index 9ecde3b..5a94839 100644 --- a/gradle/artifact-settings.gradle +++ b/gradle/artifact-settings.gradle @@ -1,5 +1,5 @@ ext { - mapboxArtifactGroupId = 'com.mapbox.base' + mapboxArtifactGroupId = project.property('POM_ARTIFACT_GROUP_ID') mapboxArtifactId = project.property('POM_ARTIFACT_ID') mapboxArtifactTitle = project.property('POM_ARTIFACT_TITLE') mapboxArtifactDescription = project.property('POM_DESCRIPTION') diff --git a/gradle/bintray-publish.gradle b/gradle/bintray-publish.gradle index b690332..31b4e62 100644 --- a/gradle/bintray-publish.gradle +++ b/gradle/bintray-publish.gradle @@ -55,7 +55,7 @@ bintray { publications('MapboxBasePublication') pkg { repo = project.ext.mapboxBintrayRepoName - name = project.ext.mapboxArtifactId + name = group + ':' + project.ext.mapboxArtifactId userOrg = project.ext.mapboxBintrayUserOrg licenses = [project.ext.mapboxArtifactLicenseName] vcsUrl = project.ext.mapboxArtifactVcsUrl diff --git a/liblogger/.gitignore b/liblogger/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/liblogger/.gitignore @@ -0,0 +1 @@ +/build diff --git a/liblogger/build.gradle.kts b/liblogger/build.gradle.kts new file mode 100644 index 0000000..daa9c54 --- /dev/null +++ b/liblogger/build.gradle.kts @@ -0,0 +1,39 @@ +plugins { + id("com.android.library") + kotlin("android") + kotlin("kapt") + id("com.jaredsburrows.license") + id("org.jetbrains.dokka-android") +} + +android { + compileSdkVersion(AndroidVersions.compileSdkVersion) + + defaultConfig { + minSdkVersion(AndroidVersions.minSdkVersion) + targetSdkVersion(AndroidVersions.targetSdkVersion) + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } +} + +dependencies { + compileOnly(project(":annotations")) + kapt(project(":annotations-processor")) + implementation(project(":common")) + implementation(Dependencies.kotlin) + + /** + * Required for @Keep annotation by the annotation-processor and the resulting generated code + */ + implementation(Dependencies.annotations) + + testImplementation(Dependencies.junit) + testImplementation(Dependencies.mockk) +} + +project.apply { + from("$rootDir/gradle/ktlint.gradle") + from("$rootDir/gradle/lint.gradle") + from("$rootDir/gradle/android-artifacts.gradle") + from("$rootDir/gradle/bintray-publish.gradle") +} \ No newline at end of file diff --git a/liblogger/gradle.properties b/liblogger/gradle.properties new file mode 100644 index 0000000..c22fe5d --- /dev/null +++ b/liblogger/gradle.properties @@ -0,0 +1,5 @@ +IS_ANDROID_PROJECT=true +POM_ARTIFACT_ID=logger +POM_ARTIFACT_GROUP_ID=com.mapbox.common +POM_ARTIFACT_TITLE=Mapbox Logger +POM_DESCRIPTION=Artifact that provides Mapbox Logger module implementation \ No newline at end of file diff --git a/liblogger/src/main/AndroidManifest.xml b/liblogger/src/main/AndroidManifest.xml new file mode 100644 index 0000000..dc15cd5 --- /dev/null +++ b/liblogger/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + diff --git a/liblogger/src/main/java/com/mapbox/common/logger/LogEntry.kt b/liblogger/src/main/java/com/mapbox/common/logger/LogEntry.kt new file mode 100644 index 0000000..7557066 --- /dev/null +++ b/liblogger/src/main/java/com/mapbox/common/logger/LogEntry.kt @@ -0,0 +1,15 @@ +package com.mapbox.common.logger + +/** + * Model of Log entry. + * + * @property tag The tag you would like your message will marked. + * @property message The message you would like logged. + * @property throwable The throwable you would like to log. + * @constructor Creates an [LogEntry] + */ +data class LogEntry( + val tag: String?, + val message: String, + val throwable: Throwable? +) \ No newline at end of file diff --git a/liblogger/src/main/java/com/mapbox/common/logger/LogPriority.kt b/liblogger/src/main/java/com/mapbox/common/logger/LogPriority.kt new file mode 100644 index 0000000..8df4b34 --- /dev/null +++ b/liblogger/src/main/java/com/mapbox/common/logger/LogPriority.kt @@ -0,0 +1,49 @@ +@file:JvmName("LogPriority") + +package com.mapbox.common.logger + +import android.util.Log + +/** + * Priority constant for the println method; use Logger.v + * + * This log priority will print all logs. + */ +const val VERBOSE = Log.VERBOSE + +/** + * Priority constant for the println method; use Logger.d. + * + * This log priority will print all logs except verbose. + */ +const val DEBUG = Log.DEBUG + +/** + * Priority constant for the println method; use Logger.i. + * + * This log priority will print all logs except verbose and debug. + * + */ +const val INFO = Log.INFO + +/** + * Priority constant for the println method; use Logger.w. + * + * This log priority will print only warn and error logs. + * + */ +const val WARN = Log.WARN + +/** + * Priority constant for the println method; use Logger.e. + * + * This log priority will print only error logs. + */ +const val ERROR = Log.ERROR + +/** + * Priority constant for the println method. + * + * This log priority won't print any logs. + */ +const val NONE = 99 \ No newline at end of file diff --git a/liblogger/src/main/java/com/mapbox/common/logger/LoggerObserver.kt b/liblogger/src/main/java/com/mapbox/common/logger/LoggerObserver.kt new file mode 100644 index 0000000..a60e2f8 --- /dev/null +++ b/liblogger/src/main/java/com/mapbox/common/logger/LoggerObserver.kt @@ -0,0 +1,17 @@ +package com.mapbox.common.logger + +import com.mapbox.common.logger.annotations.LogLevel + +/** + * Interface for observe logs we want to catch + */ +interface LoggerObserver { + + /** + * Calls when [MapboxLogger] was log any [LogEntry]. + * + * @param level is [LogLevel] used to identify the level of logged [LogEntry] + * @param entry is logged [LogEntry]. + */ + fun log(@LogLevel level: Int, entry: LogEntry) +} \ No newline at end of file diff --git a/liblogger/src/main/java/com/mapbox/common/logger/MapboxLogger.kt b/liblogger/src/main/java/com/mapbox/common/logger/MapboxLogger.kt new file mode 100644 index 0000000..db193f6 --- /dev/null +++ b/liblogger/src/main/java/com/mapbox/common/logger/MapboxLogger.kt @@ -0,0 +1,294 @@ +package com.mapbox.common.logger + +import android.util.Log +import com.mapbox.annotation.module.MapboxModule +import com.mapbox.annotation.module.MapboxModuleType +import com.mapbox.base.common.logger.Logger +import com.mapbox.base.common.logger.model.Message +import com.mapbox.base.common.logger.model.Tag +import com.mapbox.common.logger.annotations.LogLevel +import java.util.concurrent.atomic.AtomicReference + +/** + * Mapbox implementation of [Logger] interface to log some messages with possibility to observe them + * via [LoggerObserver]. + */ +@MapboxModule(MapboxModuleType.CommonLogger) +object MapboxLogger : Logger { + + private const val DEFAULT_TAG = "MapboxLogger" + + /** + * [LogLevel] you want to log + */ + @LogLevel + @Volatile + var logLevel: Int = VERBOSE + + /** + * [LoggerObserver] for observe any log events + */ + private val observer: AtomicReference = AtomicReference() + + /** + * Set [LoggerObserver] to [MapboxLogger] to observe any log events + * + * @param observer is [LoggerObserver] you set to [MapboxLogger] + */ + fun setObserver(observer: LoggerObserver) { + MapboxLogger.observer.set(observer) + } + + /** + * Set [LoggerObserver] to [MapboxLogger] to observe any log events + * + * @param observer is [LoggerObserver] you set to [MapboxLogger] + */ + fun removeObserver() { + observer.set(null) + } + + /** + * Send a verbose log message. + * + * @param msg is [Message] you would like logged. + */ + fun v(msg: Message) { + v(null, msg, null) + } + + /** + * Send a verbose log message and log the exception. + * + * @param msg is [Message] you would like logged. + * @param tr An exception to log + */ + fun v(msg: Message, tr: Throwable) { + v(null, msg, tr) + } + + /** + * Send a tagged verbose log message + * + * @param tag is [Tag] used to identify the source of a log message. It usually identifies + * the class or activity where the log call occurs. + * @param msg is [Message] you would like logged. + */ + fun v(tag: Tag, msg: Message) { + v(tag, msg, null) + } + + /** + * Send a tagged verbose log message and log the exception. + * + * @param tag is [Tag] used to identify the source of a log message. It usually identifies + * the class or activity where the log call occurs. + * @param msg is [Message] you would like logged. + * @param tr An exception to log + */ + override fun v(tag: Tag?, msg: Message, tr: Throwable?) { + log(VERBOSE, tag?.tag, msg.message, tr) { + Log.v(tag?.tag ?: DEFAULT_TAG, msg.message, tr) + } + } + + /** + * Send a debug log message. + * + * @param msg is [Message] you would like logged. + */ + fun d(msg: Message) { + d(null, msg, null) + } + + /** + * Send a debug log message and log the exception. + * + * @param msg is [Message] you would like logged. + * @param tr An exception to log + */ + fun d(msg: Message, tr: Throwable) { + d(null, msg, tr) + } + + /** + * Send a tagged debug log message. + * + * @param tag is [Tag] used to identify the source of a log message. It usually identifies + * the class or activity where the log call occurs. + * @param msg is [Message] you would like logged. + */ + fun d(tag: Tag, msg: Message) { + d(tag, msg, null) + } + + /** + * Send a tagged debug log message and log the exception. + * + * @param tag is [Tag] used to identify the source of a log message. It usually identifies + * the class or activity where the log call occurs. + * @param msg is [Message] you would like logged. + * @param tr An exception to log + */ + override fun d(tag: Tag?, msg: Message, tr: Throwable?) { + log(DEBUG, tag?.tag, msg.message, tr) { + Log.d(tag?.tag ?: DEFAULT_TAG, msg.message, tr) + } + } + + /** + * Send a info log message. + * + * @param msg is [Message] you would like logged. + */ + fun i(msg: Message) { + i(null, msg, null) + } + + /** + * Send a info log message and log the exception. + * + * @param msg is [Message] you would like logged. + * @param tr An exception to log + */ + fun i(msg: Message, tr: Throwable) { + i(null, msg, tr) + } + + /** + * Send a tagged info log message. + * + * @param tag is [Tag] used to identify the source of a log message. It usually identifies + * the class or activity where the log call occurs. + * @param msg is [Message] you would like logged. + */ + fun i(tag: Tag, msg: Message) { + i(tag, msg, null) + } + + /** + * Send a tagged info log message and log the exception. + * + * @param tag is [Tag] used to identify the source of a log message. It usually identifies + * the class or activity where the log call occurs. + * @param msg is [Message] you would like logged. + * @param tr An exception to log + */ + override fun i(tag: Tag?, msg: Message, tr: Throwable?) { + log(INFO, tag?.tag, msg.message, tr) { + Log.i(tag?.tag ?: DEFAULT_TAG, msg.message, tr) + } + } + + /** + * Send a warning log message. + * + * @param msg is [Message] you would like logged. + */ + fun w(msg: Message) { + w(null, msg, null) + } + + /** + * Send a warning log message and log the exception. + * + * @param msg is [Message] you would like logged. + * @param tr An exception to log + */ + fun w(msg: Message, tr: Throwable) { + w(null, msg, tr) + } + + /** + * Send a tagged warning log message. + * + * @param tag is [Tag] used to identify the source of a log message. It usually identifies + * the class or activity where the log call occurs. + * @param msg is [Message] you would like logged. + */ + fun w(tag: Tag, msg: Message) { + w(tag, msg, null) + } + + /** + * Send a tagged warning log message and log the exception. + * + * @param tag is [Tag] used to identify the source of a log message. It usually identifies + * the class or activity where the log call occurs. + * @param msg is [Message] you would like logged. + * @param tr An exception to log + */ + override fun w(tag: Tag?, msg: Message, tr: Throwable?) { + log(WARN, tag?.tag, msg.message, tr) { + Log.w(tag?.tag ?: DEFAULT_TAG, msg.message, tr) + } + } + + /** + * Send a error log message. + * + * @param msg is [Message] you would like logged. + */ + fun e(msg: Message) { + e(null, msg, null) + } + + /** + * Send a error log message and log the exception. + * + * @param msg is [Message] you would like logged. + * @param tr An exception to log + */ + fun e(msg: Message, tr: Throwable) { + e(null, msg, tr) + } + + /** + * Send a tagged error log message. + * + * @param tag is [Tag] used to identify the source of a log message. It usually identifies + * the class or activity where the log call occurs. + * @param msg is [Message] you would like logged. + */ + fun e(tag: Tag, msg: Message) { + e(tag, msg, null) + } + + /** + * Send a tagged error log message and log the exception. + * + * @param tag is [Tag] used to identify the source of a log message. It usually identifies + * the class or activity where the log call occurs. + * @param msg is [Message] you would like logged. + * @param tr An exception to log + */ + override fun e(tag: Tag?, msg: Message, tr: Throwable?) { + log(ERROR, tag?.tag, msg.message, tr) { + Log.e(tag?.tag ?: DEFAULT_TAG, msg.message, tr) + } + } + + /** + * Checks if [requiredLogLevel] enough for log, and if yes, set tag, log message and throwable and + * notice [observer] about log event + * + * @param requiredLogLevel is [LogLevel] use to define level of logged event + * @param tag is [Tag] used to identify the source of a log message. It usually identifies + * the class or activity where the log call occurs. + * @param msg is [Message] you would like logged. + * @param tr An exception to log + * @param logBlock is block of directly logging + */ + private fun log( + @LogLevel requiredLogLevel: Int, + tag: String?, + msg: String, + tr: Throwable?, + logBlock: () -> Unit + ) { + if (logLevel <= requiredLogLevel) { + logBlock() + observer.get()?.log(requiredLogLevel, LogEntry(tag, msg, tr)) + } + } +} \ No newline at end of file diff --git a/liblogger/src/main/java/com/mapbox/common/logger/annotations/LogLevel.kt b/liblogger/src/main/java/com/mapbox/common/logger/annotations/LogLevel.kt new file mode 100644 index 0000000..8800f92 --- /dev/null +++ b/liblogger/src/main/java/com/mapbox/common/logger/annotations/LogLevel.kt @@ -0,0 +1,16 @@ +package com.mapbox.common.logger.annotations + +import androidx.annotation.IntDef +import com.mapbox.common.logger.DEBUG +import com.mapbox.common.logger.ERROR +import com.mapbox.common.logger.INFO +import com.mapbox.common.logger.NONE +import com.mapbox.common.logger.VERBOSE +import com.mapbox.common.logger.WARN + +/** + * Log level indicates which logs are allowed to be emitted by the Mapbox Maps SDK for Android. + */ +@IntDef(VERBOSE, DEBUG, INFO, WARN, ERROR, NONE) +@Retention(AnnotationRetention.SOURCE) +internal annotation class LogLevel \ No newline at end of file diff --git a/liblogger/src/test/java/com/mapbox/common/logger/MapboxLoggerTest.kt b/liblogger/src/test/java/com/mapbox/common/logger/MapboxLoggerTest.kt new file mode 100644 index 0000000..0902f5a --- /dev/null +++ b/liblogger/src/test/java/com/mapbox/common/logger/MapboxLoggerTest.kt @@ -0,0 +1,151 @@ +package com.mapbox.common.logger + +import android.util.Log +import com.mapbox.base.common.logger.model.Message +import com.mapbox.base.common.logger.model.Tag +import io.mockk.* +import org.junit.Before +import org.junit.Test + +class MapboxLoggerTest { + + @Before + fun setUp() { + mockkStatic(Log::class) + every { Log.v(any(), any(), any()) } returns 0 + every { Log.d(any(), any(), any()) } returns 0 + every { Log.i(any(), any(), any()) } returns 0 + every { Log.w(any(), any(), any()) } returns 0 + every { Log.e(any(), any(), any()) } returns 0 + } + + @Test + fun verboseTestSuccessful() { + val throwable = mockk() + val loggerObserver = mockk(relaxed = true) + MapboxLogger.setObserver(loggerObserver) + MapboxLogger.logLevel = VERBOSE + + MapboxLogger.v(Tag("TAG"), Message("some message"), throwable) + + verify { Log.v("TAG", "some message", throwable) } + verify { loggerObserver.log(VERBOSE, LogEntry("TAG", "some message", throwable)) } + } + + @Test + fun verboseTestIncorrectLogLevel() { + val throwable = mockk() + val loggerObserver = mockk(relaxed = true) + MapboxLogger.setObserver(loggerObserver) + MapboxLogger.logLevel = DEBUG + + MapboxLogger.v(Tag("TAG"), Message("some message"), throwable) + + verify(exactly = 0) { Log.v(any(), any(), any()) } + verify(exactly = 0) { loggerObserver.log(any(), any()) } + } + + @Test + fun debugTestSuccessful() { + val throwable = mockk() + val loggerObserver = mockk(relaxed = true) + MapboxLogger.setObserver(loggerObserver) + MapboxLogger.logLevel = DEBUG + + MapboxLogger.d(Tag("TAG"), Message("some message"), throwable) + + verify { Log.d("TAG", "some message", throwable) } + verify { loggerObserver.log(DEBUG, LogEntry("TAG", "some message", throwable)) } + } + + @Test + fun debugTestIncorrectLogLevel() { + val throwable = mockk() + val loggerObserver = mockk(relaxed = true) + MapboxLogger.setObserver(loggerObserver) + MapboxLogger.logLevel = INFO + + MapboxLogger.d(Tag("TAG"), Message("some message"), throwable) + + verify(exactly = 0) { Log.d(any(), any(), any()) } + verify(exactly = 0) { loggerObserver.log(any(), any()) } + } + + @Test + fun infoTestSuccessful() { + val throwable = mockk() + val loggerObserver = mockk(relaxed = true) + MapboxLogger.setObserver(loggerObserver) + MapboxLogger.logLevel = INFO + + MapboxLogger.i(Tag("TAG"), Message("some message"), throwable) + + verify { Log.i("TAG", "some message", throwable) } + verify { loggerObserver.log(INFO, LogEntry("TAG", "some message", throwable)) } + } + + @Test + fun infoTestIncorrectLogLevel() { + val throwable = mockk() + val loggerObserver = mockk(relaxed = true) + MapboxLogger.setObserver(loggerObserver) + MapboxLogger.logLevel = WARN + + MapboxLogger.i(Tag("TAG"), Message("some message"), throwable) + + verify(exactly = 0) { Log.i(any(), any(), any()) } + verify(exactly = 0) { loggerObserver.log(any(), any()) } + } + + @Test + fun warningTestSuccessful() { + val throwable = mockk() + val loggerObserver = mockk(relaxed = true) + MapboxLogger.setObserver(loggerObserver) + MapboxLogger.logLevel = WARN + + MapboxLogger.w(Tag("TAG"), Message("some message"), throwable) + + verify { Log.w("TAG", "some message", throwable) } + verify { loggerObserver.log(WARN, LogEntry("TAG", "some message", throwable)) } + } + + @Test + fun warningTestIncorrectLogLevel() { + val throwable = mockk() + val loggerObserver = mockk(relaxed = true) + MapboxLogger.setObserver(loggerObserver) + MapboxLogger.logLevel = ERROR + + MapboxLogger.w(Tag("TAG"), Message("some message"), throwable) + + verify(exactly = 0) { Log.w(any(), any(), any()) } + verify(exactly = 0) { loggerObserver.log(any(), any()) } + } + + @Test + fun errorTestSuccessful() { + val throwable = mockk() + val loggerObserver = mockk(relaxed = true) + MapboxLogger.setObserver(loggerObserver) + MapboxLogger.logLevel = ERROR + + MapboxLogger.e(Tag("TAG"), Message("some message"), throwable) + + verify { Log.e("TAG", "some message", throwable) } + verify { loggerObserver.log(ERROR, LogEntry("TAG", "some message", throwable)) } + } + + @Test + fun errorTestIncorrectLogLevel() { + val throwable = mockk() + val loggerObserver = mockk(relaxed = true) + MapboxLogger.setObserver(loggerObserver) + MapboxLogger.logLevel = NONE + + MapboxLogger.e(Tag("TAG"), Message("some message"), throwable) + + verify(exactly = 0) { Log.e(any(), any(), any()) } + verify(exactly = 0) { loggerObserver.log(any(), any()) } + } +} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index feb62b3..d450803 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,2 +1,2 @@ -include(":common", ":annotations", ":annotations-processor", ":examples") +include(":common", ":annotations", ":annotations-processor", ":liblogger", ":examples") rootProject.name = "Mapbox Base Android" \ No newline at end of file