-
Notifications
You must be signed in to change notification settings - Fork 0
Description
There is a method io.spine.logging.ScopedLoggingContext.Builder.withMetadata(key: MetadataKey<T>, value: T)
for attaching context metadata. It accepts a metadata key, which is an interface: interface MetadataKey<T: Any>
. An attempt to create an object that implements this interface and pass it to the builder leads to an exception on JVM.
A failing code snippet:
import io.spine.logging.LoggingFactory
import io.spine.logging.MetadataKey
import io.spine.logging.WithLogging
import io.spine.logging.context.ScopedLoggingContext
typealias User = String
object UserKey : MetadataKey<User> {
override val canRepeat: Boolean = false
override val label: String = "user"
override fun cast(value: Any): User =
if (value is User) value else error("The passed `$value` can't be cast to `User`.")
}
object Example : WithLogging {
fun doAct() {
val user: User = "Bill"
val logger = LoggingFactory.forEnclosingClass()
ScopedLoggingContext.newContext()
.withMetadata(UserKey, user)
.execute {
logger.atInfo().log { "..." }
}
}
}
fun main() = Example.doAct()
It fails with the following exception:
Exception in thread "main" java.lang.ClassCastException: class logging.test.UserKey cannot be cast to class io.spine.logging.JvmMetadataKey (logging.test.UserKey and io.spine.logging.JvmMetadataKey are in unnamed module of loader 'app')
at io.spine.logging.context.DelegatingContextBuilder.withMetadata(LoggingContextFactory.kt:180)
at logging.test.AppKt.main(App.kt:38)
at logging.test.AppKt.main(App.kt)
However, it works fine if a key is created by LoggingFactory
:
val userKey = LoggingFactory.singleMetadataKey("user", User::class)
We should either document somewhere that keys can be created only by the factory, or allow passing of custom ones.
Additionally, align naming of method arguments in overloads of singleMetadataKey(...)
and repeatedMetadataKey(...)
. KClass
for values is named different. We should go with valueClass
name. It relates to LoggingFactory
for JVM.