Logger.kt

  1. package com.hexagonkt.core.logging

  2. import com.hexagonkt.core.text.stripAnsi
  3. import java.lang.System.Logger.Level
  4. import java.lang.System.Logger.Level.*
  5. import kotlin.reflect.KClass

  6. /**
  7.  * Logger class with Kotlin usability improvements. It is backed by a [System.Logger] instance.
  8.  *
  9.  * @param name Logger name. It is shown in the logs messages and used for log filtering.
  10.  * @sample com.hexagonkt.core.logging.LoggerTest.loggerUsage
  11.  */
  12. class Logger(
  13.     val name: String,
  14.     internal val logger: System.Logger = System.getLogger(name)
  15. ) {

  16.     /**
  17.      * Logger class with Kotlin improvements like lazy evaluation.
  18.      *
  19.      * @param type Logger type. It is shown in the logs messages and used for log filtering.
  20.      */
  21.     constructor(type: KClass<*>):
  22.         this(type.qualifiedName ?: error("Cannot get qualified name of type"))

  23.     /**
  24.      * Check if this logger is enabled for a given log level.
  25.      *
  26.      * @param level Level to check.
  27.      * @return True if this logger is enabled for the supplied level.
  28.      */
  29.     fun isLoggable(level: Level): Boolean =
  30.         logger.isLoggable(level)

  31.     /**
  32.      * Log a message, with associated exception information.
  33.      *
  34.      * @param level Level used in the log statement.
  35.      * @param exception The exception associated with log message.
  36.      * @param message The message supplier to use in the log statement.
  37.      */
  38.     fun <E : Throwable> log(level: Level, exception: E, message: (E) -> Any?) {
  39.         val messageSupplier = { stripAnsi(message(exception), useColor) }
  40.         logger.log(level, messageSupplier, exception)
  41.     }

  42.     /**
  43.      * Log a message.
  44.      *
  45.      * @param level Level used in the log statement.
  46.      * @param message The message supplier to use in the log statement.
  47.      */
  48.     fun log(level: Level, message: () -> Any?) {
  49.         val messageSupplier = { stripAnsi(message(), useColor) }
  50.         logger.log(level, messageSupplier)
  51.     }

  52.     /**
  53.      * Log a message using [TRACE] level.
  54.      *
  55.      * @param message The required message to log.
  56.      */
  57.     fun trace(message: () -> Any?) {
  58.         log(TRACE, message)
  59.     }

  60.     /**
  61.      * Log a message using [DEBUG] level.
  62.      *
  63.      * @param message The required message to log.
  64.      */
  65.     fun debug(message: () -> Any?) {
  66.         log(DEBUG, message)
  67.     }

  68.     /**
  69.      * Log a message using [INFO] level.
  70.      *
  71.      * @param message The required message to log.
  72.      */
  73.     fun info(message: () -> Any?) {
  74.         log(INFO, message)
  75.     }

  76.     /**
  77.      * Log a message using [WARNING] level.
  78.      *
  79.      * @param message The required message to log.
  80.      */
  81.     fun warn(message: () -> Any?) {
  82.         log(WARNING, message)
  83.     }

  84.     /**
  85.      * Log a message using [ERROR] level.
  86.      *
  87.      * @param message The required message to log.
  88.      */
  89.     fun error(message: () -> Any?) {
  90.         log(ERROR, message)
  91.     }

  92.     /**
  93.      * Log a message using [WARNING] level with associated exception information.
  94.      *
  95.      * @param exception The exception associated with log message.
  96.      * @param message The message to log (optional). If not supplied it will be empty.
  97.      */
  98.     fun <E : Throwable> warn(exception: E?, message: (E?) -> Any? = { "" }) {
  99.         if (exception == null) log(WARNING) { message(null) }
  100.         else log(WARNING, exception, message)
  101.     }

  102.     /**
  103.      * Log a message using [ERROR] level with associated exception information.
  104.      *
  105.      * @param exception The exception associated with log message.
  106.      * @param message The message to log (function to optional). If not supplied it will be empty.
  107.      */
  108.     fun <E : Throwable> error(exception: E?, message: (E?) -> Any? = { "" }) {
  109.         if (exception == null) log(ERROR) { message(null) }
  110.         else log(ERROR, exception, message)
  111.     }

  112.     internal fun <T> stripAnsi(receiver: T?, apply: Boolean): String? =
  113.         receiver?.toString()?.let { if (apply) it.stripAnsi() else it }
  114. }