Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove the legacy MDC entries and remain with the Brave MDC ones only #1221

Closed
marcingrzejszczak opened this issue Feb 26, 2019 · 8 comments
Closed

Comments

@marcingrzejszczak
Copy link
Contributor

No description provided.

@odin-delrio
Copy link

odin-delrio commented Jun 27, 2019

Hi! I'm suffering the noise of having the legacy keys added in the MDC and I would like to keep my log4j pattern printing everything in the MDC by using%X.

Current:

2019-06-27 19:36:11,774 INFO {X-B3-SpanId=e30b6a75bcff782b, X-B3-TraceId=e30b6a75bcff782b, X-Span-Export=false, spanExportable=false, spanId=e30b6a75bcff782b, traceId=e30b6a75bcff782b} some log!

Desired:

2019-06-27 19:36:11,774 INFO {spanExportable=false, spanId=e30b6a75bcff782b, traceId=e30b6a75bcff782b} some log!

So, I would vote for removing all the legacy keys in the Slf4jScopeDecorator class.

As this can be a breaking change, what do you think about adding a config key for optionally avoid adding these legacy keys to the MDC?
If you think this is a good idea I can make a PR ;)

@szczepanskikrs
Copy link

Is there some relatively easy way to remove duplicated legacy key-values pairs from MDC?

@odin-delrio
Copy link

@szczepanskikrs Not that easy, but I solved this in the following way and add it to an autoconfiguration library so I solved it for several projects.

First I created a class implementing the ScopeDecorator interface, but the trick is to do it using the original org.springframework.cloud.sleuth.log package, why? Because this class wraps the original spring scope decorator, and since this one has a "package protected" constructor, there is no other way to instantiate it, so:

package org.springframework.cloud.sleuth.log;

import brave.internal.Nullable;
import brave.propagation.TraceContext;
import org.slf4j.MDC;
import org.springframework.cloud.sleuth.autoconfig.SleuthProperties;

import java.util.HashSet;
import java.util.Set;

import static brave.propagation.CurrentTraceContext.Scope;
import static brave.propagation.CurrentTraceContext.ScopeDecorator;
import static java.util.Arrays.asList;

public class CustomSlf4ScopeDecorator implements ScopeDecorator {

    public static final Set<String> UNDESIRED_MDC_KEYS = new HashSet<>(asList(
            "X-Span-Export",
            "X-B3-ParentSpanId",
            "X-B3-TraceId",
            "X-B3-SpanId",
            "spanExportable"
    ));

    private final ScopeDecorator decorator;

    public CustomSlf4ScopeDecorator(SleuthProperties sleuthProperties, SleuthSlf4jProperties sleuthSlf4jProperties) {
        this.decorator = new Slf4jScopeDecorator(sleuthProperties, sleuthSlf4jProperties);
    }

    @Override
    public Scope decorateScope(@Nullable TraceContext currentSpan, Scope scope) {
        Scope decoratedScope = decorator.decorateScope(currentSpan, scope);
        UNDESIRED_MDC_KEYS.forEach(MDC::remove);

        return decoratedScope;
    }
}

then you need to instruct spring to use that scope decorator instead of the original one, so you need to first add this configuration class:

@Configuration
@ConditionalOnProperty(value = "spring.sleuth.enabled", matchIfMissing = true)
@AutoConfigureBefore(TraceAutoConfiguration.class)
public class CustomSleuthLogAutoConfiguration {

    /**
     * Configuration for Slf4j.
     */
    @Configuration
    @ConditionalOnClass(MDC.class)
    @EnableConfigurationProperties(SleuthSlf4jProperties.class)
    public static class CustomSlf4jConfiguration {

        @Bean
        @ConditionalOnProperty(value = "spring.sleuth.log.slf4j.enabled", matchIfMissing = true)
        public CurrentTraceContext.ScopeDecorator slf4jSpanDecorator(
                SleuthProperties sleuthProperties,
                SleuthSlf4jProperties sleuthSlf4jProperties
        ) {
            return new CustomSlf4ScopeDecorator(sleuthProperties, sleuthSlf4jProperties);
        }
    }
}

and then instruct spring to not load the original autoconfig class, so you need to register this filter:

public class SleuthLogAutoConfigurationExclusionFilter implements AutoConfigurationImportFilter {

    @Override
    public boolean[] match(String[] classNames, AutoConfigurationMetadata metadata) {
        boolean[] matches = new boolean[classNames.length];

        for (int i = 0; i < classNames.length; i++) {
            matches[i] = !SleuthLogAutoConfiguration.class.getName().equals(classNames[i]);
        }

        return matches;
    }
}

For registering this filter, I'm doing it through a spring.factories file located in "resources/META-INF/spring.factories", with this content (maybe there is other way for registering it):

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.yourcompany...CustomSleuthLogAutoConfiguration

@marcingrzejszczak
Copy link
Contributor Author

You can create sth like Slf4jScopeDecorator that will do the cleaning

@szczepanskikrs
Copy link

Thanks for help @marcingrzejszczak @odin-delrio

@cristianprofile
Copy link

@szczepanskikrs
Will this feature be available in the next release of sleuth?

@marcingrzejszczak
Copy link
Contributor Author

We will remove the legacy MDC entries and message headers in the Ilford (Sleuth 3.0) release

@marcingrzejszczak
Copy link
Contributor Author

This is partially done by @adriancole since all Sleuth code related to MDC got removed and migrated to using Brave natively.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants