Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
import static org.hypertrace.core.semantic.convention.constants.http.OTelHttpSemanticConventions.HTTP_URL;
import static org.hypertrace.core.span.constants.v1.Envoy.ENVOY_REQUEST_SIZE;
import static org.hypertrace.core.span.constants.v1.Envoy.ENVOY_RESPONSE_SIZE;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_HTTP_REQUEST_BODY;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_HTTP_RESPONSE_BODY;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_PATH;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_REQUEST_BODY_TRUNCATED;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_REQUEST_CONTENT_LENGTH;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_REQUEST_CONTENT_TYPE;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_REQUEST_HEADER_PATH;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_REQUEST_METHOD;
Expand All @@ -18,6 +22,8 @@
import static org.hypertrace.core.span.constants.v1.Http.HTTP_REQUEST_SIZE;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_REQUEST_URL;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_REQUEST_X_FORWARDED_FOR_HEADER;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_RESPONSE_BODY_TRUNCATED;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_RESPONSE_CONTENT_LENGTH;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_RESPONSE_SIZE;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_RESPONSE_STATUS_CODE;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_USER_AGENT;
Expand Down Expand Up @@ -71,6 +77,14 @@ public class HttpSemanticConventionUtils {
private static final String OTEL_HTTP_TARGET = OTelHttpSemanticConventions.HTTP_TARGET.getValue();
private static final String RELATIVE_URL_CONTEXT = "http://hypertrace.org";

private static final String HTTP_REQUEST_BODY = RawSpanConstants.getValue(HTTP_HTTP_REQUEST_BODY);
private static final String HTTP_REQUEST_BODY_TRUNCATED_ATTR =
RawSpanConstants.getValue(HTTP_REQUEST_BODY_TRUNCATED);
private static final String HTTP_RESPONSE_BODY =
RawSpanConstants.getValue(HTTP_HTTP_RESPONSE_BODY);
private static final String HTTP_RESPONSE_BODY_TRUNCATED_ATTR =
RawSpanConstants.getValue(HTTP_RESPONSE_BODY_TRUNCATED);

private static final String SLASH = "/";

private static final List<String> USER_AGENT_ATTRIBUTES =
Expand Down Expand Up @@ -116,13 +130,15 @@ public class HttpSemanticConventionUtils {
List.of(
RawSpanConstants.getValue(ENVOY_REQUEST_SIZE),
RawSpanConstants.getValue(HTTP_REQUEST_SIZE),
OTelHttpSemanticConventions.HTTP_REQUEST_SIZE.getValue());
OTelHttpSemanticConventions.HTTP_REQUEST_SIZE.getValue(),
RawSpanConstants.getValue(HTTP_REQUEST_CONTENT_LENGTH));
Comment thread
avinashkolluru marked this conversation as resolved.

private static final List<String> RESPONSE_SIZE_ATTRIBUTES =
List.of(
RawSpanConstants.getValue(ENVOY_RESPONSE_SIZE),
RawSpanConstants.getValue(HTTP_RESPONSE_SIZE),
OTelHttpSemanticConventions.HTTP_RESPONSE_SIZE.getValue());
OTelHttpSemanticConventions.HTTP_RESPONSE_SIZE.getValue(),
RawSpanConstants.getValue(HTTP_RESPONSE_CONTENT_LENGTH));

