|
@@ -6,10 +6,8 @@
|
|
|
package io.opentelemetry.instrumentation.api.instrumenter.http;
|
|
|
|
|
|
import static io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeadersUtil.lowercase;
|
|
|
-import static io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeadersUtil.oldSemconvRequestAttributeKey;
|
|
|
-import static io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeadersUtil.oldSemconvResponseAttributeKey;
|
|
|
-import static io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeadersUtil.stableSemconvRequestAttributeKey;
|
|
|
-import static io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeadersUtil.stableSemconvResponseAttributeKey;
|
|
|
+import static io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeadersUtil.requestAttributeKey;
|
|
|
+import static io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeadersUtil.responseAttributeKey;
|
|
|
import static io.opentelemetry.instrumentation.api.internal.AttributesExtractorUtil.internalSet;
|
|
|
import static io.opentelemetry.instrumentation.api.internal.HttpConstants._OTHER;
|
|
|
|
|
@@ -18,7 +16,6 @@ import io.opentelemetry.context.Context;
|
|
|
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
|
|
|
import io.opentelemetry.instrumentation.api.instrumenter.http.internal.HttpAttributes;
|
|
|
import io.opentelemetry.instrumentation.api.instrumenter.network.NetworkAttributesGetter;
|
|
|
-import io.opentelemetry.instrumentation.api.internal.SemconvStability;
|
|
|
import io.opentelemetry.semconv.SemanticAttributes;
|
|
|
import java.util.HashSet;
|
|
|
import java.util.List;
|
|
@@ -32,11 +29,14 @@ import javax.annotation.Nullable;
|
|
|
* attributes</a> that are common to client and server instrumentations.
|
|
|
*/
|
|
|
abstract class HttpCommonAttributesExtractor<
|
|
|
- REQUEST, RESPONSE, GETTER extends HttpCommonAttributesGetter<REQUEST, RESPONSE>>
|
|
|
+ REQUEST,
|
|
|
+ RESPONSE,
|
|
|
+ GETTER extends
|
|
|
+ HttpCommonAttributesGetter<REQUEST, RESPONSE>
|
|
|
+ & NetworkAttributesGetter<REQUEST, RESPONSE>>
|
|
|
implements AttributesExtractor<REQUEST, RESPONSE> {
|
|
|
|
|
|
final GETTER getter;
|
|
|
- final NetworkAttributesGetter<REQUEST, RESPONSE> networkGetter;
|
|
|
private final HttpStatusCodeConverter statusCodeConverter;
|
|
|
private final List<String> capturedRequestHeaders;
|
|
|
private final List<String> capturedResponseHeaders;
|
|
@@ -44,13 +44,11 @@ abstract class HttpCommonAttributesExtractor<
|
|
|
|
|
|
HttpCommonAttributesExtractor(
|
|
|
GETTER getter,
|
|
|
- NetworkAttributesGetter<REQUEST, RESPONSE> networkGetter,
|
|
|
HttpStatusCodeConverter statusCodeConverter,
|
|
|
List<String> capturedRequestHeaders,
|
|
|
List<String> capturedResponseHeaders,
|
|
|
Set<String> knownMethods) {
|
|
|
this.getter = getter;
|
|
|
- this.networkGetter = networkGetter;
|
|
|
this.statusCodeConverter = statusCodeConverter;
|
|
|
this.capturedRequestHeaders = lowercase(capturedRequestHeaders);
|
|
|
this.capturedResponseHeaders = lowercase(capturedResponseHeaders);
|
|
@@ -58,36 +56,24 @@ abstract class HttpCommonAttributesExtractor<
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- @SuppressWarnings("deprecation") // until old http semconv are dropped in 2.0
|
|
|
public void onStart(AttributesBuilder attributes, Context parentContext, REQUEST request) {
|
|
|
String method = getter.getHttpRequestMethod(request);
|
|
|
- if (SemconvStability.emitStableHttpSemconv()) {
|
|
|
- if (method == null || knownMethods.contains(method)) {
|
|
|
- internalSet(attributes, SemanticAttributes.HTTP_REQUEST_METHOD, method);
|
|
|
- } else {
|
|
|
- internalSet(attributes, SemanticAttributes.HTTP_REQUEST_METHOD, _OTHER);
|
|
|
- internalSet(attributes, SemanticAttributes.HTTP_REQUEST_METHOD_ORIGINAL, method);
|
|
|
- }
|
|
|
- }
|
|
|
- if (SemconvStability.emitOldHttpSemconv()) {
|
|
|
- internalSet(attributes, SemanticAttributes.HTTP_METHOD, method);
|
|
|
+ if (method == null || knownMethods.contains(method)) {
|
|
|
+ internalSet(attributes, SemanticAttributes.HTTP_REQUEST_METHOD, method);
|
|
|
+ } else {
|
|
|
+ internalSet(attributes, SemanticAttributes.HTTP_REQUEST_METHOD, _OTHER);
|
|
|
+ internalSet(attributes, SemanticAttributes.HTTP_REQUEST_METHOD_ORIGINAL, method);
|
|
|
}
|
|
|
|
|
|
for (String name : capturedRequestHeaders) {
|
|
|
List<String> values = getter.getHttpRequestHeader(request, name);
|
|
|
if (!values.isEmpty()) {
|
|
|
- if (SemconvStability.emitOldHttpSemconv()) {
|
|
|
- internalSet(attributes, oldSemconvRequestAttributeKey(name), values);
|
|
|
- }
|
|
|
- if (SemconvStability.emitStableHttpSemconv()) {
|
|
|
- internalSet(attributes, stableSemconvRequestAttributeKey(name), values);
|
|
|
- }
|
|
|
+ internalSet(attributes, requestAttributeKey(name), values);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- @SuppressWarnings("deprecation") // until old http semconv are dropped in 2.0
|
|
|
public void onEnd(
|
|
|
AttributesBuilder attributes,
|
|
|
Context context,
|
|
@@ -95,103 +81,54 @@ abstract class HttpCommonAttributesExtractor<
|
|
|
@Nullable RESPONSE response,
|
|
|
@Nullable Throwable error) {
|
|
|
|
|
|
- Long requestBodySize = requestBodySize(request);
|
|
|
- if (SemconvStability.emitOldHttpSemconv()) {
|
|
|
- internalSet(attributes, SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH, requestBodySize);
|
|
|
- }
|
|
|
-
|
|
|
Integer statusCode = null;
|
|
|
if (response != null) {
|
|
|
statusCode = getter.getHttpResponseStatusCode(request, response, error);
|
|
|
if (statusCode != null && statusCode > 0) {
|
|
|
- if (SemconvStability.emitStableHttpSemconv()) {
|
|
|
- internalSet(attributes, SemanticAttributes.HTTP_RESPONSE_STATUS_CODE, (long) statusCode);
|
|
|
- }
|
|
|
- if (SemconvStability.emitOldHttpSemconv()) {
|
|
|
- internalSet(attributes, SemanticAttributes.HTTP_STATUS_CODE, (long) statusCode);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- Long responseBodySize = responseBodySize(request, response);
|
|
|
- if (SemconvStability.emitOldHttpSemconv()) {
|
|
|
- internalSet(attributes, SemanticAttributes.HTTP_RESPONSE_CONTENT_LENGTH, responseBodySize);
|
|
|
+ internalSet(attributes, SemanticAttributes.HTTP_RESPONSE_STATUS_CODE, (long) statusCode);
|
|
|
}
|
|
|
|
|
|
for (String name : capturedResponseHeaders) {
|
|
|
List<String> values = getter.getHttpResponseHeader(request, response, name);
|
|
|
if (!values.isEmpty()) {
|
|
|
- if (SemconvStability.emitOldHttpSemconv()) {
|
|
|
- internalSet(attributes, oldSemconvResponseAttributeKey(name), values);
|
|
|
- }
|
|
|
- if (SemconvStability.emitStableHttpSemconv()) {
|
|
|
- internalSet(attributes, stableSemconvResponseAttributeKey(name), values);
|
|
|
- }
|
|
|
+ internalSet(attributes, responseAttributeKey(name), values);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (SemconvStability.emitStableHttpSemconv()) {
|
|
|
- String errorType = null;
|
|
|
- if (statusCode != null && statusCode > 0) {
|
|
|
- if (statusCodeConverter.isError(statusCode)) {
|
|
|
- errorType = statusCode.toString();
|
|
|
- }
|
|
|
- } else {
|
|
|
- errorType = getter.getErrorType(request, response, error);
|
|
|
- // fall back to exception class name & _OTHER
|
|
|
- if (errorType == null && error != null) {
|
|
|
- errorType = error.getClass().getName();
|
|
|
- }
|
|
|
- if (errorType == null) {
|
|
|
- errorType = _OTHER;
|
|
|
- }
|
|
|
+ String errorType = null;
|
|
|
+ if (statusCode != null && statusCode > 0) {
|
|
|
+ if (statusCodeConverter.isError(statusCode)) {
|
|
|
+ errorType = statusCode.toString();
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ errorType = getter.getErrorType(request, response, error);
|
|
|
+ // fall back to exception class name & _OTHER
|
|
|
+ if (errorType == null && error != null) {
|
|
|
+ errorType = error.getClass().getName();
|
|
|
+ }
|
|
|
+ if (errorType == null) {
|
|
|
+ errorType = _OTHER;
|
|
|
}
|
|
|
- internalSet(attributes, HttpAttributes.ERROR_TYPE, errorType);
|
|
|
}
|
|
|
+ internalSet(attributes, HttpAttributes.ERROR_TYPE, errorType);
|
|
|
|
|
|
- if (SemconvStability.emitStableHttpSemconv()) {
|
|
|
- String protocolName = lowercaseStr(networkGetter.getNetworkProtocolName(request, response));
|
|
|
- String protocolVersion =
|
|
|
- lowercaseStr(networkGetter.getNetworkProtocolVersion(request, response));
|
|
|
+ String protocolName = lowercaseStr(getter.getNetworkProtocolName(request, response));
|
|
|
+ String protocolVersion = lowercaseStr(getter.getNetworkProtocolVersion(request, response));
|
|
|
|
|
|
- if (protocolVersion != null) {
|
|
|
- if (!"http".equals(protocolName)) {
|
|
|
- internalSet(attributes, SemanticAttributes.NETWORK_PROTOCOL_NAME, protocolName);
|
|
|
- }
|
|
|
- internalSet(attributes, SemanticAttributes.NETWORK_PROTOCOL_VERSION, protocolVersion);
|
|
|
+ if (protocolVersion != null) {
|
|
|
+ if (!"http".equals(protocolName)) {
|
|
|
+ internalSet(attributes, SemanticAttributes.NETWORK_PROTOCOL_NAME, protocolName);
|
|
|
}
|
|
|
+ internalSet(attributes, SemanticAttributes.NETWORK_PROTOCOL_VERSION, protocolVersion);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- @Nullable
|
|
|
- private Long requestBodySize(REQUEST request) {
|
|
|
- return parseNumber(firstHeaderValue(getter.getHttpRequestHeader(request, "content-length")));
|
|
|
- }
|
|
|
-
|
|
|
- @Nullable
|
|
|
- private Long responseBodySize(REQUEST request, RESPONSE response) {
|
|
|
- return parseNumber(
|
|
|
- firstHeaderValue(getter.getHttpResponseHeader(request, response, "content-length")));
|
|
|
- }
|
|
|
-
|
|
|
@Nullable
|
|
|
static String firstHeaderValue(List<String> values) {
|
|
|
return values.isEmpty() ? null : values.get(0);
|
|
|
}
|
|
|
|
|
|
- @Nullable
|
|
|
- private static Long parseNumber(@Nullable String number) {
|
|
|
- if (number == null) {
|
|
|
- return null;
|
|
|
- }
|
|
|
- try {
|
|
|
- return Long.parseLong(number);
|
|
|
- } catch (NumberFormatException e) {
|
|
|
- // not a number
|
|
|
- return null;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
@Nullable
|
|
|
private static String lowercaseStr(@Nullable String str) {
|
|
|
return str == null ? null : str.toLowerCase(Locale.ROOT);
|