All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.com.caesarealabs.loggy.lib.InvocationToConsole.kt Maven / Gradle / Ivy

package com.caesarealabs.loggy.lib

import com.caesarealabs.logging.LogSeverity
import com.caesarealabs.loggy.shared.Invocation
import kotlinx.datetime.Instant
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime


private const val AnsiReset = "\u001B[0m"

private const val AnsiRed = "\u001B[31m"

private const val AnsiGreen = "\u001B[32m"

private const val AnsiYellow = "\u001B[33m"

private const val AnsiGrey = "\u001b[37;1m"
private const val AnsiBold = "\u001b[1m"

private fun String.colored(color: String?) = if(color == null) this else "$color$this$AnsiReset"
private fun String.bold() = "$AnsiBold$this$AnsiReset"

/**
 * Will convert this invocation into a string that looks nice when printed to the console.
 * Will use colors if [colored] is true.
 */
internal fun Invocation.renderToString(): String {
    if (logs.isEmpty() && metadata.isEmpty()) return ""

    return buildString {
        append("[${startTime.systemDate()} ${startTime.systemTimeOfDay()} -> ${endTime.systemTimeOfDay()}]".colored(AnsiGrey))
        append(" $endpoint {\n".bold())
        if (metadata.isNotEmpty()) {
            append("\t${"Details".bold()} {\n")
            for (detail in metadata) {
                append("\t\t${detail.key}: ${detail.value.colored(AnsiGreen)}\n")
            }
            append("\t}\n")
        }
        if (logs.isNotEmpty()) {
            append("\t${"Messages".bold()} {\n")
            for (message in logs) {
                val color = when (message.severity) {
                    LogSeverity.Info -> null
                    LogSeverity.Warn -> AnsiYellow
                    LogSeverity.Error -> AnsiRed
                    LogSeverity.Debug -> AnsiGreen
                    LogSeverity.Verbose -> AnsiGrey
                }
                append("\t\t")
                append("[${message.time.systemTimeOfDay()}]".colored(AnsiGrey))
                append(" ${message.severity.name.uppercase()}: ${message.message}\n".colored(color))
            }
            append("\t}\n")
        }
        val exceptions = logs.filter { it.exception != null }
        if (exceptions.isNotEmpty()) {
            append("\t${"Exceptions".bold()} {\n")
            for (message in exceptions) {
                append("\t\t")
                for(element in message.exception!!){
                    append((element.stacktrace.replace("\n", "\n\t\t") + "\n").colored(AnsiRed))
                }

            }
            append("\t}\n")
        }

        append("}".bold())
    }

}

private val Int.twoCharacters get() = toString().let { if (it.length == 1) "0$it" else it }
private val Int.threeCharacters
    get() = toString().let {
        "0".repeat(3 - it.length) + it
    }

private fun Instant.systemTimeOfDay(): String = with(toLocalDateTime(TimeZone.currentSystemDefault())) {
    "${hour.twoCharacters}:${minute.twoCharacters}:${second.twoCharacters}" +
            ".${(nanosecondsOfSecond / 1_000_000).threeCharacters}"
}

internal fun Instant.systemDate(): String = with(toLocalDateTime(TimeZone.currentSystemDefault())) {
    "${dayOfMonth.twoCharacters}/${monthNumber.twoCharacters}/$year"
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy