Skip to content

Commit

Permalink
fix: update how debug logging works
Browse files Browse the repository at this point in the history
  • Loading branch information
nicklasl committed Jun 26, 2024
1 parent 81f68fb commit 70efcfe
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 41 deletions.
15 changes: 7 additions & 8 deletions Confidence/src/main/java/com/spotify/confidence/Confidence.kt
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,7 @@ class Confidence internal constructor(

private suspend fun resolve(flags: List<String>): Result<FlagResolution> {
debugLogger?.let {
for (flag in flags) {
debugLogger.logFlags("ResolveFlag", flag)
}
debugLogger.logFlags("Resolve", flags)
}
return flagResolver.resolve(flags, getContext())
}
Expand All @@ -82,7 +80,7 @@ class Confidence internal constructor(

fun apply(flagName: String, resolveToken: String) {
flagApplier.apply(flagName, resolveToken)
debugLogger?.logFlags("ApplyFlag", flagName)
debugLogger?.logFlags("Apply", listOf(flagName))
}

fun <T> getValue(key: String, default: T) = getFlag(key, default).value
Expand Down Expand Up @@ -172,7 +170,8 @@ class Confidence internal constructor(
}

private val networkExceptionHandler by lazy {
CoroutineExceptionHandler { _, _ ->
CoroutineExceptionHandler { _, throwable ->
debugLogger?.logMessage("Network error", isWarning = true, throwable = throwable)
// network failed, provider is ready but with default/cache values
}
}
Expand Down Expand Up @@ -251,12 +250,12 @@ object ConfidenceFactory {
initialContext: Map<String, ConfidenceValue> = mapOf(),
region: ConfidenceRegion = ConfidenceRegion.GLOBAL,
dispatcher: CoroutineDispatcher = Dispatchers.IO,
debugLoggerLevel: DebugLoggerLevel = DebugLoggerLevel.NONE
loggingLevel: LoggingLevel = LoggingLevel.WARN
): Confidence {
val debugLogger: DebugLogger? = if (debugLoggerLevel == DebugLoggerLevel.NONE) {
val debugLogger: DebugLogger? = if (loggingLevel == LoggingLevel.NONE) {
null
} else {
DebugLoggerImpl(debugLoggerLevel)
DebugLoggerImpl(loggingLevel)
}
val engine = EventSenderEngineImpl.instance(
context,
Expand Down
56 changes: 35 additions & 21 deletions Confidence/src/main/java/com/spotify/confidence/DebugLogger.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,59 @@ package com.spotify.confidence

import android.util.Log

private const val TAG = "Confidence"

internal interface DebugLogger {
fun logEvent(tag: String, event: EngineEvent, details: String)
fun logMessage(tag: String, message: String, isWarning: Boolean = false)
fun logFlags(tag: String, flag: String)
fun logEvent(action: String, event: EngineEvent)
fun logMessage(message: String, isWarning: Boolean = false, throwable: Throwable? = null)
fun logFlags(action: String, flags: List<String>)
fun logContext(context: Map<String, ConfidenceValue>)
}

internal class DebugLoggerImpl(private val level: DebugLoggerLevel) : DebugLogger {
override fun logEvent(tag: String, event: EngineEvent, details: String) {
log(tag, details + event.toString())
internal class DebugLoggerImpl(private val filterLevel: LoggingLevel) : DebugLogger {

override fun logEvent(action: String, event: EngineEvent) {
debug("[$action] $event")
}

override fun logMessage(tag: String, message: String, isWarning: Boolean) {
if (!isWarning) {
log(tag, message)
override fun logMessage(message: String, isWarning: Boolean, throwable: Throwable?) {
if (isWarning) {
warn(message)
} else if (throwable != null) {
error(message, throwable)
} else {
Log.w(tag, message)
debug(message)
}
}

override fun logFlags(tag: String, flag: String) {
log(tag, flag)
override fun logFlags(action: String, flags: List<String>) {
verbose("[$action] ${flags.joinToString(", ")}")
}

override fun logContext(context: Map<String, ConfidenceValue>) {
log("CurrentContext", context.toString())
verbose(context.toString())
}

private fun log(tag: String, message: String) {
when (level) {
DebugLoggerLevel.VERBOSE -> Log.v(tag, message)
DebugLoggerLevel.DEBUG -> Log.d(tag, message)
DebugLoggerLevel.NONE -> {
// do nothing
private fun verbose(message: String) = log(LoggingLevel.VERBOSE, message)
private fun debug(message: String) = log(LoggingLevel.DEBUG, message)
private fun warn(message: String) = log(LoggingLevel.WARN, message)
private fun error(message: String, throwable: Throwable) = log(LoggingLevel.ERROR, "$message: ${throwable.message}")

private fun log(messageLevel: LoggingLevel, message: String) {
if (filterLevel <= messageLevel) {
when (messageLevel) {
LoggingLevel.VERBOSE -> Log.v(TAG, message)
LoggingLevel.DEBUG -> Log.d(TAG, message)
LoggingLevel.WARN -> Log.w(TAG, message)
LoggingLevel.ERROR -> Log.e(TAG, message)
LoggingLevel.NONE -> {
// do nothing
}
}
}
}
}

enum class DebugLoggerLevel {
VERBOSE, DEBUG, NONE
enum class LoggingLevel {
NONE, VERBOSE, DEBUG, WARN, ERROR
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ import kotlinx.coroutines.launch
import okhttp3.OkHttpClient
import java.io.File

private const val className = "ConfidenceEventSender"

internal interface EventSenderEngine {
fun onLowMemoryChannel(): Channel<List<File>>
fun emit(eventName: String, data: ConfidenceFieldsType, context: Map<String, ConfidenceValue>)
Expand Down Expand Up @@ -53,7 +51,7 @@ internal class EventSenderEngineImpl(
if (event.eventDefinition != manualFlushEvent.eventDefinition) {
// skip storing manual flush event
eventStorage.writeEvent(event)
debugLogger?.logEvent(tag = className, event = event, details = "Event written to disk ")
debugLogger?.logEvent(action = "DiskWrite ", event = event)
}
for (policy in flushPolicies) {
policy.hit(event)
Expand All @@ -63,7 +61,6 @@ internal class EventSenderEngineImpl(
for (policy in flushPolicies) {
policy.reset()
debugLogger?.logMessage(
tag = className,
message = "Flush policy $policy triggered to flush. Flushing."
)
}
Expand Down Expand Up @@ -94,7 +91,7 @@ internal class EventSenderEngineImpl(
)
runCatching {
val shouldCleanup = uploader.upload(batch)
debugLogger?.logMessage(tag = className, message = "Uploading batched events")
debugLogger?.logMessage(message = "Uploading events")
if (shouldCleanup) {
readyFile.delete()
}
Expand All @@ -105,7 +102,7 @@ internal class EventSenderEngineImpl(
}

override fun onLowMemoryChannel(): Channel<List<File>> {
debugLogger?.logMessage(tag = className, message = "Low memory", isWarning = true)
debugLogger?.logMessage(message = "LowMemory", isWarning = true)
return eventStorage.onLowMemoryChannel()
}

Expand All @@ -122,21 +119,21 @@ internal class EventSenderEngineImpl(
payload = payload
)
writeReqChannel.send(event)
debugLogger?.logEvent(tag = className, event = event, details = "Emitting event ")
debugLogger?.logEvent(action = "EmitEvent ", event = event)
}
}

override fun flush() {
coroutineScope.launch {
writeReqChannel.send(manualFlushEvent)
debugLogger?.logEvent(tag = className, event = manualFlushEvent, details = "Event flushed ")
debugLogger?.logEvent(action = "Flush ", event = manualFlushEvent)
}
}

override fun stop() {
coroutineScope.cancel()
eventStorage.stop()
debugLogger?.logMessage(tag = className, message = "$className closed ")
debugLogger?.logMessage(message = "EventSenderEngine closed ")
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ internal open class DebugLoggerMock : DebugLogger {
var messagesLogged = 0
var flagsLogged = 0
var contextLogs = 0
override fun logEvent(tag: String, event: EngineEvent, details: String) {
override fun logEvent(action: String, event: EngineEvent) {
eventsLogged++
}

override fun logMessage(tag: String, message: String, isWarning: Boolean) {
override fun logMessage(message: String, isWarning: Boolean, throwable: Throwable?) {
messagesLogged++
}

override fun logFlags(tag: String, flag: String) {
override fun logFlags(action: String, flags: List<String>) {
flagsLogged++
}

Expand Down

0 comments on commit 70efcfe

Please sign in to comment.