From d78628e349935866a05f192b81491b9a1759c23d Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sat, 13 Sep 2025 19:21:04 +0100 Subject: [PATCH 01/38] Bump version -> `2.0.0-SNAPSHOT.390` --- version.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.gradle.kts b/version.gradle.kts index 490dccc1..5a3f3015 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -24,4 +24,4 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -val versionToPublish: String by extra("2.0.0-SNAPSHOT.380") +val versionToPublish: String by extra("2.0.0-SNAPSHOT.390") From 48911d79eda73261df42c3098d1911011df9e962 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sat, 13 Sep 2025 19:46:30 +0100 Subject: [PATCH 02/38] Pull more classes to `commonMain` --- .../io/spine/logging/CountingRateLimiter.kt | 0 .../io/spine/logging/DurationRateLimiter.kt | 0 .../kotlin/io/spine/logging/LogContext.kt | 7 +++---- .../io/spine/logging/LogPerBucketingStrategy.kt | 17 ++++++++++++++++- .../io/spine/logging/LogSiteGroupingKey.kt | 0 .../kotlin/io/spine/logging/LogSiteMap.kt | 0 .../io/spine/logging/LogSiteStackTrace.kt | 13 ++++++++++++- .../kotlin/io/spine/logging/LoggingScope.kt | 10 ++++++++++ .../kotlin/io/spine/logging/MutableMetadata.kt | 0 .../kotlin/io/spine/logging/RateLimitPeriod.kt | 0 .../kotlin/io/spine/logging/RateLimitStatus.kt | 0 .../io/spine/logging/SamplingRateLimiter.kt | 0 .../io/spine/logging/StackTraceElement.kt | 9 +++++++++ .../io/spine/logging/LogPerBucketingStrategy.kt | 4 ++-- .../io/spine/logging/LogSiteStackTrace.kt | 11 ++++++++++- .../kotlin/io/spine/logging/LoggingScope.kt | 4 ++-- ...ceElement.jvm.kt => StackTraceElementJvm.kt} | 10 ++++++++++ 17 files changed, 74 insertions(+), 11 deletions(-) rename logging/src/{jvmMain => commonMain}/kotlin/io/spine/logging/CountingRateLimiter.kt (100%) rename logging/src/{jvmMain => commonMain}/kotlin/io/spine/logging/DurationRateLimiter.kt (100%) rename logging/src/{jvmMain => commonMain}/kotlin/io/spine/logging/LogContext.kt (99%) rename logging/src/{jvmMain => commonMain}/kotlin/io/spine/logging/LogSiteGroupingKey.kt (100%) rename logging/src/{jvmMain => commonMain}/kotlin/io/spine/logging/LogSiteMap.kt (100%) rename logging/src/{jvmMain => commonMain}/kotlin/io/spine/logging/MutableMetadata.kt (100%) rename logging/src/{jvmMain => commonMain}/kotlin/io/spine/logging/RateLimitPeriod.kt (100%) rename logging/src/{jvmMain => commonMain}/kotlin/io/spine/logging/RateLimitStatus.kt (100%) rename logging/src/{jvmMain => commonMain}/kotlin/io/spine/logging/SamplingRateLimiter.kt (100%) rename logging/src/jvmMain/kotlin/io/spine/logging/{StackTraceElement.jvm.kt => StackTraceElementJvm.kt} (84%) diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/CountingRateLimiter.kt b/logging/src/commonMain/kotlin/io/spine/logging/CountingRateLimiter.kt similarity index 100% rename from logging/src/jvmMain/kotlin/io/spine/logging/CountingRateLimiter.kt rename to logging/src/commonMain/kotlin/io/spine/logging/CountingRateLimiter.kt diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/DurationRateLimiter.kt b/logging/src/commonMain/kotlin/io/spine/logging/DurationRateLimiter.kt similarity index 100% rename from logging/src/jvmMain/kotlin/io/spine/logging/DurationRateLimiter.kt rename to logging/src/commonMain/kotlin/io/spine/logging/DurationRateLimiter.kt diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/LogContext.kt b/logging/src/commonMain/kotlin/io/spine/logging/LogContext.kt similarity index 99% rename from logging/src/jvmMain/kotlin/io/spine/logging/LogContext.kt rename to logging/src/commonMain/kotlin/io/spine/logging/LogContext.kt index ee76638a..56d59dff 100644 --- a/logging/src/jvmMain/kotlin/io/spine/logging/LogContext.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/LogContext.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023, The Flogger Authors; 2025, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,7 +33,6 @@ import io.spine.logging.backend.Metadata import io.spine.logging.backend.Platform import io.spine.logging.context.Tags import io.spine.logging.util.Checks.checkNotNull -import io.spine.reflect.CallerFinder.stackForCallerOf import kotlin.time.DurationUnit /** @@ -315,10 +314,10 @@ protected constructor( // // By skipping the initial code inside this method, we don't trigger any stack // capture until after the "log" method. - val context = LogSiteStackTrace( + val context = LogSiteStackTrace.create( _metadata!!.findValue(Key.LOG_CAUSE), stackSize, - stackForCallerOf(LogContext::class.java, stackSize.maxDepth, 1) + stackForCallerOf(LogContext::class, stackSize.maxDepth, 1) ) // The "cause" is a unique metadata key, we must replace any existing value. addMetadata(Key.LOG_CAUSE, context) diff --git a/logging/src/commonMain/kotlin/io/spine/logging/LogPerBucketingStrategy.kt b/logging/src/commonMain/kotlin/io/spine/logging/LogPerBucketingStrategy.kt index 1c819e20..84d0faa1 100644 --- a/logging/src/commonMain/kotlin/io/spine/logging/LogPerBucketingStrategy.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/LogPerBucketingStrategy.kt @@ -26,8 +26,23 @@ package io.spine.logging +import io.spine.annotation.TestOnly + /** * Platform-neutral marker for a bucketing strategy used by * [LoggingApi.per(key, strategy)][LoggingApi.per]. */ -public expect abstract class LogPerBucketingStrategy +public expect abstract class LogPerBucketingStrategy { + + internal fun doApply(key: T): Any? + + /** + * Access to the [apply] method for testing purposes. + * + * This method is not part of the public API and should not be used by client code. + */ + @TestOnly + internal fun applyForTesting(key: T): Any? +} + + diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/LogSiteGroupingKey.kt b/logging/src/commonMain/kotlin/io/spine/logging/LogSiteGroupingKey.kt similarity index 100% rename from logging/src/jvmMain/kotlin/io/spine/logging/LogSiteGroupingKey.kt rename to logging/src/commonMain/kotlin/io/spine/logging/LogSiteGroupingKey.kt diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/LogSiteMap.kt b/logging/src/commonMain/kotlin/io/spine/logging/LogSiteMap.kt similarity index 100% rename from logging/src/jvmMain/kotlin/io/spine/logging/LogSiteMap.kt rename to logging/src/commonMain/kotlin/io/spine/logging/LogSiteMap.kt diff --git a/logging/src/commonMain/kotlin/io/spine/logging/LogSiteStackTrace.kt b/logging/src/commonMain/kotlin/io/spine/logging/LogSiteStackTrace.kt index 803998e6..4fc78202 100644 --- a/logging/src/commonMain/kotlin/io/spine/logging/LogSiteStackTrace.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/LogSiteStackTrace.kt @@ -30,4 +30,15 @@ package io.spine.logging * A synthetic exception which can be attached to log statements when additional stack trace * information is required in log files or via tools such as ECatcher. */ -public expect class LogSiteStackTrace +@Suppress("UtilityClassWithPublicConstructor") +public expect class LogSiteStackTrace : Throwable { + + public companion object { + + public fun create( + cause: Throwable?, + stackSize: StackSize, + syntheticStackTrace: Array + ): LogSiteStackTrace + } +} diff --git a/logging/src/commonMain/kotlin/io/spine/logging/LoggingScope.kt b/logging/src/commonMain/kotlin/io/spine/logging/LoggingScope.kt index f89e2bcc..d7f05910 100644 --- a/logging/src/commonMain/kotlin/io/spine/logging/LoggingScope.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/LoggingScope.kt @@ -94,4 +94,14 @@ public expect abstract class LoggingScope { * all the currently active scopes which apply to it. */ protected abstract fun onClose(removalHook: () -> Unit) + + /** + * Opens [specialize] for the package. + */ + internal fun doSpecialize(key: LogSiteKey): LogSiteKey + + /** + * Opens access to [onClose] for the package. + */ + internal fun doOnClose(removalHook: () -> Unit) } diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/MutableMetadata.kt b/logging/src/commonMain/kotlin/io/spine/logging/MutableMetadata.kt similarity index 100% rename from logging/src/jvmMain/kotlin/io/spine/logging/MutableMetadata.kt rename to logging/src/commonMain/kotlin/io/spine/logging/MutableMetadata.kt diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/RateLimitPeriod.kt b/logging/src/commonMain/kotlin/io/spine/logging/RateLimitPeriod.kt similarity index 100% rename from logging/src/jvmMain/kotlin/io/spine/logging/RateLimitPeriod.kt rename to logging/src/commonMain/kotlin/io/spine/logging/RateLimitPeriod.kt diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/RateLimitStatus.kt b/logging/src/commonMain/kotlin/io/spine/logging/RateLimitStatus.kt similarity index 100% rename from logging/src/jvmMain/kotlin/io/spine/logging/RateLimitStatus.kt rename to logging/src/commonMain/kotlin/io/spine/logging/RateLimitStatus.kt diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/SamplingRateLimiter.kt b/logging/src/commonMain/kotlin/io/spine/logging/SamplingRateLimiter.kt similarity index 100% rename from logging/src/jvmMain/kotlin/io/spine/logging/SamplingRateLimiter.kt rename to logging/src/commonMain/kotlin/io/spine/logging/SamplingRateLimiter.kt diff --git a/logging/src/commonMain/kotlin/io/spine/logging/StackTraceElement.kt b/logging/src/commonMain/kotlin/io/spine/logging/StackTraceElement.kt index 82de9e1e..5dd0b607 100644 --- a/logging/src/commonMain/kotlin/io/spine/logging/StackTraceElement.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/StackTraceElement.kt @@ -26,7 +26,16 @@ package io.spine.logging +import java.lang.StackTraceElement +import kotlin.reflect.KClass + /** * Platform-neutral representation of a stack trace element. */ public expect class StackTraceElement + +public expect fun stackForCallerOf( + target: KClass<*>, + maxDepth: Int, + skip: Int +): Array diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/LogPerBucketingStrategy.kt b/logging/src/jvmMain/kotlin/io/spine/logging/LogPerBucketingStrategy.kt index f14ebdeb..80d1787f 100644 --- a/logging/src/jvmMain/kotlin/io/spine/logging/LogPerBucketingStrategy.kt +++ b/logging/src/jvmMain/kotlin/io/spine/logging/LogPerBucketingStrategy.kt @@ -94,7 +94,7 @@ public actual abstract class LogPerBucketingStrategy protected constructor( */ protected abstract fun apply(key: T): Any? - internal fun doApply(key: T): Any? = apply(key) + internal actual fun doApply(key: T): Any? = apply(key) /** * Access to the [apply] method for testing purposes. @@ -102,7 +102,7 @@ public actual abstract class LogPerBucketingStrategy protected constructor( * This method is not part of the public API and should not be used by client code. */ @TestOnly - internal fun applyForTesting(key: T): Any? = apply(key) + internal actual fun applyForTesting(key: T): Any? = apply(key) override fun toString(): String = "${LogPerBucketingStrategy::class.java.simpleName}[$name]" diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/LogSiteStackTrace.kt b/logging/src/jvmMain/kotlin/io/spine/logging/LogSiteStackTrace.kt index 0a9b5b9f..cc8b0d1c 100644 --- a/logging/src/jvmMain/kotlin/io/spine/logging/LogSiteStackTrace.kt +++ b/logging/src/jvmMain/kotlin/io/spine/logging/LogSiteStackTrace.kt @@ -62,8 +62,17 @@ public actual class LogSiteStackTrace( @Suppress("NonSynchronizedMethodOverridesSynchronizedMethod") override fun fillInStackTrace(): Throwable = this - public companion object { + public actual companion object { + @Serial private const val serialVersionUID: Long = 0L + + public actual fun create( + cause: Throwable?, + stackSize: StackSize, + syntheticStackTrace: Array + ): LogSiteStackTrace { + return LogSiteStackTrace(cause, stackSize, syntheticStackTrace) + } } } diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/LoggingScope.kt b/logging/src/jvmMain/kotlin/io/spine/logging/LoggingScope.kt index 492dafe5..2e005f50 100644 --- a/logging/src/jvmMain/kotlin/io/spine/logging/LoggingScope.kt +++ b/logging/src/jvmMain/kotlin/io/spine/logging/LoggingScope.kt @@ -43,12 +43,12 @@ public actual abstract class LoggingScope protected constructor(private val labe /** * Opens [specialize] for the package. */ - internal fun doSpecialize(key: LogSiteKey): LogSiteKey = specialize(key) + internal actual fun doSpecialize(key: LogSiteKey): LogSiteKey = specialize(key) /** * Opens access to [onClose] for the package. */ - internal fun doOnClose(removalHook: () -> Unit) = onClose(removalHook) + internal actual fun doOnClose(removalHook: () -> Unit) = onClose(removalHook) /** * Returns the [label] of this scope. diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/StackTraceElement.jvm.kt b/logging/src/jvmMain/kotlin/io/spine/logging/StackTraceElementJvm.kt similarity index 84% rename from logging/src/jvmMain/kotlin/io/spine/logging/StackTraceElement.jvm.kt rename to logging/src/jvmMain/kotlin/io/spine/logging/StackTraceElementJvm.kt index f19f185b..0994972e 100644 --- a/logging/src/jvmMain/kotlin/io/spine/logging/StackTraceElement.jvm.kt +++ b/logging/src/jvmMain/kotlin/io/spine/logging/StackTraceElementJvm.kt @@ -26,4 +26,14 @@ package io.spine.logging +import io.spine.reflect.CallerFinder +import kotlin.reflect.KClass + public actual typealias StackTraceElement = java.lang.StackTraceElement + +public actual fun stackForCallerOf( + target: KClass<*>, + maxDepth: Int, + skip: Int +): Array = CallerFinder.stackForCallerOf(target.java, maxDepth, skip) + From 9a7f82b59164f0823362a96884bbca9f71273b94 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sat, 13 Sep 2025 19:46:40 +0100 Subject: [PATCH 03/38] Update dependency reports --- dependencies.md | 64 ++++++++++++++++++++++++------------------------- pom.xml | 2 +- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/dependencies.md b/dependencies.md index 5a4ea5e7..9a887ab9 100644 --- a/dependencies.md +++ b/dependencies.md @@ -1,6 +1,6 @@ -# Dependencies of `io.spine:spine-logging-context-tests:2.0.0-SNAPSHOT.380` +# Dependencies of `io.spine:spine-logging-context-tests:2.0.0-SNAPSHOT.390` ## Runtime 1. **Group** : org.jetbrains. **Name** : annotations. **Version** : 26.0.2. @@ -413,14 +413,14 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 14:12:16 WEST 2025** using +This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-logging-fixtures:2.0.0-SNAPSHOT.380` +# Dependencies of `io.spine:spine-logging-fixtures:2.0.0-SNAPSHOT.390` ## Runtime ## Compile, tests, and tooling @@ -1148,14 +1148,14 @@ This report was generated on **Sat Sep 13 14:12:16 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 14:12:17 WEST 2025** using +This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-logging-grpc-context:2.0.0-SNAPSHOT.380` +# Dependencies of `io.spine:spine-logging-grpc-context:2.0.0-SNAPSHOT.390` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -1982,14 +1982,14 @@ This report was generated on **Sat Sep 13 14:12:17 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 14:12:16 WEST 2025** using +This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-logging-jul-backend:2.0.0-SNAPSHOT.380` +# Dependencies of `io.spine:spine-logging-jul-backend:2.0.0-SNAPSHOT.390` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -2800,14 +2800,14 @@ This report was generated on **Sat Sep 13 14:12:16 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 14:12:16 WEST 2025** using +This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-logging-jvm-default-platform:2.0.0-SNAPSHOT.380` +# Dependencies of `io.spine:spine-logging-jvm-default-platform:2.0.0-SNAPSHOT.390` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -3662,14 +3662,14 @@ This report was generated on **Sat Sep 13 14:12:16 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 14:12:16 WEST 2025** using +This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-logging-jvm-jul-backend-grpc-context:2.0.0-SNAPSHOT.380` +# Dependencies of `io.spine:spine-logging-jvm-jul-backend-grpc-context:2.0.0-SNAPSHOT.390` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -4520,14 +4520,14 @@ This report was generated on **Sat Sep 13 14:12:16 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 14:12:17 WEST 2025** using +This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-logging-jvm-jul-backend-std-context:2.0.0-SNAPSHOT.380` +# Dependencies of `io.spine:spine-logging-jvm-jul-backend-std-context:2.0.0-SNAPSHOT.390` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -5370,14 +5370,14 @@ This report was generated on **Sat Sep 13 14:12:17 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 14:12:17 WEST 2025** using +This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-logging-jvm-log4j2-backend-std-context:2.0.0-SNAPSHOT.380` +# Dependencies of `io.spine:spine-logging-jvm-log4j2-backend-std-context:2.0.0-SNAPSHOT.390` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -6220,14 +6220,14 @@ This report was generated on **Sat Sep 13 14:12:17 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 14:12:17 WEST 2025** using +This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-logging-jvm-slf4j-jdk14-backend-std-context:2.0.0-SNAPSHOT.380` +# Dependencies of `io.spine:spine-logging-jvm-slf4j-jdk14-backend-std-context:2.0.0-SNAPSHOT.390` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -7078,14 +7078,14 @@ This report was generated on **Sat Sep 13 14:12:17 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 14:12:17 WEST 2025** using +This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-logging-jvm-slf4j-reload4j-backend-std-context:2.0.0-SNAPSHOT.380` +# Dependencies of `io.spine:spine-logging-jvm-slf4j-reload4j-backend-std-context:2.0.0-SNAPSHOT.390` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -7940,14 +7940,14 @@ This report was generated on **Sat Sep 13 14:12:17 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 14:12:17 WEST 2025** using +This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-logging-log4j2-backend:2.0.0-SNAPSHOT.380` +# Dependencies of `io.spine:spine-logging-log4j2-backend:2.0.0-SNAPSHOT.390` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -8782,14 +8782,14 @@ This report was generated on **Sat Sep 13 14:12:17 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 14:12:16 WEST 2025** using +This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-logging:2.0.0-SNAPSHOT.380` +# Dependencies of `io.spine:spine-logging:2.0.0-SNAPSHOT.390` ## Runtime ## Compile, tests, and tooling @@ -9521,14 +9521,14 @@ This report was generated on **Sat Sep 13 14:12:16 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 14:12:17 WEST 2025** using +This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:spine-logging-testlib:2.0.0-SNAPSHOT.380` +# Dependencies of `io.spine.tools:spine-logging-testlib:2.0.0-SNAPSHOT.390` ## Runtime ## Compile, tests, and tooling @@ -10256,14 +10256,14 @@ This report was generated on **Sat Sep 13 14:12:17 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 14:12:16 WEST 2025** using +This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-logging-probe-backend:2.0.0-SNAPSHOT.380` +# Dependencies of `io.spine:spine-logging-probe-backend:2.0.0-SNAPSHOT.390` ## Runtime 1. **Group** : com.google.auto.service. **Name** : auto-service-annotations. **Version** : 1.1.1. @@ -11122,14 +11122,14 @@ This report was generated on **Sat Sep 13 14:12:16 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 14:12:16 WEST 2025** using +This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-logging-smoke-test:2.0.0-SNAPSHOT.380` +# Dependencies of `io.spine:spine-logging-smoke-test:2.0.0-SNAPSHOT.390` ## Runtime 1. **Group** : com.fasterxml.jackson. **Name** : jackson-bom. **Version** : 2.18.3. @@ -12008,14 +12008,14 @@ This report was generated on **Sat Sep 13 14:12:16 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 14:12:16 WEST 2025** using +This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-logging-std-context:2.0.0-SNAPSHOT.380` +# Dependencies of `io.spine:spine-logging-std-context:2.0.0-SNAPSHOT.390` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -12826,6 +12826,6 @@ This report was generated on **Sat Sep 13 14:12:16 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 14:12:16 WEST 2025** using +This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file diff --git a/pom.xml b/pom.xml index f3d21719..4f439c54 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ all modules and does not describe the project structure per-subproject. --> io.spine spine-logging -2.0.0-SNAPSHOT.380 +2.0.0-SNAPSHOT.390 2015 From ed40a1cfcc976613e023c26c6ae3bcbb25118dbd Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sat, 13 Sep 2025 19:51:06 +0100 Subject: [PATCH 04/38] Remove unnecessary `expect/actual` arrangement --- .../spine/logging/LogPerBucketingStrategy.kt | 229 ++++++++++++++- .../spine/logging/LogPerBucketingStrategy.kt | 263 ------------------ 2 files changed, 222 insertions(+), 270 deletions(-) delete mode 100644 logging/src/jvmMain/kotlin/io/spine/logging/LogPerBucketingStrategy.kt diff --git a/logging/src/commonMain/kotlin/io/spine/logging/LogPerBucketingStrategy.kt b/logging/src/commonMain/kotlin/io/spine/logging/LogPerBucketingStrategy.kt index 84d0faa1..f0ee8c71 100644 --- a/logging/src/commonMain/kotlin/io/spine/logging/LogPerBucketingStrategy.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/LogPerBucketingStrategy.kt @@ -1,5 +1,5 @@ /* - * Copyright 2025, TeamDev. All rights reserved. + * Copyright 2023, The Flogger Authors; 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,12 +29,72 @@ package io.spine.logging import io.spine.annotation.TestOnly /** - * Platform-neutral marker for a bucketing strategy used by - * [LoggingApi.per(key, strategy)][LoggingApi.per]. + * Provides a strategy for "bucketing" a potentially unbounded set of log + * aggregation keys used by the [LoggingApi.per] method. + * + * When implementing new strategies not provided by this class, it is important + * to ensure that the [apply] method returns values from a bounded set of + * instances wherever possible. + * + * This is important because the returned values are held persistently for + * potentially many different log sites. + * + * If a different instance is returned each time [apply] is called, a + * different instance will be held in each log site. + * + * This multiplies the amount of memory that is retained indefinitely by + * any use of [LoggingApi.per]. + * + * One way to handle arbitrary key types would be to create a strategy which + * "interns" instances in some way, to produce singleton identifiers. + * + * Unfortunately, interning can itself be a cause of unbounded memory leaks, + * so a bucketing strategy wishing to perform interning should probably + * support a user defined maximum capacity to limit the overall risk. + * + * If too many instances are seen, the strategy should begin to return `null` + * (and log an appropriate warning). + * + * The additional complexity created by this approach really tells us that + * types which require interning in order to be used as aggregation keys + * should be considered unsuitable, and callers should seek alternatives. + * + * @param name The name of this strategy, used for debugging purposes. + * + * @see + * Original Java code for historical context. */ -public expect abstract class LogPerBucketingStrategy { +public abstract class LogPerBucketingStrategy protected constructor( + private val name: String +) { + /** + * Maps a log aggregation key from a potentially unbounded set of + * key values to a bounded set of instances. + * + * Implementations of this method should be efficient and avoid + * allocating memory wherever possible. + * + * The returned value must be an immutable identifier with minimal additional + * allocation requirements and ideally have singleton semantics + * (e.g., an [Enum] or [Integer] value). + * + * **Warning**: If keys are not known to have natural singleton semantics + * (e.g. [String]) then returning the given key instance is generally a bad idea. + * + * Even if the set of key values is small, the set of distinct allocated instances + * passed to [LoggingApi.per] can be unbounded, and that's what matters. + * + * As such, it is always better to map keys to some singleton identifier or + * intern the keys in some way. + * + * @param key A non-null key from a potentially unbounded set of log aggregation keys. + * @return an immutable value from some known bounded set, which will be held persistently by + * internal Flogger data structures as part of the log aggregation feature. If + * `null` is returned, the corresponding call to `per(key, STRATEGY)` has no effect. + */ + protected abstract fun apply(key: T): Any? - internal fun doApply(key: T): Any? + internal fun doApply(key: T): Any? = apply(key) /** * Access to the [apply] method for testing purposes. @@ -42,7 +102,162 @@ public expect abstract class LogPerBucketingStrategy { * This method is not part of the public API and should not be used by client code. */ @TestOnly - internal fun applyForTesting(key: T): Any? -} + internal fun applyForTesting(key: T): Any? = apply(key) + + override fun toString(): String = + "${LogPerBucketingStrategy::class.java.simpleName}[$name]" + + public companion object { + /** + * A strategy to use only if the set of log aggregation keys is known to be + * a strictly bounded set of instances with singleton semantics. + */ + private val KNOWN_BOUNDED = object : LogPerBucketingStrategy("KnownBounded") { + override fun apply(key: Any): Any = key + } + /** + * This is a "safe" strategy as far as memory use is concerned since class objects + * are effectively singletons. + */ + private val BY_CLASS = object : LogPerBucketingStrategy("ByClass") { + override fun apply(key: Any): Any = key.javaClass + } + + /** + * This is a "safe" strategy as far as memory use is concerned, because a class object + * returns the same string instance every time its called, and class objects + * are effectively singletons. + */ + private val BY_CLASS_NAME = object : LogPerBucketingStrategy("ByClassName") { + override fun apply(key: Any): Any = key.javaClass.name /* This is a naturally interned + value, so no need to call `intern()`. */ + } + + /** + * A strategy to use only if the set of log aggregation keys is known to be + * a strictly bounded set of instances with singleton semantics. + * + * **WARNING**: When using this strategy, keys passed to [LoggingApi.per] + * are used as-is by the log aggregation code, and held indefinitely by internal + * static data structures. + * + * As such it is vital that key instances used with this strategy have singleton semantics + * (i.e., if `k1.equals(k2)` then `k1 == k2`). + * + * Failure to adhere to this requirement is likely to result in hard to detect memory leaks. + * + * If keys do not have singleton semantics then you should use a different strategy, + * such as [byHashCode] or [byClass]. + */ + @JvmStatic + public fun knownBounded(): LogPerBucketingStrategy = KNOWN_BOUNDED + + /** + * A strategy which uses the [Class] of the given key for log aggregation. + * + * This is useful when you need to aggregate over specific exceptions or similar + * type-distinguished instances. + * + * Note that using this strategy will result in a reference to the [Class] object of + * the key being retained indefinitely. + * + * This will prevent class unloading from occurring for affected classes, and + * it is up to the caller to decide if this is acceptable or not. + */ + @JvmStatic + public fun byClass(): LogPerBucketingStrategy = BY_CLASS + + /** + * A strategy which uses the [Class] name of the given key for log aggregation. + * + * This is useful when you need to aggregate over specific exceptions or similar + * type-distinguished instances. + * + * This is an alternative strategy to [byClass] which avoids holding onto the class + * instance and avoids any issues with class unloading. + * + * However, it may conflate classes if applications use complex arrangements of custom + * class-loaders, but this should be extremely rare. + */ + @JvmStatic + public fun byClassName(): LogPerBucketingStrategy = BY_CLASS_NAME + + /** + * A strategy defined for some given set of known keys. + * + * Unlike [knownBounded], this strategy maps keys to a bounded set of identifiers, and + * permits the use of non-singleton keys in [LoggingApi.per]. + * + * If keys outside this set are used this strategy returns `null`, and + * log aggregation will not occur. + * + * Duplicates in [knownKeys] are ignored. + */ + @JvmStatic + public fun forKnownKeys(knownKeys: Iterable): LogPerBucketingStrategy { + val keyMap = HashMap() + val name = buildString { + append("ForKnownKeys(") + var index = 0 + for (key in knownKeys) { + if (!keyMap.containsKey(key)) { + if (index > 0) { + append(", ") + } + append(key) + keyMap[key] = index + index++ + } + } + append(')') + } + // We check here to avoid querying `knownKeys` size just for the precondition check. + require(!keyMap.isEmpty()) { "`knownKeys` must not be empty." } + return object : LogPerBucketingStrategy(name) { + override fun apply(key: Any): Any? = keyMap[key] + } + } + + /** + * A strategy which uses the [hashCode] of a given key, modulo [maxBuckets], for + * log aggregation. + * + * This is a fallback strategy for cases where the set of possible values is + * not known in advance or could be arbitrarily large in unusual circumstances. + * + * When using this method, it is obviously important that the [hashCode] method of + * the expected keys is well distributed, since duplicate hash codes, or hash codes + * congruent to [maxBuckets] will cause keys to be conflated. + * + * The caller is responsible for deciding the number of unique log aggregation keys this + * strategy can return. This choice is a trade-off between memory usage and the risk of + * conflating keys when performing log aggregation. + * + * Each log site using this strategy will hold up to [maxBuckets] distinct versions of log + * site information to allow rate limiting and other stateful operations to be applied + * separately per bucket. + * + * The overall allocation cost depends on the type of rate limiting used alongside this + * method, but it scales linearly with [maxBuckets]. + * + * It is recommended to keep the value of [maxBuckets] below 250, since this + * guarantees no additional allocations will occur when using this strategy. + * However, the value chosen should be as small as practically possible for + * the typical expected number of unique keys. + * + * To avoid unwanted allocation at log sites, users are strongly encouraged to assign the + * returned value to a static field and pass that to any log statements which need it. + */ + @JvmStatic + public fun byHashCode(maxBuckets: Int): LogPerBucketingStrategy { + require(maxBuckets > 0) { "`maxBuckets` must be positive: $maxBuckets." } + return object : LogPerBucketingStrategy("ByHashCode($maxBuckets)") { + @Suppress("MagicNumber") + override fun apply(key: Any): Any = + Math.floorMod(key.hashCode(), maxBuckets) - 128 + } + } + } +} diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/LogPerBucketingStrategy.kt b/logging/src/jvmMain/kotlin/io/spine/logging/LogPerBucketingStrategy.kt deleted file mode 100644 index 80d1787f..00000000 --- a/logging/src/jvmMain/kotlin/io/spine/logging/LogPerBucketingStrategy.kt +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright 2025, TeamDev. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package io.spine.logging - -import io.spine.annotation.TestOnly - -/** - * Provides a strategy for "bucketing" a potentially unbounded set of log - * aggregation keys used by the [LoggingApi.per] method. - * - * When implementing new strategies not provided by this class, it is important - * to ensure that the [apply] method returns values from a bounded set of - * instances wherever possible. - * - * This is important because the returned values are held persistently for - * potentially many different log sites. - * - * If a different instance is returned each time [apply] is called, a - * different instance will be held in each log site. - * - * This multiplies the amount of memory that is retained indefinitely by - * any use of [LoggingApi.per]. - * - * One way to handle arbitrary key types would be to create a strategy which - * "interns" instances in some way, to produce singleton identifiers. - * - * Unfortunately, interning can itself be a cause of unbounded memory leaks, - * so a bucketing strategy wishing to perform interning should probably - * support a user defined maximum capacity to limit the overall risk. - * - * If too many instances are seen, the strategy should begin to return `null` - * (and log an appropriate warning). - * - * The additional complexity created by this approach really tells us that - * types which require interning in order to be used as aggregation keys - * should be considered unsuitable, and callers should seek alternatives. - * - * @param name The name of this strategy, used for debugging purposes. - * - * @see - * Original Java code for historical context. - */ -public actual abstract class LogPerBucketingStrategy protected constructor( - private val name: String -) { - /** - * Maps a log aggregation key from a potentially unbounded set of - * key values to a bounded set of instances. - * - * Implementations of this method should be efficient and avoid - * allocating memory wherever possible. - * - * The returned value must be an immutable identifier with minimal additional - * allocation requirements and ideally have singleton semantics - * (e.g., an [Enum] or [Integer] value). - * - * **Warning**: If keys are not known to have natural singleton semantics - * (e.g. [String]) then returning the given key instance is generally a bad idea. - * - * Even if the set of key values is small, the set of distinct allocated instances - * passed to [LoggingApi.per] can be unbounded, and that's what matters. - * - * As such, it is always better to map keys to some singleton identifier or - * intern the keys in some way. - * - * @param key A non-null key from a potentially unbounded set of log aggregation keys. - * @return an immutable value from some known bounded set, which will be held persistently by - * internal Flogger data structures as part of the log aggregation feature. If - * `null` is returned, the corresponding call to `per(key, STRATEGY)` has no effect. - */ - protected abstract fun apply(key: T): Any? - - internal actual fun doApply(key: T): Any? = apply(key) - - /** - * Access to the [apply] method for testing purposes. - * - * This method is not part of the public API and should not be used by client code. - */ - @TestOnly - internal actual fun applyForTesting(key: T): Any? = apply(key) - - override fun toString(): String = - "${LogPerBucketingStrategy::class.java.simpleName}[$name]" - - public companion object { - - /** - * A strategy to use only if the set of log aggregation keys is known to be - * a strictly bounded set of instances with singleton semantics. - */ - private val KNOWN_BOUNDED = object : LogPerBucketingStrategy("KnownBounded") { - override fun apply(key: Any): Any = key - } - - /** - * This is a "safe" strategy as far as memory use is concerned since class objects - * are effectively singletons. - */ - private val BY_CLASS = object : LogPerBucketingStrategy("ByClass") { - override fun apply(key: Any): Any = key.javaClass - } - - /** - * This is a "safe" strategy as far as memory use is concerned, because a class object - * returns the same string instance every time its called, and class objects - * are effectively singletons. - */ - private val BY_CLASS_NAME = object : LogPerBucketingStrategy("ByClassName") { - override fun apply(key: Any): Any = key.javaClass.name /* This is a naturally interned - value, so no need to call `intern()`. */ - } - - /** - * A strategy to use only if the set of log aggregation keys is known to be - * a strictly bounded set of instances with singleton semantics. - * - * **WARNING**: When using this strategy, keys passed to [LoggingApi.per] - * are used as-is by the log aggregation code, and held indefinitely by internal - * static data structures. - * - * As such it is vital that key instances used with this strategy have singleton semantics - * (i.e., if `k1.equals(k2)` then `k1 == k2`). - * - * Failure to adhere to this requirement is likely to result in hard to detect memory leaks. - * - * If keys do not have singleton semantics then you should use a different strategy, - * such as [byHashCode] or [byClass]. - */ - @JvmStatic - public fun knownBounded(): LogPerBucketingStrategy = KNOWN_BOUNDED - - /** - * A strategy which uses the [Class] of the given key for log aggregation. - * - * This is useful when you need to aggregate over specific exceptions or similar - * type-distinguished instances. - * - * Note that using this strategy will result in a reference to the [Class] object of - * the key being retained indefinitely. - * - * This will prevent class unloading from occurring for affected classes, and - * it is up to the caller to decide if this is acceptable or not. - */ - @JvmStatic - public fun byClass(): LogPerBucketingStrategy = BY_CLASS - - /** - * A strategy which uses the [Class] name of the given key for log aggregation. - * - * This is useful when you need to aggregate over specific exceptions or similar - * type-distinguished instances. - * - * This is an alternative strategy to [byClass] which avoids holding onto the class - * instance and avoids any issues with class unloading. - * - * However, it may conflate classes if applications use complex arrangements of custom - * class-loaders, but this should be extremely rare. - */ - @JvmStatic - public fun byClassName(): LogPerBucketingStrategy = BY_CLASS_NAME - - /** - * A strategy defined for some given set of known keys. - * - * Unlike [knownBounded], this strategy maps keys to a bounded set of identifiers, and - * permits the use of non-singleton keys in [LoggingApi.per]. - * - * If keys outside this set are used this strategy returns `null`, and - * log aggregation will not occur. - * - * Duplicates in [knownKeys] are ignored. - */ - @JvmStatic - public fun forKnownKeys(knownKeys: Iterable): LogPerBucketingStrategy { - val keyMap = HashMap() - val name = buildString { - append("ForKnownKeys(") - var index = 0 - for (key in knownKeys) { - if (!keyMap.containsKey(key)) { - if (index > 0) { - append(", ") - } - append(key) - keyMap[key] = index - index++ - } - } - append(')') - } - // We check here to avoid querying `knownKeys` size just for the precondition check. - require(!keyMap.isEmpty()) { "`knownKeys` must not be empty." } - return object : LogPerBucketingStrategy(name) { - override fun apply(key: Any): Any? = keyMap[key] - } - } - - /** - * A strategy which uses the [hashCode] of a given key, modulo [maxBuckets], for - * log aggregation. - * - * This is a fallback strategy for cases where the set of possible values is - * not known in advance or could be arbitrarily large in unusual circumstances. - * - * When using this method, it is obviously important that the [hashCode] method of - * the expected keys is well distributed, since duplicate hash codes, or hash codes - * congruent to [maxBuckets] will cause keys to be conflated. - * - * The caller is responsible for deciding the number of unique log aggregation keys this - * strategy can return. This choice is a trade-off between memory usage and the risk of - * conflating keys when performing log aggregation. - * - * Each log site using this strategy will hold up to [maxBuckets] distinct versions of log - * site information to allow rate limiting and other stateful operations to be applied - * separately per bucket. - * - * The overall allocation cost depends on the type of rate limiting used alongside this - * method, but it scales linearly with [maxBuckets]. - * - * It is recommended to keep the value of [maxBuckets] below 250, since this - * guarantees no additional allocations will occur when using this strategy. - * However, the value chosen should be as small as practically possible for - * the typical expected number of unique keys. - * - * To avoid unwanted allocation at log sites, users are strongly encouraged to assign the - * returned value to a static field and pass that to any log statements which need it. - */ - @JvmStatic - public fun byHashCode(maxBuckets: Int): LogPerBucketingStrategy { - require(maxBuckets > 0) { "`maxBuckets` must be positive: $maxBuckets." } - return object : LogPerBucketingStrategy("ByHashCode($maxBuckets)") { - @Suppress("MagicNumber") - override fun apply(key: Any): Any = - Math.floorMod(key.hashCode(), maxBuckets) - 128 - } - } - } -} From fbf76dd66305ceec85db25d61eb3a04b05be326f Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sat, 13 Sep 2025 19:53:25 +0100 Subject: [PATCH 05/38] Improve doc links --- .../src/commonMain/kotlin/io/spine/logging/RateLimitPeriod.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/logging/src/commonMain/kotlin/io/spine/logging/RateLimitPeriod.kt b/logging/src/commonMain/kotlin/io/spine/logging/RateLimitPeriod.kt index ad34cdf6..8ad06d29 100644 --- a/logging/src/commonMain/kotlin/io/spine/logging/RateLimitPeriod.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/RateLimitPeriod.kt @@ -35,8 +35,8 @@ import kotlin.time.toTimeUnit * Immutable metadata for rate limiting based on a fixed count. * * This corresponds to the - * [LOG_AT_MOST_EVERY][io.spine.logging.jvm.LogContext.Key.LOG_AT_MOST_EVERY] - * metadata key in [io.spine.logging.backend.LogData]. + * [LOG_AT_MOST_EVERY][LogContext.Key.LOG_AT_MOST_EVERY] + * metadata key in [LogData][io.spine.logging.backend.LogData]. * * Unlike the metadata for `every(N)`, we need to use a wrapper class here to preserve * the time unit information for accurate rate limit calculations. From bd20b05df39bb0bdd7884c799902929b411d6bcf Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sat, 13 Sep 2025 21:25:12 +0100 Subject: [PATCH 06/38] Remove `expect/actual` arrangement for the `LoggingScope` class --- .../kotlin/io/spine/logging/KeyPart.kt | 5 + .../kotlin/io/spine/logging/LoggingScope.kt | 71 +++++++++--- .../kotlin/io/spine/logging/KeyPart.kt | 4 +- .../kotlin/io/spine/logging/LoggingScope.kt | 103 ------------------ 4 files changed, 64 insertions(+), 119 deletions(-) delete mode 100644 logging/src/jvmMain/kotlin/io/spine/logging/LoggingScope.kt diff --git a/logging/src/commonMain/kotlin/io/spine/logging/KeyPart.kt b/logging/src/commonMain/kotlin/io/spine/logging/KeyPart.kt index 55b9cae5..9f6ad02f 100644 --- a/logging/src/commonMain/kotlin/io/spine/logging/KeyPart.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/KeyPart.kt @@ -54,6 +54,11 @@ public expect class KeyPart { public companion object { + /** + * Creates a new instance for the given [scope]. + */ + public fun create(scope: LoggingScope): KeyPart + /** * Removes keys that are no longer in use from the internal storage. * diff --git a/logging/src/commonMain/kotlin/io/spine/logging/LoggingScope.kt b/logging/src/commonMain/kotlin/io/spine/logging/LoggingScope.kt index d7f05910..f1789d60 100644 --- a/logging/src/commonMain/kotlin/io/spine/logging/LoggingScope.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/LoggingScope.kt @@ -26,6 +26,8 @@ package io.spine.logging +import io.spine.annotation.VisibleForTesting + /** * An opaque scope marker which can be attached to log sites to provide "per scope" behaviour * for stateful logging operations (e.g., rate limiting). @@ -48,19 +50,7 @@ package io.spine.logging * @see * Original Java code for historical context. */ -public expect abstract class LoggingScope { - - public companion object { - - /** - * Creates a scope which automatically removes any associated keys - * from [LogSiteMap]s when it is garbage collected. - * - * The given label is used only for debugging purposes and may appear in log - * statements, it should not contain any user data or other runtime information. - */ - public fun create(label: String): LoggingScope - } +public abstract class LoggingScope protected constructor(private val label: String) { /** * Returns a specialization of the given key which accounts for this scope instance. @@ -98,10 +88,61 @@ public expect abstract class LoggingScope { /** * Opens [specialize] for the package. */ - internal fun doSpecialize(key: LogSiteKey): LogSiteKey + internal fun doSpecialize(key: LogSiteKey): LogSiteKey = specialize(key) /** * Opens access to [onClose] for the package. */ - internal fun doOnClose(removalHook: () -> Unit) + internal fun doOnClose(removalHook: () -> Unit) = onClose(removalHook) + + /** + * Returns the [label] of this scope. + */ + override fun toString(): String = label + + public companion object { + + /** + * Creates a scope which automatically removes any associated keys + * from [LogSiteMap]s when it is garbage collected. + * + * The given label is used only for debugging purposes and may appear in log + * statements, it should not contain any user data or other runtime information. + */ + @JvmStatic + public fun create(label: String): LoggingScope = WeakScope(label) + } + + @VisibleForTesting + internal class WeakScope(label: String) : LoggingScope(label) { + + /** + * Do NOT reference the Scope directly from a specialized key, use the "key part" + * to avoid the key part weak reference is enqueued which triggers tidy up at the next + * call to `specializeForScopesIn()` where scopes are used. + * + * This must be unique per scope since it acts as a qualifier within specialized + * log site keys. Using a different weak reference per specialized key would not work + * (which is part of the reason we also need the "on close" queue as well as + * the reference queue). + */ + private val keyPart: KeyPart = KeyPart.create(this) + + override fun specialize(key: LogSiteKey): LogSiteKey = + SpecializedLogSiteKey.of(key, keyPart) + + override fun onClose(removalHook: () -> Unit) { + // Clear the reference queue about as often as we would add a new key to a map. + // This should still mean that the queue is almost always empty when we check + // it (since we expect more than one specialized log site key per scope) and it + // avoids spamming the queue clearance loop for every log statement and avoids + // class loading the reference queue until we know scopes have been used. + KeyPart.removeUnusedKeys() + keyPart.addOnCloseHook(removalHook) + } + + internal fun closeForTesting() { + keyPart.close() + } + } } diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/KeyPart.kt b/logging/src/jvmMain/kotlin/io/spine/logging/KeyPart.kt index d34aa366..e073c1a0 100644 --- a/logging/src/jvmMain/kotlin/io/spine/logging/KeyPart.kt +++ b/logging/src/jvmMain/kotlin/io/spine/logging/KeyPart.kt @@ -41,7 +41,7 @@ import java.util.concurrent.ConcurrentLinkedQueue * @see * Original Flogger code for historic reference. */ -public actual class KeyPart internal constructor(scope: LoggingScope) : +public actual class KeyPart private constructor(scope: LoggingScope) : WeakReference(scope, queue) { private val onCloseHooks = ConcurrentLinkedQueue<() -> Unit>() @@ -65,6 +65,8 @@ public actual class KeyPart internal constructor(scope: LoggingScope) : public actual companion object { + public actual fun create(scope: LoggingScope): KeyPart = KeyPart(scope) + /** * The singleton reference queue of the logging scopes. * diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/LoggingScope.kt b/logging/src/jvmMain/kotlin/io/spine/logging/LoggingScope.kt deleted file mode 100644 index 2e005f50..00000000 --- a/logging/src/jvmMain/kotlin/io/spine/logging/LoggingScope.kt +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2020, The Flogger Authors; 2025, TeamDev. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package io.spine.logging - -import io.spine.annotation.VisibleForTesting - -/** - * JVM implementation of the logging scope which provides garbage collection for the keys - * via JVM week references. - * - * @see - * Original Flogger code for historic reference. - */ -public actual abstract class LoggingScope protected constructor(private val label: String) { - - protected actual abstract fun specialize(key: LogSiteKey): LogSiteKey - protected actual abstract fun onClose(removalHook: () -> Unit) - - /** - * Opens [specialize] for the package. - */ - internal actual fun doSpecialize(key: LogSiteKey): LogSiteKey = specialize(key) - - /** - * Opens access to [onClose] for the package. - */ - internal actual fun doOnClose(removalHook: () -> Unit) = onClose(removalHook) - - /** - * Returns the [label] of this scope. - */ - override fun toString(): String = label - - public actual companion object { - - /** - * Creates a scope which automatically removes any associated keys - * from [LogSiteMap]s when it is garbage collected. - * - * The given label is used only for debugging purposes and may appear in log - * statements, it should not contain any user data or other runtime information. - */ - @JvmStatic - public actual fun create(label: String): LoggingScope = WeakScope(label) - } - - @VisibleForTesting - internal class WeakScope(label: String) : LoggingScope(label) { - - /** - * Do NOT reference the Scope directly from a specialized key, use the "key part" - * to avoid the key part weak reference is enqueued which triggers tidy up at the next - * call to `specializeForScopesIn()` where scopes are used. - * - * This must be unique per scope since it acts as a qualifier within specialized - * log site keys. Using a different weak reference per specialized key would not work - * (which is part of the reason we also need the "on close" queue as well as - * the reference queue). - */ - private val keyPart: KeyPart = KeyPart(this) - - override fun specialize(key: LogSiteKey): LogSiteKey = - SpecializedLogSiteKey.of(key, keyPart) - - override fun onClose(removalHook: () -> Unit) { - // Clear the reference queue about as often as we would add a new key to a map. - // This should still mean that the queue is almost always empty when we check - // it (since we expect more than one specialized log site key per scope) and it - // avoids spamming the queue clearance loop for every log statement and avoids - // class loading the reference queue until we know scopes have been used. - KeyPart.removeUnusedKeys() - keyPart.addOnCloseHook(removalHook) - } - - internal fun closeForTesting() { - keyPart.close() - } - } -} From e0e1e58a67fec99eca344d6885394003624474d0 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sat, 13 Sep 2025 21:40:00 +0100 Subject: [PATCH 07/38] Remove `expect/actual` arrangement for the `LogSiteLookup` object --- .../kotlin/io/spine/logging/LogSiteLookup.kt | 32 +++++----- .../kotlin/io/spine/logging/LogSiteLookup.kt | 61 ------------------- 2 files changed, 18 insertions(+), 75 deletions(-) delete mode 100644 logging/src/jvmMain/kotlin/io/spine/logging/LogSiteLookup.kt diff --git a/logging/src/commonMain/kotlin/io/spine/logging/LogSiteLookup.kt b/logging/src/commonMain/kotlin/io/spine/logging/LogSiteLookup.kt index a17e34e9..750da27d 100644 --- a/logging/src/commonMain/kotlin/io/spine/logging/LogSiteLookup.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/LogSiteLookup.kt @@ -26,32 +26,36 @@ package io.spine.logging +import io.spine.logging.backend.Platform import kotlin.reflect.KClass /** - * Determines log sites for the current line of code. - * - * Note that determining of a log site at runtime can be a slow - * operation because it usually involves some form of stack trace analysis. - * - * Methods of this class can be used with the [LoggingApi.withInjectedLogSite] - * method to implement logging helper methods. + * Determines log sites for the current line of code using + * [LogCallerFinder][io.spine.logging.backend.LogCallerFinder] + * obtained from a [io.spine.logging.backend.Platform]. */ -public expect object LogSiteLookup { +public object LogSiteLookup { /** * Returns a [LogSite] for the caller of the specified class. * - * In some platforms, log site determination may be unsupported, and in - * those cases this method should return the [LogSite.Invalid] instance. + * If log site determination is unsupported, this method returns + * the [LogSite.Invalid] instance. */ - public fun callerOf(loggingApi: KClass<*>): LogSite + public fun callerOf(loggingApi: KClass<*>): LogSite { + return Platform.Companion.getCallerFinder().findLogSite(loggingApi, 0) + } /** * Returns a [LogSite] for the current line of code. * - * In some platforms, log site determination may be unsupported, and in - * those cases this method should return the [LogSite.Invalid] instance. + * If log site determination is unsupported, this method returns + * the [LogSite.Invalid] instance. */ - public fun logSite(): LogSite + public fun logSite(): LogSite { + return Platform.Companion.getCallerFinder().findLogSite( + LogSiteLookup::class, + 0 + ) + } } diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/LogSiteLookup.kt b/logging/src/jvmMain/kotlin/io/spine/logging/LogSiteLookup.kt deleted file mode 100644 index a7d39ade..00000000 --- a/logging/src/jvmMain/kotlin/io/spine/logging/LogSiteLookup.kt +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2025, TeamDev. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package io.spine.logging - -import io.spine.logging.backend.Platform -import kotlin.reflect.KClass - -/** - * Determines log sites for the current line of code using - * [LogCallerFinder][io.spine.logging.backend.LogCallerFinder] - * obtained from a [Platform]. - */ -public actual object LogSiteLookup { - - /** - * Returns a [LogSite] for the caller of the specified class. - * - * If log site determination is unsupported, this method returns - * the [LogSite.Invalid] instance. - */ - public actual fun callerOf(loggingApi: KClass<*>): LogSite { - return Platform.getCallerFinder().findLogSite(loggingApi, 0) - } - - /** - * Returns a [LogSite] for the current line of code. - * - * If log site determination is unsupported, this method returns - * the [LogSite.Invalid] instance. - */ - public actual fun logSite(): LogSite { - return Platform.getCallerFinder().findLogSite( - LogSiteLookup::class, - 0 - ) - } -} From e752091a02fdf5142e356d8648aad32bb2b56af6 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sat, 13 Sep 2025 21:42:18 +0100 Subject: [PATCH 08/38] Move `SimpleMessageFormatter` under `commonMain` --- .../kotlin/io/spine/logging/backend/SimpleMessageFormatter.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename logging/src/{jvmMain => commonMain}/kotlin/io/spine/logging/backend/SimpleMessageFormatter.kt (99%) diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/backend/SimpleMessageFormatter.kt b/logging/src/commonMain/kotlin/io/spine/logging/backend/SimpleMessageFormatter.kt similarity index 99% rename from logging/src/jvmMain/kotlin/io/spine/logging/backend/SimpleMessageFormatter.kt rename to logging/src/commonMain/kotlin/io/spine/logging/backend/SimpleMessageFormatter.kt index 9af555d8..7d854298 100644 --- a/logging/src/jvmMain/kotlin/io/spine/logging/backend/SimpleMessageFormatter.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/backend/SimpleMessageFormatter.kt @@ -1,5 +1,5 @@ /* - * Copyright 2025, TeamDev. All rights reserved. + * Copyright 2023, The Flogger Authors; 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 1e1ae43b7ad2673b2cf8f7ce2546a0e3f4ca5992 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sat, 13 Sep 2025 21:45:42 +0100 Subject: [PATCH 09/38] Unify `LogSiteStackTrace` creation --- .../kotlin/io/spine/logging/LogSiteStackTrace.kt | 3 +++ .../kotlin/io/spine/logging/LogSiteStackTraceSpec.kt | 8 ++++---- .../jvmMain/kotlin/io/spine/logging/LogSiteStackTrace.kt | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/logging/src/commonMain/kotlin/io/spine/logging/LogSiteStackTrace.kt b/logging/src/commonMain/kotlin/io/spine/logging/LogSiteStackTrace.kt index 4fc78202..df14805e 100644 --- a/logging/src/commonMain/kotlin/io/spine/logging/LogSiteStackTrace.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/LogSiteStackTrace.kt @@ -35,6 +35,9 @@ public expect class LogSiteStackTrace : Throwable { public companion object { + /** + * Creates a new log stack trace instance with the given properties. + */ public fun create( cause: Throwable?, stackSize: StackSize, diff --git a/logging/src/commonTest/kotlin/io/spine/logging/LogSiteStackTraceSpec.kt b/logging/src/commonTest/kotlin/io/spine/logging/LogSiteStackTraceSpec.kt index 472a4682..733b0a45 100644 --- a/logging/src/commonTest/kotlin/io/spine/logging/LogSiteStackTraceSpec.kt +++ b/logging/src/commonTest/kotlin/io/spine/logging/LogSiteStackTraceSpec.kt @@ -53,26 +53,26 @@ internal class LogSiteStackTraceSpec { @Test fun `return message containing the requested stack size`() { - val trace = LogSiteStackTrace(null, StackSize.FULL, arrayOfNulls(0)) + val trace = LogSiteStackTrace.create(null, StackSize.FULL, arrayOfNulls(0)) trace shouldHaveMessage "FULL" } @Test fun `return the given cause`() { val cause = RuntimeException() - val trace = LogSiteStackTrace(cause, StackSize.SMALL, arrayOfNulls(0)) + val trace = LogSiteStackTrace.create(cause, StackSize.SMALL, arrayOfNulls(0)) trace.cause shouldBeSameInstanceAs cause } @Test fun `allow nullable cause`() { - val trace = LogSiteStackTrace(null, StackSize.NONE, arrayOfNulls(0)) + val trace = LogSiteStackTrace.create(null, StackSize.NONE, arrayOfNulls(0)) trace.cause.shouldBeNull() } @Test fun `return the given stack trace`() { - val trace = LogSiteStackTrace(null, StackSize.SMALL, FAKE_STACK) + val trace = LogSiteStackTrace.create(null, StackSize.SMALL, FAKE_STACK) trace.stackTrace shouldNotBeSameInstanceAs FAKE_STACK trace.stackTrace shouldBe FAKE_STACK } diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/LogSiteStackTrace.kt b/logging/src/jvmMain/kotlin/io/spine/logging/LogSiteStackTrace.kt index cc8b0d1c..8212cff3 100644 --- a/logging/src/jvmMain/kotlin/io/spine/logging/LogSiteStackTrace.kt +++ b/logging/src/jvmMain/kotlin/io/spine/logging/LogSiteStackTrace.kt @@ -39,7 +39,7 @@ import java.io.Serial * Original Java code for historical context. */ @Suppress("ExceptionClassNameDoesntEndWithException") -public actual class LogSiteStackTrace( +public actual class LogSiteStackTrace private constructor( cause: Throwable?, stackSize: StackSize, syntheticStackTrace: Array From 6f88f9530c34a88ffdfe17754cdf86f6b3f4f6ff Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sat, 13 Sep 2025 21:59:39 +0100 Subject: [PATCH 10/38] Remove `expect/actual` arrangement for the `WithLogging` interface --- .../kotlin/io/spine/logging/WithLogging.kt | 14 ++++- .../kotlin/io/spine/logging/WithLogging.kt | 59 ------------------- 2 files changed, 11 insertions(+), 62 deletions(-) delete mode 100644 logging/src/jvmMain/kotlin/io/spine/logging/WithLogging.kt diff --git a/logging/src/commonMain/kotlin/io/spine/logging/WithLogging.kt b/logging/src/commonMain/kotlin/io/spine/logging/WithLogging.kt index 87950902..2587eb86 100644 --- a/logging/src/commonMain/kotlin/io/spine/logging/WithLogging.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/WithLogging.kt @@ -26,6 +26,8 @@ package io.spine.logging +import io.spine.logging.LoggingFactory.loggerFor + /** * Provides [Logger] instance as a property. * @@ -64,11 +66,17 @@ package io.spine.logging * As for now, providing a default implementation for a property makes it * impossible to customize accessing of a logger in target implementations. */ -public expect interface WithLogging { +public interface WithLogging { /** * Returns the logger created for this class. */ - @Suppress("RedundantModalityModifier") // `open` is required for the JVM impl. to override. - public open val logger: Logger<*> + public val logger: Logger<*> + get() = loggerFor(this::class) + + /** + * Convenience method for obtaining the logger created for this class + * when calling from Java code, avoiding the `get` prefix. + */ + public fun logger(): Logger<*> = logger } diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/WithLogging.kt b/logging/src/jvmMain/kotlin/io/spine/logging/WithLogging.kt deleted file mode 100644 index 01d64631..00000000 --- a/logging/src/jvmMain/kotlin/io/spine/logging/WithLogging.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2023, TeamDev. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package io.spine.logging - -import io.spine.logging.LoggingFactory.loggerFor - -/** - * Provides [Logger] instance as a property. - * - * Implement this interface when logging is needed. - * - * Usage example: - * - * ```kotlin - * class MyClass : WithLogging { - * fun doAction() { - * logger.atInfo().log { "Action is in progress." } - * } - * } - * ``` - */ -public actual interface WithLogging { - - /** - * Returns the logger created for this class. - */ - public actual val logger: Logger<*> - get() = loggerFor(this::class) - - /** - * Convenience method for obtaining the logger created for this class - * when calling from Java code, avoiding the `get` prefix. - */ - public fun logger(): Logger<*> = logger -} From e0c0e027db4126ab4b0859779417a3a2bd9693fd Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sat, 13 Sep 2025 22:03:47 +0100 Subject: [PATCH 11/38] Improve var names --- .../src/jvmMain/kotlin/io/spine/logging/LoggingFactory.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/LoggingFactory.kt b/logging/src/jvmMain/kotlin/io/spine/logging/LoggingFactory.kt index 5ef55aa6..17b8c14d 100644 --- a/logging/src/jvmMain/kotlin/io/spine/logging/LoggingFactory.kt +++ b/logging/src/jvmMain/kotlin/io/spine/logging/LoggingFactory.kt @@ -72,10 +72,10 @@ public actual object LoggingFactory: ClassValue() { repeatedMetadataKey(label, type.kotlin) private fun createForClass(cls: Class<*>): JvmLogger { - val floggerBackend = Platform.getBackend(cls.name) - val flogger = Middleman(floggerBackend) + val loggerBackend = Platform.getBackend(cls.name) + val loggerImpl = Middleman(loggerBackend) // As for now, `JvmLogger` just delegates actual work to Flogger. - return JvmLogger(cls.kotlin, flogger) + return JvmLogger(cls.kotlin, loggerImpl) } @JvmStatic From 074ac06167d77b4935d53b44988b63d1c9d96f5c Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sat, 13 Sep 2025 22:04:17 +0100 Subject: [PATCH 12/38] Update build time --- dependencies.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/dependencies.md b/dependencies.md index 9a887ab9..6fa2baaa 100644 --- a/dependencies.md +++ b/dependencies.md @@ -413,7 +413,7 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using +This report was generated on **Sat Sep 13 22:03:55 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1148,7 +1148,7 @@ This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using +This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1982,7 +1982,7 @@ This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using +This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -2800,7 +2800,7 @@ This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using +This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -3662,7 +3662,7 @@ This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using +This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4520,7 +4520,7 @@ This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using +This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5370,7 +5370,7 @@ This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using +This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -6220,7 +6220,7 @@ This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using +This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7078,7 +7078,7 @@ This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using +This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7940,7 +7940,7 @@ This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using +This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8782,7 +8782,7 @@ This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using +This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9521,7 +9521,7 @@ This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using +This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -10256,7 +10256,7 @@ This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using +This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -11122,7 +11122,7 @@ This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using +This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -12008,7 +12008,7 @@ This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using +This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -12826,6 +12826,6 @@ This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 19:45:37 WEST 2025** using +This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file From 7a607f57628a49d5192a5e57bfe453a0b7d0816a Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sat, 13 Sep 2025 22:14:47 +0100 Subject: [PATCH 13/38] Make the depth increment more visible --- .../src/jvmMain/kotlin/io/spine/logging/util/RecursionDepth.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/util/RecursionDepth.kt b/logging/src/jvmMain/kotlin/io/spine/logging/util/RecursionDepth.kt index e2d3cb59..c2406a99 100644 --- a/logging/src/jvmMain/kotlin/io/spine/logging/util/RecursionDepth.kt +++ b/logging/src/jvmMain/kotlin/io/spine/logging/util/RecursionDepth.kt @@ -65,7 +65,8 @@ public actual class RecursionDepth actual constructor() : AutoCloseable { @JvmStatic public actual fun enterLogStatement(): RecursionDepth { val depth = holder.get() - if (++depth.value == 0) { + depth.value += 1 + if (depth.value == 0) { throw AssertionError( "Overflow of `RecursionDepth` (possible error in core library)." ) From 1ab0a92d27ab42475b14fa39744c9943f9045630 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sun, 14 Sep 2025 16:44:03 +0100 Subject: [PATCH 14/38] Make `RecursionDepth` platform-neutral --- .../io/spine/logging/util/RecursionDepth.kt | 82 ++++++++++++---- .../io/spine/logging/util/RecursionDepth.kt | 95 ------------------- 2 files changed, 66 insertions(+), 111 deletions(-) delete mode 100644 logging/src/jvmMain/kotlin/io/spine/logging/util/RecursionDepth.kt diff --git a/logging/src/commonMain/kotlin/io/spine/logging/util/RecursionDepth.kt b/logging/src/commonMain/kotlin/io/spine/logging/util/RecursionDepth.kt index f8b0ca69..c405374f 100644 --- a/logging/src/commonMain/kotlin/io/spine/logging/util/RecursionDepth.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/util/RecursionDepth.kt @@ -27,39 +27,89 @@ package io.spine.logging.util import io.spine.annotation.Internal +import kotlin.coroutines.CoroutineContext +import kotlin.coroutines.EmptyCoroutineContext /** * A platform-neutral API for tracking recursion depth of logging operations. * - * Use `Platform.getCurrentRecursionDepth()` to query the current depth from outside - * of the core logging internals. + * The current recursion depth is stored as a [CoroutineContext.Element] which makes it + * coroutine-friendly while remaining platform-neutral. * - * ### API Note + * Use `Platform.getCurrentRecursionDepth()` to query the current depth from the outside + * of the core logging internals. * - * This class is an internal detail and must not be used outside the core of the Logging library. + * API Note: This class is an internal detail and must not be used outside the core of + * the Logging library. Backends which need to know the recursion depth should call + * `io.spine.logging.backend.Platform.getCurrentRecursionDepth()`. */ -public expect class RecursionDepth() : AutoCloseable { +public class RecursionDepth private constructor() : CoroutineContext.Element, AutoCloseable { + + override val key: CoroutineContext.Key<*> get() = Key + + private var value: Int = 0 + + /** + * Do not call this method directly, use `Platform.getCurrentRecursionDepth()`. + */ + @Internal + public fun getValue(): Int = value + + override fun close() { + if (value > 0) { + value -= 1 + if (value == 0) { + // Remove the element from the current context when it reaches zero. + CurrentContext.set(CurrentContext.get().minusKey(Key)) + } + return + } + throw AssertionError( + "Mismatched calls to `RecursionDepth` (possible error in core library)." + ) + } - public companion object { + /** + * The [CoroutineContext.Key] for managing [RecursionDepth] in a [CoroutineContext]. + */ + public companion object Key : CoroutineContext.Key { + + /** + * Holds the current coroutine context for logging operations. + * + * The recursion depth itself is stored inside the context element, not in this holder. + */ + private object CurrentContext { + private var holder: CoroutineContext = EmptyCoroutineContext + fun get(): CoroutineContext = holder + fun set(ctx: CoroutineContext) { + holder = ctx + } + } /** * Do not call this method directly, use `Platform.getCurrentRecursionDepth()`. */ @Internal - public fun getCurrentDepth(): Int + @JvmStatic + public fun getCurrentDepth(): Int = CurrentContext.get()[Key]?.value ?: 0 /** * Do not call this method directly, use `Platform.getCurrentRecursionDepth()`. */ @Internal - public fun enterLogStatement(): RecursionDepth + @JvmStatic + public fun enterLogStatement(): RecursionDepth { + val ctx = CurrentContext.get() + val depth = ctx[Key] ?: RecursionDepth() + depth.value += 1 + if (depth.value == 0) { + throw AssertionError( + "Overflow of `RecursionDepth` (possible error in core library)." + ) + } + CurrentContext.set(ctx + depth) + return depth + } } - - /** - * Do not call this method directly, use `Platform.getCurrentRecursionDepth()`. - */ - @Internal - public fun getValue(): Int - - override fun close() } diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/util/RecursionDepth.kt b/logging/src/jvmMain/kotlin/io/spine/logging/util/RecursionDepth.kt deleted file mode 100644 index c2406a99..00000000 --- a/logging/src/jvmMain/kotlin/io/spine/logging/util/RecursionDepth.kt +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2019, The Flogger Authors; 2025, TeamDev. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package io.spine.logging.util - -import io.spine.annotation.Internal - -/** - * A thread local counter, incremented whenever a log statement is being processed by the backend. - * - * If this value is greater than 1, then reentrant logging has occurred, and some code may behave - * differently to avoid issues such as unbounded recursion. Logging may even be disabled completely - * if the depth gets too high. - * - * #### API Note - * This class is an internal detail and must not be used outside the core of the Logging library. - * Backends which need to know the recursion depth should call - * [io.spine.logging.backend.Platform.getCurrentRecursionDepth]. - * - * @see - * Original Java code for historical context. - */ -public actual class RecursionDepth actual constructor() : AutoCloseable { - - public actual companion object { - - private val holder = object : ThreadLocal() { - override fun initialValue(): RecursionDepth = RecursionDepth() - } - - /** - * Do not call this method directly, use `Platform.getCurrentRecursionDepth()`. - */ - @Internal - @JvmStatic - public actual fun getCurrentDepth(): Int = holder.get().value - - /** - * Do not call this method directly, use `Platform.getCurrentRecursionDepth()`. - */ - @Internal - @JvmStatic - public actual fun enterLogStatement(): RecursionDepth { - val depth = holder.get() - depth.value += 1 - if (depth.value == 0) { - throw AssertionError( - "Overflow of `RecursionDepth` (possible error in core library)." - ) - } - return depth - } - } - - private var value = 0 - - /** - * Do not call this method directly, use `Platform.getCurrentRecursionDepth()`. - */ - @Internal - public actual fun getValue(): Int = value - - public actual override fun close() { - if (value > 0) { - value -= 1 - return - } - throw AssertionError( - "Mismatched calls to `RecursionDepth` (possible error in core library)." - ) - } -} From 5aca1c5affa579174b41f4bc64a976585143c837 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sun, 14 Sep 2025 17:13:13 +0100 Subject: [PATCH 15/38] Simplify week references in `KeyPart` --- .../kotlin/io/spine/logging/KeyPart.kt | 63 ++++++++----- .../kotlin/io/spine/logging/WeakRef.kt | 45 ++++++++++ .../kotlin/io/spine/logging/KeyPart.kt | 89 ------------------- .../kotlin/io/spine/logging/WeakRef.kt | 44 +++++++++ 4 files changed, 128 insertions(+), 113 deletions(-) create mode 100644 logging/src/commonMain/kotlin/io/spine/logging/WeakRef.kt delete mode 100644 logging/src/jvmMain/kotlin/io/spine/logging/KeyPart.kt create mode 100644 logging/src/jvmMain/kotlin/io/spine/logging/WeakRef.kt diff --git a/logging/src/commonMain/kotlin/io/spine/logging/KeyPart.kt b/logging/src/commonMain/kotlin/io/spine/logging/KeyPart.kt index 9f6ad02f..25dadadd 100644 --- a/logging/src/commonMain/kotlin/io/spine/logging/KeyPart.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/KeyPart.kt @@ -35,35 +35,50 @@ package io.spine.logging * @see * Original Flogger code for historic reference. */ -public expect class KeyPart { +public class KeyPart private constructor(scope: LoggingScope) { - /** - * Adds a hook that will be executed when this key part is closed. - * - * @param hook the function to execute on close - */ - @Suppress("unused") // the parameter is used by `actual` impl. - public fun addOnCloseHook(hook: () -> Unit) + private val ref = WeakRef(scope) - /** - * Closes this key part and executes all registered close hooks. - * - * After closing, the key part becomes invalid and should not be used. - */ - public fun close() + //TODO:2025-09-14:alexander.yevsyukov: Guard for concurrency access. + private val onCloseHooks = mutableListOf<() -> Unit>() + + public fun addOnCloseHook(hook: () -> Unit) { + onCloseHooks += hook + } + + // If this were ever too "bursty" due to removal of many keys for the same scope, + // we could modify this code to process only a maximum number of removals each time + // and keep a single "in progress" `KeyPart` around until the next time. + public fun close() { + // This executes once for each map entry created in the enclosing scope. + // It is very dependent on logging usage in the scope and theoretically unbounded. + val it = onCloseHooks.iterator() + while (it.hasNext()) { + it.next().invoke() + it.remove() + } + } public companion object { - /** - * Creates a new instance for the given [scope]. - */ - public fun create(scope: LoggingScope): KeyPart + //TODO:2025-09-14:alexander.yevsyukov: Guard for concurrency access. + private val registry = mutableSetOf() + + public fun create(scope: LoggingScope): KeyPart = + KeyPart(scope).also { registry += it } + + public fun removeUnusedKeys() { + // There are always more specialized keys than entries in the reference queue, + // so the queue should be empty most of the time we get here. - /** - * Removes keys that are no longer in use from the internal storage. - * - * This helps prevent memory leaks by cleaning up abandoned key references. - */ - public fun removeUnusedKeys() + val dead = ArrayList() + for (k in registry) { + if (k.ref.get() == null) dead += k + } + for (k in dead) { + k.close() + registry.remove(k) + } + } } } diff --git a/logging/src/commonMain/kotlin/io/spine/logging/WeakRef.kt b/logging/src/commonMain/kotlin/io/spine/logging/WeakRef.kt new file mode 100644 index 00000000..f91d1ad3 --- /dev/null +++ b/logging/src/commonMain/kotlin/io/spine/logging/WeakRef.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.logging + +/** + * A weak reference holder that manages references which can be garbage collected. + * + * This class provides platform-specific implementation of weak references, + * which allow objects to be garbage collected when they are no longer strongly + * referenced elsewhere in the application. + * + * @param T The type of the referenced object. + * @property referent The object to be weakly referenced. + */ +internal expect class WeakRef(referent: T) { + + /** + * Returns the referent object, or `null` if it has been garbage collected. + */ + fun get(): T? +} diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/KeyPart.kt b/logging/src/jvmMain/kotlin/io/spine/logging/KeyPart.kt deleted file mode 100644 index e073c1a0..00000000 --- a/logging/src/jvmMain/kotlin/io/spine/logging/KeyPart.kt +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2020, The Flogger Authors; 2025, TeamDev. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package io.spine.logging - -import java.lang.ref.ReferenceQueue -import java.lang.ref.WeakReference -import java.util.concurrent.ConcurrentLinkedQueue - -/** - * This class is only loaded once we've seen scopes in action (Android doesn't like - * eager class loading, and many Android apps won't use scopes). This forms part of each - * log site key, so must have singleton semantics per scope. - * - * This file encapsulates Java-specific weak-reference and concurrent queue usage to keep - * the [LoggingScope] API Kotlin-only. - * - * @see - * Original Flogger code for historic reference. - */ -public actual class KeyPart private constructor(scope: LoggingScope) : - WeakReference(scope, queue) { - - private val onCloseHooks = ConcurrentLinkedQueue<() -> Unit>() - - public actual fun addOnCloseHook(hook: () -> Unit) { - onCloseHooks.offer(hook) - } - - // If this were ever too "bursty" due to removal of many keys for the same scope, - // we could modify this code to process only a maximum number of removals each time - // and keep a single "in progress" KeyPart around until the next time. - public actual fun close() { - // This executes once for each map entry created in the enclosing scope. - // It is very dependent on logging usage in the scope and theoretically unbounded. - var r = onCloseHooks.poll() - while (r != null) { - r() - r = onCloseHooks.poll() - } - } - - public actual companion object { - - public actual fun create(scope: LoggingScope): KeyPart = KeyPart(scope) - - /** - * The singleton reference queue of the logging scopes. - * - * The queue is populated via [KeyPart] which descends from [WeakReference]. - * - * @see KeyPart - */ - private val queue = ReferenceQueue() - - public actual fun removeUnusedKeys() { - // There are always more specialized keys than entries in the reference queue, - // so the queue should be empty most of the time we get here. - var p = queue.poll() as KeyPart? - while (p != null) { - p.close() - p = queue.poll() as KeyPart? - } - } - } -} diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/WeakRef.kt b/logging/src/jvmMain/kotlin/io/spine/logging/WeakRef.kt new file mode 100644 index 00000000..00669961 --- /dev/null +++ b/logging/src/jvmMain/kotlin/io/spine/logging/WeakRef.kt @@ -0,0 +1,44 @@ +/* + * Copyright 2020, The Flogger Authors; 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.logging + +import java.lang.ref.ReferenceQueue +import java.lang.ref.WeakReference + +/** + * JVM implementation of the `WeekRef` class. + */ +internal actual class WeakRef actual constructor(referent: T) { + + private val ref = WeakReference(referent, queue) + + actual fun get(): T? = ref.get() + + companion object { + internal val queue = ReferenceQueue() + } +} From b43e702ec67df4311260acb74bd7ad380086db97 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sun, 14 Sep 2025 17:25:51 +0100 Subject: [PATCH 16/38] Improve docs --- .../kotlin/io/spine/logging/KeyPart.kt | 73 +++++++++++++++---- 1 file changed, 59 insertions(+), 14 deletions(-) diff --git a/logging/src/commonMain/kotlin/io/spine/logging/KeyPart.kt b/logging/src/commonMain/kotlin/io/spine/logging/KeyPart.kt index 25dadadd..1862c964 100644 --- a/logging/src/commonMain/kotlin/io/spine/logging/KeyPart.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/KeyPart.kt @@ -39,45 +39,90 @@ public class KeyPart private constructor(scope: LoggingScope) { private val ref = WeakRef(scope) - //TODO:2025-09-14:alexander.yevsyukov: Guard for concurrency access. + /** + * The concurrency lock for accessing [onCloseHooks]. + */ + private val hookLock = Any() + + /** + * The list of functions to execute when the instance is [closed][close]. + */ private val onCloseHooks = mutableListOf<() -> Unit>() + /** + * Adds the function to be executed when the instance is [closed][close]. + */ public fun addOnCloseHook(hook: () -> Unit) { - onCloseHooks += hook + synchronized(hookLock) { + onCloseHooks += hook + } } - // If this were ever too "bursty" due to removal of many keys for the same scope, - // we could modify this code to process only a maximum number of removals each time - // and keep a single "in progress" `KeyPart` around until the next time. + /** + * Executes clean-up functions previously added by the [addOnCloseHook] functions. + */ public fun close() { + // If this were ever too "bursty" due to removal of many keys for the same scope, + // we could modify this code to process only a maximum number of removals each time + // and keep a single "in progress" `KeyPart` around until the next time. + // This executes once for each map entry created in the enclosing scope. // It is very dependent on logging usage in the scope and theoretically unbounded. - val it = onCloseHooks.iterator() - while (it.hasNext()) { - it.next().invoke() - it.remove() + val hooksToRun: List<() -> Unit> = synchronized(hookLock) { + // Snapshot and clear under lock to avoid concurrent modification. + val copy = onCloseHooks.toList() + onCloseHooks.clear() + copy + } + // Invoke hooks outside the lock to avoid holding the lock during the user code. + for (hook in hooksToRun) { + hook.invoke() } } public companion object { - //TODO:2025-09-14:alexander.yevsyukov: Guard for concurrency access. + /** + * The lock for accessing [registry]. + */ + private val registryLock = Any() + + /** + * Contains [KeyPart] instances produced by the [create] function. + */ private val registry = mutableSetOf() public fun create(scope: LoggingScope): KeyPart = - KeyPart(scope).also { registry += it } + KeyPart(scope).also { key -> + synchronized(registryLock) { + registry += key + } + } + /** + * Removes the keys that already do not have referenced scopes. + */ public fun removeUnusedKeys() { // There are always more specialized keys than entries in the reference queue, // so the queue should be empty most of the time we get here. + // Snapshot the registry to avoid concurrent modification during iteration. + val snapshot: List = synchronized(registryLock) { + registry.toList() + } + val dead = ArrayList() - for (k in registry) { - if (k.ref.get() == null) dead += k + for (k in snapshot) { + if (k.ref.get() == null) { + dead += k + } } for (k in dead) { + // Close outside the registry lock. k.close() - registry.remove(k) + synchronized(registryLock) { + registry.remove(k) + } } } } From 3042ac31e1c674266d078b8116d18ed49e1d14a7 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sun, 14 Sep 2025 18:57:29 +0100 Subject: [PATCH 17/38] Restore (c) header --- logging/src/commonMain/kotlin/io/spine/logging/LogContext.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logging/src/commonMain/kotlin/io/spine/logging/LogContext.kt b/logging/src/commonMain/kotlin/io/spine/logging/LogContext.kt index 56d59dff..a7beaa42 100644 --- a/logging/src/commonMain/kotlin/io/spine/logging/LogContext.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/LogContext.kt @@ -1,5 +1,5 @@ /* - * Copyright 2025, TeamDev. All rights reserved. + * Copyright 2023, The Flogger Authors; 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 00329367cb1670c34ff8fc579352234f05964704 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sun, 14 Sep 2025 19:03:11 +0100 Subject: [PATCH 18/38] Improve docs --- .../kotlin/io/spine/logging/StackTraceElement.kt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/logging/src/commonMain/kotlin/io/spine/logging/StackTraceElement.kt b/logging/src/commonMain/kotlin/io/spine/logging/StackTraceElement.kt index 5dd0b607..c874ae63 100644 --- a/logging/src/commonMain/kotlin/io/spine/logging/StackTraceElement.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/StackTraceElement.kt @@ -26,7 +26,6 @@ package io.spine.logging -import java.lang.StackTraceElement import kotlin.reflect.KClass /** @@ -34,8 +33,15 @@ import kotlin.reflect.KClass */ public expect class StackTraceElement +/** + * Creates a stack trace array with [io.spine.logging.StackTraceElement] for the given arguments. + * + * @param target The class who is the caller the returned stack trace will start at. + * @param maxDepth The maximum size of the returned stack (pass -1 for the complete stack). + * @param skip The minimum number of stack frames to skip before looking for callers. + */ public expect fun stackForCallerOf( target: KClass<*>, maxDepth: Int, skip: Int -): Array +): Array From e6bce744693f4db0394367ad19a6a66f9133b45c Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sun, 14 Sep 2025 19:03:28 +0100 Subject: [PATCH 19/38] Update build time --- dependencies.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/dependencies.md b/dependencies.md index 6fa2baaa..082d2930 100644 --- a/dependencies.md +++ b/dependencies.md @@ -413,7 +413,7 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 22:03:55 WEST 2025** using +This report was generated on **Sun Sep 14 19:03:11 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1148,7 +1148,7 @@ This report was generated on **Sat Sep 13 22:03:55 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using +This report was generated on **Sun Sep 14 19:03:16 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1982,7 +1982,7 @@ This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using +This report was generated on **Sun Sep 14 19:03:12 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -2800,7 +2800,7 @@ This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using +This report was generated on **Sun Sep 14 19:03:12 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -3662,7 +3662,7 @@ This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using +This report was generated on **Sun Sep 14 19:03:13 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4520,7 +4520,7 @@ This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using +This report was generated on **Sun Sep 14 19:03:14 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5370,7 +5370,7 @@ This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using +This report was generated on **Sun Sep 14 19:03:14 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -6220,7 +6220,7 @@ This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using +This report was generated on **Sun Sep 14 19:03:14 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7078,7 +7078,7 @@ This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using +This report was generated on **Sun Sep 14 19:03:14 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7940,7 +7940,7 @@ This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using +This report was generated on **Sun Sep 14 19:03:14 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8782,7 +8782,7 @@ This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using +This report was generated on **Sun Sep 14 19:03:12 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9521,7 +9521,7 @@ This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using +This report was generated on **Sun Sep 14 19:03:10 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -10256,7 +10256,7 @@ This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using +This report was generated on **Sun Sep 14 19:03:15 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -11122,7 +11122,7 @@ This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using +This report was generated on **Sun Sep 14 19:03:13 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -12008,7 +12008,7 @@ This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using +This report was generated on **Sun Sep 14 19:03:12 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -12826,6 +12826,6 @@ This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sat Sep 13 22:03:56 WEST 2025** using +This report was generated on **Sun Sep 14 19:03:12 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file From d8566e4f2a5e73867163a488e4c2e7f49b3f0499 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sun, 14 Sep 2025 19:10:42 +0100 Subject: [PATCH 20/38] Fix (c) header --- logging/src/jvmMain/kotlin/io/spine/logging/WeakRef.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/WeakRef.kt b/logging/src/jvmMain/kotlin/io/spine/logging/WeakRef.kt index 00669961..06db1c8e 100644 --- a/logging/src/jvmMain/kotlin/io/spine/logging/WeakRef.kt +++ b/logging/src/jvmMain/kotlin/io/spine/logging/WeakRef.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020, The Flogger Authors; 2025, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 7389c7fb1b8725295f73e004a2293b9544543213 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sun, 14 Sep 2025 19:18:08 +0100 Subject: [PATCH 21/38] Update logging/src/commonMain/kotlin/io/spine/logging/util/RecursionDepth.kt Fix guarding overflow Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../commonMain/kotlin/io/spine/logging/util/RecursionDepth.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/logging/src/commonMain/kotlin/io/spine/logging/util/RecursionDepth.kt b/logging/src/commonMain/kotlin/io/spine/logging/util/RecursionDepth.kt index c405374f..afe8f941 100644 --- a/logging/src/commonMain/kotlin/io/spine/logging/util/RecursionDepth.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/util/RecursionDepth.kt @@ -102,12 +102,12 @@ public class RecursionDepth private constructor() : CoroutineContext.Element, Au public fun enterLogStatement(): RecursionDepth { val ctx = CurrentContext.get() val depth = ctx[Key] ?: RecursionDepth() - depth.value += 1 - if (depth.value == 0) { + if (depth.value == Int.MAX_VALUE) { throw AssertionError( "Overflow of `RecursionDepth` (possible error in core library)." ) } + depth.value += 1 CurrentContext.set(ctx + depth) return depth } From 1461efcd3c1db94dbd92e8422c5709732d54caa8 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sun, 14 Sep 2025 19:18:26 +0100 Subject: [PATCH 22/38] Improve diags --- .../src/commonMain/kotlin/io/spine/logging/AbstractLogger.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logging/src/commonMain/kotlin/io/spine/logging/AbstractLogger.kt b/logging/src/commonMain/kotlin/io/spine/logging/AbstractLogger.kt index fb58a501..cb5aa9a9 100644 --- a/logging/src/commonMain/kotlin/io/spine/logging/AbstractLogger.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/AbstractLogger.kt @@ -184,7 +184,7 @@ public abstract class AbstractLogger> protected constructo if (depth.getValue() <= MAX_ALLOWED_RECURSION_DEPTH) { backend.log(data) } else { - reportError("unbounded recursion in log statement", data) + reportError("Unbounded recursion in log statement (depth: $depth).", data) } } } catch (logError: RuntimeException) { From dbdf09759c4f4ed464d4a907953d4495d18223a7 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sun, 14 Sep 2025 19:19:44 +0100 Subject: [PATCH 23/38] Update build time --- dependencies.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/dependencies.md b/dependencies.md index 082d2930..25915649 100644 --- a/dependencies.md +++ b/dependencies.md @@ -413,7 +413,7 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:03:11 WEST 2025** using +This report was generated on **Sun Sep 14 19:18:45 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1148,7 +1148,7 @@ This report was generated on **Sun Sep 14 19:03:11 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:03:16 WEST 2025** using +This report was generated on **Sun Sep 14 19:18:51 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1982,7 +1982,7 @@ This report was generated on **Sun Sep 14 19:03:16 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:03:12 WEST 2025** using +This report was generated on **Sun Sep 14 19:18:48 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -2800,7 +2800,7 @@ This report was generated on **Sun Sep 14 19:03:12 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:03:12 WEST 2025** using +This report was generated on **Sun Sep 14 19:18:48 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -3662,7 +3662,7 @@ This report was generated on **Sun Sep 14 19:03:12 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:03:13 WEST 2025** using +This report was generated on **Sun Sep 14 19:18:48 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4520,7 +4520,7 @@ This report was generated on **Sun Sep 14 19:03:13 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:03:14 WEST 2025** using +This report was generated on **Sun Sep 14 19:18:50 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5370,7 +5370,7 @@ This report was generated on **Sun Sep 14 19:03:14 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:03:14 WEST 2025** using +This report was generated on **Sun Sep 14 19:18:50 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -6220,7 +6220,7 @@ This report was generated on **Sun Sep 14 19:03:14 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:03:14 WEST 2025** using +This report was generated on **Sun Sep 14 19:18:50 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7078,7 +7078,7 @@ This report was generated on **Sun Sep 14 19:03:14 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:03:14 WEST 2025** using +This report was generated on **Sun Sep 14 19:18:50 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7940,7 +7940,7 @@ This report was generated on **Sun Sep 14 19:03:14 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:03:14 WEST 2025** using +This report was generated on **Sun Sep 14 19:18:50 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8782,7 +8782,7 @@ This report was generated on **Sun Sep 14 19:03:14 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:03:12 WEST 2025** using +This report was generated on **Sun Sep 14 19:18:48 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9521,7 +9521,7 @@ This report was generated on **Sun Sep 14 19:03:12 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:03:10 WEST 2025** using +This report was generated on **Sun Sep 14 19:18:45 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -10256,7 +10256,7 @@ This report was generated on **Sun Sep 14 19:03:10 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:03:15 WEST 2025** using +This report was generated on **Sun Sep 14 19:18:51 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -11122,7 +11122,7 @@ This report was generated on **Sun Sep 14 19:03:15 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:03:13 WEST 2025** using +This report was generated on **Sun Sep 14 19:18:48 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -12008,7 +12008,7 @@ This report was generated on **Sun Sep 14 19:03:13 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:03:12 WEST 2025** using +This report was generated on **Sun Sep 14 19:18:48 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -12826,6 +12826,6 @@ This report was generated on **Sun Sep 14 19:03:12 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:03:12 WEST 2025** using +This report was generated on **Sun Sep 14 19:18:48 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file From d3352859fe394cf298e741b001eba15905ecdff5 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sun, 14 Sep 2025 19:27:31 +0100 Subject: [PATCH 24/38] Undo the change suggested by Copilot The change was incorrect because the code guards against going the depth below zero. When the recursion depth becomes zero the context should be freed: see `close()` on this. When we encounter a depth instance which is `-1` it's the error we should report. --- .../kotlin/io/spine/logging/util/RecursionDepth.kt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/logging/src/commonMain/kotlin/io/spine/logging/util/RecursionDepth.kt b/logging/src/commonMain/kotlin/io/spine/logging/util/RecursionDepth.kt index afe8f941..2aa17eec 100644 --- a/logging/src/commonMain/kotlin/io/spine/logging/util/RecursionDepth.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/util/RecursionDepth.kt @@ -102,12 +102,10 @@ public class RecursionDepth private constructor() : CoroutineContext.Element, Au public fun enterLogStatement(): RecursionDepth { val ctx = CurrentContext.get() val depth = ctx[Key] ?: RecursionDepth() - if (depth.value == Int.MAX_VALUE) { - throw AssertionError( - "Overflow of `RecursionDepth` (possible error in core library)." - ) - } depth.value += 1 + if (depth.value == 0) { + error("Negative `RecursionDepth` (-1) encountered.") + } CurrentContext.set(ctx + depth) return depth } From 45fa164fd1862b5a80128feb7904928b5ec23f9e Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sun, 14 Sep 2025 19:27:37 +0100 Subject: [PATCH 25/38] Update build time --- dependencies.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/dependencies.md b/dependencies.md index 25915649..20e7c571 100644 --- a/dependencies.md +++ b/dependencies.md @@ -413,7 +413,7 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:18:45 WEST 2025** using +This report was generated on **Sun Sep 14 19:27:10 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1148,7 +1148,7 @@ This report was generated on **Sun Sep 14 19:18:45 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:18:51 WEST 2025** using +This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1982,7 +1982,7 @@ This report was generated on **Sun Sep 14 19:18:51 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:18:48 WEST 2025** using +This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -2800,7 +2800,7 @@ This report was generated on **Sun Sep 14 19:18:48 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:18:48 WEST 2025** using +This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -3662,7 +3662,7 @@ This report was generated on **Sun Sep 14 19:18:48 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:18:48 WEST 2025** using +This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4520,7 +4520,7 @@ This report was generated on **Sun Sep 14 19:18:48 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:18:50 WEST 2025** using +This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5370,7 +5370,7 @@ This report was generated on **Sun Sep 14 19:18:50 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:18:50 WEST 2025** using +This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -6220,7 +6220,7 @@ This report was generated on **Sun Sep 14 19:18:50 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:18:50 WEST 2025** using +This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7078,7 +7078,7 @@ This report was generated on **Sun Sep 14 19:18:50 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:18:50 WEST 2025** using +This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7940,7 +7940,7 @@ This report was generated on **Sun Sep 14 19:18:50 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:18:50 WEST 2025** using +This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8782,7 +8782,7 @@ This report was generated on **Sun Sep 14 19:18:50 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:18:48 WEST 2025** using +This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9521,7 +9521,7 @@ This report was generated on **Sun Sep 14 19:18:48 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:18:45 WEST 2025** using +This report was generated on **Sun Sep 14 19:27:10 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -10256,7 +10256,7 @@ This report was generated on **Sun Sep 14 19:18:45 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:18:51 WEST 2025** using +This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -11122,7 +11122,7 @@ This report was generated on **Sun Sep 14 19:18:51 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:18:48 WEST 2025** using +This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -12008,7 +12008,7 @@ This report was generated on **Sun Sep 14 19:18:48 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:18:48 WEST 2025** using +This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -12826,6 +12826,6 @@ This report was generated on **Sun Sep 14 19:18:48 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:18:48 WEST 2025** using +This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file From d275dddf10c66acb8b919b2232e5e4583edd3722 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sun, 14 Sep 2025 19:33:39 +0100 Subject: [PATCH 26/38] Use Kotlin class names --- .../kotlin/io/spine/logging/LogPerBucketingStrategy.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/logging/src/commonMain/kotlin/io/spine/logging/LogPerBucketingStrategy.kt b/logging/src/commonMain/kotlin/io/spine/logging/LogPerBucketingStrategy.kt index f0ee8c71..e298be5e 100644 --- a/logging/src/commonMain/kotlin/io/spine/logging/LogPerBucketingStrategy.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/LogPerBucketingStrategy.kt @@ -105,7 +105,7 @@ public abstract class LogPerBucketingStrategy protected constructor( internal fun applyForTesting(key: T): Any? = apply(key) override fun toString(): String = - "${LogPerBucketingStrategy::class.java.simpleName}[$name]" + "${LogPerBucketingStrategy::class.simpleName}[$name]" public companion object { @@ -122,7 +122,7 @@ public abstract class LogPerBucketingStrategy protected constructor( * are effectively singletons. */ private val BY_CLASS = object : LogPerBucketingStrategy("ByClass") { - override fun apply(key: Any): Any = key.javaClass + override fun apply(key: Any): Any = key::class } /** @@ -131,8 +131,8 @@ public abstract class LogPerBucketingStrategy protected constructor( * are effectively singletons. */ private val BY_CLASS_NAME = object : LogPerBucketingStrategy("ByClassName") { - override fun apply(key: Any): Any = key.javaClass.name /* This is a naturally interned - value, so no need to call `intern()`. */ + override fun apply(key: Any): Any = key::class.qualifiedName!! + /* This is a naturally interned value, so no need to call `intern()`. */ } /** From 044fac1177f6871a6daa3c6505514cb4746ae1eb Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sun, 14 Sep 2025 19:33:47 +0100 Subject: [PATCH 27/38] Update build time --- dependencies.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/dependencies.md b/dependencies.md index 20e7c571..bf44ab6d 100644 --- a/dependencies.md +++ b/dependencies.md @@ -413,7 +413,7 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:27:10 WEST 2025** using +This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1148,7 +1148,7 @@ This report was generated on **Sun Sep 14 19:27:10 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using +This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1982,7 +1982,7 @@ This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using +This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -2800,7 +2800,7 @@ This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using +This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -3662,7 +3662,7 @@ This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using +This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4520,7 +4520,7 @@ This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using +This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5370,7 +5370,7 @@ This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using +This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -6220,7 +6220,7 @@ This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using +This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7078,7 +7078,7 @@ This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using +This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7940,7 +7940,7 @@ This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using +This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8782,7 +8782,7 @@ This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using +This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9521,7 +9521,7 @@ This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:27:10 WEST 2025** using +This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -10256,7 +10256,7 @@ This report was generated on **Sun Sep 14 19:27:10 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using +This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -11122,7 +11122,7 @@ This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using +This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -12008,7 +12008,7 @@ This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using +This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -12826,6 +12826,6 @@ This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:27:11 WEST 2025** using +This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file From 8fe2c166ef09a98a752d2065048835b53608c1b3 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sun, 14 Sep 2025 19:35:22 +0100 Subject: [PATCH 28/38] Remove unnecessary `Companion` references --- .../kotlin/io/spine/logging/LogSiteLookup.kt | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/logging/src/commonMain/kotlin/io/spine/logging/LogSiteLookup.kt b/logging/src/commonMain/kotlin/io/spine/logging/LogSiteLookup.kt index 750da27d..b18610ac 100644 --- a/logging/src/commonMain/kotlin/io/spine/logging/LogSiteLookup.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/LogSiteLookup.kt @@ -42,9 +42,8 @@ public object LogSiteLookup { * If log site determination is unsupported, this method returns * the [LogSite.Invalid] instance. */ - public fun callerOf(loggingApi: KClass<*>): LogSite { - return Platform.Companion.getCallerFinder().findLogSite(loggingApi, 0) - } + public fun callerOf(loggingApi: KClass<*>): LogSite = + Platform.getCallerFinder().findLogSite(loggingApi, 0) /** * Returns a [LogSite] for the current line of code. @@ -52,10 +51,6 @@ public object LogSiteLookup { * If log site determination is unsupported, this method returns * the [LogSite.Invalid] instance. */ - public fun logSite(): LogSite { - return Platform.Companion.getCallerFinder().findLogSite( - LogSiteLookup::class, - 0 - ) - } + public fun logSite(): LogSite = + Platform.getCallerFinder().findLogSite(LogSiteLookup::class, 0) } From 193f26671781d37bccc25d4d73f63a1756d1e62b Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sun, 14 Sep 2025 19:35:43 +0100 Subject: [PATCH 29/38] Update build time --- dependencies.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/dependencies.md b/dependencies.md index bf44ab6d..5ae074e8 100644 --- a/dependencies.md +++ b/dependencies.md @@ -413,7 +413,7 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using +This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1148,7 +1148,7 @@ This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using +This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1982,7 +1982,7 @@ This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using +This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -2800,7 +2800,7 @@ This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using +This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -3662,7 +3662,7 @@ This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using +This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4520,7 +4520,7 @@ This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using +This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5370,7 +5370,7 @@ This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using +This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -6220,7 +6220,7 @@ This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using +This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7078,7 +7078,7 @@ This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using +This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7940,7 +7940,7 @@ This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using +This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8782,7 +8782,7 @@ This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using +This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9521,7 +9521,7 @@ This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using +This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -10256,7 +10256,7 @@ This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using +This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -11122,7 +11122,7 @@ This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using +This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -12008,7 +12008,7 @@ This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using +This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -12826,6 +12826,6 @@ This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:33:25 WEST 2025** using +This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file From 23cfd880bc1625d46c2fd114e603ab211f053b37 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sun, 14 Sep 2025 19:45:19 +0100 Subject: [PATCH 30/38] Improve diags. of recursion depths --- .../kotlin/io/spine/logging/AbstractLogger.kt | 4 +++- .../io/spine/logging/util/RecursionDepth.kt | 22 ++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/logging/src/commonMain/kotlin/io/spine/logging/AbstractLogger.kt b/logging/src/commonMain/kotlin/io/spine/logging/AbstractLogger.kt index cb5aa9a9..08c60dde 100644 --- a/logging/src/commonMain/kotlin/io/spine/logging/AbstractLogger.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/AbstractLogger.kt @@ -184,7 +184,9 @@ public abstract class AbstractLogger> protected constructo if (depth.getValue() <= MAX_ALLOWED_RECURSION_DEPTH) { backend.log(data) } else { - reportError("Unbounded recursion in log statement (depth: $depth).", data) + reportError( + "Unbounded recursion in log statement (depth: ${depth.getValue()}).", data + ) } } } catch (logError: RuntimeException) { diff --git a/logging/src/commonMain/kotlin/io/spine/logging/util/RecursionDepth.kt b/logging/src/commonMain/kotlin/io/spine/logging/util/RecursionDepth.kt index 2aa17eec..fbe20910 100644 --- a/logging/src/commonMain/kotlin/io/spine/logging/util/RecursionDepth.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/util/RecursionDepth.kt @@ -69,11 +69,12 @@ public class RecursionDepth private constructor() : CoroutineContext.Element, Au ) } + + /** * The [CoroutineContext.Key] for managing [RecursionDepth] in a [CoroutineContext]. */ public companion object Key : CoroutineContext.Key { - /** * Holds the current coroutine context for logging operations. * @@ -109,5 +110,24 @@ public class RecursionDepth private constructor() : CoroutineContext.Element, Au CurrentContext.set(ctx + depth) return depth } + + } + + override fun toString(): String { + return "RecursionDepth(value=$value)" + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null) return false + if (this::class != other::class) return false + + other as RecursionDepth + + return value == other.value + } + + override fun hashCode(): Int { + return value } } From 3d1ed4c5dd97283e3665104e2dd54994121f96f2 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sun, 14 Sep 2025 19:45:51 +0100 Subject: [PATCH 31/38] Update build time --- dependencies.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/dependencies.md b/dependencies.md index 5ae074e8..6cd737a0 100644 --- a/dependencies.md +++ b/dependencies.md @@ -413,7 +413,7 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using +This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1148,7 +1148,7 @@ This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using +This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1982,7 +1982,7 @@ This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using +This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -2800,7 +2800,7 @@ This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using +This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -3662,7 +3662,7 @@ This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using +This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4520,7 +4520,7 @@ This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using +This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5370,7 +5370,7 @@ This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using +This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -6220,7 +6220,7 @@ This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using +This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7078,7 +7078,7 @@ This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using +This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7940,7 +7940,7 @@ This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using +This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8782,7 +8782,7 @@ This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using +This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9521,7 +9521,7 @@ This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using +This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -10256,7 +10256,7 @@ This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using +This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -11122,7 +11122,7 @@ This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using +This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -12008,7 +12008,7 @@ This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using +This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -12826,6 +12826,6 @@ This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:35:26 WEST 2025** using +This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file From 22d2e32c371bc0c4402b7fb87852cc283653d784 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sun, 14 Sep 2025 19:48:35 +0100 Subject: [PATCH 32/38] Fix typo --- logging/src/jvmMain/kotlin/io/spine/logging/WeakRef.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/WeakRef.kt b/logging/src/jvmMain/kotlin/io/spine/logging/WeakRef.kt index 06db1c8e..1f051311 100644 --- a/logging/src/jvmMain/kotlin/io/spine/logging/WeakRef.kt +++ b/logging/src/jvmMain/kotlin/io/spine/logging/WeakRef.kt @@ -30,7 +30,7 @@ import java.lang.ref.ReferenceQueue import java.lang.ref.WeakReference /** - * JVM implementation of the `WeekRef` class. + * JVM implementation of the `WeakRef` class. */ internal actual class WeakRef actual constructor(referent: T) { From 716bdc17a8816727928dd8d8cfd27aefb0030538 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sun, 14 Sep 2025 19:52:56 +0100 Subject: [PATCH 33/38] Improve diags of `RecursionDepth` --- .../kotlin/io/spine/logging/util/RecursionDepth.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/logging/src/commonMain/kotlin/io/spine/logging/util/RecursionDepth.kt b/logging/src/commonMain/kotlin/io/spine/logging/util/RecursionDepth.kt index fbe20910..070b1106 100644 --- a/logging/src/commonMain/kotlin/io/spine/logging/util/RecursionDepth.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/util/RecursionDepth.kt @@ -64,9 +64,7 @@ public class RecursionDepth private constructor() : CoroutineContext.Element, Au } return } - throw AssertionError( - "Mismatched calls to `RecursionDepth` (possible error in core library)." - ) + error("Mismatched calls to `RecursionDepth`.") } @@ -105,7 +103,7 @@ public class RecursionDepth private constructor() : CoroutineContext.Element, Au val depth = ctx[Key] ?: RecursionDepth() depth.value += 1 if (depth.value == 0) { - error("Negative `RecursionDepth` (-1) encountered.") + error("`RecursionDepth` with -1 value encountered.") } CurrentContext.set(ctx + depth) return depth From a95e2a2b5068e7747ef3a55628b2f3b3e3e84f46 Mon Sep 17 00:00:00 2001 From: Alexander Yevsyukov Date: Sun, 14 Sep 2025 19:53:32 +0100 Subject: [PATCH 34/38] Update build time --- dependencies.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/dependencies.md b/dependencies.md index 6cd737a0..51514f0a 100644 --- a/dependencies.md +++ b/dependencies.md @@ -413,7 +413,7 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using +This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1148,7 +1148,7 @@ This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using +This report was generated on **Sun Sep 14 19:53:15 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1982,7 +1982,7 @@ This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using +This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -2800,7 +2800,7 @@ This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using +This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -3662,7 +3662,7 @@ This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using +This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4520,7 +4520,7 @@ This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using +This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5370,7 +5370,7 @@ This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using +This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -6220,7 +6220,7 @@ This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using +This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7078,7 +7078,7 @@ This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using +This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7940,7 +7940,7 @@ This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using +This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8782,7 +8782,7 @@ This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using +This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9521,7 +9521,7 @@ This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using +This report was generated on **Sun Sep 14 19:53:15 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -10256,7 +10256,7 @@ This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using +This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -11122,7 +11122,7 @@ This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using +This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -12008,7 +12008,7 @@ This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using +This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -12826,6 +12826,6 @@ This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:45:23 WEST 2025** using +This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file From 1e2737720053a59438dc81bdc3fbc64d80cfa0a4 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Mon, 15 Sep 2025 11:54:22 +0100 Subject: [PATCH 35/38] Backtick the display name of the test suite --- .../jvmTest/kotlin/io/spine/logging/backend/AnyExtsJvmSpec.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logging/src/jvmTest/kotlin/io/spine/logging/backend/AnyExtsJvmSpec.kt b/logging/src/jvmTest/kotlin/io/spine/logging/backend/AnyExtsJvmSpec.kt index 3bb2789d..9f2da734 100644 --- a/logging/src/jvmTest/kotlin/io/spine/logging/backend/AnyExtsJvmSpec.kt +++ b/logging/src/jvmTest/kotlin/io/spine/logging/backend/AnyExtsJvmSpec.kt @@ -32,7 +32,7 @@ import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test -@DisplayName("Any? extensions under JVM should") +@DisplayName("`Any?` extensions under JVM should") internal class AnyExtsJvmSpec { @Nested inner class From e2db9c9ba8bc7cacd8695f5df1b3e0f91bfd1d48 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Mon, 15 Sep 2025 11:54:31 +0100 Subject: [PATCH 36/38] Update build time --- dependencies.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/dependencies.md b/dependencies.md index 51514f0a..9282b6f5 100644 --- a/dependencies.md +++ b/dependencies.md @@ -413,7 +413,7 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using +This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1148,7 +1148,7 @@ This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:53:15 WEST 2025** using +This report was generated on **Mon Sep 15 11:53:30 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1982,7 +1982,7 @@ This report was generated on **Sun Sep 14 19:53:15 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using +This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -2800,7 +2800,7 @@ This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using +This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -3662,7 +3662,7 @@ This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using +This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4520,7 +4520,7 @@ This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using +This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5370,7 +5370,7 @@ This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using +This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -6220,7 +6220,7 @@ This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using +This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7078,7 +7078,7 @@ This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using +This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7940,7 +7940,7 @@ This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using +This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8782,7 +8782,7 @@ This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using +This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9521,7 +9521,7 @@ This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:53:15 WEST 2025** using +This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -10256,7 +10256,7 @@ This report was generated on **Sun Sep 14 19:53:15 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using +This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -11122,7 +11122,7 @@ This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using +This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -12008,7 +12008,7 @@ This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using +This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -12826,6 +12826,6 @@ This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Sun Sep 14 19:53:14 WEST 2025** using +This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file From 1e5f0e50d39f8bd8178e19128b31ca62575ee157 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Mon, 15 Sep 2025 12:07:51 +0100 Subject: [PATCH 37/38] Improve param docs Also: * Remove extra empty line. --- .../src/commonMain/kotlin/io/spine/logging/StackTraceElement.kt | 2 +- .../src/jvmMain/kotlin/io/spine/logging/StackTraceElementJvm.kt | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/logging/src/commonMain/kotlin/io/spine/logging/StackTraceElement.kt b/logging/src/commonMain/kotlin/io/spine/logging/StackTraceElement.kt index c874ae63..5386c2b8 100644 --- a/logging/src/commonMain/kotlin/io/spine/logging/StackTraceElement.kt +++ b/logging/src/commonMain/kotlin/io/spine/logging/StackTraceElement.kt @@ -36,7 +36,7 @@ public expect class StackTraceElement /** * Creates a stack trace array with [io.spine.logging.StackTraceElement] for the given arguments. * - * @param target The class who is the caller the returned stack trace will start at. + * @param target The class to get the stack from. * @param maxDepth The maximum size of the returned stack (pass -1 for the complete stack). * @param skip The minimum number of stack frames to skip before looking for callers. */ diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/StackTraceElementJvm.kt b/logging/src/jvmMain/kotlin/io/spine/logging/StackTraceElementJvm.kt index 0994972e..37d15808 100644 --- a/logging/src/jvmMain/kotlin/io/spine/logging/StackTraceElementJvm.kt +++ b/logging/src/jvmMain/kotlin/io/spine/logging/StackTraceElementJvm.kt @@ -36,4 +36,3 @@ public actual fun stackForCallerOf( maxDepth: Int, skip: Int ): Array = CallerFinder.stackForCallerOf(target.java, maxDepth, skip) - From 5fba00f7c5f10fe92830c962eef79af47a75e35b Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Mon, 15 Sep 2025 12:08:19 +0100 Subject: [PATCH 38/38] Update build time --- dependencies.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/dependencies.md b/dependencies.md index 9282b6f5..c49adee6 100644 --- a/dependencies.md +++ b/dependencies.md @@ -413,7 +413,7 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using +This report was generated on **Mon Sep 15 12:08:00 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1148,7 +1148,7 @@ This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Sep 15 11:53:30 WEST 2025** using +This report was generated on **Mon Sep 15 12:08:01 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1982,7 +1982,7 @@ This report was generated on **Mon Sep 15 11:53:30 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using +This report was generated on **Mon Sep 15 12:08:00 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -2800,7 +2800,7 @@ This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using +This report was generated on **Mon Sep 15 12:08:00 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -3662,7 +3662,7 @@ This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using +This report was generated on **Mon Sep 15 12:08:00 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4520,7 +4520,7 @@ This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using +This report was generated on **Mon Sep 15 12:08:01 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5370,7 +5370,7 @@ This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using +This report was generated on **Mon Sep 15 12:08:01 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -6220,7 +6220,7 @@ This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using +This report was generated on **Mon Sep 15 12:08:01 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7078,7 +7078,7 @@ This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using +This report was generated on **Mon Sep 15 12:08:01 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -7940,7 +7940,7 @@ This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using +This report was generated on **Mon Sep 15 12:08:01 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -8782,7 +8782,7 @@ This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using +This report was generated on **Mon Sep 15 12:08:00 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -9521,7 +9521,7 @@ This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using +This report was generated on **Mon Sep 15 12:08:01 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -10256,7 +10256,7 @@ This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using +This report was generated on **Mon Sep 15 12:08:00 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -11122,7 +11122,7 @@ This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using +This report was generated on **Mon Sep 15 12:08:00 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -12008,7 +12008,7 @@ This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using +This report was generated on **Mon Sep 15 12:08:00 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -12826,6 +12826,6 @@ This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Sep 15 11:53:29 WEST 2025** using +This report was generated on **Mon Sep 15 12:08:00 WEST 2025** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file