Skip to content

Commit

Permalink
viewer adjusted:
Browse files Browse the repository at this point in the history
* collapsing filter view
* added menu to clear files and to open any existing log file
* changed functions to use the new IFileLoggingSetup class instead of File
* added the ability to provide a custom log level and date extractor (from a line in a log file) + added a default extractor that supports the default format of the default file logging setup
  • Loading branch information
MFlisar committed Jun 10, 2021
1 parent 0a71dd6 commit 26f08b9
Show file tree
Hide file tree
Showing 19 changed files with 367 additions and 172 deletions.
1 change: 1 addition & 0 deletions library-filelogger/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
id 'com.android.library'
id 'kotlin-android'
id 'kotlin-parcelize'
}

group = 'com.github.MFlisar'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
package com.michaelflisar.lumberjack

import android.content.Context
import android.os.Parcelable
import com.michaelflisar.lumberjack.interfaces.IFileLoggingSetup
import kotlinx.parcelize.Parcelize
import java.io.File
import java.io.PrintWriter
import java.util.regex.Pattern

sealed class FileLoggingSetup {
sealed class FileLoggingSetup : IFileLoggingSetup {

protected abstract val pattern: String
abstract val context: Context
abstract val folder: String
abstract val logOnBackgroundThread: Boolean
abstract val setup: Setup

fun getAllExistingLogFiles() = getFilesInFolder().filter { Pattern.matches(pattern, it.name) }
open fun getLatestLogFiles() = getAllExistingLogFiles().sortedByDescending { it.lastModified() }.firstOrNull()
override fun getAllExistingLogFiles() = getFilesInFolder().filter { Pattern.matches(pattern, it.name) }
override fun getLatestLogFiles() = getAllExistingLogFiles().sortedByDescending { it.lastModified() }.firstOrNull()

fun clearLogFiles() {
override fun clearLogFiles() {
val newestFile = getLatestLogFiles()
val filesToDelete = getAllExistingLogFiles().filter { it != newestFile }
filesToDelete.forEach {
Expand All @@ -29,13 +31,20 @@ sealed class FileLoggingSetup {
}
}

@Parcelize
class NumberedFiles(
override val context: Context,
override val folder: String = context.getFileStreamPath("").absolutePath,
override val logOnBackgroundThread: Boolean = true,
val sizeLimit: String = "1MB",
override val setup: Setup = Setup()
override val folder: String,
override val logOnBackgroundThread: Boolean,
val sizeLimit: String,
override val setup: Setup
) : FileLoggingSetup() {

constructor(context: Context,
folder: String = context.getFileStreamPath("").absolutePath,
logOnBackgroundThread: Boolean = true,
sizeLimit: String = "1MB",
setup: Setup = Setup()) : this(folder, logOnBackgroundThread, sizeLimit, setup)

override val pattern = String.format(
FileLoggingTree.NUMBERED_FILE_NAME_PATTERN,
setup.fileName,
Expand All @@ -48,12 +57,18 @@ sealed class FileLoggingSetup {
override fun getLatestLogFiles() = File(baseFilePath)
}

@Parcelize
class DateFiles(
override val context: Context,
override val folder: String = context.getFileStreamPath("").absolutePath,
override val logOnBackgroundThread: Boolean = true,
override val setup: Setup = Setup()
override val folder: String,
override val logOnBackgroundThread: Boolean,
override val setup: Setup
) : FileLoggingSetup() {

constructor(context: Context,
folder: String = context.getFileStreamPath("").absolutePath,
logOnBackgroundThread: Boolean = true,
setup: Setup = Setup()) : this(folder, logOnBackgroundThread, setup)

override val pattern = String.format(
FileLoggingTree.DATE_FILE_NAME_PATTERN,
setup.fileName,
Expand All @@ -69,12 +84,13 @@ sealed class FileLoggingSetup {
* fileName... define a custom basic file name for your log files
* fileExtension... define a custom file extension for your log files
*/
@Parcelize
class Setup(
val logsToKeep: Int = 7,
val logPattern: String = "%d %-5level %msg%n",
val fileName: String = "log",
val fileExtension: String = "log"
)
) : Parcelable

protected fun getFilesInFolder(): List<File> {
val folder = File(folder)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import android.content.Context
import androidx.core.app.NotificationCompat
import com.michaelflisar.feedbackmanager.FeedbackBuilder
import com.michaelflisar.lumberjack.core.CoreUtil
import com.michaelflisar.lumberjack.interfaces.IFileLoggingSetup
import com.michaelflisar.lumberjack.interfaces.ILumberjackViewActivityProvider
import java.io.File

Expand Down Expand Up @@ -76,16 +77,16 @@ fun L.showInfoNotification(
*/
fun L.showInfoNotification(
context: Context,
logFile: File?,
fileLoggingSetup: IFileLoggingSetup?,
notificationChannelId: String,
notificationId: Int,
notificationTitle: String,
notificationText: String,
notificationIcon: Int,
lumberjackViewerActivityProvider: ILumberjackViewActivityProvider
) {
val pendingIntent: PendingIntent? = logFile?.let {
val clickIntent = lumberjackViewerActivityProvider.createIntent(context, logFile)
val pendingIntent: PendingIntent? = fileLoggingSetup?.let {
val clickIntent = lumberjackViewerActivityProvider.createIntent(context, fileLoggingSetup)
PendingIntent.getActivity(context, 0, clickIntent, 0)
}

Expand Down
1 change: 1 addition & 0 deletions library-viewer/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
id 'com.android.library'
id 'kotlin-android'
id 'kotlin-parcelize'
}

group = 'com.github.MFlisar'
Expand Down
2 changes: 1 addition & 1 deletion library-viewer/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<application>
<activity
android:name="com.michaelflisar.lumberjack.LumberjackViewerActivity"
android:name="com.michaelflisar.lumberjack.view.LumberjackViewerActivity"
android:theme="@style/Theme.MaterialComponents.DayNight.NoActionBar" />
</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.michaelflisar.lumberjack

import com.michaelflisar.lumberjack.interfaces.IDataExtractor
import com.michaelflisar.lumberjack.core.Level
import kotlinx.parcelize.Parcelize

@Parcelize
object DefaultDataExtractor : IDataExtractor {

override fun extract(line: Int, fullLogLine: String): IDataExtractor.Data? {
// default log line looks like following:
// 2000-01-01 00:00:00.000 INFO Some log
// => 23 chars (including 1 space) + 2nd space + TAG + 3rd space + rest
if (fullLogLine.trim().isNotEmpty()) {
var date = ""
var level = Level.UNKNOWN
var log = ""
if (fullLogLine.count { it == ' ' } > 3) {
val ind1 = fullLogLine.indexOf(' ')
val ind2 = fullLogLine.indexOf(' ', ind1 + 1)
val ind3 = fullLogLine.indexOf(' ', ind2 + 1)
val levelString = fullLogLine.substring(ind2, ind3).trim()
date = fullLogLine.substring(0, ind2).trim()
level = Level.values().find { it.name == levelString }
?: Level.UNKNOWN
log = fullLogLine.substring(ind3).trimStart()

}
return IDataExtractor.Data(line, fullLogLine, level, date, log)
}
return null
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
package com.michaelflisar.lumberjack

import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.pm.PackageManager
import androidx.core.app.NotificationCompat
import com.michaelflisar.feedbackmanager.FeedbackBuilder
import java.io.File
import com.michaelflisar.lumberjack.interfaces.IFileLoggingSetup
import com.michaelflisar.lumberjack.view.LumberjackViewer

/*
* convenient extension to show a log file
*/
fun L.showLog(
context: Context,
fileLoggingSetup: FileLoggingSetup
fileLoggingSetup: IFileLoggingSetup
) {
LumberjackViewer.show(context, fileLoggingSetup.getLatestLogFiles()!!)
LumberjackViewer.show(context, fileLoggingSetup)
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.michaelflisar.lumberjack
package com.michaelflisar.lumberjack.view

import android.content.Context
import android.graphics.Color
Expand All @@ -13,11 +13,15 @@ import android.view.ViewGroup
import android.widget.TextView
import androidx.core.text.toSpannable
import androidx.recyclerview.widget.RecyclerView
import com.michaelflisar.lumberjack.getColorFromAttr
import com.michaelflisar.lumberjack.core.Level
import com.michaelflisar.lumberjack.interfaces.IDataExtractor
import com.michaelflisar.lumberjack.isCurrentThemeDark
import com.michaelflisar.lumberjack.viewer.databinding.LogItemRowBinding

internal class LogAdapter(
context: Context,
var items: List<Item>,
var items: List<IDataExtractor.Data>,
var filter: String
) : RecyclerView.Adapter<LogAdapter.ViewHolder>() {

Expand All @@ -27,7 +31,11 @@ internal class LogAdapter(
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) context.getColorFromAttr(android.R.attr.colorPrimary) else Color.BLUE
private val textColor: Int = TextView(context).textColors.defaultColor

fun update(items: List<Item>, filter: String) {
fun clear() {
update(emptyList(), "")
}

fun update(items: List<IDataExtractor.Data>, filter: String) {
this.items = items
this.filter = filter
notifyDataSetChanged()
Expand Down Expand Up @@ -61,13 +69,13 @@ internal class LogAdapter(
) : RecyclerView.ViewHolder(binding.root) {


fun bind(item: Item, filter: String, pos: Int) {
binding.tvNumber.text = "${item.row + 1}"
fun bind(item: IDataExtractor.Data, filter: String, pos: Int) {
binding.tvNumber.text = "${item.line + 1}"
binding.tvType.setTextColor(item.level.getTitleColor(textColor))
binding.tvType.text = item.level.name
binding.tvDate.text = item.date
binding.tvRow.setTextColor(item.level.getTextColor(textColor))
binding.tvRow.text = getHighlightedText(item.text, filter, true)
binding.tvRow.text = getHighlightedText(item.log, filter, true)
}

fun unbind() {
Expand Down Expand Up @@ -109,34 +117,5 @@ internal class LogAdapter(
}
return wordToSpan
}


}

class Item(val row: Int, val text: String, val level: Level, val date: String?) {

enum class Level(val level: Int, val useDefaultTextColor: Boolean, private val color: Int) {
TRACE(0, true, -1),
DEBUG(1, true, -1),
INFO(2, true, -1),
WARN(3, false, Color.parseColor("#FFA500") /* orange */),
ERROR(4, false, Color.RED),
UNKNOWN(-1, false, android.R.color.transparent)
;

private var c: Int? = null
private var c2: Int? = null

fun getTitleColor(textColor: Int): Int {
return if (useDefaultTextColor) textColor else color
}

fun getTextColor(textColor: Int): Int {
val c = getTitleColor(textColor)
return if (!useDefaultTextColor && c == android.R.color.transparent)
textColor
else c
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.michaelflisar.lumberjack.view

import android.content.Context
import android.content.Intent
import android.os.Bundle
import com.michaelflisar.lumberjack.DefaultDataExtractor
import com.michaelflisar.lumberjack.interfaces.IDataExtractor
import com.michaelflisar.lumberjack.interfaces.IFileLoggingSetup
import com.michaelflisar.lumberjack.interfaces.ILumberjackViewActivityProvider

object LumberjackViewer : ILumberjackViewActivityProvider {

const val FILE_LOGGING_SETUP = "FILE-LOGGING_SETUP"
const val DATA_EXTRACTOR = "DATA-EXTRACTOR"

fun show(
context: Context,
fileLoggingSetup: IFileLoggingSetup,
dataExtractor: IDataExtractor = DefaultDataExtractor
) {
context.startActivity(createIntent(context, fileLoggingSetup, dataExtractor))
}

override fun createIntent(context: Context, fileLoggingSetup: IFileLoggingSetup): Intent {
return createIntent(context, fileLoggingSetup, DefaultDataExtractor)
}

override fun createIntent(
context: Context,
fileLoggingSetup: IFileLoggingSetup,
dataExtractor: IDataExtractor
): Intent {
return Intent(
context,
LumberjackViewerActivity::class.java
).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
putExtra(FILE_LOGGING_SETUP, fileLoggingSetup)
putExtra(DATA_EXTRACTOR, dataExtractor)
}
}
}
Loading

0 comments on commit 26f08b9

Please sign in to comment.