Releases: Numichi/reactive-logger
v4.0.4
v4.0.3
v4.0.2
v4.0.1
v4.0.0
v4.0.0-RC0
- All v3.2
- bug fixes
- Spring support fix
application.yml
orapplication.properties
configuration for custom registries, similar resilience4j spring boot solution.- MDCHook can be added via Bean, which will activate it for logging.
- old methods removed
- MDC reader throws an exception if the context key does not exist
- added snapshot methods, which give MDC and trigger hooks
- MDC has ceased to be a MAP, from here MDC is an immutable data class
- added operators support in MDC like
mdc + mapOf("foo" to "bar")
(for Kotlin). Simular in Javamdc.plus(Map.of("foo", "bar"))
- not just for Map
v3.2.0-RC0
v3.1.0
Blocking wrong configuration
There is an option in Coroutine with more context class configuration. Like: coroutineContext[CustomClass]
. ReactorContext is used In Spring Reactive and it will work in unexpected ways with custom resolvers, so that's why the custom context resolver was removed.
Example - if you fill in all the fields
// Before
CoroutineLogger.getLogger("...", null, null) { Context.empty() }
CoroutineKLogger.getLogger("...", null, null) { Context.empty() }
// After
CoroutineLogger.getLogger("...", null, null)
CoroutineKLogger.getLogger("...", null, null)
Add new methods MDCContext.modifyContext
You can add map into modifyContext
and merge it with the current MDC map.
.contextWrite { ctx -> MDCContext.modifyContext(ctx, mapOf("key" to "example")) }
.contextWrite { ctx -> MDCContext.modifyContext(ctx, "key", mapOf("key" to "example")) }
Support .doOnEach() method
In Java: <T> void logConsumer(BiConsumer<Logger, Signal<T>> consumer)
var logger = ReactiveLogger.getLogger(JavaClassExample.class); // and ReactiveKLogger
.doOnEach(logger.logConsumer((log, signal) -> {
if (signal.getType() == SignalType.ON_NEXT) log.info(signal.get());
if (signal.getType() == SignalType.ON_ERROR) {
Optional.ofNullable(signal.getThrowable()).ifPresent(it -> {
log.error(it.getMessage());
});
}
}))
In Kotlin: above and also fun <T> logSignal(signal: Signal<T>, fn: (Logger) -> Unit)
val logger = CoroutineLogger.getLogger({}) // and CoroutineKLogger
.doOnEach(reactiveLogger.logConsumer { log, signal ->
if (signal.type == SignalType.ON_NEXT) log.info(signal.get())
if (signal.type == SignalType.ON_ERROR) log.error(signal.throwable?.message)
})
// or
.doOnEach { signal ->
if (s.isOnNext) logger.logSignal(signal) { it.info(s.get()) }
if (s.isOnError) logger.logSignal(signal) { it.error(s.throwable?.message) }
}
v3.0.1
Easier to use for Java language. Not need INSTANCE
when calling methods like in Kotlin. There are new methods in ReactiveLogger with one parameter without defaults because Java language can not understand like ... , param = 0): ...
.
Java Example:
// Before (can also be used after modification)
Configuration.INSTANCE.addGenericHook("test", "foo", 0, (String value, MDC mdc) -> Map.of("key", value));
Configuration.INSTANCE.setDefaultReactorContextMdcKey("custom");
var logger = ReactiveLogger.Companion.getLogger(JavaExample.class, null, null);
logger.info("message");
// After
Configuration.addGenericHook("test", "foo", (String value, MDC mdc) -> Map.of("key", value)); // order default value is 0
Configuration.setDefaultReactorContextMdcKey("custom");
var logger = ReactiveLogger.getLogger(JavaExample.class);
logger.info("message"); // result: Mono<ViewContext>