### API Reference Code Example Placeholder Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/MANIFEST.md A section for real usage examples should be included. ```kotlin // Real usage examples ``` -------------------------------- ### Multiplatform Project Logging Setup Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/configuration.md Configure logging for a multiplatform project by defining common setup and platform-specific implementations for log levels. ```kotlin // src/commonMain/kotlin/logging/LoggingSetup.kt import io.github.oshai.kotlinlogging.KotlinLogging val logger = KotlinLogging.logger {} expect fun setupLogging() ``` ```kotlin // src/jvmMain/kotlin/logging/LoggingSetup.kt import io.github.oshai.kotlinlogging.KotlinLoggingConfiguration import io.github.oshai.kotlinlogging.Level actual fun setupLogging() { KotlinLoggingConfiguration.direct.logLevel = Level.DEBUG } ``` ```kotlin // src/jsMain/kotlin/logging/LoggingSetup.kt import io.github.oshai.kotlinlogging.KotlinLoggingConfiguration import io.github.oshai.kotlinlogging.Level actual fun setupLogging() { KotlinLoggingConfiguration.direct.logLevel = Level.INFO // JS-specific configuration } ``` ```kotlin // src/nativeMain/kotlin/logging/LoggingSetup.kt import io.github.oshai.kotlinlogging.KotlinLoggingConfiguration import io.github.oshai.kotlinlogging.Level actual fun setupLogging() { KotlinLoggingConfiguration.direct.logLevel = Level.WARN // Native-specific configuration } ``` -------------------------------- ### Basic Logging Example Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/INDEX.md Demonstrates basic info logging using the default logger. Ensure the logger is initialized. ```kotlin import io.github.oshai.kotlinlogging.KotlinLogging private val logger = KotlinLogging.logger {} fun handleRequest() { logger.info { "Processing request" } } ``` -------------------------------- ### Complete Fluent Logging Example Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/types.md A comprehensive example of fluent logging, including message, null cause, and structured data built with a map. ```kotlin logger.atInfo { message = "Request processed" cause = null payload = buildMap(capacity = 3) { put("requestId", "req123") put("userId", "user456") put("responseTime", 145L) } } ``` -------------------------------- ### Using DirectLoggerFactory Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/KLoggerFactory.md Example demonstrating how to switch to and use the DirectLoggerFactory. This is useful for platforms without standard logging frameworks or when direct logging is preferred. ```kotlin import io.github.oshai.kotlinlogging.KotlinLoggingConfiguration import io.github.oshai.kotlinlogging.DirectLoggerFactory // Switch to direct logging KotlinLoggingConfiguration.loggerFactory = DirectLoggerFactory val logger = KotlinLogging.logger("com.example.MyClass") logger.info { "Using direct logging" } ``` -------------------------------- ### Basic Kotlin Logging Setup Source: https://github.com/oshai/kotlin-logging/blob/master/README.md Demonstrates how to initialize a logger and use it for debug messages in Kotlin. Ensure the kotlin-logging library is added as a dependency. ```Kotlin import io.github.oshai.kotlinlogging.KotlinLogging private val logger = KotlinLogging.logger {} class FooWithLogging { val message = "world" fun bar() { logger.debug { "hello $message" } } } ``` -------------------------------- ### File Appender Example Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/Formatter_and_Appender.md Example implementation of a FormattingAppender that writes log messages to a specified file. ```APIDOC ### Example - File Appender ```kotlin import io.github.oshai.kotlinlogging.FormattingAppender import io.github.oshai.kotlinlogging.KLoggingEvent import io.github.oshai.kotlinlogging.KotlinLoggingConfiguration import java.io.File import java.io.FileWriter class FileAppender(private val filePath: String) : FormattingAppender() { private val file = File(filePath) init { file.createNewFile() } override fun logFormattedMessage(loggingEvent: KLoggingEvent, formattedMessage: Any?) { FileWriter(file, true).use { writer -> writer.append(formattedMessage.toString()) writer.append("\n") } } } KotlinLoggingConfiguration.direct.appender = FileAppender("app.log") ``` ``` -------------------------------- ### Complete Direct Logging Configuration Example Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/KotlinLoggingConfiguration.md Demonstrates how to initialize and configure direct logging in Kotlin. This includes disabling startup messages, setting the logger factory, and configuring log level, formatter, and appender. ```kotlin import io.github.oshai.kotlinlogging.KotlinLogging import io.github.oshai.kotlinlogging.KotlinLoggingConfiguration import io.github.oshai.kotlinlogging.Level import io.github.oshai.kotlinlogging.DirectLoggerFactory import io.github.oshai.kotlinlogging.Formatter import io.github.oshai.kotlinlogging.Appender import io.github.oshai.kotlinlogging.KLoggingEvent class Application { fun initialize() { // Disable startup message KotlinLoggingConfiguration.logStartupMessage = false // Use direct logging KotlinLoggingConfiguration.loggerFactory = DirectLoggerFactory // Configure direct logging with(KotlinLoggingConfiguration.direct) { logLevel = Level.DEBUG formatter = DefaultMessageFormatter(includePrefix = true) appender = ConsoleAppender() } } } class ConsoleAppender : Appender { override fun log(loggingEvent: KLoggingEvent) { val formatter = KotlinLoggingConfiguration.direct.formatter val message = formatter.formatMessage(loggingEvent) println(message) } } fun main() { Application().initialize() val logger = KotlinLogging.logger {} logger.debug { "Application started" } } ``` -------------------------------- ### JsonFormatter Implementation Example Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/Formatter_and_Appender.md An example implementation of the Formatter interface that formats log events into a JSON string. ```kotlin import io.github.oshai.kotlinlogging.Formatter import io.github.oshai.kotlinlogging.KLoggingEvent import java.time.Instant import java.time.ZoneId import java.time.format.DateTimeFormatter class JsonFormatter : Formatter { override fun formatMessage(loggingEvent: KLoggingEvent): String { val instant = Instant.ofEpochMilli(loggingEvent.timestamp) val dateTime = instant.atZone(ZoneId.systemDefault()) val formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME return buildString { append("{") append("\"timestamp\":\"${formatter.format(dateTime)}\",") append("\"level\":\"${loggingEvent.level}\",") append("\"logger\":\"${loggingEvent.loggerName}\",") append("\"message\":\"${loggingEvent.message}\"") append("}") } } } ``` -------------------------------- ### Example: File Appender Implementation Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/Formatter_and_Appender.md A concrete implementation of FormattingAppender that writes formatted log messages to a specified file. Ensure the file path is correctly provided when creating an instance. ```kotlin import io.github.oshai.kotlinlogging.FormattingAppender import io.github.oshai.kotlinlogging.KLoggingEvent import io.github.oshai.kotlinlogging.KotlinLoggingConfiguration import java.io.File import java.io.FileWriter class FileAppender(private val filePath: String) : FormattingAppender() { private val file = File(filePath) init { file.createNewFile() } override fun logFormattedMessage(loggingEvent: KLoggingEvent, formattedMessage: Any?) { FileWriter(file, true).use { writer -> writer.append(formattedMessage.toString()) writer.append("\n") } } } KotlinLoggingConfiguration.direct.appender = FileAppender("app.log") ``` -------------------------------- ### Rotating File Appender Example Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/Formatter_and_Appender.md Example implementation of a FormattingAppender that rotates log files based on size. ```APIDOC ### Example - Rotating File Appender ```kotlin import io.github.oshai.kotlinlogging.FormattingAppender import io.github.oshai.kotlinlogging.KLoggingEvent import io.github.oshai.kotlinlogging.KotlinLoggingConfiguration import java.io.File import java.io.FileWriter class RotatingFileAppender( private val baseDir: String, private val maxFileSizeBytes: Long = 10 * 1024 * 1024 ) : FormattingAppender() { private var currentFile = File(baseDir, "app.log") private var currentSize = 0L init { currentFile.parentFile?.mkdirs() currentFile.createNewFile() } override fun logFormattedMessage(loggingEvent: KLoggingEvent, formattedMessage: Any?) { val line = "$formattedMessage\n" if (currentSize + line.length > maxFileSizeBytes) { rotateFile() } FileWriter(currentFile, true).use { writer -> writer.append(line) currentSize += line.length } } private fun rotateFile() { val timestamp = System.currentTimeMillis() val backupFile = File(currentFile.parent, "app.log.$timestamp") currentFile.renameTo(backupFile) currentFile = File(currentFile.parent, "app.log") currentFile.createNewFile() currentSize = 0L } } KotlinLoggingConfiguration.direct.appender = RotatingFileAppender("/var/log") ``` ``` -------------------------------- ### ConsoleAppender Implementation Example Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/Formatter_and_Appender.md An example implementation of the Appender interface that logs messages to the console (stdout or stderr). It uses the configured formatter. ```kotlin import io.github.oshai.kotlinlogging.Appender import io.github.oshai.kotlinlogging.KLoggingEvent import io.github.oshai.kotlinlogging.KotlinLoggingConfiguration class ConsoleAppender : Appender { override fun log(loggingEvent: KLoggingEvent) { val formatter = KotlinLoggingConfiguration.direct.formatter val formattedMessage = formatter.formatMessage(loggingEvent) if (loggingEvent.level == Level.ERROR) { System.err.println(formattedMessage) } else { System.out.println(formattedMessage) } } } KotlinLoggingConfiguration.direct.appender = ConsoleAppender() ``` -------------------------------- ### Exception Logging Example Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/INDEX.md Logs an error with an exception and a message. Use the appropriate overload for exceptions. ```kotlin try { riskyOperation() } catch (e: Exception) { logger.error(e) { "Operation failed" } } ``` -------------------------------- ### Structured Logging Example Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/INDEX.md Logs a message with a structured payload. Use the fluent API for adding payloads. ```kotlin logger.atInfo { message = "Order processed" payload = mapOf("orderId" to orderId, "amount" to amount) } ``` -------------------------------- ### Example Usage of KLoggingEvent Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/types.md Demonstrates how to create an instance of the KLoggingEvent data class with various properties, including structured payload data. Ensure necessary imports are present. ```kotlin import io.github.oshai.kotlinlogging.KLoggingEvent import io.github.oshai.kotlinlogging.Level import io.github.oshai.kotlinlogging.Marker val event = KLoggingEvent( level = Level.INFO, marker = null, loggerName = "com.example.Service", message = "User login successful", cause = null, payload = mapOf( "userId" to "user123", "timestamp" to System.currentTimeMillis(), "ipAddress" to "192.168.1.1" ), timestamp = System.currentTimeMillis() ) ``` -------------------------------- ### Set Log Level with Logback Source: https://github.com/oshai/kotlin-logging/wiki/Home Configure log level globally for JVM projects using Logback. This example shows how to set and retrieve the log level. ```kotlin import ch.qos.logback.classic.Level import ch.qos.logback.classic.Logger var slf4jLogger get() = (logger as DelegatingKLogger).underlyingLogger var logbackLogger get() = (slf4jLogger.underlyingLogger) as ch.qos.logback.classic.Logger var io.github.oshai.kotlinlogging.KLogger.level get() = logbackLogger.level set(value) { logbackLogger.level = value } logger.level = Level.DEBUG logger.level //=> Level.DEBUG ``` -------------------------------- ### Example: Rotating File Appender Implementation Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/Formatter_and_Appender.md An appender that writes logs to a file and rotates it when it reaches a maximum size. Configure the base directory and optionally set a maximum file size. ```kotlin import io.github.oshai.kotlinlogging.FormattingAppender import io.github.oshai.kotlinlogging.KLoggingEvent import io.github.oshai.kotlinlogging.KotlinLoggingConfiguration import java.io.File import java.io.FileWriter class RotatingFileAppender( private val baseDir: String, private val maxFileSizeBytes: Long = 10 * 1024 * 1024 ) : FormattingAppender() { private var currentFile = File(baseDir, "app.log") private var currentSize = 0L init { currentFile.parentFile?.mkdirs() currentFile.createNewFile() } override fun logFormattedMessage(loggingEvent: KLoggingEvent, formattedMessage: Any?) { val line = "$formattedMessage\n" if (currentSize + line.length > maxFileSizeBytes) { rotateFile() } FileWriter(currentFile, true).use { writer -> writer.append(line) currentSize += line.length } } private fun rotateFile() { val timestamp = System.currentTimeMillis() val backupFile = File(currentFile.parent, "app.log.$timestamp") currentFile.renameTo(backupFile) currentFile = File(currentFile.parent, "app.log") currentFile.createNewFile() currentSize = 0L } } KotlinLoggingConfiguration.direct.appender = RotatingFileAppender("/var/log") ``` -------------------------------- ### Example Usage of DefaultMessageFormatter Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/Formatter_and_Appender.md Demonstrates how to configure the KotlinLoggingConfiguration to use DefaultMessageFormatter with or without a prefix. ```kotlin import io.github.oshai.kotlinlogging.KotlinLoggingConfiguration import io.github.oshai.kotlinlogging.DefaultMessageFormatter // Use formatter with prefix KotlinLoggingConfiguration.direct.formatter = DefaultMessageFormatter(includePrefix = true) // Use formatter without prefix KotlinLoggingConfiguration.direct.formatter = DefaultMessageFormatter(includePrefix = false) ``` -------------------------------- ### Darwin DelegatingKLogger Example Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/DelegatingKLogger.md Illustrates how to check if a Darwin logger (iOS/macOS) is a `DelegatingKLogger` wrapping an `os_log_t` and access the native OS log API. ```kotlin import io.github.oshai.kotlinlogging.KotlinLogging import io.github.oshai.kotlinlogging.DelegatingKLogger import platform.darwin.os_log_t val logger = KotlinLogging.logger("com.example.App") if (logger is DelegatingKLogger) { val osLog = logger.underlyingLogger // Use os_log_t directly if needed } ``` -------------------------------- ### Example Usage of DelegatingKLogger in Kotlin Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/types.md Demonstrates how to check if a logger is a DelegatingKLogger and access its underlying logger. Requires importing KotlinLogging and DelegatingKLogger. ```kotlin import io.github.oshai.kotlinlogging.KotlinLogging import io.github.oshai.kotlinlogging.DelegatingKLogger val logger = KotlinLogging.logger("com.example.MyClass") if (logger is DelegatingKLogger<*>) { val underlying = logger.underlyingLogger println("Underlying logger type: ${underlying::class.simpleName}") } ``` -------------------------------- ### JVM LocationAwareKLogger Example Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/DelegatingKLogger.md Demonstrates how to check if a logger is a `DelegatingKLogger` wrapping a `LocationAwareLogger` on the JVM and access the underlying logger. ```kotlin import io.github.oshai.kotlinlogging.KotlinLogging import io.github.oshai.kotlinlogging.DelegatingKLogger import org.slf4j.spi.LocationAwareLogger val logger = KotlinLogging.logger("com.example.MyClass") if (logger is DelegatingKLogger) { val locationAware = logger.underlyingLogger println("Logger supports location awareness") } ``` -------------------------------- ### Successful Signature Verification Output Source: https://github.com/oshai/kotlin-logging/blob/master/SECURITY.md This is an example of the expected output when a GPG signature verification is successful. Look for 'Good signature' to confirm authenticity. ```bash $ gpg --verify kotlin-logging-jvm-7.0.3.jar.asc kotlin-logging-jvm-7.0.3.jar gpg: using RSA key 36D4E9618F3ADAB5 gpg: Good signature from "Ohad Shai " [unknown] gpg: WARNING: This key is not certified with a trusted signature! gpg: There is no indication that the signature belongs to the owner. Primary key fingerprint: 47EB 6836 245D 2D40 E89D FB41 36D4 E961 8F3A DAB5 ``` -------------------------------- ### Implementing a Custom Logger Factory Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/KLoggerFactory.md Create a custom logger factory by implementing the KLoggerFactory interface. This involves defining a custom logger and installing the factory. ```kotlin import io.github.oshai.kotlinlogging.KLogger import io.github.oshai.kotlinlogging.KLoggerFactory import io.github.oshai.kotlinlogging.KLoggingEventBuilder import io.github.oshai.kotlinlogging.Level import io.github.oshai.kotlinlogging.Marker class CustomLoggerFactory : KLoggerFactory { override fun logger(name: String): KLogger { return CustomLogger(name) } } class CustomLogger(override val name: String) : KLogger { override fun at(level: Level, marker: Marker?, block: KLoggingEventBuilder.() -> Unit) { val builder = KLoggingEventBuilder() builder.apply(block) // Custom logic to send log event to your system sendToCustomBackend(level, marker, builder.message, builder.cause) } override fun isLoggingEnabledFor(level: Level, marker: Marker?): Boolean { // Custom logic to determine if level is enabled return true } private fun sendToCustomBackend(level: Level, marker: Marker?, message: String?, cause: Throwable?) { // Implementation specific to your logging backend } } // Install your factory KotlinLoggingConfiguration.loggerFactory = CustomLoggerFactory() ``` -------------------------------- ### Android DelegatingKLogger Example Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/DelegatingKLogger.md Shows how to check if an Android logger is a `DelegatingKLogger` and access its underlying logger. Note that Android loggers may not always implement `DelegatingKLogger`. ```kotlin import io.github.oshai.kotlinlogging.KotlinLogging import io.github.oshai.kotlinlogging.DelegatingKLogger val logger = KotlinLogging.logger("com.example.App") // Android loggers may or may not implement DelegatingKLogger if (logger is DelegatingKLogger<*>) { val underlying = logger.underlyingLogger } ``` -------------------------------- ### Import Public Key from keys.openpgp.org Source: https://github.com/oshai/kotlin-logging/blob/master/SECURITY.md Use this command to import the public GPG key from the keys.openpgp.org keyserver. This is the first step in verifying artifact signatures. ```bash gpg --keyserver hkps://keys.openpgp.org --recv-keys 47EB6836245D2D40E89DFB4136D4E9618F3ADAB5 ``` -------------------------------- ### Get Logger Name Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/KLogger.md Retrieves the name of the current logger instance. ```kotlin public val name: String ``` -------------------------------- ### Basic Logging with Kotlin Logging Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/README.md Demonstrates basic logging of informational, debug, and error messages. Ensure the `io.github.oshai.kotlinlogging.KotlinLogging` library is imported. ```kotlin import io.github.oshai.kotlinlogging.KotlinLogging private val logger = KotlinLogging.logger {} fun main() { logger.info { "Hello World" } logger.debug { "Debug message with lazy evaluation" } logger.error(exception) { "Error occurred" } } ``` -------------------------------- ### Import Public Key for Versions 2.0.8-2.0.11 Source: https://github.com/oshai/kotlin-logging/blob/master/SECURITY.md Command to import the GPG public key for older versions of kotlin-logging (2.0.8-2.0.11) from the Ubuntu keyserver. ```bash > FINGER_PRINT=637B8FB6CD0B57CA1E833E897F083A4AB2AF5107 > gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys $FINGER_PRINT ``` -------------------------------- ### Get String Representation of a Log Level Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/Level.md Returns the string representation of this level. This is useful for display purposes. ```kotlin println(Level.ERROR.toString()) // Output: ERROR ``` -------------------------------- ### Import Public Key from Ubuntu Keyserver Source: https://github.com/oshai/kotlin-logging/blob/master/SECURITY.md Use this command to import the public GPG key from the Ubuntu keyserver. This is an alternative to using keys.openpgp.org for key retrieval. ```bash gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys 47EB6836245D2D40E89DFB4136D4E9618F3ADAB5 ``` -------------------------------- ### Simple Fluent Logging Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/types.md Demonstrates basic fluent logging using the logger instance and setting only the message. ```kotlin logger.atInfo { message = "User action completed" } ``` -------------------------------- ### Dynamic Context Building with Kotlin Logging Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/JVM_MDC.md Demonstrates building a context map dynamically before passing it to `withLoggingContext` for setting MDC values. ```kotlin withLoggingContext(buildMap { put("userId", userId) put("orderId", orderId) put("amount", amount.toString()) }) { logger.info { "Processing order" } } ``` -------------------------------- ### Get Underlying Logger Instance Source: https://github.com/oshai/kotlin-logging/wiki/Home Access the actual SLF4J logger instance using the 'underlyingLogger' property on DelegatingKLogger. This is platform-dependent. ```kotlin (logger as? DelegatingKLogger)?.underlyingLogger ``` -------------------------------- ### Configure JVM with SLF4J and Logback Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/configuration.md Set up kotlin-logging to use SLF4J with Logback as the logging implementation. Ensure SLF4J and Logback dependencies are included. ```kotlin import io.github.oshai.kotlinlogging.KotlinLogging import io.github.oshai.kotlinlogging.KotlinLoggingConfiguration import io.github.oshai.kotlinlogging.slf4j.internal.Slf4jLoggerFactory // This is the default, but explicitly set for clarity KotlinLoggingConfiguration.loggerFactory = Slf4jLoggerFactory KotlinLoggingConfiguration.logStartupMessage = true val logger = KotlinLogging.logger {} logger.info { "Using SLF4J with Logback" } ``` ```gradle dependencies { implementation 'io.github.oshai:kotlin-logging-jvm:8.0.5' runtimeOnly 'ch.qos.logback:logback-classic:1.4.x' } ``` ```xml %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n ``` -------------------------------- ### Import Public Key for Versions 2.0.2-2.0.7 Source: https://github.com/oshai/kotlin-logging/blob/master/SECURITY.md Command to import the GPG public key for even older versions of kotlin-logging (2.0.2-2.0.7) from the Ubuntu keyserver. ```bash > FINGER_PRINT=E52567D2589415BD74EB4C2867631BC0568801C3 > gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys $FINGER_PRINT ``` -------------------------------- ### Run Full Build Source: https://github.com/oshai/kotlin-logging/blob/master/CONTRIBUTING.md Execute the complete build process, including tests and compilation. This is a standard command for ensuring code integrity. ```bash ./gradlew clean build ``` -------------------------------- ### Configure JVM with Direct Logging Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/configuration.md Switch to using the direct logging implementation provided by kotlin-logging. This avoids external dependencies like SLF4J. ```kotlin import io.github.oshai.kotlinlogging.KotlinLogging import io.github.oshai.kotlinlogging.KotlinLoggingConfiguration import io.github.oshai.kotlinlogging.DirectLoggerFactory import io.github.oshai.kotlinlogging.Level import io.github.oshai.kotlinlogging.DefaultMessageFormatter // Switch to direct logging KotlinLoggingConfiguration.loggerFactory = DirectLoggerFactory KotlinLoggingConfiguration.logStartupMessage = false // Configure direct logging output with(KotlinLoggingConfiguration.direct) { logLevel = Level.DEBUG formatter = DefaultMessageFormatter(includePrefix = true) appender = DefaultAppender() } val logger = KotlinLogging.logger {} logger.debug { "Using direct logging" } ``` ```gradle dependencies { implementation 'io.github.oshai:kotlin-logging-jvm:8.0.5' } ``` -------------------------------- ### Global Logging Configuration Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/INDEX.md Configure the logger factory and whether to log a startup message globally. ```kotlin KotlinLoggingConfiguration.loggerFactory: KLoggerFactory KotlinLoggingConfiguration.logStartupMessage: Boolean ``` -------------------------------- ### Get Integer Value of a Log Level Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/Level.md Returns the integer value representing this logging level. Use this to compare log levels numerically. ```kotlin val level = Level.DEBUG println(level.toInt()) // Output: 10 ``` -------------------------------- ### Basic Marker Usage in a Service Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/Marker.md Illustrates how to use markers to log debug information within a service class, differentiating between database and cache operations. ```kotlin import io.github.oshai.kotlinlogging.KotlinLogging import io.github.oshai.kotlinlogging.KMarkerFactory private val logger = KotlinLogging.logger {} private val dbMarker = KMarkerFactory.getMarker("DATABASE") private val cacheMarker = KMarkerFactory.getMarker("CACHE") class DataService { fun loadUser(userId: String) { logger.debug(dbMarker) { "Loading user from database: $userId" } // ... } fun getCachedUser(userId: String) { logger.debug(cacheMarker) { "Retrieving user from cache: $userId" } // ... } } ``` -------------------------------- ### Direct Logging Configuration Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/INDEX.md Configure the log level, formatter, and appender for direct logging. ```kotlin KotlinLoggingConfiguration.direct.logLevel: Level KotlinLoggingConfiguration.direct.formatter: Formatter KotlinLoggingConfiguration.direct.appender: Appender ``` -------------------------------- ### kotlin-logging withLoggingContext Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/JVM_MDC.md Shows the simplified approach to MDC context management provided by kotlin-logging's `withLoggingContext` function. ```kotlin import io.github.oshai.kotlinlogging.withLoggingContext withLoggingContext("userId" to userId) { // do work } ``` -------------------------------- ### API Reference Title Format Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/MANIFEST.md Each API reference file should begin with a title, package information, source, and platform. ```markdown # Type Name Package: ... Source: ... Platform: ... ``` -------------------------------- ### Exclude Kotlin Logging from Jacoco Report Source: https://github.com/oshai/kotlin-logging/wiki/Coverage-reporting Add this configuration to your Jacoco setup to exclude lines related to the logger field name from coverage reports. This is useful when log configuration is marked as uncalled. ```xml **/*$log$*.class ``` -------------------------------- ### Fluent Logging with Structured Data Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/types.md Illustrates logging with structured data using the 'payload' property for key-value pairs. ```kotlin logger.atWarn { message = "Performance issue detected" payload = mapOf( "duration" to 500L, "threshold" to 100L, "endpoint" to "/api/users" ) } ``` -------------------------------- ### Logging Exceptions with Markers Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/Marker.md Demonstrates how to attach a marker to an error log when an exception occurs, providing context for critical failures. ```kotlin val errorMarker = KMarkerFactory.getMarker("CRITICAL_ERROR") try { riskyDatabaseOperation() } catch (e: DatabaseException) { logger.error(errorMarker, e) { "Database operation failed" } } ``` -------------------------------- ### Apply Code Formatting Source: https://github.com/oshai/kotlin-logging/blob/master/CONTRIBUTING.md Automatically format the code to comply with project standards. Use this to fix any formatting issues detected by spotlessCheck. ```bash ./gradlew spotlessApply ``` -------------------------------- ### Log Method Entry with Arguments Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/KLogger.md Logs the entry into a method with optional arguments at the TRACE level. Use this to track method invocations and their parameters. ```kotlin fun processOrder(orderId: String, amount: Double) { logger.entry(orderId, amount) // ... } ``` -------------------------------- ### Basic Usage of withLoggingContextAsync Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/KotlinLoggingAsyncMDC.md Demonstrates setting multiple MDC values from a map for a suspend block and logging within that context. ```kotlin import io.github.oshai.kotlinlogging.KotlinLogging import io.github.oshai.kotlinlogging.coroutines.withLoggingContextAsync private val logger = KotlinLogging.logger {} suspend fun handleRequest(contextMap: Map) { withLoggingContextAsync(contextMap) { logger.info { "Processing with context" } doAsyncWork() } } suspend fun doAsyncWork() { logger.debug { "Async work with inherited context" } delay(100) } ``` -------------------------------- ### Nested Async Context Management Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/KotlinLoggingAsyncMDC.md Demonstrates how `withLoggingContextAsync` can be nested to manage different MDC contexts at various levels of operation. ```kotlin suspend fun outerOperation(operationId: String) { withLoggingContextAsync("operationId" to operationId) { logger.info { "Outer operation started" } innerOperation() logger.info { "Outer operation completed" } } } suspend fun innerOperation() { withLoggingContextAsync("step" to "initialization") { logger.info { "Step 1: Initialization" } delay(100) } withLoggingContextAsync("step" to "processing") { logger.info { "Step 2: Processing" } delay(100) } withLoggingContextAsync("step" to "finalization") { logger.info { "Step 3: Finalization" } delay(100) } } ``` -------------------------------- ### Multi-tenant Context with MDC Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/JVM_MDC.md Add tenant and user IDs to the MDC for logging operations specific to a tenant. This helps in isolating and analyzing logs for different tenants. ```kotlin fun processForTenant(tenantId: String, userId: String) { withLoggingContext( "tenantId" to tenantId, "userId" to userId ) { logger.info { "Processing for tenant" } performTenantOperation() } } ``` -------------------------------- ### Using SLF4J Marker with kotlin-logging Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/types.md Demonstrates how to convert an SLF4J marker to a kotlin-logging marker and use it for logging. Ensure SLF4J is configured. ```kotlin import io.github.oshai.kotlinlogging.slf4j.toKotlinLogging import org.slf4j.MarkerFactory val slf4jMarker = MarkerFactory.getMarker("REQUEST_ID") val kMarker = slf4jMarker.toKotlinLogging() logger.info(kMarker) { "Processing request" } ``` -------------------------------- ### Raw SLF4J MDC Usage Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/JVM_MDC.md Demonstrates the manual way to manage MDC context using raw SLF4J, including setting, retrieving, and cleaning up values. ```kotlin import org.slf4j.MDC val previousValue = MDC.get("userId") try { MDC.put("userId", userId) // do work } finally { if (previousValue != null) { MDC.put("userId", previousValue) } else { MDC.remove("userId") } } ``` -------------------------------- ### Calling Framework-Specific Methods (SLF4J/Logback) Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/DelegatingKLogger.md Illustrates how to cast the underlying logger to an SLF4J Logger and use both kotlin-logging and SLF4J APIs. ```kotlin import io.github.oshai.kotlinlogging.KotlinLogging import io.github.oshai.kotlinlogging.DelegatingKLogger import org.slf4j.Logger val klogger = KotlinLogging.logger("com.example.Service") if (klogger is DelegatingKLogger<*>) { val slf4jLogger = klogger.underlyingLogger as? Logger // Use kotlin-logging API klogger.info { "Using kotlin-logging" } // Use SLF4J API when needed slf4jLogger?.info("Using SLF4J directly") } ``` -------------------------------- ### Configure MDC Context for Logging (JVM) Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/configuration.md Add contextual information like user ID and request ID to log messages using MDC (Mapped Diagnostic Context). Requires Logback configuration for pattern matching. ```kotlin import io.github.oshai.kotlinlogging.KotlinLogging import io.github.oshai.kotlinlogging.withLoggingContext val logger = KotlinLogging.logger {} fun handleRequest(userId: String, requestId: String) { withLoggingContext( "userId" to userId, "requestId" to requestId ) { logger.info { "Handling request" } processRequest() } } ``` ```xml %d [%X{userId}] [%X{requestId}] %-5level %logger{36} - %msg%n ``` -------------------------------- ### Enable or Disable Startup Message Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/configuration.md Control whether a startup message is logged when the library initializes. This is enabled by default. ```kotlin import io.github.oshai.kotlinlogging.KotlinLoggingConfiguration // Enable startup message (default) KotlinLoggingConfiguration.logStartupMessage = true // Output: kotlin-logging: initializing... active logger factory: Slf4jLoggerFactory // Disable startup message KotlinLoggingConfiguration.logStartupMessage = false ``` -------------------------------- ### Request Tracing with Logging Context (JVM) Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/README.md Illustrates how to add context like user ID and request ID to log messages within a specific block using `withLoggingContext`. This is particularly useful for tracing requests in a JVM environment. ```kotlin import io.github.oshai.kotlinlogging.withLoggingContext withLoggingContext("userId" to userId, "requestId" to requestId) { logger.info { "Processing request" } processRequest() } ``` -------------------------------- ### Using Markers with Fluent API Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/Marker.md Shows how to leverage markers within the fluent logging API to include structured payload data along with the log message. ```kotlin val auditMarker = KMarkerFactory.getMarker("AUDIT") logger.atInfo(auditMarker) { message = "User login successful" payload = mapOf( "userId" to "user123", "loginTime" to System.currentTimeMillis(), "ipAddress" to "192.168.1.1" ) } ``` -------------------------------- ### atInfo(block: KLoggingEventBuilder.() -> Unit) Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/KLogger.md Logs a message at the INFO level using the fluent API. It accepts a lambda block that configures the logging event. ```APIDOC ## atInfo(block: KLoggingEventBuilder.() -> Unit) ### Description Logs a message at the INFO level using the fluent API. It accepts a lambda block that configures the logging event. ### Method `atInfo` ### Parameters #### Lambda Block - `block` (KLoggingEventBuilder.() -> Unit) - Required - A lambda function that configures the logging event using the `KLoggingEventBuilder`. ``` -------------------------------- ### entry(vararg arguments: Any?): Unit Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/KLogger.md Logs method entry with optional arguments at TRACE level. ```APIDOC ## entry(vararg arguments: Any?): Unit ### Description Logs method entry with optional arguments at TRACE level. ### Signature ```kotlin public fun entry(vararg arguments: Any?): Unit ``` ### Example ```kotlin fun processOrder(orderId: String, amount: Double) { logger.entry(orderId, amount) // ... } ``` ``` -------------------------------- ### Darwin Logging Configuration Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/KotlinLoggingConfiguration.md Configures the logger factory and startup message for Darwin platforms. Uses DarwinLoggerFactory by default. ```kotlin // src/darwinMain/kotlin/io/github/oshai/kotlinlogging/KotlinLoggingConfiguration.kt public actual object KotlinLoggingConfiguration { public actual var loggerFactory: KLoggerFactory = DarwinLoggerFactory public actual var logStartupMessage: Boolean = true public actual val direct: DirectLoggingConfiguration = DirectLoggingConfigurationImpl() } ``` -------------------------------- ### Async Request Handling with MDC Context Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/KotlinLoggingAsyncMDC.md Illustrates setting request-specific MDC context (requestId, userId, path) for handling an asynchronous HTTP request. ```kotlin import io.github.oshai.kotlinlogging.KotlinLogging import io.github.oshai.kotlinlogging.coroutines.withLoggingContextAsync import kotlinx.coroutines.delay import java.util.UUID private val logger = KotlinLogging.logger {} suspend fun handleRequest(request: HttpRequest) { val requestId = UUID.randomUUID().toString() val userId = request.headers["X-User-Id"] ?: "anonymous" withLoggingContextAsync( "requestId" to requestId, "userId" to userId, "path" to request.path ) { logger.info { "Request received" } try { val response = processRequestAsync(request) logger.info { "Request completed successfully" } sendResponse(response) } catch (e: Exception) { logger.error(e) { "Request failed" } sendError(e) } } } suspend fun processRequestAsync(request: HttpRequest): Response { // userId, requestId, path are all available in MDC logger.debug { "Starting request processing" } delay(100) return Response() } ``` -------------------------------- ### Verify Artifact Signature Source: https://github.com/oshai/kotlin-logging/blob/master/SECURITY.md Use this command to verify the signature of a downloaded artifact against its corresponding .asc signature file. Ensure you replace the filenames with the actual downloaded files. ```bash gpg --verify kotlin-logging-jvm-7.0.3.jar.asc kotlin-logging-jvm-7.0.3.jar ``` -------------------------------- ### Using Markers for Log Categorization Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/README.md Shows how to use `KMarkerFactory` to create and apply markers to log messages, enabling categorization and filtering of logs, such as for auditing or performance monitoring. ```kotlin import io.github.oshai.kotlinlogging.KMarkerFactory private val auditMarker = KMarkerFactory.getMarker("AUDIT") private val perfMarker = KMarkerFactory.getMarker("PERFORMANCE") logger.info(auditMarker) { "User login" } logger.warn(perfMarker) { "Slow request: 500ms" } ``` -------------------------------- ### API Reference Parameter Table Format Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/MANIFEST.md Parameters should be documented in a table format with columns for Parameter, Type, Required, Default, and Description. ```markdown | Parameter | Type | Required | Default | Description | | ``` -------------------------------- ### Log Info Message with Marker and Throwable Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/KLogger.md Logs an INFO message with both a marker and a throwable. The message is lazily evaluated. ```kotlin public fun info(marker: Marker?, throwable: Throwable?, message: () -> Any?): Unit ``` -------------------------------- ### Platform-Specific Conversions (Logback) Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/Marker.md Provides an extension function to convert kotlin-logging Marker to Logback Marker. ```APIDOC ### Logback ```kotlin // Convert kotlin-logging Marker to Logback Marker public fun Marker.toLogback(): org.slf4j.Marker ``` **Example** ```kotlin import io.github.oshai.kotlinlogging.logback.toLogback val kMarker = KMarkerFactory.getMarker("EVENT") val logbackMarker = kMarker.toLogback() ``` ``` -------------------------------- ### JVM/Android Logging Configuration Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/KotlinLoggingConfiguration.md Configures the logger factory and startup message for JVM/Android platforms. Uses Slf4jLoggerFactory by default. ```kotlin // src/jvmMain/kotlin/io/github/oshai/kotlinlogging/KotlinLoggingConfiguration.kt public actual object KotlinLoggingConfiguration { public actual var loggerFactory: KLoggerFactory = Slf4jLoggerFactory public actual var logStartupMessage: Boolean = true public actual val direct: DirectLoggingConfiguration = DirectLoggingConfigurationImpl() } ``` -------------------------------- ### Obtain a Logger Instance Source: https://github.com/oshai/kotlin-logging/wiki/Multiplatform-support Instantiate a logger using `KotlinLogging.logger {}`. This method is supported only by a field and does not support inheritance at the moment. ```kotlin private val logger = KotlinLogging.logger {} ``` -------------------------------- ### KMarkerFactory getMarker() Method Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/Marker.md Shows how to create Marker instances using the KMarkerFactory. This is useful for associating specific contexts with log messages. ```kotlin import io.github.oshai.kotlinlogging.KMarkerFactory val performanceMarker = KMarkerFactory.getMarker("PERFORMANCE") val securityMarker = KMarkerFactory.getMarker("SECURITY") logger.info(securityMarker) { "Unauthorized access attempt" } logger.warn(performanceMarker) { "Request took 500ms" } ``` -------------------------------- ### atWarn(block: KLoggingEventBuilder.() -> Unit) Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/KLogger.md Logs a message at the WARN level using the fluent API. It accepts a lambda block that configures the logging event. ```APIDOC ## atWarn(block: KLoggingEventBuilder.() -> Unit) ### Description Logs a message at the WARN level using the fluent API. It accepts a lambda block that configures the logging event. ### Method `atWarn` ### Parameters #### Lambda Block - `block` (KLoggingEventBuilder.() -> Unit) - Required - A lambda function that configures the logging event using the `KLoggingEventBuilder`. ``` -------------------------------- ### Fluent Logging with Exception Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/types.md Shows how to log an error with an associated exception using the fluent API. ```kotlin logger.atError { message = "Operation failed" cause = exception } ``` -------------------------------- ### SimpleMarker Implementation Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/Marker.md Internal implementation of the Marker interface, providing a basic, immutable marker with a name. ```kotlin internal data class SimpleMarker(private val name: String) : Marker { override fun getName(): String = this.name } ``` -------------------------------- ### MDC Context Configuration (JVM only) Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/INDEX.md Configure the MDC (Mapped Diagnostic Context) for structured logging on the JVM. ```APIDOC ## MDC Context Configuration (JVM only) ### Description Configure the MDC (Mapped Diagnostic Context) for structured logging on the JVM. ### Functions - `withLoggingContext(pair: Pair, block: () -> Unit)` - `withLoggingContext(vararg pairs: Pair, block: () -> Unit)` - `withLoggingContext(map: Map, block: () -> Unit)` - `withLoggingContextAsync(pair: Pair, block: suspend () -> Unit)` - `withLoggingContextAsync(vararg pairs: Pair, block: suspend () -> Unit)` - `withLoggingContextAsync(map: Map, block: suspend () -> Unit)` ``` -------------------------------- ### Define Direct Logging Configuration Interface Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/KotlinLoggingConfiguration.md Defines the interface for direct logging configuration, specifying properties for log level, formatter, and appender. ```kotlin public interface DirectLoggingConfiguration { public var logLevel: Level public var formatter: Formatter public var appender: Appender } ``` -------------------------------- ### atInfo(marker: Marker?, block: KLoggingEventBuilder.() -> Unit) Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/KLogger.md Logs a message at the INFO level with an associated marker using the fluent API. ```APIDOC ## atInfo(marker: Marker?, block: KLoggingEventBuilder.() -> Unit) ### Description Logs a message at the INFO level with an associated marker using the fluent API. It accepts a lambda block that configures the logging event. ### Method `atInfo` ### Parameters #### Path Parameters - **marker** (Marker?) - Optional - The marker to associate with the log event. #### Lambda Block - `block` (KLoggingEventBuilder.() -> Unit) - Required - A lambda function that configures the logging event using the `KLoggingEventBuilder`. ``` -------------------------------- ### Utility Logging Methods Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/INDEX.md Provides utility methods for logging method entries, exits, and exceptions. ```APIDOC ## Utility Logging Methods ### Description Provides utility methods for logging method entries, exits, and exceptions. ### Methods - `entry()` — Log method entry with arguments. - `exit()` — Log method exit. - `throwing(throwable: Throwable)` — Log exception before throwing. - `catching(throwable: Throwable)` — Log caught exception. ``` -------------------------------- ### API Reference Signature Format Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/MANIFEST.md The complete signature of the method or function should be provided. ```kotlin public fun methodName(param: Type): ReturnType ``` -------------------------------- ### Platform-Specific Conversions (SLF4J/JVM) Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/Marker.md Provides extension functions to convert between kotlin-logging Marker and SLF4J Marker. ```APIDOC ## Platform-Specific Conversions Different platforms support different marker implementations. kotlin-logging provides conversion functions: ### SLF4J/JVM (Java) ```kotlin // Convert kotlin-logging Marker to SLF4J Marker public fun Marker.toSlf4j(): org.slf4j.Marker // Convert SLF4J Marker to kotlin-logging Marker public fun org.slf4j.Marker.toKotlinLogging(): Marker ``` **Example** ```kotlin import io.github.oshai.kotlinlogging.slf4j.toSlf4j val kMarker = KMarkerFactory.getMarker("REQUEST_ID") val slf4jMarker = kMarker.toSlf4j() // Use slf4jMarker with SLF4J loggers ``` ``` -------------------------------- ### Level Comparison Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/api-reference/Level.md Demonstrates how Level enumerations can be compared using standard operators based on their integer values. ```APIDOC ## Level Comparison Levels can be compared using standard comparison operators since they are comparable by their integer values: ```kotlin if (Level.ERROR > Level.WARN) { // True - ERROR has higher priority } val enabledLevels = listOf(Level.WARN, Level.INFO, Level.TRACE) .sortedDescending() // Result: [WARN, INFO, TRACE] (by priority) ``` ``` -------------------------------- ### Custom Formatter and File Appender Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/configuration.md Defines a custom formatter for ISO timestamp logging and a file appender to write logs to a file. Import necessary classes for formatting and logging events. ```kotlin import io.github.oshai.kotlinlogging.KotlinLoggingConfiguration import io.github.oshai.kotlinlogging.Formatter import io.github.oshai.kotlinlogging.FormattingAppender import io.github.oshai.kotlinlogging.KLoggingEvent import java.time.Instant import java.time.ZoneId import java.time.format.DateTimeFormatter class IsoTimestampFormatter : Formatter { private val formatter = DateTimeFormatter .ISO_LOCAL_DATE_TIME .withZone(ZoneId.systemDefault()) override fun formatMessage(loggingEvent: KLoggingEvent): String { val timestamp = formatter.format( Instant.ofEpochMilli(loggingEvent.timestamp) ) return "$timestamp [${loggingEvent.level}] ${loggingEvent.loggerName}: ${loggingEvent.message}" } } class FileAppender(private val filePath: String) : FormattingAppender() { override fun logFormattedMessage(loggingEvent: KLoggingEvent, formattedMessage: Any?) { java.io.File(filePath).appendText("$formattedMessage\n") } } fun configureLogging() { KotlinLoggingConfiguration.direct.formatter = IsoTimestampFormatter() KotlinLoggingConfiguration.direct.appender = FileAppender("app.log") } ``` -------------------------------- ### Obtain a Logger with KotlinLogging Source: https://github.com/oshai/kotlin-logging/wiki/Home Use KotlinLogging.logger {} to obtain an idiomatic logger instance. Place it above the class declaration for static accessibility within the file. ```kotlin import io.github.oshai.kotlinlogging.KotlinLogging // Place definition above class declaration, below imports, // to make field static and accessible only within the file private val logger = KotlinLogging.logger {} ``` -------------------------------- ### Structured Logging with Payload Source: https://github.com/oshai/kotlin-logging/blob/master/_autodocs/README.md Shows how to log structured messages with a payload, useful for including contextual data like order IDs or amounts. This requires the logger instance to be available. ```kotlin logger.atInfo { message = "Order processed" payload = mapOf( "orderId" to "ORD-123", "amount" to 99.99, "status" to "completed" ) } ```