private static final List<String> STATUS_CODE_ATTRIBUTES =
List.of(
Expand Down Expand Up @@ -474,13 +490,31 @@ public static Optional<String> getHttpQueryString(Event event) {
public static Optional<Integer> getHttpRequestSize(Event event) {
String httpRequestSize =
SpanAttributeUtils.getFirstAvailableStringAttribute(event, REQUEST_SIZE_ATTRIBUTES);
return Optional.ofNullable(httpRequestSize).map(Integer::parseInt);

Optional<String> requestSize = Optional.ofNullable(httpRequestSize);
if (!requestSize.isEmpty()) return requestSize.map(Integer::parseInt);

if (SpanAttributeUtils.getBooleanAttribute(event, HTTP_REQUEST_BODY_TRUNCATED_ATTR)) {
return Optional.empty();
}

String requestBody = SpanAttributeUtils.getStringAttribute(event, HTTP_REQUEST_BODY);
Comment thread
avinashkolluru marked this conversation as resolved.
return Optional.ofNullable(requestBody).map(String::length);
}

public static Optional<Integer> getHttpResponseSize(Event event) {
String httpResponseSize =
SpanAttributeUtils.getFirstAvailableStringAttribute(event, RESPONSE_SIZE_ATTRIBUTES);
return Optional.ofNullable(httpResponseSize).map(Integer::parseInt);

Optional<String> responseSize = Optional.ofNullable(httpResponseSize);
if (!responseSize.isEmpty()) return responseSize.map(Integer::parseInt);

if (SpanAttributeUtils.getBooleanAttribute(event, HTTP_RESPONSE_BODY_TRUNCATED_ATTR)) {
return Optional.empty();
}

String responseBody = SpanAttributeUtils.getStringAttribute(event, HTTP_RESPONSE_BODY);
return Optional.ofNullable(responseBody).map(String::length);
}

public static int getHttpResponseStatusCode(Event event) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,22 @@
import static org.hypertrace.core.span.constants.v1.Envoy.ENVOY_RESPONSE_SIZE;
import static org.hypertrace.core.span.constants.v1.Grpc.GRPC_ERROR_MESSAGE;
import static org.hypertrace.core.span.constants.v1.Grpc.GRPC_REQUEST_BODY;
import static org.hypertrace.core.span.constants.v1.Grpc.GRPC_REQUEST_BODY_TRUNCATED;
import static org.hypertrace.core.span.constants.v1.Grpc.GRPC_RESPONSE_BODY;
import static org.hypertrace.core.span.constants.v1.Grpc.GRPC_RESPONSE_BODY_TRUNCATED;
import static org.hypertrace.core.span.normalizer.constants.OTelSpanTag.OTEL_SPAN_TAG_RPC_METHOD;
import static org.hypertrace.core.span.normalizer.constants.OTelSpanTag.OTEL_SPAN_TAG_RPC_SYSTEM;
import static org.hypertrace.core.span.normalizer.constants.RpcSpanTag.RPC_ERROR_MESSAGE;
import static org.hypertrace.core.span.normalizer.constants.RpcSpanTag.RPC_REQUEST_BODY;
import static org.hypertrace.core.span.normalizer.constants.RpcSpanTag.RPC_REQUEST_BODY_TRUNCATED;
import static org.hypertrace.core.span.normalizer.constants.RpcSpanTag.RPC_REQUEST_METADATA_AUTHORITY;
import static org.hypertrace.core.span.normalizer.constants.RpcSpanTag.RPC_REQUEST_METADATA_CONTENT_LENGTH;
import static org.hypertrace.core.span.normalizer.constants.RpcSpanTag.RPC_REQUEST_METADATA_PATH;
import static org.hypertrace.core.span.normalizer.constants.RpcSpanTag.RPC_REQUEST_METADATA_USER_AGENT;
import static org.hypertrace.core.span.normalizer.constants.RpcSpanTag.RPC_REQUEST_METADATA_X_FORWARDED_FOR;
import static org.hypertrace.core.span.normalizer.constants.RpcSpanTag.RPC_RESPONSE_BODY;
import static org.hypertrace.core.span.normalizer.constants.RpcSpanTag.RPC_RESPONSE_BODY_TRUNCATED;
import static org.hypertrace.core.span.normalizer.constants.RpcSpanTag.RPC_RESPONSE_METADATA_CONTENT_LENGTH;

import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
Expand Down Expand Up @@ -79,6 +85,28 @@ public class RpcSemanticConventionUtils {
RawSpanConstants.getValue(CENSUS_RESPONSE_STATUS_MESSAGE),
RawSpanConstants.getValue(ENVOY_GRPC_STATUS_MESSAGE));

private static final String GRPC_REQUEST_BODY_TRUNCATED_ATTR =
RawSpanConstants.getValue(GRPC_REQUEST_BODY_TRUNCATED);
private static final String RPC_REQUEST_BODY_TRUNCATED_ATTR =
RPC_REQUEST_BODY_TRUNCATED.getValue();
private static final String ENVOY_REQUEST_SIZE_ATTR =
RawSpanConstants.getValue(ENVOY_REQUEST_SIZE);
private static final String RPC_REQUEST_METADATA_CONTENT_LENGTH_ATTR =
RPC_REQUEST_METADATA_CONTENT_LENGTH.getValue();
private static final String GRPC_REQUEST_BODY_ATTR = RawSpanConstants.getValue(GRPC_REQUEST_BODY);
private static final String RPC_REQUEST_BODY_ATTR = RPC_REQUEST_BODY.getValue();
private static final String GRPC_RESPONSE_BODY_TRUNCATED_ATTR =
RawSpanConstants.getValue(GRPC_RESPONSE_BODY_TRUNCATED);
private static final String RPC_RESPONSE_BODY_TRUNCATED_ATTR =
RPC_RESPONSE_BODY_TRUNCATED.getValue();
private static final String ENVOY_RESPONSE_SIZE_ATTR =
RawSpanConstants.getValue(ENVOY_RESPONSE_SIZE);
private static final String RPC_RESPONSE_METADATA_CONTENT_LENGTH_ATTR =
RPC_RESPONSE_METADATA_CONTENT_LENGTH.getValue();
private static final String GRPC_RESPONSE_BODY_ATTR =
RawSpanConstants.getValue(GRPC_RESPONSE_BODY);
private static final String RPC_RESPONSE_BODY_ATTR = RPC_RESPONSE_BODY.getValue();

/**
* Differs from {@link
* org.hypertrace.semantic.convention.utils.rpc.RpcSemanticConventionUtils#getGrpcURI(Event) in
Expand Down Expand Up @@ -269,55 +297,99 @@ public static Optional<String> getGrpcAuthority(Event event) {
return Optional.empty();
}

private static boolean isGrpcRequestBodyTruncated(Map<String, AttributeValue> attributeValueMap) {
Optional<AttributeValue> attributeValue =
Optional.ofNullable(attributeValueMap.get(GRPC_REQUEST_BODY_TRUNCATED_ATTR));

return attributeValue.filter(av -> Boolean.parseBoolean(av.getValue())).isPresent();
}

private static boolean isRpcRequestBodyTruncated(Map<String, AttributeValue> attributeValueMap) {
Optional<AttributeValue> attributeValue =
Optional.ofNullable(attributeValueMap.get(RPC_REQUEST_BODY_TRUNCATED_ATTR));

return attributeValue.filter(av -> Boolean.parseBoolean(av.getValue())).isPresent();
}

public static Optional<Integer> getGrpcRequestSize(Event event) {
if (event.getAttributes() == null || event.getAttributes().getAttributeMap() == null) {
return Optional.empty();
}

Map<String, AttributeValue> attributeValueMap = event.getAttributes().getAttributeMap();
if ((attributeValueMap.get(RawSpanConstants.getValue(GRPC_REQUEST_BODY)) != null)
|| (isRpcSystemGrpc(attributeValueMap)
&& attributeValueMap.get(RPC_REQUEST_BODY.getValue()) != null)) {

if (attributeValueMap.get(RawSpanConstants.getValue(ENVOY_REQUEST_SIZE)) != null) {
return Optional.of(
Integer.parseInt(
attributeValueMap.get(RawSpanConstants.getValue(ENVOY_REQUEST_SIZE)).getValue()));
} else if (attributeValueMap.get(RawSpanConstants.getValue(GRPC_REQUEST_BODY)) != null) {
String requestBody =
attributeValueMap.get(RawSpanConstants.getValue(GRPC_REQUEST_BODY)).getValue();
return Optional.of(requestBody.length());
} else if (attributeValueMap.get(RPC_REQUEST_BODY.getValue()) != null) {
String requestBody = attributeValueMap.get(RPC_REQUEST_BODY.getValue()).getValue();
return Optional.of(requestBody.length());
}

Optional<AttributeValue> attributeValue =
Optional.ofNullable(attributeValueMap.get(ENVOY_REQUEST_SIZE_ATTR));
if (attributeValue.isPresent()) {
return attributeValue.map(av -> av.getValue()).map(Integer::parseInt);
}

attributeValue =
Optional.ofNullable(attributeValueMap.get(RPC_REQUEST_METADATA_CONTENT_LENGTH_ATTR));
if (attributeValue.isPresent() && isRpcSystemGrpc(attributeValueMap)) {
return attributeValue.map(av -> av.getValue()).map(Integer::parseInt);
}

attributeValue = Optional.ofNullable(attributeValueMap.get(GRPC_REQUEST_BODY_ATTR));
if (attributeValue.isPresent() && !isGrpcRequestBodyTruncated(attributeValueMap)) {
return attributeValue.map(av -> av.getValue()).map(String::length);
}

attributeValue = Optional.ofNullable(attributeValueMap.get(RPC_REQUEST_BODY_ATTR));
if (attributeValue.isPresent()
&& isRpcSystemGrpc(attributeValueMap)
&& !isRpcRequestBodyTruncated(attributeValueMap)) {
return attributeValue.map(av -> av.getValue()).map(String::length);
}

return Optional.empty();
}

private static boolean isGrpcResponseBodyTruncated(
Map<String, AttributeValue> attributeValueMap) {
Optional<AttributeValue> attributeValue =
Optional.ofNullable(attributeValueMap.get(GRPC_RESPONSE_BODY_TRUNCATED_ATTR));

return attributeValue.filter(av -> Boolean.parseBoolean(av.getValue())).isPresent();
}

private static boolean isRpcResponseBodyTruncated(Map<String, AttributeValue> attributeValueMap) {
Optional<AttributeValue> attributeValue =
Optional.ofNullable(attributeValueMap.get(RPC_RESPONSE_BODY_TRUNCATED_ATTR));

return attributeValue.filter(av -> Boolean.parseBoolean(av.getValue())).isPresent();
}

public static Optional<Integer> getGrpcResponseSize(Event event) {
if (event.getAttributes() == null || event.getAttributes().getAttributeMap() == null) {
return Optional.empty();
}

Map<String, AttributeValue> attributeValueMap = event.getAttributes().getAttributeMap();
if ((attributeValueMap.get(RawSpanConstants.getValue(GRPC_RESPONSE_BODY)) != null)
|| (isRpcSystemGrpc(attributeValueMap)
&& attributeValueMap.get(RPC_RESPONSE_BODY.getValue()) != null)) {

if (attributeValueMap.get(RawSpanConstants.getValue(ENVOY_RESPONSE_SIZE)) != null) {
return Optional.of(
Integer.parseInt(
attributeValueMap.get(RawSpanConstants.getValue(ENVOY_RESPONSE_SIZE)).getValue()));
} else if (attributeValueMap.get(RawSpanConstants.getValue(GRPC_RESPONSE_BODY)) != null) {
String requestBody =
attributeValueMap.get(RawSpanConstants.getValue(GRPC_RESPONSE_BODY)).getValue();
return Optional.of(requestBody.length());
} else if (attributeValueMap.get(RPC_RESPONSE_BODY.getValue()) != null) {
String requestBody = attributeValueMap.get(RPC_RESPONSE_BODY.getValue()).getValue();
return Optional.of(requestBody.length());
}
Optional<AttributeValue> attributeValue =
Optional.ofNullable(attributeValueMap.get(ENVOY_RESPONSE_SIZE_ATTR));
if (attributeValue.isPresent()) {
return attributeValue.map(av -> av.getValue()).map(Integer::parseInt);
}

attributeValue =
Optional.ofNullable(attributeValueMap.get(RPC_RESPONSE_METADATA_CONTENT_LENGTH_ATTR));
if (attributeValue.isPresent() && isRpcSystemGrpc(attributeValueMap)) {
return attributeValue.map(av -> av.getValue()).map(Integer::parseInt);
}

attributeValue = Optional.ofNullable(attributeValueMap.get(GRPC_RESPONSE_BODY_ATTR));
if (attributeValue.isPresent() && !isGrpcResponseBodyTruncated(attributeValueMap)) {
return attributeValue.map(av -> av.getValue()).map(String::length);
}

attributeValue = Optional.ofNullable(attributeValueMap.get(RPC_RESPONSE_BODY_ATTR));
if (attributeValue.isPresent()
&& isRpcSystemGrpc(attributeValueMap)
&& !isRpcResponseBodyTruncated(attributeValueMap)) {
return attributeValue.map(av -> av.getValue()).map(String::length);
}

return Optional.empty();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@
import static org.hypertrace.core.span.constants.v1.CensusResponse.CENSUS_RESPONSE_CENSUS_STATUS_CODE;
import static org.hypertrace.core.span.constants.v1.Envoy.ENVOY_REQUEST_SIZE;
import static org.hypertrace.core.span.constants.v1.Envoy.ENVOY_RESPONSE_SIZE;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_HTTP_REQUEST_BODY;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_HTTP_RESPONSE_BODY;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_PATH;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_REQUEST_BODY_TRUNCATED;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_REQUEST_CONTENT_LENGTH;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_REQUEST_CONTENT_TYPE;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_REQUEST_HEADER_PATH;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_REQUEST_METHOD;
Expand All @@ -22,6 +26,8 @@
import static org.hypertrace.core.span.constants.v1.Http.HTTP_REQUEST_SIZE;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_REQUEST_URL;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_REQUEST_X_FORWARDED_FOR_HEADER;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_RESPONSE_BODY_TRUNCATED;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_RESPONSE_CONTENT_LENGTH;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_RESPONSE_SIZE;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_USER_AGENT_REQUEST_HEADER;
import static org.hypertrace.core.span.constants.v1.Http.HTTP_USER_AGENT_WITH_DASH;
Expand Down Expand Up @@ -385,9 +391,35 @@ public void testGetHttpRequestSize() {
OTelHttpSemanticConventions.HTTP_REQUEST_SIZE.getValue(),
AttributeValue.newBuilder().setValue("150").build(),
RawSpanConstants.getValue(HTTP_REQUEST_SIZE),
AttributeValue.newBuilder().setValue("200").build()))
AttributeValue.newBuilder().setValue("200").build(),
RawSpanConstants.getValue(HTTP_REQUEST_CONTENT_LENGTH),
AttributeValue.newBuilder().setValue("300").build(),
RawSpanConstants.getValue(HTTP_HTTP_REQUEST_BODY),
AttributeValue.newBuilder().setValue("Hello, there!").build()))
.build());
assertEquals(Optional.of(100), HttpSemanticConventionUtils.getHttpRequestSize(event));

event =
createMockEventWithAttribute(RawSpanConstants.getValue(HTTP_REQUEST_CONTENT_LENGTH), "300");
assertEquals(Optional.of(300), HttpSemanticConventionUtils.getHttpRequestSize(event));

event =
createMockEventWithAttribute(
RawSpanConstants.getValue(HTTP_HTTP_REQUEST_BODY), "Hello, there!");
assertEquals(Optional.of(13), HttpSemanticConventionUtils.getHttpRequestSize(event));

event = mock(Event.class);
when(event.getAttributes())
.thenReturn(
Attributes.newBuilder()
.setAttributeMap(
Map.of(
RawSpanConstants.getValue(HTTP_HTTP_REQUEST_BODY),
AttributeValue.newBuilder().setValue("Hello, there!").build(),
RawSpanConstants.getValue(HTTP_REQUEST_BODY_TRUNCATED),
AttributeValue.newBuilder().setValue("true").build()))
.build());
assertEquals(Optional.empty(), HttpSemanticConventionUtils.getHttpRequestSize(event));
}

@Test
Expand All @@ -407,9 +439,36 @@ public void testGetHttpResponseSize() {
RawSpanConstants.getValue(HTTP_RESPONSE_SIZE),
AttributeValue.newBuilder().setValue("150").build(),
OTelHttpSemanticConventions.HTTP_RESPONSE_SIZE.getValue(),
AttributeValue.newBuilder().setValue("200").build()))
AttributeValue.newBuilder().setValue("200").build(),
RawSpanConstants.getValue(HTTP_RESPONSE_CONTENT_LENGTH),
AttributeValue.newBuilder().setValue("300").build(),
RawSpanConstants.getValue(HTTP_HTTP_RESPONSE_BODY),
AttributeValue.newBuilder().setValue("Hello World!").build()))
.build());
assertEquals(Optional.of(100), HttpSemanticConventionUtils.getHttpResponseSize(event));

event =
createMockEventWithAttribute(
RawSpanConstants.getValue(HTTP_RESPONSE_CONTENT_LENGTH), "300");
assertEquals(Optional.of(300), HttpSemanticConventionUtils.getHttpResponseSize(event));

event =
createMockEventWithAttribute(
RawSpanConstants.getValue(HTTP_HTTP_RESPONSE_BODY), "Hello World!");
assertEquals(Optional.of(12), HttpSemanticConventionUtils.getHttpResponseSize(event));

event = mock(Event.class);
when(event.getAttributes())
.thenReturn(
Attributes.newBuilder()
.setAttributeMap(
Map.of(
RawSpanConstants.getValue(HTTP_HTTP_RESPONSE_BODY),
AttributeValue.newBuilder().setValue("Hello World!").build(),
RawSpanConstants.getValue(HTTP_RESPONSE_BODY_TRUNCATED),
AttributeValue.newBuilder().setValue("true").build()))
.build());
assertEquals(Optional.empty(), HttpSemanticConventionUtils.getHttpResponseSize(event));
}

@Test
Expand Down
Loading