Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle new session in log file appender #191

Merged
merged 3 commits into from
Dec 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package gq.kirmanak.mealient.data.baseurl.impl

import androidx.core.net.toUri
import gq.kirmanak.mealient.architecture.configuration.AppDispatchers
import gq.kirmanak.mealient.data.baseurl.ServerInfoStorage
import gq.kirmanak.mealient.data.storage.PreferencesStorage
import gq.kirmanak.mealient.logging.LogRedactor
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
Expand All @@ -14,11 +14,13 @@ import javax.inject.Singleton

@Singleton
class BaseUrlLogRedactor @Inject constructor(
private val serverInfoStorageProvider: Provider<ServerInfoStorage>,
private val preferencesStorageProvider: Provider<PreferencesStorage>,
private val dispatchers: AppDispatchers,
) : LogRedactor {

private val hostState = MutableStateFlow<String?>(null)
private val preferencesStorage: PreferencesStorage
get() = preferencesStorageProvider.get()

init {
setInitialBaseUrl()
Expand All @@ -27,10 +29,9 @@ class BaseUrlLogRedactor @Inject constructor(
private fun setInitialBaseUrl() {
val scope = CoroutineScope(dispatchers.default + SupervisorJob())
scope.launch {
val serverInfoStorage = serverInfoStorageProvider.get()
hostState.compareAndSet(
expect = null,
update = serverInfoStorage.getBaseURL()?.extractHost(),
update = preferencesStorage.getValue(preferencesStorage.baseUrlKey)
)
}
}
Expand All @@ -41,8 +42,12 @@ class BaseUrlLogRedactor @Inject constructor(


override fun redact(message: String): String {
val host = hostState.value ?: return message
return message.replace(host, "<host>")
val host = hostState.value
return when {
host == null && message.contains(preferencesStorage.baseUrlKey.name) -> "<redacted>"
host == null -> message
else -> message.replace(host, "<host>")
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package gq.kirmanak.mealient.logging

import android.app.Activity
import android.app.Application
import android.app.Application.ActivityLifecycleCallbacks
import android.os.Bundle
import gq.kirmanak.mealient.architecture.configuration.AppDispatchers
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
Expand All @@ -13,7 +16,6 @@ import java.io.FileWriter
import java.io.IOException
import java.io.Writer
import java.time.Instant
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import javax.inject.Inject
import javax.inject.Singleton
Expand Down Expand Up @@ -42,11 +44,24 @@ internal class FileAppender @Inject constructor(

private val coroutineScope = CoroutineScope(dispatchers.io + SupervisorJob())

private val dateTimeFormatter =
DateTimeFormatter.ISO_LOCAL_DATE_TIME.withZone(ZoneId.systemDefault())

init {
startLogWriter()
startLifecycleObserver()
}

private fun startLifecycleObserver() {
val observer = object : DefaultActivityLifecycleCallbacks() {
override fun onActivityPaused(activity: Activity) {
super.onActivityPaused(activity)
try {
fileWriter?.flush()
} catch (e: IOException) {
// Ignore
}
}
}

application.registerActivityLifecycleCallbacks(observer)
}

private fun createFileWriter(): Writer? {
Expand All @@ -70,8 +85,10 @@ internal class FileAppender @Inject constructor(
}

coroutineScope.launch {
fileWriter.appendLine("Session started at ${Instant.now().formatted()}")

for (logInfo in logChannel) {
val time = dateTimeFormatter.format(logInfo.logTime)
val time = logInfo.logTime.formatted()
val level = logInfo.logLevel.name.first()
logInfo.message.lines().forEach {
try {
Expand All @@ -84,6 +101,8 @@ internal class FileAppender @Inject constructor(
}
}

private fun Instant.formatted(): String = DateTimeFormatter.ISO_INSTANT.format(this)

override fun isLoggable(logLevel: LogLevel): Boolean = true

override fun isLoggable(logLevel: LogLevel, tag: String): Boolean = true
Expand All @@ -106,4 +125,22 @@ internal class FileAppender @Inject constructor(
// Ignore
}
}
}

private open class DefaultActivityLifecycleCallbacks : ActivityLifecycleCallbacks {

override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) = Unit

override fun onActivityStarted(activity: Activity) = Unit

override fun onActivityResumed(activity: Activity) = Unit

override fun onActivityPaused(activity: Activity) = Unit

override fun onActivityStopped(activity: Activity) = Unit

override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) = Unit

override fun onActivityDestroyed(activity: Activity) = Unit

}