Skip to content

Commit

Permalink
Merge pull request #133 from rladstaetter/12-extract-time-instant-inf…
Browse files Browse the repository at this point in the history
…ormation-from-log-files

12 extract time instant information from log files
  • Loading branch information
rladstaetter authored Jan 16, 2023
2 parents d42404b + bacb1f8 commit dd01bd4
Show file tree
Hide file tree
Showing 49 changed files with 642 additions and 282 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ fact, when you get an error, you may simply want to see what happened as fast as
is a tool that does precisely that and provides you with a quick way to filter out critical events or other points of
interest.

![Screenshot of LogoRRR, version 22.3.0](docs/releases/23.1.0/screenshot-23.1.0.png?raw=true)
![Screenshot of LogoRRR, version 23.1.0](docs/releases/23.1.0/screenshot-23.1.0.png?raw=true)

## Usage

Expand All @@ -18,7 +18,7 @@ See [Technology](Technology.md) for a short summary of used technologies.
## Installation

You can give it a try by downloading
a [prebuilt installer for `LogoRRR`](https://github.com/rladstaetter/LogoRRR/releases/tag/22.3.0) from the releases
a [prebuilt installer for `LogoRRR`](https://github.com/rladstaetter/LogoRRR/releases/tag/23.1.0) from the releases
page. There are installer for Windows and MacOs available.

## Features
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/scala/app/logorrr/LogoRRRApp.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package app.logorrr

import app.logorrr.conf.{LogoRRRGlobals, Settings, SettingsIO}
import app.logorrr.meta.AppMeta
import app.logorrr.util.CanLog
import app.logorrr.views.main.LogoRRRStage
import javafx.stage.Stage
Expand All @@ -21,6 +22,7 @@ object LogoRRRApp {
class LogoRRRApp extends javafx.application.Application with CanLog {

def start(stage: Stage): Unit = {
logInfo(s"Started " + AppMeta.fullAppNameWithVersion)
val settings: Settings = SettingsIO.fromFile()
LogoRRRGlobals.set(settings, getHostServices)
LogoRRRStage(stage).show()
Expand Down
2 changes: 0 additions & 2 deletions app/src/main/scala/app/logorrr/conf/Settings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ case class Settings(stageSettings: StageSettings
, logFileSettings: Map[String, LogFileSettings]
, someActive: Option[String]) {

def asOrderedSeq: Seq[LogFileSettings] = logFileSettings.values.toSeq.sortWith((lt, gt) => lt.firstOpened < gt.firstOpened)

def remove(pathAsString: String): Settings = {
copy(stageSettings
, logFileSettings - pathAsString
Expand Down
30 changes: 22 additions & 8 deletions app/src/main/scala/app/logorrr/conf/mut/MutLogFileSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import app.logorrr.conf.BlockSettings
import app.logorrr.model.{LogEntryInstantFormat, LogFileSettings}
import app.logorrr.util.LogoRRRFonts
import app.logorrr.views.search.Filter
import javafx.beans.binding.StringBinding
import javafx.beans.binding.{BooleanBinding, StringBinding}
import javafx.beans.property._
import javafx.beans.value.ObservableValue
import javafx.collections.FXCollections

import scala.jdk.CollectionConverters._
Expand All @@ -22,7 +21,7 @@ object MutLogFileSettings {
s.firstOpenedProperty.set(logFileSettings.firstOpened)
s.setDividerPosition(logFileSettings.dividerPosition)
s.filtersProperty.setAll(logFileSettings.filters.asJava)
s.someLogEntrySettings.set(logFileSettings.someLogEntrySetting)
s.someLogEntrySettingsProperty.set(logFileSettings.someLogEntryInstantFormat)
s.setAutoScroll(logFileSettings.autoScroll)
s
}
Expand All @@ -33,19 +32,34 @@ class MutLogFileSettings {
private val pathAsStringProperty = new SimpleStringProperty()
private val firstOpenedProperty = new SimpleLongProperty()
val selectedIndexProperty = new SimpleIntegerProperty()
val dividerPositionProperty = new SimpleDoubleProperty()
val fontSizeProperty = new SimpleIntegerProperty()
private val dividerPositionProperty = new SimpleDoubleProperty()
private val fontSizeProperty = new SimpleIntegerProperty()

val autoScrollProperty = new SimpleBooleanProperty()
val filtersProperty = new SimpleListProperty[Filter](FXCollections.observableArrayList())
val someLogEntrySettings = new SimpleObjectProperty[Option[LogEntryInstantFormat]]()
val someLogEntrySettingsProperty = new SimpleObjectProperty[Option[LogEntryInstantFormat]](None)
val blockWidthSettingsProperty = new SimpleIntegerProperty()

val fontStyle: ObservableValue[_ <: String] = new StringBinding {
def getSomeLogEntrySetting: Option[LogEntryInstantFormat] = someLogEntrySettingsProperty.get()

val hasLogEntrySettingBinding = new BooleanBinding {
bind(someLogEntrySettingsProperty)

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

val fontStyleBinding: StringBinding = new StringBinding {
bind(fontSizeProperty)

override def computeValue(): String = LogoRRRFonts.jetBrainsMono(fontSizeProperty.get())
}

def setLogEntryInstantFormat(lef: LogEntryInstantFormat): Unit = {
someLogEntrySettingsProperty.set(Option(lef))
}

def setAutoScroll(autoScroll: Boolean): Unit = autoScrollProperty.set(autoScroll)

def isAutoScroll(): Boolean = autoScrollProperty.get()
Expand Down Expand Up @@ -79,7 +93,7 @@ class MutLogFileSettings {
, fontSizeProperty.get()
, filtersProperty.get().asScala.toSeq
, BlockSettings(blockWidthSettingsProperty.get())
, someLogEntrySettings.get()
, someLogEntrySettingsProperty.get()
, autoScrollProperty.get())
lfs
}
Expand Down
29 changes: 19 additions & 10 deletions app/src/main/scala/app/logorrr/model/LogEntryInstantFormat.scala
Original file line number Diff line number Diff line change
@@ -1,36 +1,45 @@
package app.logorrr.model

import app.logorrr.views.SimpleRange
import app.logorrr.util.CanLog
import app.logorrr.views.settings.timer.SimpleRange
import pureconfig.generic.semiauto.{deriveReader, deriveWriter}

import java.time.format.DateTimeFormatter
import java.time.{Instant, LocalDateTime, ZoneId, ZoneOffset}
import scala.util.Try
import scala.util.{Failure, Success, Try}

object LogEntryInstantFormat {
object LogEntryInstantFormat extends CanLog {

val DefaultPattern = "yyyy-MM-dd HH:mm:ss.SSS"
val DefaultPattern = "yyyy-MM-dd HH:mm:ss.nnnnnnnnn"
/** just my preferred time format */
val Default = LogEntryInstantFormat(SimpleRange(1, 24), DefaultPattern)

implicit lazy val reader = deriveReader[LogEntryInstantFormat]
implicit lazy val writer = deriveWriter[LogEntryInstantFormat]

def parseInstant(line: String, entrySetting: LogEntryInstantFormat): Option[Instant] =
if (line.length >= entrySetting.dateTimeRange.end) {
if (line.length >= entrySetting.endCol) {
val dateTimeAsString = line.substring(entrySetting.startCol, entrySetting.endCol)
Try {
val dateTimeAsString = line.substring(entrySetting.dateTimeRange.start, entrySetting.dateTimeRange.end)
val dtf: DateTimeFormatter = entrySetting.dateTimeFormatter
LocalDateTime.parse(dateTimeAsString, dtf).toInstant(ZoneOffset.of(entrySetting.zoneOffset))
}.toOption
} else None
} match {
case Success(value) => Option(value)
case Failure(_) =>
logTrace(s"Could not parse '$dateTimeAsString' at pos (${entrySetting.startCol}/${entrySetting.endCol}) with pattern '$${entrySetting.dateTimePattern}'")
None
}
} else {
None
}


}

case class LogEntryInstantFormat(dateTimeRange: SimpleRange
case class LogEntryInstantFormat(range: SimpleRange
, dateTimePattern: String
, zoneOffset: String = "+1") {

val startCol = range.start
val endCol = range.end
val dateTimeFormatter = DateTimeFormatter.ofPattern(dateTimePattern).withZone(ZoneId.of(zoneOffset))
}
8 changes: 4 additions & 4 deletions app/src/main/scala/app/logorrr/model/LogFileSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ case class LogFileSettings(pathAsString: String
, fontSize: Int
, filters: Seq[Filter]
, blockSettings: BlockSettings
, someLogEntrySetting: Option[LogEntryInstantFormat]
, someLogEntryInstantFormat: Option[LogEntryInstantFormat]
, autoScroll: Boolean) extends CanLog {

val path: Path = Paths.get(pathAsString)
Expand All @@ -69,12 +69,12 @@ case class LogFileSettings(pathAsString: String

def readEntries(): ObservableList[LogEntry] = {
if (isPathValid) {
Try(someLogEntrySetting match {
case Some(value) => LogEntryFileReader.from(path, filters, value)
Try(someLogEntryInstantFormat match {
case Some(instantFormat) => LogEntryFileReader.from(path, filters, instantFormat)
case None => LogEntryFileReader.from(path, filters)
}) match {
case Success(logEntries) =>
logInfo(s"Opening ${pathAsString} ... ")
logTrace(s"Opened ${pathAsString} ... ")
logEntries
case Failure(ex) =>
val msg = s"Could not import file ${pathAsString}"
Expand Down
19 changes: 19 additions & 0 deletions app/src/main/scala/app/logorrr/util/LabelUtil.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package app.logorrr.util

import javafx.geometry.Insets
import javafx.scene.control.Label
import javafx.scene.layout.{Background, BackgroundFill}
import javafx.scene.paint.Color

object LabelUtil {

def setStyle(label: Label, textFill: Color, padding: Insets, backgroundColor: Color): Unit = {
label.setTextFill(textFill)
label.setPadding(padding)
label.setBackground(new Background(new BackgroundFill(backgroundColor, null, null)))
}

def resetStyle(label: Label): Unit = {
label.setBackground(null)
}
}
11 changes: 11 additions & 0 deletions app/src/main/scala/app/logorrr/util/LogFileUtil.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package app.logorrr.util

import java.nio.file.Paths

object LogFileUtil {

/** compute file name from a LogFilePath */
def logFileName(pathAsString: String): String =
Paths.get(pathAsString).getFileName.toString

}
8 changes: 8 additions & 0 deletions app/src/main/scala/app/logorrr/util/StringUtil.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,13 @@ package app.logorrr.util
import java.nio.charset.StandardCharsets

object StringUtil {

val utf8 = StandardCharsets.UTF_8.name()

/** handy for conversions where T has a string representation. if f returns null, a 'n/a' string will be displayed */
def tOrNa[T](f: => T): String = Option(f) match {
case Some(value) => value.toString
case None => "n/a"
}

}
Loading

0 comments on commit dd01bd4

Please sign in to comment.