diff --git a/instrumentation/apache-httpasyncclient-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpasyncclient/ApacheHttpAsyncClientHttpAttributesExtractor.java b/instrumentation/apache-httpasyncclient-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpasyncclient/ApacheHttpAsyncClientHttpAttributesExtractor.java index b3900a312bd9..556d6d571fa9 100644 --- a/instrumentation/apache-httpasyncclient-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpasyncclient/ApacheHttpAsyncClientHttpAttributesExtractor.java +++ b/instrumentation/apache-httpasyncclient-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpasyncclient/ApacheHttpAsyncClientHttpAttributesExtractor.java @@ -5,12 +5,11 @@ package io.opentelemetry.javaagent.instrumentation.apachehttpasyncclient; +import static io.opentelemetry.javaagent.instrumentation.apachehttpasyncclient.ApacheHttpClientRequest.headersToList; + import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor; import io.opentelemetry.javaagent.instrumentation.api.config.HttpHeadersConfig; -import java.util.Arrays; import java.util.List; -import java.util.stream.Collectors; -import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.StatusLine; import org.checkerframework.checker.nullness.qual.Nullable; @@ -80,8 +79,6 @@ protected Long responseContentLengthUncompressed( @Override protected List responseHeader( ApacheHttpClientRequest request, HttpResponse response, String name) { - return Arrays.stream(response.getHeaders(name)) - .map(Header::getValue) - .collect(Collectors.toList()); + return headersToList(response.getHeaders(name)); } } diff --git a/instrumentation/apache-httpasyncclient-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpasyncclient/ApacheHttpClientRequest.java b/instrumentation/apache-httpasyncclient-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpasyncclient/ApacheHttpClientRequest.java index a880d7e4f8ca..118efd19e4c9 100644 --- a/instrumentation/apache-httpasyncclient-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpasyncclient/ApacheHttpClientRequest.java +++ b/instrumentation/apache-httpasyncclient-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpasyncclient/ApacheHttpClientRequest.java @@ -8,9 +8,9 @@ import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; import java.net.URI; import java.net.URISyntaxException; -import java.util.Arrays; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; @@ -38,9 +38,19 @@ public ApacheHttpClientRequest(HttpHost httpHost, HttpRequest httpRequest) { } public List getHeader(String name) { - return Arrays.stream(delegate.getHeaders(name)) - .map(Header::getValue) - .collect(Collectors.toList()); + return headersToList(delegate.getHeaders(name)); + } + + // minimize memory overhead by not using streams + static List headersToList(Header[] headers) { + if (headers.length == 0) { + return Collections.emptyList(); + } + List headersList = new ArrayList<>(headers.length); + for (int i = 0; i < headers.length; ++i) { + headersList.set(i, headers[i].getValue()); + } + return headersList; } public void setHeader(String name, String value) { diff --git a/instrumentation/apache-httpclient/apache-httpclient-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpclient/v4_0/ApacheHttpClientHttpAttributesExtractor.java b/instrumentation/apache-httpclient/apache-httpclient-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpclient/v4_0/ApacheHttpClientHttpAttributesExtractor.java index 8ca63f2f513f..72f67311bf65 100644 --- a/instrumentation/apache-httpclient/apache-httpclient-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpclient/v4_0/ApacheHttpClientHttpAttributesExtractor.java +++ b/instrumentation/apache-httpclient/apache-httpclient-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpclient/v4_0/ApacheHttpClientHttpAttributesExtractor.java @@ -5,12 +5,11 @@ package io.opentelemetry.javaagent.instrumentation.apachehttpclient.v4_0; +import static io.opentelemetry.javaagent.instrumentation.apachehttpclient.v4_0.ApacheHttpClientRequest.headersToList; + import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor; import io.opentelemetry.javaagent.instrumentation.api.config.HttpHeadersConfig; -import java.util.Arrays; import java.util.List; -import java.util.stream.Collectors; -import org.apache.http.Header; import org.apache.http.HttpResponse; import org.checkerframework.checker.nullness.qual.Nullable; @@ -77,8 +76,6 @@ protected Long responseContentLengthUncompressed( @Override protected List responseHeader( ApacheHttpClientRequest request, HttpResponse response, String name) { - return Arrays.stream(response.getHeaders(name)) - .map(Header::getValue) - .collect(Collectors.toList()); + return headersToList(response.getHeaders(name)); } } diff --git a/instrumentation/apache-httpclient/apache-httpclient-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpclient/v4_0/ApacheHttpClientRequest.java b/instrumentation/apache-httpclient/apache-httpclient-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpclient/v4_0/ApacheHttpClientRequest.java index 4b54e41f1d6c..29d77363f7a9 100644 --- a/instrumentation/apache-httpclient/apache-httpclient-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpclient/v4_0/ApacheHttpClientRequest.java +++ b/instrumentation/apache-httpclient/apache-httpclient-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpclient/v4_0/ApacheHttpClientRequest.java @@ -8,9 +8,9 @@ import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; import java.net.URI; import java.net.URISyntaxException; -import java.util.Arrays; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; @@ -44,9 +44,19 @@ public ApacheHttpClientRequest(HttpUriRequest httpRequest) { } public List getHeader(String name) { - return Arrays.stream(delegate.getHeaders(name)) - .map(Header::getValue) - .collect(Collectors.toList()); + return headersToList(delegate.getHeaders(name)); + } + + // minimize memory overhead by not using streams + static List headersToList(Header[] headers) { + if (headers.length == 0) { + return Collections.emptyList(); + } + List headersList = new ArrayList<>(headers.length); + for (int i = 0; i < headers.length; ++i) { + headersList.set(i, headers[i].getValue()); + } + return headersList; } public void setHeader(String name, String value) { diff --git a/instrumentation/apache-httpclient/apache-httpclient-4.3/library/src/main/java/io/opentelemetry/instrumentation/apachehttpclient/v4_3/ApacheHttpClientHttpAttributesExtractor.java b/instrumentation/apache-httpclient/apache-httpclient-4.3/library/src/main/java/io/opentelemetry/instrumentation/apachehttpclient/v4_3/ApacheHttpClientHttpAttributesExtractor.java index dac1dc695d78..c17a0d4fc483 100644 --- a/instrumentation/apache-httpclient/apache-httpclient-4.3/library/src/main/java/io/opentelemetry/instrumentation/apachehttpclient/v4_3/ApacheHttpClientHttpAttributesExtractor.java +++ b/instrumentation/apache-httpclient/apache-httpclient-4.3/library/src/main/java/io/opentelemetry/instrumentation/apachehttpclient/v4_3/ApacheHttpClientHttpAttributesExtractor.java @@ -5,12 +5,11 @@ package io.opentelemetry.instrumentation.apachehttpclient.v4_3; +import static io.opentelemetry.instrumentation.apachehttpclient.v4_3.ApacheHttpClientRequest.headersToList; + import io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor; -import java.util.Arrays; import java.util.List; -import java.util.stream.Collectors; -import org.apache.http.Header; import org.apache.http.HttpResponse; import org.checkerframework.checker.nullness.qual.Nullable; @@ -79,8 +78,6 @@ protected Long responseContentLengthUncompressed( @Override protected List responseHeader( ApacheHttpClientRequest request, HttpResponse response, String name) { - return Arrays.stream(response.getHeaders(name)) - .map(Header::getValue) - .collect(Collectors.toList()); + return headersToList(response.getHeaders(name)); } } diff --git a/instrumentation/apache-httpclient/apache-httpclient-4.3/library/src/main/java/io/opentelemetry/instrumentation/apachehttpclient/v4_3/ApacheHttpClientRequest.java b/instrumentation/apache-httpclient/apache-httpclient-4.3/library/src/main/java/io/opentelemetry/instrumentation/apachehttpclient/v4_3/ApacheHttpClientRequest.java index ad52ef2fe612..2845b2b4d843 100644 --- a/instrumentation/apache-httpclient/apache-httpclient-4.3/library/src/main/java/io/opentelemetry/instrumentation/apachehttpclient/v4_3/ApacheHttpClientRequest.java +++ b/instrumentation/apache-httpclient/apache-httpclient-4.3/library/src/main/java/io/opentelemetry/instrumentation/apachehttpclient/v4_3/ApacheHttpClientRequest.java @@ -8,9 +8,9 @@ import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; import java.net.URI; import java.net.URISyntaxException; -import java.util.Arrays; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; @@ -43,9 +43,19 @@ public HttpRequest getDelegate() { } List getHeader(String name) { - return Arrays.stream(delegate.getHeaders(name)) - .map(Header::getValue) - .collect(Collectors.toList()); + return headersToList(delegate.getHeaders(name)); + } + + // minimize memory overhead by not using streams + static List headersToList(Header[] headers) { + if (headers.length == 0) { + return Collections.emptyList(); + } + List headersList = new ArrayList<>(headers.length); + for (int i = 0; i < headers.length; ++i) { + headersList.set(i, headers[i].getValue()); + } + return headersList; } void setHeader(String name, String value) { diff --git a/instrumentation/apache-httpclient/apache-httpclient-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpclient/v5_0/ApacheHttpClientHttpAttributesExtractor.java b/instrumentation/apache-httpclient/apache-httpclient-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpclient/v5_0/ApacheHttpClientHttpAttributesExtractor.java index b7987a05cf40..d92866717ae4 100644 --- a/instrumentation/apache-httpclient/apache-httpclient-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpclient/v5_0/ApacheHttpClientHttpAttributesExtractor.java +++ b/instrumentation/apache-httpclient/apache-httpclient-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpclient/v5_0/ApacheHttpClientHttpAttributesExtractor.java @@ -8,9 +8,9 @@ import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor; import io.opentelemetry.javaagent.instrumentation.api.config.HttpHeadersConfig; import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; -import java.util.Arrays; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; import org.apache.hc.core5.http.ClassicHttpRequest; import org.apache.hc.core5.http.Header; import org.apache.hc.core5.http.HttpResponse; @@ -77,9 +77,7 @@ protected String userAgent(ClassicHttpRequest request) { @Override protected List requestHeader(ClassicHttpRequest request, String name) { - return Arrays.stream(request.getHeaders(name)) - .map(Header::getValue) - .collect(Collectors.toList()); + return headersToList(request.getHeaders(name)); } @Override @@ -142,8 +140,18 @@ protected Long responseContentLengthUncompressed( @Override protected List responseHeader( ClassicHttpRequest request, HttpResponse response, String name) { - return Arrays.stream(response.getHeaders(name)) - .map(Header::getValue) - .collect(Collectors.toList()); + return headersToList(response.getHeaders(name)); + } + + // minimize memory overhead by not using streams + private static List headersToList(Header[] headers) { + if (headers.length == 0) { + return Collections.emptyList(); + } + List headersList = new ArrayList<>(headers.length); + for (int i = 0; i < headers.length; ++i) { + headersList.set(i, headers[i].getValue()); + } + return headersList; } } diff --git a/instrumentation/jaxrs-client/jaxrs-client-1.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxrsclient/v1_1/JaxRsClientHttpAttributesExtractor.java b/instrumentation/jaxrs-client/jaxrs-client-1.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxrsclient/v1_1/JaxRsClientHttpAttributesExtractor.java index 293082bda2f2..f6042c553aa1 100644 --- a/instrumentation/jaxrs-client/jaxrs-client-1.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxrsclient/v1_1/JaxRsClientHttpAttributesExtractor.java +++ b/instrumentation/jaxrs-client/jaxrs-client-1.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxrsclient/v1_1/JaxRsClientHttpAttributesExtractor.java @@ -12,8 +12,8 @@ import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor; import io.opentelemetry.javaagent.instrumentation.api.config.HttpHeadersConfig; import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; +import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; import org.checkerframework.checker.nullness.qual.Nullable; final class JaxRsClientHttpAttributesExtractor @@ -41,9 +41,16 @@ protected String url(ClientRequest httpRequest) { @Override protected List requestHeader(ClientRequest httpRequest, String name) { - return httpRequest.getHeaders().getOrDefault(name, emptyList()).stream() - .map(String::valueOf) - .collect(Collectors.toList()); + List rawHeaders = httpRequest.getHeaders().getOrDefault(name, emptyList()); + if (rawHeaders.isEmpty()) { + return emptyList(); + } + List stringHeaders = new ArrayList<>(rawHeaders.size()); + int i = 0; + for (Object headerValue : rawHeaders) { + stringHeaders.set(i++, String.valueOf(headerValue)); + } + return stringHeaders; } @Override diff --git a/instrumentation/jaxrs-client/jaxrs-client-2.0/jaxrs-client-2.0-resteasy-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxrsclient/v2_0/ResteasyClientHttpAttributesExtractor.java b/instrumentation/jaxrs-client/jaxrs-client-2.0/jaxrs-client-2.0-resteasy-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxrsclient/v2_0/ResteasyClientHttpAttributesExtractor.java index 43a67cdd3614..50d65ee5eeb0 100644 --- a/instrumentation/jaxrs-client/jaxrs-client-2.0/jaxrs-client-2.0-resteasy-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxrsclient/v2_0/ResteasyClientHttpAttributesExtractor.java +++ b/instrumentation/jaxrs-client/jaxrs-client-2.0/jaxrs-client-2.0-resteasy-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxrsclient/v2_0/ResteasyClientHttpAttributesExtractor.java @@ -10,8 +10,8 @@ import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor; import io.opentelemetry.javaagent.instrumentation.api.config.HttpHeadersConfig; import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; +import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; import javax.ws.rs.core.Response; import org.checkerframework.checker.nullness.qual.Nullable; import org.jboss.resteasy.client.jaxrs.internal.ClientInvocation; @@ -40,9 +40,16 @@ protected String url(ClientInvocation httpRequest) { @Override protected List requestHeader(ClientInvocation httpRequest, String name) { - return httpRequest.getHeaders().getHeaders().getOrDefault(name, emptyList()).stream() - .map(String::valueOf) - .collect(Collectors.toList()); + List rawHeaders = httpRequest.getHeaders().getHeaders().getOrDefault(name, emptyList()); + if (rawHeaders.isEmpty()) { + return emptyList(); + } + List stringHeaders = new ArrayList<>(rawHeaders.size()); + int i = 0; + for (Object headerValue : rawHeaders) { + stringHeaders.set(i++, String.valueOf(headerValue)); + } + return stringHeaders; } @Override diff --git a/instrumentation/restlet/restlet-1.0/library/src/main/java/io/opentelemetry/instrumentation/restlet/v1_0/RestletHttpAttributesExtractor.java b/instrumentation/restlet/restlet-1.0/library/src/main/java/io/opentelemetry/instrumentation/restlet/v1_0/RestletHttpAttributesExtractor.java index fa75ab11667c..f8ad04897949 100644 --- a/instrumentation/restlet/restlet-1.0/library/src/main/java/io/opentelemetry/instrumentation/restlet/v1_0/RestletHttpAttributesExtractor.java +++ b/instrumentation/restlet/restlet-1.0/library/src/main/java/io/opentelemetry/instrumentation/restlet/v1_0/RestletHttpAttributesExtractor.java @@ -10,13 +10,15 @@ import io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractor; import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; import org.checkerframework.checker.nullness.qual.Nullable; import org.restlet.data.Parameter; import org.restlet.data.Reference; import org.restlet.data.Request; import org.restlet.data.Response; +import org.restlet.util.Series; final class RestletHttpAttributesExtractor extends HttpServerAttributesExtractor { @@ -61,9 +63,7 @@ protected String host(Request request) { @Override protected List requestHeader(Request request, String name) { - return getHeaders(request).subList(name, /* ignoreCase = */ true).stream() - .map(Parameter::getValue) - .collect(Collectors.toList()); + return parametersToList(getHeaders(request).subList(name, /* ignoreCase = */ true)); } @Override @@ -115,8 +115,19 @@ protected Integer statusCode(Request request, Response response) { @Override protected List responseHeader(Request request, Response response, String name) { - return getHeaders(response).subList(name, /* ignoreCase = */ true).stream() - .map(Parameter::getValue) - .collect(Collectors.toList()); + return parametersToList(getHeaders(response).subList(name, /* ignoreCase = */ true)); + } + + // minimize memory overhead by not using streams + private static List parametersToList(Series headers) { + if (headers.isEmpty()) { + return Collections.emptyList(); + } + List stringHeaders = new ArrayList<>(headers.size()); + int i = 0; + for (Parameter header : headers) { + stringHeaders.set(i++, header.getValue()); + } + return stringHeaders; } }