Skip to content

Commit

Permalink
Merge pull request #260 from rladstaetter/43-time-range-filter
Browse files Browse the repository at this point in the history
43 time range filter
  • Loading branch information
rladstaetter authored Aug 15, 2024
2 parents dfdb212 + 2b486ea commit 04eeee7
Show file tree
Hide file tree
Showing 47 changed files with 973 additions and 443 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ logfiles/
.idea/
**/.flattened-pom.xml
/develop-logging.properties
/target/
4 changes: 1 addition & 3 deletions app/src/main/scala/app/logorrr/conf/LogoRRRGlobals.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ object LogoRRRGlobals extends CanLog {

private val hostServicesProperty = new SimpleObjectProperty[LogoRRRHostServices]()

def persist(): Unit = {
persist(LogoRRRGlobals.getSettings)
}
def persist(): Unit = persist(LogoRRRGlobals.getSettings)

def persist(settings: Settings): Unit = {
Fs.write(FilePaths.settingsFilePath, ConfigWriter[Settings].to(settings).render(renderOptions))
Expand Down
96 changes: 81 additions & 15 deletions app/src/main/scala/app/logorrr/conf/mut/MutLogFileSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ package app.logorrr.conf.mut

import app.logorrr.conf.BlockSettings
import app.logorrr.io.FileId
import app.logorrr.model.{LogEntryInstantFormat, LogFileSettings}
import app.logorrr.model.{LogEntry, LogFileSettings, TimestampSettings}
import app.logorrr.util.LogoRRRFonts
import app.logorrr.views.search.Filter
import app.logorrr.views.search.{AnyFilter, Filter, FilterButton, Fltr}
import javafx.beans.binding.{BooleanBinding, StringBinding}
import javafx.beans.property._
import javafx.collections.FXCollections
import javafx.collections.transformation.FilteredList
import javafx.collections.{FXCollections, ObservableList}

import java.time.format.DateTimeFormatter
import scala.jdk.CollectionConverters._

object MutLogFileSettings {
Expand All @@ -22,37 +24,95 @@ object MutLogFileSettings {
s.firstOpenedProperty.set(logFileSettings.firstOpened)
s.setDividerPosition(logFileSettings.dividerPosition)
s.setFilters(logFileSettings.filters)
s.someLogEntrySettingsProperty.set(logFileSettings.someLogEntryInstantFormat)
s.someTimestampSettings.set(logFileSettings.someTimestampSettings)
logFileSettings.someTimestampSettings match {
case Some(sts) => s.setDateTimeFormatter(sts.dateTimeFormatter)
case None =>
}
s.setAutoScroll(logFileSettings.autoScroll)
s.setLowerTimestamp(logFileSettings.lowerTimestamp)
s.setUpperTimestamp(logFileSettings.upperTimestamp)
s
}
}


class MutLogFileSettings {

var someUnclassifiedFilter: Option[(Filter, FilterButton)] = None
var filterButtons: Map[Filter, FilterButton] = Map[Filter, FilterButton]()

/**
* Filters are only active if selected.
*
* UnclassifiedFilter gets an extra handling since it depends on other filters
*
* @return
*/
def computeCurrentFilter(): Fltr = {
new AnyFilter(someUnclassifiedFilter.map(fst => if (fst._2.isSelected) Set(fst._1) else Set()).getOrElse(Set()) ++
filterButtons.filter(fst => fst._2.isSelected).keySet)
}

/**
* Reduce current displayed log entries by applying text filters and consider also the time stamp range.
*
* @param filteredList list to filter
*/
def updateActiveFilter(filteredList: FilteredList[LogEntry]): Unit = {
filteredList.setPredicate((entry: LogEntry) =>
(entry.someInstant match {
case None => true // if instant is not set, return true
case Some(value) =>
val asMilli = value.toEpochMilli
getLowTimestampBoundary <= asMilli && asMilli <= getHighTimestampBoundary
}) && computeCurrentFilter().matches(entry.value))
}


private val fileIdProperty = new SimpleObjectProperty[FileId]()
private val firstOpenedProperty = new SimpleLongProperty()
private val someTimestampSettings = new SimpleObjectProperty[Option[TimestampSettings]](None)
private val dateTimeFormatterProperty = new SimpleObjectProperty[DateTimeFormatter](TimestampSettings.DefaultFormatter)

val fontSizeProperty = new SimpleIntegerProperty()
val blockSizeProperty = new SimpleIntegerProperty()
val selectedLineNumberProperty = new SimpleIntegerProperty()
val firstVisibleTextCellIndexProperty = new SimpleIntegerProperty()
val lastVisibleTextCellIndexProperty = new SimpleIntegerProperty()
val dividerPositionProperty = new SimpleDoubleProperty()
val fontSizeProperty = new SimpleIntegerProperty()
private val lowerTimestampProperty = new SimpleLongProperty(LogFileSettings.DefaultLowerTimestamp)
private val upperTimestampProperty = new SimpleLongProperty(LogFileSettings.DefaultUpperTimestamp)

def setLowerTimestamp(lowerValue: Long): Unit = lowerTimestampProperty.set(lowerValue)

def getLowTimestampBoundary: Long = lowerTimestampProperty.get()

def setUpperTimestamp(upperValue: Long): Unit = upperTimestampProperty.set(upperValue)

def getHighTimestampBoundary: Long = upperTimestampProperty.get()

val dividerPositionProperty = new SimpleDoubleProperty()
val autoScrollActiveProperty = new SimpleBooleanProperty()
val filtersProperty = new SimpleListProperty[Filter](FXCollections.observableArrayList())
val someLogEntrySettingsProperty = new SimpleObjectProperty[Option[LogEntryInstantFormat]](None)
val blockSizeProperty = new SimpleIntegerProperty()

def getSomeTimestampSettings: Option[TimestampSettings] = someTimestampSettings.get()

def getDateTimeFormatter: DateTimeFormatter = dateTimeFormatterProperty.get()

def setDateTimeFormatter(dateTimeFormatter: DateTimeFormatter): Unit = dateTimeFormatterProperty.set(dateTimeFormatter)

def setFilters(filters: Seq[Filter]): Unit = {
filtersProperty.setAll(filters.asJava)
}

def getFilters: ObservableList[Filter] = filtersProperty.get()


val hasLogEntrySettingBinding: BooleanBinding = new BooleanBinding {
bind(someLogEntrySettingsProperty)
bind(someTimestampSettings)

override def computeValue(): Boolean = {
Option(someLogEntrySettingsProperty.get()).exists(_.isDefined)
Option(someTimestampSettings.get()).exists(_.isDefined)
}
}

Expand All @@ -66,8 +126,12 @@ class MutLogFileSettings {
override def computeValue(): String = LogoRRRFonts.jetBrainsMono(fontSizeProperty.get())
}

def setLogEntryInstantFormat(lef: LogEntryInstantFormat): Unit = {
someLogEntrySettingsProperty.set(Option(lef))
def setSomeLogEntryInstantFormat(someLef: Option[TimestampSettings]): Unit = {
someTimestampSettings.set(someLef)
someLef match {
case Some(value) => setDateTimeFormatter(value.dateTimeFormatter)
case None => setDateTimeFormatter(null)
}
}

def setAutoScroll(autoScroll: Boolean): Unit = autoScrollActiveProperty.set(autoScroll)
Expand Down Expand Up @@ -101,12 +165,14 @@ class MutLogFileSettings {
, firstOpenedProperty.get()
, dividerPositionProperty.get()
, fontSizeProperty.get()
, filtersProperty.get().asScala.toSeq
, getFilters.asScala.toSeq
, BlockSettings(blockSizeProperty.get())
, someLogEntrySettingsProperty.get()
, someTimestampSettings.get()
, autoScrollActiveProperty.get()
, firstVisibleTextCellIndexProperty.get()
, lastVisibleTextCellIndexProperty.get())
, lastVisibleTextCellIndexProperty.get()
, lowerTimestampProperty.get()
, upperTimestampProperty.get())
lfs
}
}
Expand Down
30 changes: 21 additions & 9 deletions app/src/main/scala/app/logorrr/io/IoManager.scala
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package app.logorrr.io

import app.logorrr.model.{LogEntry, LogEntryInstantFormat}
import app.logorrr.model.{LogEntry, TimestampSettings}
import app.logorrr.util.{CanLog, OsUtil}
import javafx.collections.{FXCollections, ObservableList}

import java.io._
import java.nio.file.{Files, Path}
import java.time.{Duration, Instant}
import java.util
import java.util.zip.{ZipEntry, ZipInputStream}
import scala.util.{Failure, Success, Try}
Expand Down Expand Up @@ -58,7 +59,7 @@ object IoManager extends CanLog {
val arraylist = new java.util.ArrayList[LogEntry]()
toSeq(mkReader(asBytes)).map(l => {
lineNumber = lineNumber + 1
arraylist.add(LogEntry(lineNumber, l, None))
arraylist.add(LogEntry(lineNumber, l, None, None))
})
FXCollections.observableList(arraylist)

Expand All @@ -69,22 +70,34 @@ object IoManager extends CanLog {
val arraylist = new java.util.ArrayList[LogEntry]()
fromPathUsingSecurityBookmarks(logFile).map(l => {
lineNumber = lineNumber + 1
arraylist.add(LogEntry(lineNumber, l, None))
arraylist.add(LogEntry(lineNumber, l, None, None))
})
FXCollections.observableList(arraylist)
}

def from(logFile: Path, logEntryTimeFormat: LogEntryInstantFormat): ObservableList[LogEntry] = {
def from(logFile: Path, logEntryTimeFormat: TimestampSettings): ObservableList[LogEntry] = {
var lineNumber: Int = 0
var someFirstEntryTimestamp: Option[Instant] = None
val arraylist = new util.ArrayList[LogEntry]()
fromPathUsingSecurityBookmarks(logFile).map(l => {
lineNumber = lineNumber + 1
arraylist.add(LogEntry(lineNumber, l, LogEntryInstantFormat.parseInstant(l, logEntryTimeFormat)))
val someInstant: Option[Instant] = TimestampSettings.parseInstant(l, logEntryTimeFormat)
if (someFirstEntryTimestamp.isEmpty) {
someFirstEntryTimestamp = someInstant
}

val diffFromStart: Option[Duration] = for {
firstEntry <- someFirstEntryTimestamp
instant <- someInstant
} yield Duration.between(firstEntry, instant)

// first entry
arraylist.add(LogEntry(lineNumber, l, someInstant, diffFromStart))
})
FXCollections.observableList(arraylist)
}

def readEntries(path : Path, someLogEntryInstantFormat: Option[LogEntryInstantFormat]): ObservableList[LogEntry] = {
def readEntries(path: Path, someLogEntryInstantFormat: Option[TimestampSettings]): ObservableList[LogEntry] = {
if (isPathValid(path)) {
Try(someLogEntryInstantFormat match {
case None => IoManager.from(path)
Expand All @@ -102,7 +115,7 @@ object IoManager extends CanLog {
}
}

def isPathValid(path : Path): Boolean =
def isPathValid(path: Path): Boolean =
if (OsUtil.isMac) {
Files.exists(path)
} else {
Expand Down Expand Up @@ -143,7 +156,6 @@ object IoManager extends CanLog {
}



def isZip(path : Path) : Boolean = path.getFileName.toString.endsWith(".zip")
def isZip(path: Path): Boolean = path.getFileName.toString.endsWith(".zip")

}
14 changes: 10 additions & 4 deletions app/src/main/scala/app/logorrr/model/LogEntry.scala
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
package app.logorrr.model


import java.time.Instant
import java.time.{Duration, Instant}

/**
* represents one line in a log file
*
* @param lineNumber line number of this log entry
* @param value contens of line in plaintext
* @param lineNumber line number of this log entry
* @param value contens of line in plaintext
* @param someInstant a timestamp if there is any
* */
case class LogEntry(lineNumber: Int
, value: String
, someInstant: Option[Instant])
, someInstant: Option[Instant]
, someDurationSinceFirstInstant: Option[Duration]) {

/** returns a copy of this log entry without timestamp information */
def withOutTimestamp(): LogEntry = copy(someInstant = None, someDurationSinceFirstInstant = None)

}
46 changes: 0 additions & 46 deletions app/src/main/scala/app/logorrr/model/LogEntryInstantFormat.scala

This file was deleted.

16 changes: 11 additions & 5 deletions app/src/main/scala/app/logorrr/model/LogFileSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ object LogFileSettings {
private val DefaultSelectedIndex = 0
private val DefaultDividerPosition = 0.5
private val DefaultBlockSettings = BlockSettings(10)
private val DefaultLogFormat: Option[LogEntryInstantFormat] = None
private val DefaultLogFormat: Option[TimestampSettings] = None
private val DefaultAutoScroll = false
private val DefaultFirstViewIndex = -1
private val DefaultLastViewIndex = -1
val DefaultLowerTimestamp: Int = 0
val DefaultUpperTimestamp: Long = Instant.now().toEpochMilli
private val FinestFilter: Filter = new Filter("FINEST", Color.GREY, true)
private val InfoFilter: Filter = new Filter("INFO", Color.GREEN, true)
private val WarningFilter: Filter = new Filter("WARNING", Color.ORANGE, true)
Expand All @@ -41,7 +43,9 @@ object LogFileSettings {
, DefaultLogFormat
, DefaultAutoScroll
, DefaultFirstViewIndex
, DefaultLastViewIndex)
, DefaultLastViewIndex
, DefaultLowerTimestamp
, Instant.now().toEpochMilli)
}

}
Expand All @@ -62,7 +66,7 @@ object LogFileSettings {
* @param fontSize font size to use
* @param filters filters which should be applied
* @param blockSettings settings for the left view
* @param someLogEntryInstantFormat used timestamp format
* @param someTimestampSettings used timestamp format
* @param autoScroll true if 'follow mode' is active
* @param firstVisibleTextCellIndex which index is the first visible on the screen (depending on resolution, window size ...)
* @param lastVisibleTextCellIndex which index is the last visible on the screen (depending on resolution, window size ...)
Expand All @@ -74,10 +78,12 @@ case class LogFileSettings(fileId: FileId
, fontSize: Int
, filters: Seq[Filter]
, blockSettings: BlockSettings
, someLogEntryInstantFormat: Option[LogEntryInstantFormat]
, someTimestampSettings: Option[TimestampSettings]
, autoScroll: Boolean
, firstVisibleTextCellIndex: Int
, lastVisibleTextCellIndex: Int) {
, lastVisibleTextCellIndex: Int
, lowerTimestamp: Long
, upperTimestamp: Long) {

val path: Path = fileId.asPath.toAbsolutePath

Expand Down
Loading

0 comments on commit 04eeee7

Please sign in to comment.