Skip to content

Commit

Permalink
Make server.socket.* attributes on the HTTP server side opt-in
Browse files Browse the repository at this point in the history
  • Loading branch information
Mateusz Rzeszutek committed Jul 14, 2023
1 parent 1e9b47b commit 655ad34
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ public static <REQUEST, RESPONSE> HttpClientAttributesExtractorBuilder<REQUEST,
addressPortExtractor,
SemconvStability.emitStableHttpSemconv(),
SemconvStability.emitOldHttpSemconv(),
InternalServerAttributesExtractor.Mode.PEER);
InternalServerAttributesExtractor.Mode.PEER,
/* captureServerSocketAttributes= */ true);
this.resendCountIncrementer = resendCountIncrementer;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,14 @@ public static <REQUEST, RESPONSE> HttpServerAttributesExtractorBuilder<REQUEST,
HttpServerAttributesGetter<REQUEST, RESPONSE> httpAttributesGetter,
NetServerAttributesGetter<REQUEST, RESPONSE> netAttributesGetter,
List<String> capturedRequestHeaders,
List<String> capturedResponseHeaders) {
List<String> capturedResponseHeaders,
boolean captureServerSocketAttributes) {
this(
httpAttributesGetter,
netAttributesGetter,
capturedRequestHeaders,
capturedResponseHeaders,
captureServerSocketAttributes,
HttpRouteHolder::getRoute);
}

Expand All @@ -93,6 +95,7 @@ public static <REQUEST, RESPONSE> HttpServerAttributesExtractorBuilder<REQUEST,
NetServerAttributesGetter<REQUEST, RESPONSE> netAttributesGetter,
List<String> capturedRequestHeaders,
List<String> capturedResponseHeaders,
boolean captureServerSocketAttributes,
Function<Context, String> httpRouteHolderGetter) {
super(httpAttributesGetter, capturedRequestHeaders, capturedResponseHeaders);
HttpNetAddressPortExtractor<REQUEST> addressPortExtractor =
Expand All @@ -119,7 +122,10 @@ public static <REQUEST, RESPONSE> HttpServerAttributesExtractorBuilder<REQUEST,
addressPortExtractor,
SemconvStability.emitStableHttpSemconv(),
SemconvStability.emitOldHttpSemconv(),
InternalServerAttributesExtractor.Mode.HOST);
InternalServerAttributesExtractor.Mode.HOST,
// we're not capturing these by default, since they're opt-in
// we'll add a configuration flag if someone happens to request them
/* captureServerSocketAttributes= */ false);
internalClientExtractor =
new InternalClientAttributesExtractor<>(
netAttributesGetter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public final class HttpServerAttributesExtractorBuilder<REQUEST, RESPONSE> {
final NetServerAttributesGetter<REQUEST, RESPONSE> netAttributesGetter;
List<String> capturedRequestHeaders = emptyList();
List<String> capturedResponseHeaders = emptyList();
boolean captureServerSocketAttributes = false;

HttpServerAttributesExtractorBuilder(
HttpServerAttributesGetter<REQUEST, RESPONSE> httpAttributesGetter,
Expand Down Expand Up @@ -64,12 +65,30 @@ public HttpServerAttributesExtractorBuilder<REQUEST, RESPONSE> setCapturedRespon
return this;
}

/**
* Configures the extractor to capture the optional {@code server.socket.address} and {@code
* server.socket.port} attributes, which are not collected by default.
*
* @param captureServerSocketAttributes {@code true} if the extractor should collect the optional
* {@code server.socket.address} and {@code server.socket.port} attributes.
*/
@CanIgnoreReturnValue
public HttpServerAttributesExtractorBuilder<REQUEST, RESPONSE> setCaptureServerSocketAttributes(
boolean captureServerSocketAttributes) {
this.captureServerSocketAttributes = captureServerSocketAttributes;
return this;
}

/**
* Returns a new {@link HttpServerAttributesExtractor} with the settings of this {@link
* HttpServerAttributesExtractorBuilder}.
*/
public AttributesExtractor<REQUEST, RESPONSE> build() {
return new HttpServerAttributesExtractor<>(
httpAttributesGetter, netAttributesGetter, capturedRequestHeaders, capturedResponseHeaders);
httpAttributesGetter,
netAttributesGetter,
capturedRequestHeaders,
capturedResponseHeaders,
captureServerSocketAttributes);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ private NetClientAttributesExtractor(NetClientAttributesGetter<REQUEST, RESPONSE
FallbackAddressPortExtractor.noop(),
SemconvStability.emitStableHttpSemconv(),
SemconvStability.emitOldHttpSemconv(),
InternalServerAttributesExtractor.Mode.PEER);
InternalServerAttributesExtractor.Mode.PEER,
/* captureServerSocketAttributes= */ true);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ private NetServerAttributesExtractor(NetServerAttributesGetter<REQUEST, RESPONSE
FallbackAddressPortExtractor.noop(),
SemconvStability.emitStableHttpSemconv(),
SemconvStability.emitOldHttpSemconv(),
InternalServerAttributesExtractor.Mode.HOST);
InternalServerAttributesExtractor.Mode.HOST,
/* captureServerSocketAttributes= */ true);
internalClientExtractor =
new InternalClientAttributesExtractor<>(
getter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ public static <REQUEST, RESPONSE> ServerAttributesExtractor<REQUEST, RESPONSE> c
/* emitStableUrlAttributes= */ true,
/* emitOldHttpAttributes= */ false,
// this param does not matter when old semconv is off
InternalServerAttributesExtractor.Mode.HOST);
InternalServerAttributesExtractor.Mode.HOST,
/* captureServerSocketAttributes= */ true);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,23 @@ public final class InternalServerAttributesExtractor<REQUEST, RESPONSE> {
private final boolean emitStableUrlAttributes;
private final boolean emitOldHttpAttributes;
private final Mode oldSemconvMode;
private final boolean captureServerSocketAttributes;

public InternalServerAttributesExtractor(
ServerAttributesGetter<REQUEST, RESPONSE> getter,
BiPredicate<Integer, REQUEST> captureServerPortCondition,
FallbackAddressPortExtractor<REQUEST> fallbackAddressPortExtractor,
boolean emitStableUrlAttributes,
boolean emitOldHttpAttributes,
Mode oldSemconvMode) {
Mode oldSemconvMode,
boolean captureServerSocketAttributes) {
this.getter = getter;
this.captureServerPortCondition = captureServerPortCondition;
this.fallbackAddressPortExtractor = fallbackAddressPortExtractor;
this.emitStableUrlAttributes = emitStableUrlAttributes;
this.emitOldHttpAttributes = emitOldHttpAttributes;
this.oldSemconvMode = oldSemconvMode;
this.captureServerSocketAttributes = captureServerSocketAttributes;
}

public void onStart(AttributesBuilder attributes, REQUEST request) {
Expand Down Expand Up @@ -69,7 +72,7 @@ public void onEnd(AttributesBuilder attributes, REQUEST request, @Nullable RESPO

String serverSocketAddress = getter.getServerSocketAddress(request, response);
if (serverSocketAddress != null && !serverSocketAddress.equals(serverAddressAndPort.address)) {
if (emitStableUrlAttributes) {
if (emitStableUrlAttributes && captureServerSocketAttributes) {
internalSet(attributes, NetworkAttributes.SERVER_SOCKET_ADDRESS, serverSocketAddress);
}
if (emitOldHttpAttributes) {
Expand All @@ -81,7 +84,7 @@ public void onEnd(AttributesBuilder attributes, REQUEST request, @Nullable RESPO
if (serverSocketPort != null
&& serverSocketPort > 0
&& !serverSocketPort.equals(serverAddressAndPort.port)) {
if (emitStableUrlAttributes) {
if (emitStableUrlAttributes && captureServerSocketAttributes) {
internalSet(attributes, NetworkAttributes.SERVER_SOCKET_PORT, (long) serverSocketPort);
}
if (emitOldHttpAttributes) {
Expand All @@ -91,7 +94,7 @@ public void onEnd(AttributesBuilder attributes, REQUEST request, @Nullable RESPO

String serverSocketDomain = getter.getServerSocketDomain(request, response);
if (serverSocketDomain != null && !serverSocketDomain.equals(serverAddressAndPort.address)) {
if (emitStableUrlAttributes) {
if (emitStableUrlAttributes && captureServerSocketAttributes) {
internalSet(attributes, NetworkAttributes.SERVER_SOCKET_DOMAIN, serverSocketDomain);
}
if (emitOldHttpAttributes && oldSemconvMode.socketDomain != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ void normal() {
new TestNetServerAttributesGetter(),
singletonList("Custom-Request-Header"),
singletonList("Custom-Response-Header"),
false,
routeFromContext);

AttributesBuilder startAttributes = Attributes.builder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ void normal() {
new TestNetServerAttributesGetter(),
singletonList("Custom-Request-Header"),
singletonList("Custom-Response-Header"),
false,
routeFromContext);

AttributesBuilder startAttributes = Attributes.builder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,103 +38,119 @@
class HttpServerAttributesExtractorStableSemconvTest {

static class TestHttpServerAttributesGetter
implements HttpServerAttributesGetter<Map<String, Object>, Map<String, Object>> {
implements HttpServerAttributesGetter<Map<String, String>, Map<String, String>> {

@Override
public String getHttpRequestMethod(Map<String, Object> request) {
return (String) request.get("method");
public String getHttpRequestMethod(Map<String, String> request) {
return request.get("method");
}

@Override
public String getUrlScheme(Map<String, Object> request) {
return (String) request.get("scheme");
public String getUrlScheme(Map<String, String> request) {
return request.get("scheme");
}

@Nullable
@Override
public String getUrlPath(Map<String, Object> request) {
return (String) request.get("path");
public String getUrlPath(Map<String, String> request) {
return request.get("path");
}

@Nullable
@Override
public String getUrlQuery(Map<String, Object> request) {
return (String) request.get("query");
public String getUrlQuery(Map<String, String> request) {
return request.get("query");
}

@Override
public String getHttpRoute(Map<String, Object> request) {
return (String) request.get("route");
public String getHttpRoute(Map<String, String> request) {
return request.get("route");
}

@Override
public List<String> getHttpRequestHeader(Map<String, Object> request, String name) {
String values = (String) request.get("header." + name);
public List<String> getHttpRequestHeader(Map<String, String> request, String name) {
String values = request.get("header." + name);
return values == null ? emptyList() : asList(values.split(","));
}

@Override
public Integer getHttpResponseStatusCode(
Map<String, Object> request, Map<String, Object> response, @Nullable Throwable error) {
String value = (String) response.get("statusCode");
Map<String, String> request, Map<String, String> response, @Nullable Throwable error) {
String value = response.get("statusCode");
return value == null ? null : Integer.parseInt(value);
}

@Override
public List<String> getHttpResponseHeader(
Map<String, Object> request, Map<String, Object> response, String name) {
String values = (String) response.get("header." + name);
Map<String, String> request, Map<String, String> response, String name) {
String values = response.get("header." + name);
return values == null ? emptyList() : asList(values.split(","));
}
}

static class TestNetServerAttributesGetter
implements NetServerAttributesGetter<Map<String, Object>, Map<String, Object>> {
implements NetServerAttributesGetter<Map<String, String>, Map<String, String>> {

@Nullable
@Override
public String getNetworkTransport(
Map<String, Object> request, @Nullable Map<String, Object> response) {
return (String) request.get("transport");
Map<String, String> request, @Nullable Map<String, String> response) {
return request.get("transport");
}

@Nullable
@Override
public String getNetworkType(
Map<String, Object> request, @Nullable Map<String, Object> response) {
return (String) request.get("type");
Map<String, String> request, @Nullable Map<String, String> response) {
return request.get("type");
}

@Nullable
@Override
public String getNetworkProtocolName(
Map<String, Object> request, Map<String, Object> response) {
return (String) request.get("protocolName");
Map<String, String> request, Map<String, String> response) {
return request.get("protocolName");
}

@Nullable
@Override
public String getNetworkProtocolVersion(
Map<String, Object> request, Map<String, Object> response) {
return (String) request.get("protocolVersion");
Map<String, String> request, Map<String, String> response) {
return request.get("protocolVersion");
}

@Nullable
@Override
public String getServerAddress(Map<String, Object> request) {
return (String) request.get("hostName");
public String getServerAddress(Map<String, String> request) {
return request.get("hostName");
}

@Nullable
@Override
public Integer getServerPort(Map<String, Object> request) {
return (Integer) request.get("hostPort");
public Integer getServerPort(Map<String, String> request) {
String value = request.get("hostPort");
return value == null ? null : Integer.parseInt(value);
}

@Nullable
@Override
public String getServerSocketAddress(
Map<String, String> request, @Nullable Map<String, String> response) {
return request.get("serverSocketAddress");
}

@Nullable
@Override
public Integer getServerSocketPort(
Map<String, String> request, @Nullable Map<String, String> response) {
String value = request.get("serverSocketPort");
return value == null ? null : Integer.parseInt(value);
}
}

@Test
void normal() {
Map<String, Object> request = new HashMap<>();
Map<String, String> request = new HashMap<>();
request.put("method", "POST");
request.put("url", "http://github.com");
request.put("path", "/repositories/1");
Expand All @@ -150,20 +166,23 @@ void normal() {
request.put("type", "ipv4");
request.put("protocolName", "http");
request.put("protocolVersion", "2.0");
request.put("serverSocketAddress", "1.2.3.4");
request.put("serverSocketPort", "42");

Map<String, Object> response = new HashMap<>();
Map<String, String> response = new HashMap<>();
response.put("statusCode", "202");
response.put("header.content-length", "20");
response.put("header.custom-response-header", "654,321");

Function<Context, String> routeFromContext = ctx -> "/repositories/{repoId}";

HttpServerAttributesExtractor<Map<String, Object>, Map<String, Object>> extractor =
HttpServerAttributesExtractor<Map<String, String>, Map<String, String>> extractor =
new HttpServerAttributesExtractor<>(
new TestHttpServerAttributesGetter(),
new TestNetServerAttributesGetter(),
singletonList("Custom-Request-Header"),
singletonList("Custom-Response-Header"),
false,
routeFromContext);

AttributesBuilder startAttributes = Attributes.builder();
Expand Down Expand Up @@ -212,9 +231,8 @@ void skipNetworkTransportIfDefaultForProtocol(
request.put("transport", observedTransport);

AttributesExtractor<Map<String, String>, Map<String, String>> extractor =
HttpClientAttributesExtractor.create(
new HttpClientAttributesExtractorStableSemconvTest.TestHttpClientAttributesGetter(),
new HttpClientAttributesExtractorStableSemconvTest.TestNetClientAttributesGetter());
HttpServerAttributesExtractor.create(
new TestHttpServerAttributesGetter(), new TestNetServerAttributesGetter());

AttributesBuilder attributes = Attributes.builder();
extractor.onStart(attributes, Context.root(), request);
Expand Down

0 comments on commit 655ad34

Please sign in to comment.