Kotlin, Spring, WebFlux, MDC, Webfilter

Zongatel

Mitglied
Hallo allesamt,
In einer Anwendung, die ich seit neuerem mit warte gibt es die obigen Themen.
Ich versuche Mittels MDC Logs anzureichern.
Irgendwo hatte ich Code aus dem Netz zusammengeklaubt.
Leider verstehe ich nicht, ich bin herzlich neu bei obigen Themen, warum der Webfilter scheinbar nicht von Spring angesprochen wird.
Mein Verdacht ist, dass er vielleicht von Spring nicht erkannt wird, nur warum nicht?

Java:
import org.reactivestreams.Subscription
import org.slf4j.MDC
import org.springframework.context.annotation.Configuration
import org.springframework.stereotype.Component
import org.springframework.web.server.ServerWebExchange
import org.springframework.web.server.WebFilter
import org.springframework.web.server.WebFilterChain
import reactor.core.CoreSubscriber
import reactor.core.publisher.Hooks
import reactor.core.publisher.Mono
import reactor.core.publisher.Operators
import reactor.util.context.Context
import java.util.concurrent.ThreadLocalRandom
import java.util.stream.Collectors
import javax.annotation.PostConstruct
import javax.annotation.PreDestroy


@Component
class LoggingWebFilter : WebFilter {
    override fun filter(exchange: ServerWebExchange, chain: WebFilterChain): Mono<Void> {
        return chain.filter(exchange).subscriberContext { ctx ->
            ctx.put("interaction_id", ThreadLocalRandom.current().nextLong().toString())
        }
    }
}

@Configuration
class MdcContextLifterConfiguration {

    companion object {
        val MDC_CONTEXT_REACTOR_KEY: String = MdcContextLifterConfiguration::class.java.name
    }

    @PostConstruct
    fun contextOperatorHook() {
        Hooks.onEachOperator(MDC_CONTEXT_REACTOR_KEY, Operators.lift { _, subscriber -> MdcContextLifter(subscriber) })
    }

    @PreDestroy
    fun cleanupHook() {
        Hooks.resetOnEachOperator(MDC_CONTEXT_REACTOR_KEY)
    }

}

/**
 * Helper that copies the state of Reactor [Context] to MDC on the #onNext function.
 */
class MdcContextLifter<T>(private val coreSubscriber: CoreSubscriber<T>) : CoreSubscriber<T> {

    override fun onNext(t: T) {
        coreSubscriber.currentContext().copyToMdc()
        coreSubscriber.onNext(t)
    }

    override fun onSubscribe(subscription: Subscription) {
        coreSubscriber.onSubscribe(subscription)
    }

    override fun onComplete() {
        coreSubscriber.onComplete()
    }

    override fun onError(throwable: Throwable?) {
        coreSubscriber.onError(throwable)
    }

    override fun currentContext(): Context {
        return coreSubscriber.currentContext()
    }
}

/**
 * Extension function for the Reactor [Context]. Copies the current context to the MDC, if context is empty clears the MDC.
 * State of the MDC after calling this method should be same as Reactor [Context] state.
 * One thread-local access only.
 */
private fun Context.copyToMdc() {
    if (!this.isEmpty) {
        val map: Map<String, String> = this.stream()
            .collect(Collectors.toMap({ e -> e.key.toString() }, { e -> e.value.toString() }))

        MDC.setContextMap(map)
    } else {
        MDC.clear()
    }
In die Routine "private fun Context.copyToMdc()" kommt er rein, was ich beim debuggen feststellen konnte, da aber
this.Empty true ist setzt er die map nicht in die ContextMap von MDC

Breakpoints bezüglich des oben definierten Webfilters werden beim Debuggen nicht angespochen.
Was mache ich falsch?
 

Jw456

Top Contributor
Na worauf zeigt den this was prüfst du hier ? Du willst doch bestimmt eine Variable prüfen und nicht "this" das wird immer true sein.
 

Ähnliche Java Themen

Neue Themen


Oben