PatternFormat.kt
- package com.hexagontk.jul
- import com.hexagontk.core.text.AnsiColor.DEFAULT
- import com.hexagontk.core.text.AnsiColor.YELLOW
- import com.hexagontk.core.text.AnsiColor.BLUE
- import com.hexagontk.core.text.AnsiColor.BRIGHT_BLACK
- import com.hexagontk.core.text.AnsiColor.CYAN
- import com.hexagontk.core.text.AnsiColor.MAGENTA
- import com.hexagontk.core.text.AnsiColor.RED
- import com.hexagontk.core.text.AnsiEffect.BOLD
- import com.hexagontk.core.text.Ansi.RESET
- import com.hexagontk.core.text.eol
- import com.hexagontk.core.fail
- import com.hexagontk.core.toText
- import java.time.Instant
- import java.time.LocalDateTime
- import java.time.ZoneId
- import java.util.logging.Formatter
- import java.util.logging.Level
- import java.util.logging.LogRecord
- /**
- * A Formatter implements [Formatter] provides support for formatting Logs.
- *
- * @property useColor Use colors in log messages.
- */
- class PatternFormat(
- private val useColor: Boolean,
- private val messageOnly: Boolean = false,
- ) : Formatter() {
- internal companion object {
- private const val TIMESTAMP = "%tH:%<tM:%<tS,%<tL"
- private const val LEVEL = "%-5s"
- private const val THREAD = "[%-15s]"
- private const val LOGGER = "%-30s"
- const val PATTERN = "$TIMESTAMP $LEVEL $THREAD $LOGGER | %s%n"
- const val COLOR_PATTERN =
- "$BRIGHT_BLACK$TIMESTAMP %s$LEVEL$RESET $MAGENTA$THREAD $CYAN$LOGGER$RESET | %s%n$RESET"
- }
- private val pattern: String = if (useColor) COLOR_PATTERN else PATTERN
- private val levelColors: Map<Level, String> = mapOf(
- Level.FINER to DEFAULT,
- Level.FINE to DEFAULT,
- Level.INFO to BLUE,
- Level.WARNING to YELLOW,
- Level.SEVERE to RED + BOLD
- )
- private val levelNames: Map<Level, String> = mapOf(
- Level.FINER to "TRACE",
- Level.FINE to "DEBUG",
- Level.INFO to "INFO",
- Level.WARNING to "WARN",
- Level.SEVERE to "ERROR"
- )
- override fun format(record: LogRecord): String {
- if (messageOnly)
- return record.message + "\n"
- val instant = Instant.ofEpochMilli(record.millis)
- val dateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault())
- val thrown = record.thrown
- val trace = when {
- thrown == null -> ""
- useColor -> "$eol${thrown.toText()}".replace("\n", "\n$RED")
- else -> "$eol${thrown.toText()}"
- }
- val level = record.level
- val levelName = levelNames[level] ?: fail
- val levelColor = levelColors[level] ?: BLUE
- val message = record.message
- val loggerName = record.loggerName
- val threadName = Thread.currentThread().name
- return if (useColor)
- pattern.format(dateTime, levelColor, levelName, threadName, loggerName, message + trace)
- else
- pattern.format(dateTime, levelName, threadName, loggerName, message + trace)
- }
- }