package com.shr4pnel.ferretirc.util import ch.qos.logback.classic.Level import ch.qos.logback.classic.spi.ILoggingEvent import ch.qos.logback.core.pattern.CompositeConverter import ch.qos.logback.core.pattern.color.BoldWhiteCompositeConverter import ch.qos.logback.core.pattern.color.ForegroundCompositeConverterBase import ch.qos.logback.core.pattern.color.ANSIConstants as ANSI private fun center(severity: String, width: Int = 7): String { val pad = width - severity.length if (pad <= 0) return severity val leading = pad / 2 return buildString { repeat(leading) { append(" ") } append(severity) repeat(pad - leading) { append(" ") } } } /** 8 bit ANSI codes (logback uses 3/4 bit which isn't always equivalent) */ object Codes { const val SET_DEFAULT_COLOR = ANSI.ESC_START + ANSI.RESET + ANSI.DEFAULT_FG + ANSI.ESC_END const val FG_START = ANSI.ESC_START + "38;5;" const val FG_BOLD_START = ANSI.ESC_START + ANSI.BOLD + "38;5;" const val BG_START = ANSI.ESC_START + "48;5;" const val RED = "9" const val BLACK = "16" const val GREEN = "22" const val BLUE = "27" const val ORANGE = "202" const val DIMMED_WHITE = "250" const val WHITE = "255" const val UNSET = "" } /** * Interface of HighlightingCompositeConverterExt, used to colour the background and foreground of log messages * depending on their severity. * * Inheritor of ForegroundCompositeConverterBase, the implementation controlling colour-based transformations of * log events * * @see HighlightingCompositeConverterExt * @see CompositeConverter */ abstract class ForegroundBackgroundCompositeConverter : ForegroundCompositeConverterBase() { override fun transform(event: E, `in`: String) = buildString { val fg = getForegroundColorCode(event) val bg = getBackgroundColourCode(event) val severity = center(`in`.trim()) if (fg.isNotEmpty()) { append(Codes.FG_BOLD_START) append(fg) append(ANSI.ESC_END) } if (bg.isNotEmpty()) { append(Codes.BG_START) append(getBackgroundColourCode(event)) append(ANSI.ESC_END) } append(severity) append(Codes.SET_DEFAULT_COLOR) } abstract fun getBackgroundColourCode(event: ILoggingEvent): String } /** * Converter class extension for control over backgrounds and foregrounds< * * Overrides methods of ForegroundBackgroundCompositeConverter to specify the bg/fg colours depending on severity * * Adapted from [shuwada/logback-custom-color](https://github.com/shuwada/logback-custom-color) */ class HighlightingCompositeConverterExt : ForegroundBackgroundCompositeConverter() { override fun getForegroundColorCode(event: ILoggingEvent) = when (event.level) { Level.TRACE -> Codes.WHITE Level.DEBUG -> Codes.WHITE Level.WARN -> Codes.WHITE Level.INFO -> Codes.WHITE Level.ERROR -> Codes.WHITE else -> Codes.UNSET } override fun getBackgroundColourCode(event: ILoggingEvent) = when (event.level) { Level.TRACE -> Codes.BLACK Level.DEBUG -> Codes.GREEN Level.WARN -> Codes.ORANGE Level.INFO -> Codes.BLUE Level.ERROR -> Codes.RED else -> Codes.UNSET } } /** * Converter rule which pulls out the last string of the thread split by spaces */ class ThreadConverter : CompositeConverter() { override fun transform(event: E, `in`: String) = `in`.split(" ").last() } /** * Converter rule which converts text to bold white */ class BoldWhiteCompositeConverterExt : BoldWhiteCompositeConverter() { override fun transform(event: E, `in`: String) = Codes.FG_BOLD_START + Codes.DIMMED_WHITE + ANSI.ESC_END + `in` + Codes.SET_DEFAULT_COLOR }