Skip to content

Custom AttributeExtractor not adding attributes to ApacheHttpClient5 #12412

@Dimagreg

Description

@Dimagreg

Describe the bug

After merging PR #12394 from issue #12393, I tried testing the possibility of adding attributes on ApacheHttpClient5 but they are not created.

Steps to reproduce

Create ApacheHttpClient5Configurator.java

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.apachehttpclient.v5_2.ApacheHttpClient5Telemetry;
import io.opentelemetry.instrumentation.apachehttpclient.v5_2.ApacheHttpClient5Request;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;

import org.apache.hc.client5.http.classic.HttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.core5.http.HttpResponse;

public class ApacheHttpClient5Configurator {

    // creates a new http client builder for constructing http clients with open telemetry instrumentation
    public HttpClientBuilder createBuilder(OpenTelemetry openTelemetry) {
        try { 
            return ApacheHttpClient5Telemetry.builder(openTelemetry)
                .addAttributeExtractor(new ServiceNameAttributeExtractor("ApacheHttpClient5Service"))   
                .build()
                .newHttpClientBuilder();
        } catch (Exception e) {
            throw new RuntimeException("Failed to create ApacheHttpClient5 builder", e);
        }
    }

    // creates a new http client with open telemetry instrumentation
    public HttpClient newHttpClient(OpenTelemetry openTelemetry) {
        try { 
            return ApacheHttpClient5Telemetry.builder(openTelemetry).build().newHttpClient();
        } catch (Exception e) {
            throw new RuntimeException("Failed to create ApacheHttpClient5", e);
        }
    }

    private class ServiceNameAttributeExtractor implements AttributesExtractor<ApacheHttpClient5Request, HttpResponse> {
        private final String serviceName;

        public ServiceNameAttributeExtractor(String serviceName) {
            this.serviceName = serviceName;
        }

        @Override
        public void onStart(AttributesBuilder attributes, Context context, ApacheHttpClient5Request request) {
            System.out.println("!!!!!!!!Setting service name attribute to: " + serviceName);
            attributes.put("service.name", serviceName);
        }

        @Override
        public void onEnd(AttributesBuilder attributes, Context context, ApacheHttpClient5Request request,
                          HttpResponse response, Throwable error) {
            // We don't need to add anything here, as we're only setting the attribute on start
        }
    }
}

Create JavaHttpClientConfigurator.java for comparison

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.httpclient.JavaHttpClientTelemetry;

import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class JavaHttpClientConfigurator {

    //Use this HttpClient implementation for making standard http client calls.
    public HttpClient createTracedClient(OpenTelemetry openTelemetry) {
        try { 
            return JavaHttpClientTelemetry.builder(openTelemetry)
                    .addAttributeExtractor(new ServiceNameAttributeExtractor("JavaHttpClientService"))
                    .build()
                    .newHttpClient(createClient());
        } catch (Exception e) {
            throw new RuntimeException("Failed to create JavaHttpClient", e);
        }
    }

    //your configuration of the Java HTTP Client goes here:
    HttpClient createClient() {
        try { 
            return HttpClient.newBuilder().build();
        } catch (Exception e) {
            throw new RuntimeException("Failed to create JavaHttpClient", e);
        }
    }

    public class ServiceNameAttributeExtractor implements AttributesExtractor<HttpRequest, HttpResponse<?>> {

        private final String serviceName;
    
        public ServiceNameAttributeExtractor(String serviceName) {
            this.serviceName = serviceName;
        }
    
        @Override
        public void onStart(AttributesBuilder attributes, Context context, HttpRequest request) {
            System.out.println("!!!!!!!!Setting service name attribute to: " + serviceName);
            attributes.put("service.name", serviceName);
        }
    
        @Override
        public void onEnd(AttributesBuilder attributes, Context context, HttpRequest request,
                          HttpResponse<?> response, Throwable error) {
            // We don't need to add anything here, as we're only setting the attribute on start
        }
    }
}

In main initialize OpenTelemetry and create each of the clients.

Expected behavior

Attribute is set on both ApacheHttpClient5 and JavaHttpClient and following println will trigger:

!!!!!!!!Setting service name attribute to: JavaHttpClientService
!!!!!!!!Setting service name attribute to: ApacheHttpClient5Service

Actual behavior

Attribute is set only to JavaHttpClient and println triggers:

!!!!!!!!Setting service name attribute to: JavaHttpClientService

No attributes are set for ApacheHttpClient5 and no println is triggered.

Javaagent or library instrumentation version

2.9.0-SNAPSHOT

Environment

JDK: amazoncorreto 21
OS: amazoncorretto:21 (docker)
Using build for opentelemetry-apache-httpclient-5.2-2.9.0-alpha to get version that fixed the issue
https://oss.sonatype.org/content/repositories/snapshots/io/opentelemetry/instrumentation/opentelemetry-apache-httpclient-5.2/2.9.0-alpha-SNAPSHOT/opentelemetry-apache-httpclient-5.2-2.9.0-alpha-20241007.155811-75.jar
opentelemetry version 1.40.0 Apache httpclient5 5.3.1

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingneeds reproneeds triageNew issue that requires triage

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions