commonMain.com.caesarealabs.loggy.shared.Invocation.kt Maven / Gradle / Ivy
The newest version!
package com.caesarealabs.loggy.shared
import com.benasher44.uuid.uuid4
import com.caesarealabs.logging.LogSeverity
import com.caesarealabs.rpc4k.runtime.user.UUID
import kotlinx.datetime.Instant
import kotlinx.serialization.Contextual
import kotlinx.serialization.Serializable
import kotlin.jvm.JvmInline
/**
* The logging content of a single invocation of an endpoint.
*/
@Serializable
data class Invocation(
val endpoint: String,
// Use date-based serialization on mongo
@Contextual val startTime: Instant, @Contextual val endTime: Instant,
val metadata: List, val logs: List,
val id: InvocationId
) {
override fun toString(): String {
val metadataString = if(metadata.isEmpty()) "" else "{\n\t${metadata.joinToString("\n\t")}\n},\n"
return "<$endpoint #$id>: From $startTime to $endTime:\n${metadataString}[\n\t${logs.joinToString("\n\t")}\n]"
}
/**
* While [Invocation]s may not have severity by themselves, they do contain [Log]s that have an attached severity for each.
* We consider the importance of an entire [Invocation] by the maximum severity of its messages.
* If it has no messages, the importance is considered [LogSeverity.Verbose].
*/
val importance: LogSeverity by lazy {
logs.maxOfOrNull { it.severity } ?: LogSeverity.Verbose
}
}
@Serializable
@JvmInline
value class InvocationId private constructor(val value: UUID) {
override fun toString(): String = value.toString()
companion object {
fun generate() = InvocationId(uuid4())
}
}
/**
* Data representing a single line of logging.
* @param exception A caught exception, prompting this log to occur. Usually severity will be Error when exception is not null.
*/
@Serializable
data class Log(val message: String, @Contextual val time: Instant, val severity: LogSeverity, val exception: SerializableThrowable? = null) {
override fun toString(): String {
val str = "$severity at $time: $message"
return if (exception == null) str else "$str Error:\n$exception"
}
}
/**
* Additional information attached to an invocation. Generally, [key] is constant while [value] changes on each invocation.
*/
@Serializable
data class InvocationMetadata(
val key: String,
val value: String
) {
override fun toString(): String {
return "$key: $value"
}
}