Skip to content

Commit

Permalink
* Compose Viewer shows file sizes now
Browse files Browse the repository at this point in the history
* Lumberjack Setups do use Companion.create functions instead of overloaded constructors
* added a BaseFileLoggerSetup
* added a new file size based setup to the lumberjack file logger setups
  • Loading branch information
MFlisar committed Apr 4, 2024
1 parent 9e36aef commit 49ee875
Show file tree
Hide file tree
Showing 13 changed files with 237 additions and 120 deletions.
2 changes: 1 addition & 1 deletion demo/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ dependencies {
implementation(platform(compose.bom))
implementation(compose.material3)
implementation(compose.activity)
implementation(compose.material.extendedicons)
implementation(compose.icons.material.extendedicons)
implementation(compose.drawablepainter)

// ------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import timber.log.Timber
object DemoLogging {

lateinit var FILE_LOGGING_SETUP: IFileLoggingSetup
var FILE_LOGGING_SETUP2: IFileLoggingSetup? = null

fun init(context: Context) {

Expand All @@ -39,11 +40,16 @@ object DemoLogging {
Timber.plant(ConsoleTree())
Timber.plant(FileLoggingTree(setup))
} else {
val setup = FileLoggerSetup.Daily(context).also {
val setup = FileLoggerSetup.Daily.create(context, fileBaseName = "log_daily").also {
FILE_LOGGING_SETUP = it
}
L.plant(ConsoleLogger())
L.plant(FileLogger(setup))

val setup2 = FileLoggerSetup.FileSize.create(context, maxFileSizeInBytes = 1000 * 10 /* 10 kB */, fileBaseName = "log_size", filesToKeep = 2).also {
FILE_LOGGING_SETUP2 = it
}
L.plant(FileLogger(setup2))
}

// EXAMPLE on how you could use lumberjack inside a library with the minimal dependency on the core module
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import com.michaelflisar.lumberjack.demo.DemoLogging
import com.michaelflisar.lumberjack.extensions.composeviewer.LumberjackDialog
import com.michaelflisar.lumberjack.extensions.feedback.sendFeedback
import com.michaelflisar.lumberjack.extensions.viewer.showLog
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

class MainActivity : DemoBaseActivity() {
Expand All @@ -50,9 +51,8 @@ class MainActivity : DemoBaseActivity() {
var mail by rememberSaveable {
mutableStateOf("")
}
val showComposeLogView = rememberSaveable {
mutableStateOf(false)
}
val showComposeLogView = rememberSaveable { mutableStateOf(false) }
val showComposeLogView2 = rememberSaveable { mutableStateOf(false) }

Column(
modifier = modifier
Expand Down Expand Up @@ -85,6 +85,15 @@ class MainActivity : DemoBaseActivity() {
}) {
Text("Log Viewer (Compose)")
}
if (DemoLogging.FILE_LOGGING_SETUP2 != null) {
OutlinedButton(
modifier = Modifier.fillMaxWidth(),
onClick = {
showComposeLogView2.value = true
}) {
Text("Log Viewer (Compose) - Setup2")
}
}
}
DemoCollapsibleRegion(
title = "Actions",
Expand Down Expand Up @@ -131,6 +140,17 @@ class MainActivity : DemoBaseActivity() {
}) {
Text("Log something")
}
OutlinedButton(
modifier = Modifier.fillMaxWidth(),
onClick = {
scope.launch(Dispatchers.IO) {
(1..100).forEach {
L.d { "Logging a lot $it..." }
}
}
}) {
Text("Log a lot")
}
}
}

Expand All @@ -141,5 +161,15 @@ class MainActivity : DemoBaseActivity() {
darkTheme = theme.isDark(),
//mail = "[email protected]"
)

if (DemoLogging.FILE_LOGGING_SETUP2 != null) {
LumberjackDialog(
visible = showComposeLogView2,
title = "Logs",
setup = DemoLogging.FILE_LOGGING_SETUP2!!,
darkTheme = theme.isDark(),
//mail = "[email protected]"
)
}
}
}
4 changes: 1 addition & 3 deletions gradle/androidx.versions.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
[versions]
core = "1.12.0"
lifecycle = "2.6.2"
constraintlayout = "2.1.4"
lifecycle = "2.7.0"
recyclerview = "1.3.2"


[libraries]
core = { module = "androidx.core:core-ktx", version.ref = "core" }
lifecycle = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycle" }
constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "constraintlayout" }
recyclerview = { module = "androidx.recyclerview:recyclerview", version.ref = "recyclerview" }
26 changes: 8 additions & 18 deletions gradle/compose.versions.toml
Original file line number Diff line number Diff line change
@@ -1,25 +1,15 @@
[versions]
composeBom = "2023.10.01"
compiler = "1.5.3"
composeBom = "2024.03.00"
compiler = "1.5.10"

lifecycle = "2.6.2"
activity = "1.8.0"
activity = "1.8.2"
accompanist = "0.32.0"

[libraries]
bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
animation = { group = "androidx.compose.animation", name = "animation" }
foundation = { group = "androidx.compose.foundation", name = "foundation" }
material = { group = "androidx.compose.material", name = "material" }
runtime = { group = "androidx.compose.runtime", name = "runtime" }
ui = { group = "androidx.compose.ui", name = "ui" }
ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
material-extendedicons = { group = "androidx.compose.material", name = "material-icons-extended" }
material3 = { group = "androidx.compose.material3", name = "material3" }
bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
icons-material-extendedicons = { group = "androidx.compose.material", name = "material-icons-extended" }
material3 = { group = "androidx.compose.material3", name = "material3" }

lifecycle = { module = "androidx.lifecycle:lifecycle-runtime-compose", version.ref = "lifecycle" }
activity = { module = "androidx.activity:activity-compose", version.ref = "activity" }
activity = { module = "androidx.activity:activity-compose", version.ref = "activity" }

systemuicontroller = { module = "com.google.accompanist:accompanist-systemuicontroller", version.ref = "accompanist" }
drawablepainter = { module = "com.google.accompanist:accompanist-drawablepainter", version.ref = "accompanist" }
drawablepainter = { module = "com.google.accompanist:accompanist-drawablepainter", version.ref = "accompanist" }
4 changes: 2 additions & 2 deletions gradle/dependencies.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ fastscroller = "1.0.0"

# mflisar
feedback = "2.0.4"
composedemobaseactivity = "0.4"
composedemobaseactivity = "0.6"

# google
material = "1.10.0"
material = "1.11.0"

# ---------
# libraries
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
2 changes: 1 addition & 1 deletion library/extensions/composeviewer/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ dependencies {
implementation(platform(compose.bom))
implementation(compose.material3)
implementation(compose.activity)
implementation(compose.material.extendedicons)
implementation(compose.icons.material.extendedicons)
implementation(compose.drawablepainter)

// ------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExposedDropdownMenuBox
import androidx.compose.material3.ExposedDropdownMenuDefaults
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
Expand Down Expand Up @@ -190,7 +191,7 @@ fun LumberjackDialog(
}
)
if (mail != null) {
Divider()
HorizontalDivider()
DropdownMenuItem(
text = { Text("Send Mail") },
leadingIcon = {
Expand Down Expand Up @@ -463,10 +464,11 @@ private fun Info(file: File?, filteredCount: Int, totalCount: Int) {
Row(
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
) {
val info = "%.2fkB".format((file?.length()?.toDouble() ?: 0.0) / 1000.0)
Text(
modifier = Modifier.weight(1f),
maxLines = 1,
text = file?.name ?: "",
text = file?.let { "${it.name} ($info)" } ?: "",
style = MaterialTheme.typography.bodySmall
)
Text(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package com.michaelflisar.lumberjack.loggers.file

import com.michaelflisar.lumberjack.implementation.LumberjackLogger
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.parcelize.IgnoredOnParcel
import java.io.File

abstract class BaseFileLoggerSetup : FileLoggerSetup() {

abstract val folder: File
abstract val fileBaseName: String
abstract val fileExtension: String
abstract var lastFileKey: String
abstract var lastFileKeyChanged: Boolean

@IgnoredOnParcel
override val fileConverter = FileConverter

override fun filePath(data: FileLogger.Event.Data): String {
val lastPath = "${folder.path}/${fileBaseName}_${lastFileKey}.$fileExtension"
val key = getFileKey(data, lastPath)
val path = "${folder.path}/${fileBaseName}_${key}.$fileExtension"
if (key != lastFileKey) {
lastFileKey = key
lastFileKeyChanged = true
}
return path
}

abstract fun getFileKey(data: FileLogger.Event.Data, lastPath: String): String
abstract fun filterLogFilesToDelete(files: List<File>): List<File>

protected fun getKeyFromFile(file: File) : String {
return file.nameWithoutExtension.replace(fileBaseName, "").substring(1)
}

override fun onLogged(scope: CoroutineScope) {
if (lastFileKeyChanged) {
lastFileKeyChanged = false
scope.launch {
clearLogFiles(false)
}
}
}

override suspend fun clearLogFiles() {
clearLogFiles(true)
}

override fun getAllExistingLogFiles(): List<File> {
return folder.listFiles()?.filter {
it.name.startsWith(fileBaseName)
}?.sortedByDescending { it.name } ?: emptyList()
}

override fun getLatestLogFiles(): File? {
return getAllExistingLogFiles().firstOrNull()
}

private suspend fun clearLogFiles(all: Boolean) {
withContext(Dispatchers.IO) {
val files = getAllExistingLogFiles()
val filesToDelete = if (all) files else filterLogFilesToDelete(files)
if (filesToDelete.isNotEmpty()) {
LumberjackLogger.loggers()
.filterIsInstance<FileLogger>()
.filter {
it.setup == this@BaseFileLoggerSetup
}
.forEach {
it.onLogFilesWillBeDeleted(filesToDelete)
}
filesToDelete.forEach {
it.delete()
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class FileLogger(
withContext(Dispatchers.IO) {
// try/catch - in no circumstance we want that any problem crashes the app because of the logger
try {
val path = setup.filePath(data.time)
val path = setup.filePath(data)
if (path != file?.path || bufferWriter == null) {
bufferWriter?.close()
file = File(path)
Expand Down
Loading

0 comments on commit 49ee875

Please sign in to comment.