<commit_before>package wvlet.log

import scala.scalajs.js.Dynamic.global
import java.util.{logging => jl}

/**
  *
  */
class JSConsoleLogHandler() extends jl.Handler {

  def cssOf(l:LogLevel) : String = l match {
    case LogLevel.ERROR => "color:#D32F2F"
    case LogLevel.WARN => "color:#E64A19"
    case LogLevel.INFO =>  "color:#0097A7"
    case LogLevel.DEBUG => "color:#388E3C"
    case LogLevel.TRACE => "color:#7B1FA2"
    case _ => ""
  }

  override def flush(): Unit = {}

  override def publish(record: jl.LogRecord): Unit = {
    record match {
      case r: LogRecord =>
        val ts = LogTimestampFormatter.formatTimestamp(r.getMillis)
        val level = f"${r.level.name}%5s"
        val logLevelCSS = cssOf(r.level)
        val loc =
          r.source
          .map(source => s"- (${source.fileLoc})")
          .getOrElse("")

        import scala.scalajs.js.DynamicImplicits.truthValue
        if (global.selectDynamic("console")) {
          global.console.log(
            s"""%c${ts} %c${level} %c[${r.leafLoggerName}] %c${r.message} %c${loc}""",
            "color:#5C6BC0", // timestamp
            logLevelCSS,
            "color:#78909C", // logger name
            logLevelCSS,     // log message
            "color:#B0BEC5" // loc
          )
        }
      case _ =>
        publish(LogRecord(record))
    }
  }

  override def close(): Unit = {}
}<commit_msg>Add color palette<commit_after>package wvlet.log

import scala.scalajs.js.Dynamic.global
import java.util.{logging => jl}

import wvlet.log.JSConsoleLogHandler.JSLogColorPalette


class JSConsoleLogHandler(logColorPalette: JSLogColorPalette = JSConsoleLogHandler.DEFAULT_COLOR_PALETTE) extends jl.Handler {

  override def publish(record: jl.LogRecord): Unit = {
    record match {
      case r: LogRecord =>
        val ts = LogTimestampFormatter.formatTimestamp(r.getMillis)
        val level = f"${r.level.name}%5s"
        val logLevelCSS = logColorPalette.cssOf(r.level)
        val loc =
          r.source
          .map(source => s"- (${source.fileLoc})")
          .getOrElse("")

        import scala.scalajs.js.DynamicImplicits.truthValue
        if (global.selectDynamic("console")) {
          global.console.log(
            s"""%c${ts} %c${level} %c[${r.leafLoggerName}] %c${r.message} %c${loc}""",
            s"color:${logColorPalette.timestamp}", // timestamp
            logLevelCSS,
            s"color:${logColorPalette.loggerName}", // logger name
            logLevelCSS,     // log message
            s"color:${logColorPalette.codeLocation}" // loc
          )
        }
      case _ =>
        publish(LogRecord(record))
    }
  }

  override def flush(): Unit = {}
  override def close(): Unit = {}
}

object JSConsoleLogHandler {
  val DEFAULT_COLOR_PALETTE : JSLogColorPalette = new JSLogColorPalette()

  case class JSLogColorPalette(
    error:String = "#D32F2F",
    warn:String = "#E64A19",
    info:String = "#0097A7",
    debug:String = "#388E3C",
    trace:String = "#7B1FA2",
    timestamp:String = "#5C6BC0",
    loggerName:String = "#78909C",
    codeLocation:String = "#B0BEC5",
    default:String = ""
  ) {
    def cssOf(l:LogLevel) : String = l match {
      case LogLevel.ERROR => s"color:${error}"
      case LogLevel.WARN => s"color:${debug}"
      case LogLevel.INFO =>  s"color:${info}"
      case LogLevel.DEBUG => s"color:${debug}"
      case LogLevel.TRACE => s"color:${trace}"
      case _ => default
    }
  }
}

{'fraction_non_alphanumeric': 0.14615829000577701, 'fraction_numerical': 0.01733102253032929, 'mean_word_length': 2.548155737704918, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6719809', 'n_tokens_mistral': 1182, 'n_tokens_neox': 1135, 'n_words': 212}