quarkusopen-telemetryquarkus-rest-client

How to disable trace ids for specific REST Clients invocations?


Currently, when using REST Client to do API calls and Open Telemetry extension for tracing, a tracing header is added to all API calls, which is fine.

However, in case I want to explicitly omit the addition of this header when interacting with third party systems (externals / not in my control), is there any annotation (method or class level) I can use? If not, is there any way to omit it?


Solution

  • For this purpose, OpenTelemetry uses a Sampler.

    You can create your own CDI bean sampler with Quarkus, like this:

    @Singleton
    public class CustomConfiguration {
    
        /** Creates a custom sampler for OpenTelemetry */
        @Produces
        @Singleton
        public Sampler sampler() {
            List<String> targets = List.of("http://address-you-must-drop");
            return new CustomSampler(targets);
        }
     }
    

    Where the CustomSampler could be inspired by Quarkus own target sampler. It would look something like:

    public class CustomSampler implements Sampler {
    
    private final List<String> dropTargets;
    
    public CustomSampler(final List<String> dropTargets) {
        // The targets to drop.
        this.dropTargets = dropTargets;
    }
    
    @Override
    public SamplingResult shouldSample(Context context,
            String s,
            String s1,
            SpanKind spanKind,
            Attributes attributes,
            List<LinkData> list) {
        if (spanKind.equals(SpanKind.CLIENT)) {
            String target = attributes.get(SemanticAttributes.HTTP_URL);
            if (target == null) {
                target = attributes.get(SemanticAttributes.URL_FULL);
            }
            if (shouldDrop(target)) {
                return SamplingResult.drop();
            }
        }
        return Sampler.alwaysOn().shouldSample(context, s, s1, spanKind, attributes, list);
    }
    
    @Override
    public String getDescription() {
        return "custom-endpoint-sampler";
    }
    
    private boolean shouldDrop(String target) {
        if ((target == null) || target.isEmpty()) {
            return false;
        }
        if (safeContains(target)) { // check exact match
            return true;
        }
        if (target.charAt(target.length() - 1) == '/') { // check if the path without the ending slash matched
            if (safeContains(target.substring(0, target.length() - 1))) {
                return true;
            }
        }
        int lastSlashIndex = target.lastIndexOf('/');
        if (lastSlashIndex != -1) {
            if (safeContains(target.substring(0, lastSlashIndex) + "*")
                    || safeContains(target.substring(0, lastSlashIndex) + "/*")) { // check if a wildcard matches
                return true;
            }
        }
        return false;
    }
    
    private boolean safeContains(String target) {
        return dropTargets.contains(target);
    }
    

    }