Skip to content

Commit

Permalink
Split NetAttributesExtractor into NetClientAttributesExtractor and Ne…
Browse files Browse the repository at this point in the history
…tServerAttributesExtractor (#4287)

* Net Extractors

* Either request or response but not both

* Fix merge conflicts

* Separate by OnStart/OnEnd

* PeerServiceAttributes

* Fix test

* Restructure to client/server

* Fix merge conflict in main

* more

* peer.service

* Feedback

* peer.service is only for clients

* Fix merge conflict

* rename

* Armeria

* peer.service is only for clients

* rename

* WIP

* Sync Dubbo with Armeria

* More Dubbo and Armeria

* gRPC

* Revert some Dubbo changes

* more peer.service

* Fix test

* Fix merge

* Fixes
  • Loading branch information
trask authored Oct 7, 2021
1 parent 581a5e3 commit 63a2383
Show file tree
Hide file tree
Showing 77 changed files with 835 additions and 407 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.net.InetSocketAddressNetAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.net.InetSocketAddressNetServerAttributesExtractor;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.net.InetSocketAddress;
import java.util.Collections;
Expand Down Expand Up @@ -120,13 +120,13 @@ protected List<String> responseHeader(Void unused, Void unused2, String name) {
}

static class ConstantNetAttributesExtractor
extends InetSocketAddressNetAttributesExtractor<Void, Void> {
extends InetSocketAddressNetServerAttributesExtractor<Void, Void> {

private static final InetSocketAddress ADDRESS =
InetSocketAddress.createUnresolved("localhost", 8080);

@Override
public @Nullable InetSocketAddress getAddress(Void unused, @Nullable Void unused2) {
public @Nullable InetSocketAddress getAddress(Void unused) {
return ADDRESS;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.db.DbAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.net.NetAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.net.NetServerAttributesExtractor;
import org.checkerframework.checker.nullness.qual.Nullable;

/**
Expand All @@ -22,7 +22,7 @@
*
* @see DbAttributesExtractor
* @see HttpClientAttributesExtractor
* @see NetAttributesExtractor
* @see NetServerAttributesExtractor
*/
public abstract class AttributesExtractor<REQUEST, RESPONSE> {
/**
Expand Down Expand Up @@ -51,4 +51,13 @@ protected static <T> void set(
attributes.put(key, value);
}
}

/**
* Returns an {@link AttributesExtractor} implementation that always extracts the provided
* constant value.
*/
public static <REQUEST, RESPONSE, T> AttributesExtractor<REQUEST, RESPONSE> constant(
AttributeKey<T> attributeKey, T attributeValue) {
return new ConstantAttributesExtractor<>(attributeKey, attributeValue);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.api.instrumenter;

import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.AttributesBuilder;
import org.checkerframework.checker.nullness.qual.Nullable;

final class ConstantAttributesExtractor<REQUEST, RESPONSE, T>
extends AttributesExtractor<REQUEST, RESPONSE> {

private final AttributeKey<T> attributeKey;
private final T attributeValue;

ConstantAttributesExtractor(AttributeKey<T> attributeKey, T attributeValue) {
this.attributeKey = attributeKey;
this.attributeValue = attributeValue;
}

@Override
protected void onStart(AttributesBuilder attributes, REQUEST request) {
attributes.put(attributeKey, attributeValue);
}

@Override
protected void onEnd(
AttributesBuilder attributes,
REQUEST request,
@Nullable RESPONSE response,
@Nullable Throwable error) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.net.NetAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.net.NetClientAttributesExtractor;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.util.Map;
import org.checkerframework.checker.nullness.qual.Nullable;
Expand All @@ -27,41 +27,39 @@ public final class PeerServiceAttributesExtractor<REQUEST, RESPONSE>
Config.get().getMap("otel.instrumentation.common.peer-service-mapping");

private final Map<String, String> peerServiceMapping;
private final NetAttributesExtractor<REQUEST, RESPONSE> netAttributesExtractor;
private final NetClientAttributesExtractor<REQUEST, RESPONSE> netClientAttributesExtractor;

// visible for tests
PeerServiceAttributesExtractor(
Map<String, String> peerServiceMapping,
NetAttributesExtractor<REQUEST, RESPONSE> netAttributesExtractor) {
NetClientAttributesExtractor<REQUEST, RESPONSE> netClientAttributesExtractor) {
this.peerServiceMapping = peerServiceMapping;
this.netAttributesExtractor = netAttributesExtractor;
this.netClientAttributesExtractor = netClientAttributesExtractor;
}

/**
* Returns a new {@link PeerServiceAttributesExtractor} that will use the passed {@code
* netAttributesExtractor} instance to determine the value of the {@code peer.service} attribute.
*/
public static <REQUEST, RESPONSE> PeerServiceAttributesExtractor<REQUEST, RESPONSE> create(
NetAttributesExtractor<REQUEST, RESPONSE> netAttributesExtractor) {
NetClientAttributesExtractor<REQUEST, RESPONSE> netAttributesExtractor) {
return new PeerServiceAttributesExtractor<>(
JAVAAGENT_PEER_SERVICE_MAPPING, netAttributesExtractor);
}

@Override
protected void onStart(AttributesBuilder attributes, REQUEST request) {
onEnd(attributes, request, null, null);
}
protected void onStart(AttributesBuilder attributes, REQUEST request) {}

@Override
protected void onEnd(
AttributesBuilder attributes,
REQUEST request,
@Nullable RESPONSE response,
@Nullable Throwable error) {
String peerName = netAttributesExtractor.peerName(request, response);
String peerName = netClientAttributesExtractor.peerName(request, response);
String peerService = mapToPeerService(peerName);
if (peerService == null) {
String peerIp = netAttributesExtractor.peerIp(request, response);
String peerIp = netClientAttributesExtractor.peerIp(request, response);
peerService = mapToPeerService(peerIp);
}
if (peerService != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,12 @@
* Extractor of <a
* href="https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/span-general.md#general-network-connection-attributes">Network
* attributes</a> from a {@link InetSocketAddress}. Most network libraries will provide access to a
* {@link InetSocketAddress} so this is a convenient alternative to {@link NetAttributesExtractor}.
* There is no meaning to implement both in the same instrumentation.
* {@link InetSocketAddress} so this is a convenient alternative to {@link
* NetClientAttributesExtractor}. There is no meaning to implement both in the same instrumentation.
*/
public abstract class InetSocketAddressNetAttributesExtractor<REQUEST, RESPONSE>
extends NetAttributesExtractor<REQUEST, RESPONSE> {
public abstract class InetSocketAddressNetClientAttributesExtractor<REQUEST, RESPONSE>
extends NetClientAttributesExtractor<REQUEST, RESPONSE> {

/**
* This method will be called twice: both when the request starts ({@code response} is always null
* then) and when the response ends. This way it is possible to capture net attributes in both
* phases of processing.
*/
@Nullable
public abstract InetSocketAddress getAddress(REQUEST request, @Nullable RESPONSE response);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.api.instrumenter.net;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import org.checkerframework.checker.nullness.qual.Nullable;

/**
* Extractor of <a
* href="https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/span-general.md#general-network-connection-attributes">Network
* attributes</a> from a {@link InetSocketAddress}. Most network libraries will provide access to a
* {@link InetSocketAddress} so this is a convenient alternative to {@link
* NetServerAttributesExtractor}. There is no meaning to implement both in the same instrumentation.
*/
public abstract class InetSocketAddressNetServerAttributesExtractor<REQUEST, RESPONSE>
extends NetServerAttributesExtractor<REQUEST, RESPONSE> {

@Nullable
public abstract InetSocketAddress getAddress(REQUEST request);

@Override
@Nullable
public final String peerName(REQUEST request) {
InetSocketAddress address = getAddress(request);
if (address == null) {
return null;
}
if (address.getAddress() != null) {
return address.getAddress().getHostName();
}
return address.getHostString();
}

@Override
@Nullable
public final Integer peerPort(REQUEST request) {
InetSocketAddress address = getAddress(request);
if (address == null) {
return null;
}
return address.getPort();
}

@Override
@Nullable
public final String peerIp(REQUEST request) {
InetSocketAddress address = getAddress(request);
if (address == null) {
return null;
}
InetAddress remoteAddress = address.getAddress();
if (remoteAddress != null) {
return remoteAddress.getHostAddress();
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,13 @@
* Extractor of <a
* href="https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/span-general.md#general-network-connection-attributes">Network
* attributes</a>. It is common to have access to {@link java.net.InetSocketAddress}, in which case
* it is more convenient to use {@link InetSocketAddressNetAttributesExtractor}.
* it is more convenient to use {@link InetSocketAddressNetClientAttributesExtractor}.
*/
public abstract class NetAttributesExtractor<REQUEST, RESPONSE>
public abstract class NetClientAttributesExtractor<REQUEST, RESPONSE>
extends AttributesExtractor<REQUEST, RESPONSE> {

@Override
protected final void onStart(AttributesBuilder attributes, REQUEST request) {
set(attributes, SemanticAttributes.NET_TRANSPORT, transport(request));

String peerIp = peerIp(request, null);
String peerName = peerName(request, null);

if (peerName != null && !peerName.equals(peerIp)) {
set(attributes, SemanticAttributes.NET_PEER_NAME, peerName);
}
set(attributes, SemanticAttributes.NET_PEER_IP, peerIp);

Integer peerPort = peerPort(request, null);
if (peerPort != null) {
set(attributes, SemanticAttributes.NET_PEER_PORT, (long) peerPort);
}
}
protected final void onStart(AttributesBuilder attributes, REQUEST request) {}

@Override
protected final void onEnd(
Expand All @@ -44,6 +29,8 @@ protected final void onEnd(
@Nullable RESPONSE response,
@Nullable Throwable error) {

set(attributes, SemanticAttributes.NET_TRANSPORT, transport(request, response));

String peerIp = peerIp(request, response);
String peerName = peerName(request, response);

Expand All @@ -59,29 +46,14 @@ protected final void onEnd(
}

@Nullable
public abstract String transport(REQUEST request);
public abstract String transport(REQUEST request, @Nullable RESPONSE response);

/**
* This method will be called twice: both when the request starts ({@code response} is always null
* then) and when the response ends. This way it is possible to capture net attributes in both
* phases of processing.
*/
@Nullable
public abstract String peerName(REQUEST request, @Nullable RESPONSE response);

/**
* This method will be called twice: both when the request starts ({@code response} is always null
* then) and when the response ends. This way it is possible to capture net attributes in both
* phases of processing.
*/
@Nullable
public abstract Integer peerPort(REQUEST request, @Nullable RESPONSE response);

/**
* This method will be called twice: both when the request starts ({@code response} is always null
* then) and when the response ends. This way it is possible to capture net attributes in both
* phases of processing.
*/
@Nullable
public abstract String peerIp(REQUEST request, @Nullable RESPONSE response);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.api.instrumenter.net;

import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import org.checkerframework.checker.nullness.qual.Nullable;

/**
* Extractor of <a
* href="https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/span-general.md#general-network-connection-attributes">Network
* attributes</a>. It is common to have access to {@link java.net.InetSocketAddress}, in which case
* it is more convenient to use {@link InetSocketAddressNetServerAttributesExtractor}.
*/
public abstract class NetServerAttributesExtractor<REQUEST, RESPONSE>
extends AttributesExtractor<REQUEST, RESPONSE> {

@Override
protected final void onStart(AttributesBuilder attributes, REQUEST request) {
set(attributes, SemanticAttributes.NET_TRANSPORT, transport(request));

String peerIp = peerIp(request);
String peerName = peerName(request);

if (peerName != null && !peerName.equals(peerIp)) {
set(attributes, SemanticAttributes.NET_PEER_NAME, peerName);
}
set(attributes, SemanticAttributes.NET_PEER_IP, peerIp);

Integer peerPort = peerPort(request);
if (peerPort != null) {
set(attributes, SemanticAttributes.NET_PEER_PORT, (long) peerPort);
}
}

@Override
protected final void onEnd(
AttributesBuilder attributes,
REQUEST request,
@Nullable RESPONSE response,
@Nullable Throwable error) {}

@Nullable
public abstract String transport(REQUEST request);

@Nullable
public abstract String peerName(REQUEST request);

@Nullable
public abstract Integer peerPort(REQUEST request);

@Nullable
public abstract String peerIp(REQUEST request);
}
Loading

0 comments on commit 63a2383

Please sign in to comment.