From 4d8c4015f11b7b68379873705e195c35df120c3a Mon Sep 17 00:00:00 2001 From: jiwen624 Date: Wed, 22 Sep 2021 14:09:44 -0700 Subject: [PATCH 01/21] remove appoptics propagator --- .../extensions/AppOpticsPropagator.java | 125 ------------------ .../AppOpticsPropagatorProvider.java | 19 --- .../extensions/AppOpticsPropertySource.java | 1 - 3 files changed, 145 deletions(-) delete mode 100644 custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsPropagator.java delete mode 100644 custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsPropagatorProvider.java diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsPropagator.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsPropagator.java deleted file mode 100644 index 2b415adf..00000000 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsPropagator.java +++ /dev/null @@ -1,125 +0,0 @@ -package com.appoptics.opentelemetry.extensions; - -import com.appoptics.opentelemetry.core.Util; -import com.tracelytics.instrumentation.HeaderConstants; -import com.tracelytics.joboe.Metadata; -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.api.trace.SpanContext; -import io.opentelemetry.api.trace.TraceState; -import io.opentelemetry.api.trace.TraceStateBuilder; -import io.opentelemetry.context.Context; -import io.opentelemetry.context.propagation.TextMapGetter; -import io.opentelemetry.context.propagation.TextMapPropagator; -import io.opentelemetry.context.propagation.TextMapSetter; - -import javax.annotation.Nullable; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - -public class AppOpticsPropagator implements TextMapPropagator { - private static final String TRACE_STATE_APPOPTICS_KEY = "appoptics"; - static final String TRACE_PARENT = "traceparent"; - static final String TRACE_STATE = "tracestate"; - private static final List FIELDS = - Collections.unmodifiableList(Arrays.asList(TRACE_PARENT, TRACE_STATE, HeaderConstants.XTRACE_HEADER)); - private static final int TRACESTATE_MAX_SIZE = 512; - private static final int TRACESTATE_MAX_MEMBERS = 32; - private static final char TRACESTATE_KEY_VALUE_DELIMITER = '='; - private static final char TRACESTATE_ENTRY_DELIMITER = ','; - - @Override - public Collection fields() { - return FIELDS; - } - - /** - * Injects the both the AppOptics x-trace ID and the updated w3c `tracestate` with our x-trace ID prepended - * into the carrier with values provided by current context - * @param context - * @param carrier - * @param setter - * @param - */ - @Override - public void inject(Context context, @Nullable C carrier, TextMapSetter setter) { - if (context == null || setter == null) { - return; - } - - SpanContext spanContext = Span.fromContext(context).getSpanContext(); - if (!spanContext.isValid()) { - return; - } - - Metadata metadata = Util.buildMetadata(spanContext); - - if (metadata.isValid()) { - String xTraceId = metadata.toHexString(); - setter.set(carrier, HeaderConstants.XTRACE_HEADER, xTraceId); - - //update trace state too: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#tracestate - //https://www.w3.org/TR/trace-context/#mutating-the-tracestate-field - TraceState traceState = spanContext.getTraceState(); - StringBuilder stringBuilder = new StringBuilder(TRACESTATE_MAX_SIZE); - - stringBuilder.append(TRACE_STATE_APPOPTICS_KEY).append(TRACESTATE_KEY_VALUE_DELIMITER).append(metadata.toHexString()); - AtomicInteger count = new AtomicInteger(1); - traceState.forEach( - (key, value) -> { - if (!TRACE_STATE_APPOPTICS_KEY.equals(key) && count.getAndIncrement() <= TRACESTATE_MAX_MEMBERS) { - stringBuilder.append(TRACESTATE_ENTRY_DELIMITER); - stringBuilder.append(key).append(TRACESTATE_KEY_VALUE_DELIMITER).append(value); - } - }); - setter.set(carrier, TRACE_STATE, stringBuilder.toString()); - } - } - - /** - * Extract context from the carrier, first scanning for appoptics x-trace header. - * If not found, try the w3c `tracestate` - * @param context - * @param carrier - * @param getter - * @param - * @return - */ - @Override - public Context extract(Context context, @Nullable C carrier, TextMapGetter getter) { - if (context == null || getter == null) { - return context; - } - - //it should have a spanContext extracted by W3CTraceContextPropagator - //since we expect propagators config: `-Dotel.propagators=tracecontext,baggage,appoptics` - SpanContext spanContext = Span.fromContext(context).getSpanContext(); - if (!spanContext.isValid()) { - return context; - } - - String xTraceId = getter.get(carrier, HeaderConstants.XTRACE_HEADER); - if (xTraceId == null) { //then try W3C tracestate - xTraceId = spanContext.getTraceState().get(TRACE_STATE_APPOPTICS_KEY); - } - - if (xTraceId == null) { - return context; - } - - TraceStateBuilder traceStateBuilder = Span.fromContext(context).getSpanContext().getTraceState().toBuilder(); - //step 1: include full x-trace ID as trace state - traceStateBuilder.put(TRACE_STATE_APPOPTICS_KEY, xTraceId); - - Util.W3TraceContextHolder w3Context = Util.toW3TraceContext(xTraceId); - //step 2: create span context from ao x-trace ID - SpanContext newSpanContext = SpanContext.createFromRemoteParent(w3Context.traceId, w3Context.spanId, w3Context.traceFlags, traceStateBuilder.build()); - - return context.with(Span.wrap(newSpanContext)); - } - - - -} diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsPropagatorProvider.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsPropagatorProvider.java deleted file mode 100644 index c91ffb49..00000000 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsPropagatorProvider.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.appoptics.opentelemetry.extensions; - -import com.google.auto.service.AutoService; -import io.opentelemetry.context.propagation.TextMapPropagator; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurablePropagatorProvider; - -@AutoService(ConfigurablePropagatorProvider.class) -public class AppOpticsPropagatorProvider implements ConfigurablePropagatorProvider { - - @Override - public TextMapPropagator getPropagator() { - return new AppOpticsPropagator(); - } - - @Override - public String getName() { - return "appoptics"; - } -} diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsPropertySource.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsPropertySource.java index e8a4fea6..3bec8853 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsPropertySource.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsPropertySource.java @@ -17,7 +17,6 @@ public class AppOpticsPropertySource implements PropertySource { PROPERTIES.put("otel.traces.exporter", "appoptics"); PROPERTIES.put("otel.traces.sampler", "appoptics"); PROPERTIES.put("otel.metrics.exporter", "none"); - PROPERTIES.put("otel.propagators", "tracecontext,baggage,appoptics"); } @Override From c1e3b9edcfe7a455206fe97190c30d7d6140c9e9 Mon Sep 17 00:00:00 2001 From: jiwen624 Date: Wed, 22 Sep 2021 15:05:04 -0700 Subject: [PATCH 02/21] sampling decision based on tracestate --- .../extensions/AppOpticsSampler.java | 47 ++++++++++++++----- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java index d47ceca1..fb9f27c4 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java @@ -8,9 +8,7 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.api.trace.SpanContext; -import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.api.trace.*; import io.opentelemetry.context.Context; import io.opentelemetry.sdk.trace.data.LinkData; import io.opentelemetry.sdk.trace.samplers.Sampler; @@ -27,6 +25,7 @@ */ @AutoService(Sampler.class) public class AppOpticsSampler implements Sampler { + private static final String SW_TRACESTATE_KEY = "sw"; private SamplingResult PARENT_SAMPLED = SamplingResult.create(SamplingDecision.RECORD_AND_SAMPLE, Attributes.of( AttributeKey.booleanKey(Constants.AO_DETAILED_TRACING), true, @@ -54,18 +53,42 @@ public class AppOpticsSampler implements Sampler { @Override public SamplingResult shouldSample(Context parentContext, String traceId, String name, SpanKind spanKind, Attributes attributes, List parentLinks) { SpanContext parentSpanContext = Span.fromContext(parentContext).getSpanContext(); + TraceState traceState = parentSpanContext.getTraceState(); + TraceStateBuilder traceStateBuilder = traceState.toBuilder(); - if (!parentSpanContext.isValid() || parentSpanContext.isRemote()) { //then a root span of this service - String xTraceId = null; - if (parentSpanContext.isRemote()) { - xTraceId = Util.buildXTraceId(parentSpanContext); - } - String resource = getResource(attributes); - TraceDecision aoTraceDecision = TraceDecisionUtil.shouldTraceRequest(name, xTraceId, null, resource); + if (!parentSpanContext.isValid() || traceState.isEmpty()) { + // TODO: new sample decision, create new tracestate + return PARENT_NOT_SAMPLED; + } + + String swVal = traceState.get(SW_TRACESTATE_KEY); + String resource = getResource(attributes); + + if (swVal == null) { + // TODO: new sample decision, prepend sw in tracestate + // TODO: FIXME: how to get the new trace/span id here??? + TraceDecision aoTraceDecision = TraceDecisionUtil.shouldTraceRequest(name, null, null, resource); return toOtSamplingResult(aoTraceDecision); - } else { //follow parent's decision - return parentSpanContext.isSampled() ? PARENT_SAMPLED : PARENT_NOT_SAMPLED; + } else { + boolean sampled = false; + // TODO parse sw tracestate + if (sampled) { + // TODO: update sw in tracestate + } else { + // TODO: continue non-sampled trace, update tracestate + } } +// if (!parentSpanContext.isValid() || parentSpanContext.isRemote()) { //then a root span of this service +// String xTraceId = null; +// if (parentSpanContext.isRemote()) { +// xTraceId = Util.buildXTraceId(parentSpanContext); +// } +// String resource = getResource(attributes); +// TraceDecision aoTraceDecision = TraceDecisionUtil.shouldTraceRequest(name, xTraceId, null, resource); +// return toOtSamplingResult(aoTraceDecision); +// } else { //follow parent's decision +// return parentSpanContext.isSampled() ? PARENT_SAMPLED : PARENT_NOT_SAMPLED; +// } } private String getResource(Attributes attributes) { From aaefc93a0dcf249f4fffb7cc176ba77c9f745274 Mon Sep 17 00:00:00 2001 From: jiwen624 Date: Mon, 27 Sep 2021 13:19:59 -0700 Subject: [PATCH 03/21] appoptics sampler based on tracestate --- .../extensions/AppOpticsSampler.java | 76 ++++++++++--------- .../extensions/TraceStateSamplingResult.java | 38 ++++++++++ 2 files changed, 77 insertions(+), 37 deletions(-) create mode 100644 custom/src/main/java/com/appoptics/opentelemetry/extensions/TraceStateSamplingResult.java diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java index fb9f27c4..6d2c95ac 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java @@ -15,6 +15,8 @@ import io.opentelemetry.sdk.trace.samplers.SamplingDecision; import io.opentelemetry.sdk.trace.samplers.SamplingResult; import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; +import static com.appoptics.opentelemetry.extensions.TraceStateSamplingResult.SW_TRACESTATE_KEY; +import static com.appoptics.opentelemetry.extensions.TraceStateSamplingResult.SW_SPAN_PLACEHOLDER; import java.util.List; @@ -25,26 +27,25 @@ */ @AutoService(Sampler.class) public class AppOpticsSampler implements Sampler { - private static final String SW_TRACESTATE_KEY = "sw"; - private SamplingResult PARENT_SAMPLED = SamplingResult.create(SamplingDecision.RECORD_AND_SAMPLE, + private final SamplingResult PARENT_SAMPLED = SamplingResult.create(SamplingDecision.RECORD_AND_SAMPLE, Attributes.of( AttributeKey.booleanKey(Constants.AO_DETAILED_TRACING), true, AttributeKey.booleanKey(Constants.AO_METRICS), true, AttributeKey.booleanKey(Constants.AO_SAMPLER), true)); - private SamplingResult PARENT_NOT_SAMPLED = SamplingResult.create(SamplingDecision.DROP, + private final SamplingResult PARENT_NOT_SAMPLED = SamplingResult.create(SamplingDecision.DROP, Attributes.of( AttributeKey.booleanKey(Constants.AO_DETAILED_TRACING), false, AttributeKey.booleanKey(Constants.AO_METRICS), false, AttributeKey.booleanKey(Constants.AO_SAMPLER), true)); - private SamplingResult METRICS_ONLY = SamplingResult.create(SamplingDecision.RECORD_ONLY, + private final SamplingResult METRICS_ONLY = SamplingResult.create(SamplingDecision.RECORD_ONLY, Attributes.of( AttributeKey.booleanKey(Constants.AO_DETAILED_TRACING), false, AttributeKey.booleanKey(Constants.AO_METRICS), true, AttributeKey.booleanKey(Constants.AO_SAMPLER), true )); - private SamplingResult NOT_TRACED = SamplingResult.create(SamplingDecision.DROP, + private final SamplingResult NOT_TRACED = SamplingResult.create(SamplingDecision.DROP, Attributes.of( AttributeKey.booleanKey(Constants.AO_DETAILED_TRACING), false, AttributeKey.booleanKey(Constants.AO_METRICS), false, @@ -53,42 +54,36 @@ public class AppOpticsSampler implements Sampler { @Override public SamplingResult shouldSample(Context parentContext, String traceId, String name, SpanKind spanKind, Attributes attributes, List parentLinks) { SpanContext parentSpanContext = Span.fromContext(parentContext).getSpanContext(); - TraceState traceState = parentSpanContext.getTraceState(); - TraceStateBuilder traceStateBuilder = traceState.toBuilder(); + TraceState traceState = parentSpanContext.getTraceState() != null ? parentSpanContext.getTraceState() : TraceState.getDefault(); + String resource = getResource(attributes); if (!parentSpanContext.isValid() || traceState.isEmpty()) { - // TODO: new sample decision, create new tracestate - return PARENT_NOT_SAMPLED; + // new sample decision, create new tracestate + return toOtSamplingResult(TraceDecisionUtil.shouldTraceRequest(name, null, null, resource), TraceState.getDefault()); } String swVal = traceState.get(SW_TRACESTATE_KEY); - String resource = getResource(attributes); - - if (swVal == null) { - // TODO: new sample decision, prepend sw in tracestate - // TODO: FIXME: how to get the new trace/span id here??? + if (!isValidSWTraceStateKey(swVal)) { TraceDecision aoTraceDecision = TraceDecisionUtil.shouldTraceRequest(name, null, null, resource); - return toOtSamplingResult(aoTraceDecision); + return toOtSamplingResult(aoTraceDecision, traceState); } else { - boolean sampled = false; - // TODO parse sw tracestate - if (sampled) { - // TODO: update sw in tracestate + if (swVal.equals(SW_SPAN_PLACEHOLDER)) { + return (parentSpanContext.isSampled() ? Sampler.alwaysOn() : Sampler.alwaysOff()) + .shouldSample(parentContext, traceId, name, spanKind, attributes, parentLinks); } else { - // TODO: continue non-sampled trace, update tracestate + TraceFlags traceFlags = TraceFlags.fromByte(swVal.split("-")[1].getBytes()[1]); + return (traceFlags.isSampled() ? Sampler.alwaysOn() : Sampler.alwaysOff()) + .shouldSample(parentContext, traceId, name, spanKind, attributes, parentLinks); } } -// if (!parentSpanContext.isValid() || parentSpanContext.isRemote()) { //then a root span of this service -// String xTraceId = null; -// if (parentSpanContext.isRemote()) { -// xTraceId = Util.buildXTraceId(parentSpanContext); -// } -// String resource = getResource(attributes); -// TraceDecision aoTraceDecision = TraceDecisionUtil.shouldTraceRequest(name, xTraceId, null, resource); -// return toOtSamplingResult(aoTraceDecision); -// } else { //follow parent's decision -// return parentSpanContext.isSampled() ? PARENT_SAMPLED : PARENT_NOT_SAMPLED; -// } + } + + private boolean isValidSWTraceStateKey(String swVal) { + if (swVal == null || !swVal.contains("-")) { + return false; + } + String traceFlagStr = swVal.split("-")[1]; + return traceFlagStr.equals("00") || traceFlagStr.equals("01"); } private String getResource(Attributes attributes) { @@ -102,26 +97,33 @@ public String getDescription() { return "AppOptics Sampler"; } - private SamplingResult toOtSamplingResult(TraceDecision aoTraceDecision) { + private SamplingResult toOtSamplingResult(TraceDecision aoTraceDecision, TraceState traceState) { + SamplingResult result = NOT_TRACED; + if (aoTraceDecision.isSampled()) { SamplingDecision samplingDecision = SamplingDecision.RECORD_AND_SAMPLE; AttributesBuilder builder = Attributes.builder(); builder.put(Constants.AO_KEY_PREFIX + "SampleRate", aoTraceDecision.getTraceConfig().getSampleRate()); builder.put(Constants.AO_KEY_PREFIX + "SampleSource", aoTraceDecision.getTraceConfig().getSampleRateSourceValue()); - builder.put(Constants.AO_KEY_PREFIX + "BucketRate",aoTraceDecision.getTraceConfig().getBucketRate(aoTraceDecision.getRequestType().getBucketType())); - builder.put(Constants.AO_KEY_PREFIX + "BucketCapacity",aoTraceDecision.getTraceConfig().getBucketCapacity(aoTraceDecision.getRequestType().getBucketType())); + builder.put(Constants.AO_KEY_PREFIX + "BucketRate", aoTraceDecision.getTraceConfig().getBucketRate(aoTraceDecision.getRequestType().getBucketType())); + builder.put(Constants.AO_KEY_PREFIX + "BucketCapacity", aoTraceDecision.getTraceConfig().getBucketCapacity(aoTraceDecision.getRequestType().getBucketType())); builder.put(Constants.AO_KEY_PREFIX + "RequestType", aoTraceDecision.getRequestType().name()); builder.put(Constants.AO_DETAILED_TRACING, aoTraceDecision.isSampled()); builder.put(Constants.AO_METRICS, aoTraceDecision.isReportMetrics()); builder.put(Constants.AO_SAMPLER, true); //mark that it has been sampled by us + + if (!traceState.isEmpty()) { + builder.put(Constants.AO_KEY_PREFIX + "UpstreamTraceVendors", String.join(",", traceState.asMap().keySet())); + } Attributes attributes = builder.build(); - return SamplingResult.create(samplingDecision, attributes); + result = SamplingResult.create(samplingDecision, attributes); } else { if (aoTraceDecision.isReportMetrics()) { - return METRICS_ONLY; // is this correct? probably not... + result = METRICS_ONLY; // is this correct? probably not... } else { - return NOT_TRACED; + result = NOT_TRACED; } } + return TraceStateSamplingResult.wrap(result); } } diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/TraceStateSamplingResult.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/TraceStateSamplingResult.java new file mode 100644 index 00000000..8b3966f4 --- /dev/null +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/TraceStateSamplingResult.java @@ -0,0 +1,38 @@ +package com.appoptics.opentelemetry.extensions; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.trace.TraceState; +import io.opentelemetry.sdk.trace.samplers.SamplingDecision; +import io.opentelemetry.sdk.trace.samplers.SamplingResult; + +/** + * A SamplingResult wrapper offering the `sw=spanIdPlaceHolder` tracestate + */ +public class TraceStateSamplingResult implements SamplingResult { + public static final String SW_TRACESTATE_KEY = "sw"; + public static final String SW_SPAN_PLACEHOLDER = "SWSpanIdPlaceHolder"; + private final SamplingResult delegated; + + private TraceStateSamplingResult(SamplingResult delegated) { + this.delegated = delegated; + } + + public static SamplingResult wrap(SamplingResult result) { + return new TraceStateSamplingResult(result); + } + + @Override + public SamplingDecision getDecision() { + return delegated.getDecision(); + } + + @Override + public Attributes getAttributes() { + return delegated.getAttributes(); + } + + @Override + public TraceState getUpdatedTraceState(TraceState parentTraceState) { + return parentTraceState.toBuilder().put(SW_TRACESTATE_KEY, SW_SPAN_PLACEHOLDER).build(); + } +} From c23d12e4189f32c3f3570deb915da15544ae9c0d Mon Sep 17 00:00:00 2001 From: jiwen624 Date: Mon, 27 Sep 2021 13:59:32 -0700 Subject: [PATCH 04/21] appoptics context propagator --- .../AppOpticsContextPropagator.java | 83 +++++++++++++++++++ .../AppOpticsContextPropagatorProvider.java | 19 +++++ 2 files changed, 102 insertions(+) create mode 100644 custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagator.java create mode 100644 custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagatorProvider.java diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagator.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagator.java new file mode 100644 index 00000000..2973d137 --- /dev/null +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagator.java @@ -0,0 +1,83 @@ +package com.appoptics.opentelemetry.extensions; + +import com.appoptics.opentelemetry.core.Util; +import com.tracelytics.instrumentation.HeaderConstants; +import com.tracelytics.joboe.Metadata; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.api.trace.TraceState; +import io.opentelemetry.api.trace.TraceStateBuilder; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.propagation.TextMapGetter; +import io.opentelemetry.context.propagation.TextMapPropagator; +import io.opentelemetry.context.propagation.TextMapSetter; + +import javax.annotation.Nullable; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +public class AppOpticsContextPropagator implements TextMapPropagator { + private static final String TRACE_STATE_APPOPTICS_KEY = "sw"; + static final String TRACE_PARENT = "traceparent"; + static final String TRACE_STATE = "tracestate"; + private static final List FIELDS = + Collections.unmodifiableList(Arrays.asList(TRACE_PARENT, TRACE_STATE, HeaderConstants.XTRACE_HEADER)); + private static final int TRACESTATE_MAX_SIZE = 512; + private static final int TRACESTATE_MAX_MEMBERS = 32; + private static final char TRACESTATE_KEY_VALUE_DELIMITER = '='; + private static final char TRACESTATE_ENTRY_DELIMITER = ','; + + @Override + public Collection fields() { + return FIELDS; + } + + /** + * Injects the both the AppOptics x-trace ID and the updated w3c `tracestate` with our x-trace ID prepended + * into the carrier with values provided by current context + * @param context + * @param carrier + * @param setter + * @param + */ + @Override + public void inject(Context context, @Nullable C carrier, TextMapSetter setter) { + SpanContext spanContext = Span.fromContext(context).getSpanContext(); + if (carrier == null || !spanContext.isValid()) { + return; + } + //update trace state too: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#tracestate + //https://www.w3.org/TR/trace-context/#mutating-the-tracestate-field + TraceState traceState = spanContext.getTraceState(); + StringBuilder traceStateBuilder = new StringBuilder(TRACESTATE_MAX_SIZE); + String swTraceStateValue = spanContext.getSpanId() + "-" + (spanContext.isSampled() ? "01" : "00"); + traceStateBuilder.append(TRACE_STATE_APPOPTICS_KEY).append(TRACESTATE_KEY_VALUE_DELIMITER).append(swTraceStateValue); + AtomicInteger count = new AtomicInteger(1); + traceState.forEach( + (key, value) -> { + if (!TRACE_STATE_APPOPTICS_KEY.equals(key) && count.getAndIncrement() <= TRACESTATE_MAX_MEMBERS) { + traceStateBuilder.append(TRACESTATE_ENTRY_DELIMITER); + traceStateBuilder.append(key).append(TRACESTATE_KEY_VALUE_DELIMITER).append(value); + } + }); + setter.set(carrier, TRACE_STATE, traceStateBuilder.toString()); + } + + /** + * Extract context from the carrier, first scanning for appoptics x-trace header. + * If not found, try the w3c `tracestate` + * @param context + * @param carrier + * @param getter + * @param + * @return + */ + @Override + public Context extract(Context context, @Nullable C carrier, TextMapGetter getter) { + // do nothing + return context; + } +} \ No newline at end of file diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagatorProvider.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagatorProvider.java new file mode 100644 index 00000000..d22cc303 --- /dev/null +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagatorProvider.java @@ -0,0 +1,19 @@ +package com.appoptics.opentelemetry.extensions; + +import com.google.auto.service.AutoService; +import io.opentelemetry.context.propagation.TextMapPropagator; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigurablePropagatorProvider; + +@AutoService(ConfigurablePropagatorProvider.class) +public class AppOpticsContextPropagatorProvider implements ConfigurablePropagatorProvider { + + @Override + public TextMapPropagator getPropagator() { + return new AppOpticsContextPropagator(); + } + + @Override + public String getName() { + return "appoptics"; + } +} \ No newline at end of file From 7c116710387478508b353d40dde8ed5c11f28590 Mon Sep 17 00:00:00 2001 From: jiwen624 Date: Mon, 27 Sep 2021 17:22:53 -0700 Subject: [PATCH 05/21] tracestate propagation --- .../extensions/AppOpticsPropertySource.java | 1 + .../opentelemetry/extensions/AppOpticsSampler.java | 12 ++++-------- .../extensions/TraceStateSamplingResult.java | 8 ++++++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsPropertySource.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsPropertySource.java index 3bec8853..e8a4fea6 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsPropertySource.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsPropertySource.java @@ -17,6 +17,7 @@ public class AppOpticsPropertySource implements PropertySource { PROPERTIES.put("otel.traces.exporter", "appoptics"); PROPERTIES.put("otel.traces.sampler", "appoptics"); PROPERTIES.put("otel.metrics.exporter", "none"); + PROPERTIES.put("otel.propagators", "tracecontext,baggage,appoptics"); } @Override diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java index 6d2c95ac..794b5e0c 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java @@ -15,11 +15,11 @@ import io.opentelemetry.sdk.trace.samplers.SamplingDecision; import io.opentelemetry.sdk.trace.samplers.SamplingResult; import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; -import static com.appoptics.opentelemetry.extensions.TraceStateSamplingResult.SW_TRACESTATE_KEY; -import static com.appoptics.opentelemetry.extensions.TraceStateSamplingResult.SW_SPAN_PLACEHOLDER; import java.util.List; +import static com.appoptics.opentelemetry.extensions.TraceStateSamplingResult.*; + /** * Sampler that uses trace decision logic from our joboe core (consult local and remote settings) * @@ -67,7 +67,7 @@ public SamplingResult shouldSample(Context parentContext, String traceId, String TraceDecision aoTraceDecision = TraceDecisionUtil.shouldTraceRequest(name, null, null, resource); return toOtSamplingResult(aoTraceDecision, traceState); } else { - if (swVal.equals(SW_SPAN_PLACEHOLDER)) { + if (swVal.equals(SW_SPAN_PLACEHOLDER_SAMPLED)) { return (parentSpanContext.isSampled() ? Sampler.alwaysOn() : Sampler.alwaysOff()) .shouldSample(parentContext, traceId, name, spanKind, attributes, parentLinks); } else { @@ -87,9 +87,7 @@ private boolean isValidSWTraceStateKey(String swVal) { } private String getResource(Attributes attributes) { - String resource = Util.parsePath(attributes.get(SemanticAttributes.HTTP_URL)); - //TODO consider other resource too like MQ - return resource; + return Util.parsePath(attributes.get(SemanticAttributes.HTTP_URL)); } @Override @@ -120,8 +118,6 @@ private SamplingResult toOtSamplingResult(TraceDecision aoTraceDecision, TraceSt } else { if (aoTraceDecision.isReportMetrics()) { result = METRICS_ONLY; // is this correct? probably not... - } else { - result = NOT_TRACED; } } return TraceStateSamplingResult.wrap(result); diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/TraceStateSamplingResult.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/TraceStateSamplingResult.java index 8b3966f4..70a30d32 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/TraceStateSamplingResult.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/TraceStateSamplingResult.java @@ -10,11 +10,15 @@ */ public class TraceStateSamplingResult implements SamplingResult { public static final String SW_TRACESTATE_KEY = "sw"; - public static final String SW_SPAN_PLACEHOLDER = "SWSpanIdPlaceHolder"; + public static final String SW_SPAN_PLACEHOLDER_SAMPLED = "SWSpanIdPlaceHolder-01"; + public static final String SW_SPAN_PLACEHOLDER_NOT_SAMPLED = "SWSpanIdPlaceHolder-00"; private final SamplingResult delegated; + private final String swTraceState; private TraceStateSamplingResult(SamplingResult delegated) { this.delegated = delegated; + this.swTraceState = (delegated.getDecision() == SamplingDecision.RECORD_AND_SAMPLE + ? SW_SPAN_PLACEHOLDER_SAMPLED : SW_SPAN_PLACEHOLDER_NOT_SAMPLED); } public static SamplingResult wrap(SamplingResult result) { @@ -33,6 +37,6 @@ public Attributes getAttributes() { @Override public TraceState getUpdatedTraceState(TraceState parentTraceState) { - return parentTraceState.toBuilder().put(SW_TRACESTATE_KEY, SW_SPAN_PLACEHOLDER).build(); + return parentTraceState.toBuilder().put(SW_TRACESTATE_KEY, swTraceState).build(); } } From 56d98297034a1cee77bd126eb9241d185c73e96a Mon Sep 17 00:00:00 2001 From: jiwen624 Date: Mon, 27 Sep 2021 17:52:41 -0700 Subject: [PATCH 06/21] deal with tracestate span id --- .../extensions/AppOpticsSampler.java | 20 +++++++++---------- .../extensions/TraceStateSamplingResult.java | 5 +++-- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java index 794b5e0c..0a2e0632 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java @@ -67,14 +67,9 @@ public SamplingResult shouldSample(Context parentContext, String traceId, String TraceDecision aoTraceDecision = TraceDecisionUtil.shouldTraceRequest(name, null, null, resource); return toOtSamplingResult(aoTraceDecision, traceState); } else { - if (swVal.equals(SW_SPAN_PLACEHOLDER_SAMPLED)) { - return (parentSpanContext.isSampled() ? Sampler.alwaysOn() : Sampler.alwaysOff()) - .shouldSample(parentContext, traceId, name, spanKind, attributes, parentLinks); - } else { - TraceFlags traceFlags = TraceFlags.fromByte(swVal.split("-")[1].getBytes()[1]); - return (traceFlags.isSampled() ? Sampler.alwaysOn() : Sampler.alwaysOff()) - .shouldSample(parentContext, traceId, name, spanKind, attributes, parentLinks); - } + TraceFlags traceFlags = TraceFlags.fromByte(swVal.split("-")[1].getBytes()[1]); + return TraceStateSamplingResult.wrap((traceFlags.isSampled() ? Sampler.alwaysOn() : Sampler.alwaysOff()) + .shouldSample(parentContext, traceId, name, spanKind, attributes, parentLinks)); } } @@ -82,8 +77,13 @@ private boolean isValidSWTraceStateKey(String swVal) { if (swVal == null || !swVal.contains("-")) { return false; } - String traceFlagStr = swVal.split("-")[1]; - return traceFlagStr.equals("00") || traceFlagStr.equals("01"); + String[] swTraceState = swVal.split("-"); + if (swTraceState.length != 2) { + return false; + } + + return swTraceState[0].length() == 16 + && (swTraceState[1].equals("00") || swTraceState[1].equals("01")); } private String getResource(Attributes attributes) { diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/TraceStateSamplingResult.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/TraceStateSamplingResult.java index 70a30d32..750093ac 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/TraceStateSamplingResult.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/TraceStateSamplingResult.java @@ -10,8 +10,9 @@ */ public class TraceStateSamplingResult implements SamplingResult { public static final String SW_TRACESTATE_KEY = "sw"; - public static final String SW_SPAN_PLACEHOLDER_SAMPLED = "SWSpanIdPlaceHolder-01"; - public static final String SW_SPAN_PLACEHOLDER_NOT_SAMPLED = "SWSpanIdPlaceHolder-00"; + public static final String SW_SPAN_PLACEHOLDER = "SWSpanIdPlaceHolder"; + public static final String SW_SPAN_PLACEHOLDER_SAMPLED = SW_SPAN_PLACEHOLDER + "-01"; + public static final String SW_SPAN_PLACEHOLDER_NOT_SAMPLED = SW_SPAN_PLACEHOLDER + "-00"; private final SamplingResult delegated; private final String swTraceState; From 2bb5abac9ba13c9b6f5e3a6fc2311728fc4c8a20 Mon Sep 17 00:00:00 2001 From: jiwen624 Date: Tue, 28 Sep 2021 09:58:09 -0700 Subject: [PATCH 07/21] add additional attributes --- .../extensions/AppOpticsSampler.java | 33 ++++++++++++------- .../extensions/TraceStateSamplingResult.java | 12 ++++--- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java index 0a2e0632..8b35a894 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java @@ -27,6 +27,8 @@ */ @AutoService(Sampler.class) public class AppOpticsSampler implements Sampler { + private static final String SW_UPSTREAM_VENDORS = "ao.UpstreamTraceVendors"; + private static final String SW_PARENT_ID = "ao.SWParentID"; private final SamplingResult PARENT_SAMPLED = SamplingResult.create(SamplingDecision.RECORD_AND_SAMPLE, Attributes.of( AttributeKey.booleanKey(Constants.AO_DETAILED_TRACING), true, @@ -56,21 +58,30 @@ public SamplingResult shouldSample(Context parentContext, String traceId, String SpanContext parentSpanContext = Span.fromContext(parentContext).getSpanContext(); TraceState traceState = parentSpanContext.getTraceState() != null ? parentSpanContext.getTraceState() : TraceState.getDefault(); String resource = getResource(attributes); - + SamplingResult samplingResult; + AttributesBuilder additionalAttributesBuilder = Attributes.builder(); if (!parentSpanContext.isValid() || traceState.isEmpty()) { // new sample decision, create new tracestate - return toOtSamplingResult(TraceDecisionUtil.shouldTraceRequest(name, null, null, resource), TraceState.getDefault()); + samplingResult = toOtSamplingResult(TraceDecisionUtil.shouldTraceRequest(name, null, null, resource), TraceState.getDefault()); + } else { + String swVal = traceState.get(SW_TRACESTATE_KEY); + if (!isValidSWTraceStateKey(swVal)) { + TraceDecision aoTraceDecision = TraceDecisionUtil.shouldTraceRequest(name, null, null, resource); + samplingResult = toOtSamplingResult(aoTraceDecision, traceState); + } else { + TraceFlags traceFlags = TraceFlags.fromByte(swVal.split("-")[1].getBytes()[1]); + samplingResult = (traceFlags.isSampled() ? Sampler.alwaysOn() : Sampler.alwaysOff()) + .shouldSample(parentContext, traceId, name, spanKind, attributes, parentLinks); + if (parentSpanContext.isRemote()) { + additionalAttributesBuilder.put(SW_PARENT_ID, swVal.split("-")[0]); + } + } } - String swVal = traceState.get(SW_TRACESTATE_KEY); - if (!isValidSWTraceStateKey(swVal)) { - TraceDecision aoTraceDecision = TraceDecisionUtil.shouldTraceRequest(name, null, null, resource); - return toOtSamplingResult(aoTraceDecision, traceState); - } else { - TraceFlags traceFlags = TraceFlags.fromByte(swVal.split("-")[1].getBytes()[1]); - return TraceStateSamplingResult.wrap((traceFlags.isSampled() ? Sampler.alwaysOn() : Sampler.alwaysOff()) - .shouldSample(parentContext, traceId, name, spanKind, attributes, parentLinks)); + if (!traceState.isEmpty()) { + additionalAttributesBuilder.put(SW_UPSTREAM_VENDORS, String.join(",", traceState.asMap().keySet())); } + return TraceStateSamplingResult.wrap(samplingResult, additionalAttributesBuilder.build()); } private boolean isValidSWTraceStateKey(String swVal) { @@ -120,6 +131,6 @@ private SamplingResult toOtSamplingResult(TraceDecision aoTraceDecision, TraceSt result = METRICS_ONLY; // is this correct? probably not... } } - return TraceStateSamplingResult.wrap(result); + return result; } } diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/TraceStateSamplingResult.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/TraceStateSamplingResult.java index 750093ac..d52c42a4 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/TraceStateSamplingResult.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/TraceStateSamplingResult.java @@ -6,7 +6,7 @@ import io.opentelemetry.sdk.trace.samplers.SamplingResult; /** - * A SamplingResult wrapper offering the `sw=spanIdPlaceHolder` tracestate + * A SamplingResult wrapper offering the `sw=spanIdPlaceHolder` tracestate and additional attributes */ public class TraceStateSamplingResult implements SamplingResult { public static final String SW_TRACESTATE_KEY = "sw"; @@ -15,15 +15,17 @@ public class TraceStateSamplingResult implements SamplingResult { public static final String SW_SPAN_PLACEHOLDER_NOT_SAMPLED = SW_SPAN_PLACEHOLDER + "-00"; private final SamplingResult delegated; private final String swTraceState; + private final Attributes additionalAttributes; - private TraceStateSamplingResult(SamplingResult delegated) { + private TraceStateSamplingResult(SamplingResult delegated, Attributes additionalAttributes) { this.delegated = delegated; this.swTraceState = (delegated.getDecision() == SamplingDecision.RECORD_AND_SAMPLE ? SW_SPAN_PLACEHOLDER_SAMPLED : SW_SPAN_PLACEHOLDER_NOT_SAMPLED); + this.additionalAttributes = additionalAttributes; } - public static SamplingResult wrap(SamplingResult result) { - return new TraceStateSamplingResult(result); + public static SamplingResult wrap(SamplingResult result, Attributes additionalAttributes) { + return new TraceStateSamplingResult(result, additionalAttributes); } @Override @@ -33,7 +35,7 @@ public SamplingDecision getDecision() { @Override public Attributes getAttributes() { - return delegated.getAttributes(); + return delegated.getAttributes().toBuilder().putAll(additionalAttributes).build(); } @Override From bf2059ee66da2c0967e117bcb6e506be3b1c601e Mon Sep 17 00:00:00 2001 From: jiwen624 Date: Tue, 28 Sep 2021 10:24:00 -0700 Subject: [PATCH 08/21] remove duplicate KVs --- .../extensions/AppOpticsSampler.java | 38 +++++++++---------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java index 8b35a894..ccb50807 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java @@ -60,16 +60,16 @@ public SamplingResult shouldSample(Context parentContext, String traceId, String String resource = getResource(attributes); SamplingResult samplingResult; AttributesBuilder additionalAttributesBuilder = Attributes.builder(); - if (!parentSpanContext.isValid() || traceState.isEmpty()) { - // new sample decision, create new tracestate - samplingResult = toOtSamplingResult(TraceDecisionUtil.shouldTraceRequest(name, null, null, resource), TraceState.getDefault()); + if (!parentSpanContext.isValid() || traceState.isEmpty()) { // no traceparent or tracestate, treat it as a new trace + samplingResult = toOtSamplingResult(TraceDecisionUtil.shouldTraceRequest(name, null, null, resource)); } else { String swVal = traceState.get(SW_TRACESTATE_KEY); - if (!isValidSWTraceStateKey(swVal)) { + if (!isValidSWTraceStateKey(swVal)) { // broken or non-exist sw tracestate, treat it as a new trace TraceDecision aoTraceDecision = TraceDecisionUtil.shouldTraceRequest(name, null, null, resource); - samplingResult = toOtSamplingResult(aoTraceDecision, traceState); - } else { + samplingResult = toOtSamplingResult(aoTraceDecision); + } else { // follow the upstream sw trace decision TraceFlags traceFlags = TraceFlags.fromByte(swVal.split("-")[1].getBytes()[1]); + // TODO: roll the dice! samplingResult = (traceFlags.isSampled() ? Sampler.alwaysOn() : Sampler.alwaysOff()) .shouldSample(parentContext, traceId, name, spanKind, attributes, parentLinks); if (parentSpanContext.isRemote()) { @@ -106,26 +106,22 @@ public String getDescription() { return "AppOptics Sampler"; } - private SamplingResult toOtSamplingResult(TraceDecision aoTraceDecision, TraceState traceState) { + private SamplingResult toOtSamplingResult(TraceDecision aoTraceDecision) { SamplingResult result = NOT_TRACED; if (aoTraceDecision.isSampled()) { SamplingDecision samplingDecision = SamplingDecision.RECORD_AND_SAMPLE; - AttributesBuilder builder = Attributes.builder(); - builder.put(Constants.AO_KEY_PREFIX + "SampleRate", aoTraceDecision.getTraceConfig().getSampleRate()); - builder.put(Constants.AO_KEY_PREFIX + "SampleSource", aoTraceDecision.getTraceConfig().getSampleRateSourceValue()); - builder.put(Constants.AO_KEY_PREFIX + "BucketRate", aoTraceDecision.getTraceConfig().getBucketRate(aoTraceDecision.getRequestType().getBucketType())); - builder.put(Constants.AO_KEY_PREFIX + "BucketCapacity", aoTraceDecision.getTraceConfig().getBucketCapacity(aoTraceDecision.getRequestType().getBucketType())); - builder.put(Constants.AO_KEY_PREFIX + "RequestType", aoTraceDecision.getRequestType().name()); - builder.put(Constants.AO_DETAILED_TRACING, aoTraceDecision.isSampled()); - builder.put(Constants.AO_METRICS, aoTraceDecision.isReportMetrics()); - builder.put(Constants.AO_SAMPLER, true); //mark that it has been sampled by us + AttributesBuilder aoAttributesBuilder = Attributes.builder(); + aoAttributesBuilder.put(Constants.AO_KEY_PREFIX + "SampleRate", aoTraceDecision.getTraceConfig().getSampleRate()); + aoAttributesBuilder.put(Constants.AO_KEY_PREFIX + "SampleSource", aoTraceDecision.getTraceConfig().getSampleRateSourceValue()); + aoAttributesBuilder.put(Constants.AO_KEY_PREFIX + "BucketRate", aoTraceDecision.getTraceConfig().getBucketRate(aoTraceDecision.getRequestType().getBucketType())); + aoAttributesBuilder.put(Constants.AO_KEY_PREFIX + "BucketCapacity", aoTraceDecision.getTraceConfig().getBucketCapacity(aoTraceDecision.getRequestType().getBucketType())); + aoAttributesBuilder.put(Constants.AO_KEY_PREFIX + "RequestType", aoTraceDecision.getRequestType().name()); + aoAttributesBuilder.put(Constants.AO_DETAILED_TRACING, aoTraceDecision.isSampled()); + aoAttributesBuilder.put(Constants.AO_METRICS, aoTraceDecision.isReportMetrics()); + aoAttributesBuilder.put(Constants.AO_SAMPLER, true); //mark that it has been sampled by us - if (!traceState.isEmpty()) { - builder.put(Constants.AO_KEY_PREFIX + "UpstreamTraceVendors", String.join(",", traceState.asMap().keySet())); - } - Attributes attributes = builder.build(); - result = SamplingResult.create(samplingDecision, attributes); + result = SamplingResult.create(samplingDecision, aoAttributesBuilder.build()); } else { if (aoTraceDecision.isReportMetrics()) { result = METRICS_ONLY; // is this correct? probably not... From 3567d9236524eefcba78ae12f7f45a55859ded7b Mon Sep 17 00:00:00 2001 From: jiwen624 Date: Tue, 28 Sep 2021 11:20:28 -0700 Subject: [PATCH 09/21] remove redundant code from xtrace id convert method --- .../appoptics/opentelemetry/core/Util.java | 14 ++--------- .../extensions/AppOpticsSampler.java | 25 ++++++++++++++----- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/core-bootstrap/src/main/java/com/appoptics/opentelemetry/core/Util.java b/core-bootstrap/src/main/java/com/appoptics/opentelemetry/core/Util.java index 68abe1a3..382c29b2 100644 --- a/core-bootstrap/src/main/java/com/appoptics/opentelemetry/core/Util.java +++ b/core-bootstrap/src/main/java/com/appoptics/opentelemetry/core/Util.java @@ -29,17 +29,7 @@ public class Util { * @return */ public static String buildXTraceId(SpanContext context) { - String aoId = context.getTraceState().get(APPOPTICS_TRACE_STATE_KEY); - - String traceId = context.getTraceId(); - if (aoId != null) { - try { - traceId = new Metadata(aoId).taskHexString(); - } catch (OboeException e) { - logger.warn("Failed to convert appoptics trace state [" + aoId + "] to OT trace id", e); - } - } - return buildXTraceId(traceId, context.getSpanId(), context.isSampled()); + return buildXTraceId(context.getTraceId(), context.getSpanId(), context.isSampled()); } /** @@ -67,7 +57,7 @@ public static Metadata buildSpanExitMetadata(SpanContext context) { * @param isSampled * @return */ - public static String buildXTraceId(String traceId, String spanId, boolean isSampled) { + private static String buildXTraceId(String traceId, String spanId, boolean isSampled) { final String HEADER = "2B"; String hexString = HEADER + Strings.padEnd(traceId, Constants.MAX_TASK_ID_LEN * 2, '0') + diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java index ccb50807..23ab0ca0 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java @@ -17,6 +17,7 @@ import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; import java.util.List; +import java.util.stream.Collectors; import static com.appoptics.opentelemetry.extensions.TraceStateSamplingResult.*; @@ -69,17 +70,29 @@ public SamplingResult shouldSample(Context parentContext, String traceId, String samplingResult = toOtSamplingResult(aoTraceDecision); } else { // follow the upstream sw trace decision TraceFlags traceFlags = TraceFlags.fromByte(swVal.split("-")[1].getBytes()[1]); - // TODO: roll the dice! - samplingResult = (traceFlags.isSampled() ? Sampler.alwaysOn() : Sampler.alwaysOff()) - .shouldSample(parentContext, traceId, name, spanKind, attributes, parentLinks); + if (parentSpanContext.isRemote()) { // root span needs to roll the dice + String xTraceId = Util.buildXTraceId(parentSpanContext); + TraceDecision aoTraceDecision = TraceDecisionUtil.shouldTraceRequest(name, xTraceId, null, resource); + samplingResult = toOtSamplingResult(aoTraceDecision); + } else { // non-root span just follows the parent span's decision + samplingResult = (traceFlags.isSampled() ? Sampler.alwaysOn() : Sampler.alwaysOff()) + .shouldSample(parentContext, traceId, name, spanKind, attributes, parentLinks); + } if (parentSpanContext.isRemote()) { additionalAttributesBuilder.put(SW_PARENT_ID, swVal.split("-")[0]); } } } - if (!traceState.isEmpty()) { - additionalAttributesBuilder.put(SW_UPSTREAM_VENDORS, String.join(",", traceState.asMap().keySet())); + if (parentSpanContext.isRemote() && !traceState.isEmpty()) { + String upstreamVendors = traceState.asMap() + .keySet() + .stream() + .filter(key->!key.equals(SW_TRACESTATE_KEY)) + .collect(Collectors.joining(",")); + if (!upstreamVendors.isEmpty()) { + additionalAttributesBuilder.put(SW_UPSTREAM_VENDORS, upstreamVendors); + } } return TraceStateSamplingResult.wrap(samplingResult, additionalAttributesBuilder.build()); } @@ -93,7 +106,7 @@ private boolean isValidSWTraceStateKey(String swVal) { return false; } - return swTraceState[0].length() == 16 + return (swTraceState[0].equals(SW_SPAN_PLACEHOLDER) || swTraceState[0].length() == 16) // 16 is the HEXLENGTH of the Otel trace id && (swTraceState[1].equals("00") || swTraceState[1].equals("01")); } From 383b993e9b5b18f1ad0930da65911acfbabb18de Mon Sep 17 00:00:00 2001 From: jiwen624 Date: Tue, 28 Sep 2021 12:57:53 -0700 Subject: [PATCH 10/21] trigger trace support --- .../AppOpticsContextPropagator.java | 24 ++++++++++++++++++- .../extensions/AppOpticsSampler.java | 9 ++++--- .../extensions/TriggerTraceContextKey.java | 16 +++++++++++++ 3 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 custom/src/main/java/com/appoptics/opentelemetry/extensions/TriggerTraceContextKey.java diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagator.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagator.java index 2973d137..9a30577a 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagator.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagator.java @@ -3,6 +3,8 @@ import com.appoptics.opentelemetry.core.Util; import com.tracelytics.instrumentation.HeaderConstants; import com.tracelytics.joboe.Metadata; +import com.tracelytics.joboe.XTraceHeader; +import com.tracelytics.joboe.XTraceOptions; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.api.trace.TraceState; @@ -23,6 +25,8 @@ public class AppOpticsContextPropagator implements TextMapPropagator { private static final String TRACE_STATE_APPOPTICS_KEY = "sw"; static final String TRACE_PARENT = "traceparent"; static final String TRACE_STATE = "tracestate"; + static final String XTRACE_OPTIONS = "xtrace-options"; + static final String XTRACE_OPTIONS_SIGNATURE = "xtrace-options-signature"; private static final List FIELDS = Collections.unmodifiableList(Arrays.asList(TRACE_PARENT, TRACE_STATE, HeaderConstants.XTRACE_HEADER)); private static final int TRACESTATE_MAX_SIZE = 512; @@ -64,6 +68,15 @@ public void inject(Context context, @Nullable C carrier, TextMapSetter se } }); setter.set(carrier, TRACE_STATE, traceStateBuilder.toString()); + + String traceOptions = context.get(TriggerTraceContextKey.XTRACE_OPTIONS); + String traceOptionsSignature = context.get(TriggerTraceContextKey.XTRACE_OPTIONS_SIGNATURE); + if (traceOptions != null) { + setter.set(carrier, XTRACE_OPTIONS, traceOptions); + } + if (traceOptionsSignature != null) { + setter.set(carrier, XTRACE_OPTIONS_SIGNATURE, traceOptionsSignature); + } } /** @@ -77,7 +90,16 @@ public void inject(Context context, @Nullable C carrier, TextMapSetter se */ @Override public Context extract(Context context, @Nullable C carrier, TextMapGetter getter) { - // do nothing + String traceOptions = getter.get(carrier, XTRACE_OPTIONS); + String traceOptionsSignature = getter.get(carrier, XTRACE_OPTIONS_SIGNATURE); + XTraceOptions xTraceOptions = XTraceOptions.getXTraceOptions(traceOptions, traceOptionsSignature); + if (xTraceOptions != null) { + context = context.with(TriggerTraceContextKey.KEY, xTraceOptions); + context = context.with(TriggerTraceContextKey.XTRACE_OPTIONS, traceOptions); + if (traceOptionsSignature != null) { + context = context.with(TriggerTraceContextKey.XTRACE_OPTIONS_SIGNATURE, traceOptionsSignature); + } + } return context; } } \ No newline at end of file diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java index 23ab0ca0..80edf233 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java @@ -5,6 +5,7 @@ import com.google.auto.service.AutoService; import com.tracelytics.joboe.TraceDecision; import com.tracelytics.joboe.TraceDecisionUtil; +import com.tracelytics.joboe.XTraceOptions; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; @@ -61,18 +62,20 @@ public SamplingResult shouldSample(Context parentContext, String traceId, String String resource = getResource(attributes); SamplingResult samplingResult; AttributesBuilder additionalAttributesBuilder = Attributes.builder(); + XTraceOptions xTraceOptions = parentContext.get(TriggerTraceContextKey.KEY); + if (!parentSpanContext.isValid() || traceState.isEmpty()) { // no traceparent or tracestate, treat it as a new trace - samplingResult = toOtSamplingResult(TraceDecisionUtil.shouldTraceRequest(name, null, null, resource)); + samplingResult = toOtSamplingResult(TraceDecisionUtil.shouldTraceRequest(name, null, xTraceOptions, resource)); } else { String swVal = traceState.get(SW_TRACESTATE_KEY); if (!isValidSWTraceStateKey(swVal)) { // broken or non-exist sw tracestate, treat it as a new trace - TraceDecision aoTraceDecision = TraceDecisionUtil.shouldTraceRequest(name, null, null, resource); + TraceDecision aoTraceDecision = TraceDecisionUtil.shouldTraceRequest(name, null, xTraceOptions, resource); samplingResult = toOtSamplingResult(aoTraceDecision); } else { // follow the upstream sw trace decision TraceFlags traceFlags = TraceFlags.fromByte(swVal.split("-")[1].getBytes()[1]); if (parentSpanContext.isRemote()) { // root span needs to roll the dice String xTraceId = Util.buildXTraceId(parentSpanContext); - TraceDecision aoTraceDecision = TraceDecisionUtil.shouldTraceRequest(name, xTraceId, null, resource); + TraceDecision aoTraceDecision = TraceDecisionUtil.shouldTraceRequest(name, xTraceId, xTraceOptions, resource); samplingResult = toOtSamplingResult(aoTraceDecision); } else { // non-root span just follows the parent span's decision samplingResult = (traceFlags.isSampled() ? Sampler.alwaysOn() : Sampler.alwaysOff()) diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/TriggerTraceContextKey.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/TriggerTraceContextKey.java new file mode 100644 index 00000000..5a35b108 --- /dev/null +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/TriggerTraceContextKey.java @@ -0,0 +1,16 @@ +package com.appoptics.opentelemetry.extensions; + +import com.tracelytics.joboe.XTraceOptions; +import io.opentelemetry.context.ContextKey; + +import javax.annotation.concurrent.Immutable; + +@Immutable +final class TriggerTraceContextKey { + static final ContextKey KEY = ContextKey.named("sw-trigger-trace-key"); + static final ContextKey XTRACE_OPTIONS = ContextKey.named("xtrace-options"); + static final ContextKey XTRACE_OPTIONS_SIGNATURE = ContextKey.named("xtrace-options-signature"); + + private TriggerTraceContextKey() {} +} + From e574161665d32d7604ad8ea4196ccba5299f15a6 Mon Sep 17 00:00:00 2001 From: jiwen624 Date: Tue, 28 Sep 2021 14:32:50 -0700 Subject: [PATCH 11/21] clean up code --- .../extensions/AppOpticsContextPropagator.java | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagator.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagator.java index 9a30577a..8b3f4230 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagator.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagator.java @@ -1,14 +1,10 @@ package com.appoptics.opentelemetry.extensions; -import com.appoptics.opentelemetry.core.Util; import com.tracelytics.instrumentation.HeaderConstants; -import com.tracelytics.joboe.Metadata; -import com.tracelytics.joboe.XTraceHeader; import com.tracelytics.joboe.XTraceOptions; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.api.trace.TraceState; -import io.opentelemetry.api.trace.TraceStateBuilder; import io.opentelemetry.context.Context; import io.opentelemetry.context.propagation.TextMapGetter; import io.opentelemetry.context.propagation.TextMapPropagator; @@ -25,8 +21,8 @@ public class AppOpticsContextPropagator implements TextMapPropagator { private static final String TRACE_STATE_APPOPTICS_KEY = "sw"; static final String TRACE_PARENT = "traceparent"; static final String TRACE_STATE = "tracestate"; - static final String XTRACE_OPTIONS = "xtrace-options"; - static final String XTRACE_OPTIONS_SIGNATURE = "xtrace-options-signature"; + static final String X_TRACE_OPTIONS = "X-Trace-Options"; + static final String X_TRACE_OPTIONS_SIGNATURE = "X-Trace-Options-Signature"; private static final List FIELDS = Collections.unmodifiableList(Arrays.asList(TRACE_PARENT, TRACE_STATE, HeaderConstants.XTRACE_HEADER)); private static final int TRACESTATE_MAX_SIZE = 512; @@ -72,10 +68,10 @@ public void inject(Context context, @Nullable C carrier, TextMapSetter se String traceOptions = context.get(TriggerTraceContextKey.XTRACE_OPTIONS); String traceOptionsSignature = context.get(TriggerTraceContextKey.XTRACE_OPTIONS_SIGNATURE); if (traceOptions != null) { - setter.set(carrier, XTRACE_OPTIONS, traceOptions); + setter.set(carrier, X_TRACE_OPTIONS, traceOptions); } if (traceOptionsSignature != null) { - setter.set(carrier, XTRACE_OPTIONS_SIGNATURE, traceOptionsSignature); + setter.set(carrier, X_TRACE_OPTIONS_SIGNATURE, traceOptionsSignature); } } @@ -90,8 +86,8 @@ public void inject(Context context, @Nullable C carrier, TextMapSetter se */ @Override public Context extract(Context context, @Nullable C carrier, TextMapGetter getter) { - String traceOptions = getter.get(carrier, XTRACE_OPTIONS); - String traceOptionsSignature = getter.get(carrier, XTRACE_OPTIONS_SIGNATURE); + String traceOptions = getter.get(carrier, X_TRACE_OPTIONS); + String traceOptionsSignature = getter.get(carrier, X_TRACE_OPTIONS_SIGNATURE); XTraceOptions xTraceOptions = XTraceOptions.getXTraceOptions(traceOptions, traceOptionsSignature); if (xTraceOptions != null) { context = context.with(TriggerTraceContextKey.KEY, xTraceOptions); From c10dee7af727bc1822be26d7df7afb6881abf00c Mon Sep 17 00:00:00 2001 From: jiwen624 Date: Tue, 28 Sep 2021 16:03:57 -0700 Subject: [PATCH 12/21] report unknown parent id --- .../opentelemetry/extensions/AppOpticsSampler.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java index 80edf233..02a61aa8 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java @@ -64,13 +64,14 @@ public SamplingResult shouldSample(Context parentContext, String traceId, String AttributesBuilder additionalAttributesBuilder = Attributes.builder(); XTraceOptions xTraceOptions = parentContext.get(TriggerTraceContextKey.KEY); - if (!parentSpanContext.isValid() || traceState.isEmpty()) { // no traceparent or tracestate, treat it as a new trace + if (!parentSpanContext.isValid()) { // no valid traceparent, it is a new trace samplingResult = toOtSamplingResult(TraceDecisionUtil.shouldTraceRequest(name, null, xTraceOptions, resource)); } else { String swVal = traceState.get(SW_TRACESTATE_KEY); + String parentId; if (!isValidSWTraceStateKey(swVal)) { // broken or non-exist sw tracestate, treat it as a new trace - TraceDecision aoTraceDecision = TraceDecisionUtil.shouldTraceRequest(name, null, xTraceOptions, resource); - samplingResult = toOtSamplingResult(aoTraceDecision); + samplingResult = toOtSamplingResult(TraceDecisionUtil.shouldTraceRequest(name, null, xTraceOptions, resource)); + parentId = "unknown"; } else { // follow the upstream sw trace decision TraceFlags traceFlags = TraceFlags.fromByte(swVal.split("-")[1].getBytes()[1]); if (parentSpanContext.isRemote()) { // root span needs to roll the dice @@ -81,9 +82,10 @@ public SamplingResult shouldSample(Context parentContext, String traceId, String samplingResult = (traceFlags.isSampled() ? Sampler.alwaysOn() : Sampler.alwaysOff()) .shouldSample(parentContext, traceId, name, spanKind, attributes, parentLinks); } - if (parentSpanContext.isRemote()) { - additionalAttributesBuilder.put(SW_PARENT_ID, swVal.split("-")[0]); - } + parentId = swVal.split("-")[0]; + } + if (parentSpanContext.isRemote()) { + additionalAttributesBuilder.put(SW_PARENT_ID, parentId); } } From 070c44dee8be2a5a7cc3e3c578163b5c092a2ceb Mon Sep 17 00:00:00 2001 From: jiwen624 Date: Thu, 30 Sep 2021 11:32:32 -0700 Subject: [PATCH 13/21] do not report unknown SWParentID --- .../appoptics/opentelemetry/extensions/AppOpticsSampler.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java index 02a61aa8..b7a95423 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java @@ -68,10 +68,9 @@ public SamplingResult shouldSample(Context parentContext, String traceId, String samplingResult = toOtSamplingResult(TraceDecisionUtil.shouldTraceRequest(name, null, xTraceOptions, resource)); } else { String swVal = traceState.get(SW_TRACESTATE_KEY); - String parentId; + String parentId = null; if (!isValidSWTraceStateKey(swVal)) { // broken or non-exist sw tracestate, treat it as a new trace samplingResult = toOtSamplingResult(TraceDecisionUtil.shouldTraceRequest(name, null, xTraceOptions, resource)); - parentId = "unknown"; } else { // follow the upstream sw trace decision TraceFlags traceFlags = TraceFlags.fromByte(swVal.split("-")[1].getBytes()[1]); if (parentSpanContext.isRemote()) { // root span needs to roll the dice @@ -84,7 +83,7 @@ public SamplingResult shouldSample(Context parentContext, String traceId, String } parentId = swVal.split("-")[0]; } - if (parentSpanContext.isRemote()) { + if (parentSpanContext.isRemote() && parentId != null) { additionalAttributesBuilder.put(SW_PARENT_ID, parentId); } } From 6e2a88ecd383fe60644aa3df54c713a0713ec322 Mon Sep 17 00:00:00 2001 From: jiwen624 Date: Tue, 5 Oct 2021 10:41:39 -0700 Subject: [PATCH 14/21] AO exporter uses W3C context format --- .../appoptics/api/ext/impl/TraceHandler.java | 2 +- .../appoptics/opentelemetry/core/Util.java | 86 ++++--------------- .../extensions/AppOpticsSampler.java | 2 +- .../extensions/AppOpticsSpanExporter.java | 8 +- 4 files changed, 24 insertions(+), 74 deletions(-) diff --git a/appoptics-opentelemetry-sdk/src/main/java/com/appoptics/api/ext/impl/TraceHandler.java b/appoptics-opentelemetry-sdk/src/main/java/com/appoptics/api/ext/impl/TraceHandler.java index 3a115579..79d8a642 100644 --- a/appoptics-opentelemetry-sdk/src/main/java/com/appoptics/api/ext/impl/TraceHandler.java +++ b/appoptics-opentelemetry-sdk/src/main/java/com/appoptics/api/ext/impl/TraceHandler.java @@ -184,7 +184,7 @@ public void logException(Throwable error) { * {@inheritDoc} */ public String getCurrentXTraceID() { - return Util.buildXTraceId(Span.current().getSpanContext()); + return Util.W3CContextToHexString(Span.current().getSpanContext()); } @Override diff --git a/core-bootstrap/src/main/java/com/appoptics/opentelemetry/core/Util.java b/core-bootstrap/src/main/java/com/appoptics/opentelemetry/core/Util.java index 382c29b2..e814b252 100644 --- a/core-bootstrap/src/main/java/com/appoptics/opentelemetry/core/Util.java +++ b/core-bootstrap/src/main/java/com/appoptics/opentelemetry/core/Util.java @@ -1,9 +1,7 @@ package com.appoptics.opentelemetry.core; -import com.tracelytics.ext.google.common.base.Strings; import com.tracelytics.joboe.Metadata; import com.tracelytics.joboe.OboeException; -import com.tracelytics.joboe.Constants; import io.opentelemetry.api.trace.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,19 +15,22 @@ import static com.appoptics.opentelemetry.core.Constants.*; public class Util { - private static Logger logger = LoggerFactory.getLogger(Util.class.getName()); - private static String APPOPTICS_TRACE_STATE_KEY = "appoptics"; - private static byte EXIT_OP_ID_MASK = 0xf; + private static final Logger logger = LoggerFactory.getLogger(Util.class.getName()); + private static final byte EXIT_OP_ID_MASK = 0xf; - /** - * Build an AO x-trace ID from OT span context. Take note that we will have to check the value of `appoptics` in - * `tracestate` first as AO x-trace ID has longer task ID than its OT counterpart traceid. More details in - * https://github.com/librato/joboe/issues/1079 + /** Converts an OpenTelemetry span context to a hex string. + * * @param context * @return */ - public static String buildXTraceId(SpanContext context) { - return buildXTraceId(context.getTraceId(), context.getSpanId(), context.isSampled()); + public static String W3CContextToHexString(SpanContext context) { + return Metadata.CURRENT_VERSION_HEXSTRING + + Metadata.HEXSTRING_DELIMETER + + context.getTraceId() + + Metadata.HEXSTRING_DELIMETER + + context.getSpanId() + + Metadata.HEXSTRING_DELIMETER + + context.getTraceFlags().asHex(); } /** @@ -49,25 +50,6 @@ public static Metadata buildSpanExitMetadata(SpanContext context) { return exitContext; } - /** - * Builds an AO x-trace ID with OT trace id and span id - * - * @param traceId - * @param spanId - * @param isSampled - * @return - */ - private static String buildXTraceId(String traceId, String spanId, boolean isSampled) { - final String HEADER = "2B"; - String hexString = HEADER + - Strings.padEnd(traceId, Constants.MAX_TASK_ID_LEN * 2, '0') + - Strings.padEnd(spanId, Constants.MAX_OP_ID_LEN * 2, '0'); - hexString += isSampled ? "01" : "00"; - - - return hexString.toUpperCase(); - } - /** * Builds an AO metadata with OT span context * @@ -76,15 +58,12 @@ private static String buildXTraceId(String traceId, String spanId, boolean isSam */ public static Metadata buildMetadata(SpanContext context) { try { - Metadata metadata = new Metadata(buildXTraceId(context)); - metadata.setTraceId(toTraceId(context.getTraceIdBytes())); - return metadata; + return new Metadata(W3CContextToHexString(context)); } catch (OboeException e) { return null; } } - /** * Generate a deterministic AO trace id from the OT trace id bytes * @param traceIdBytes @@ -106,34 +85,18 @@ public static Long toTraceId(byte[] traceIdBytes) { * @return */ public static SpanContext toSpanContext(String xTrace, boolean isRemote) { - W3TraceContextHolder w3TraceContext = toW3TraceContext(xTrace); - return isRemote - ? SpanContext.createFromRemoteParent(w3TraceContext.traceId, w3TraceContext.spanId, w3TraceContext.traceFlags, TraceState.getDefault()) - : SpanContext.create(w3TraceContext.traceId, w3TraceContext.spanId, w3TraceContext.traceFlags, TraceState.getDefault()); - } - - /** - * Builds a w3c formatted trace context with AO x-trace ID - * @param xTrace - * @return - */ - public static W3TraceContextHolder toW3TraceContext(String xTrace) { - Metadata metadata; + Metadata metadata = null; try { metadata = new Metadata(xTrace); } catch (OboeException e) { - e.printStackTrace(); - return null; + return SpanContext.getInvalid(); } - String w3TraceId = TraceId.fromBytes(metadata.getTaskID()); - String w3SpanId = SpanId.fromBytes(metadata.getOpID()); - TraceFlags w3TraceFlags = metadata.isSampled() ? TraceFlags.getSampled() : TraceFlags.getDefault(); - - return new W3TraceContextHolder(w3TraceId, w3SpanId, w3TraceFlags); + return isRemote + ? SpanContext.createFromRemoteParent(metadata.taskHexString(), metadata.opHexString(), TraceFlags.fromByte(metadata.getFlags()), TraceState.getDefault()) + : SpanContext.create(metadata.taskHexString(), metadata.opHexString(), TraceFlags.fromByte(metadata.getFlags()), TraceState.getDefault()); } - public static String parsePath(String url) { if (url != null) { try { @@ -145,19 +108,6 @@ public static String parsePath(String url) { return null; } - - public static class W3TraceContextHolder { - public final String traceId; - public final String spanId; - public final TraceFlags traceFlags; - - W3TraceContextHolder(String traceId, String spanId, TraceFlags traceFlags) { - this.traceId = traceId; - this.spanId = spanId; - this.traceFlags = traceFlags; - } - } - public static Map keyValuePairsToMap(Object... keyValuePairs) { Map map = new HashMap(); if (keyValuePairs.length % 2 == 1) { diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java index b7a95423..f94c15e3 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java @@ -74,7 +74,7 @@ public SamplingResult shouldSample(Context parentContext, String traceId, String } else { // follow the upstream sw trace decision TraceFlags traceFlags = TraceFlags.fromByte(swVal.split("-")[1].getBytes()[1]); if (parentSpanContext.isRemote()) { // root span needs to roll the dice - String xTraceId = Util.buildXTraceId(parentSpanContext); + String xTraceId = Util.W3CContextToHexString(parentSpanContext); TraceDecision aoTraceDecision = TraceDecisionUtil.shouldTraceRequest(name, xTraceId, xTraceOptions, resource); samplingResult = toOtSamplingResult(aoTraceDecision); } else { // non-root span just follows the parent span's decision diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSpanExporter.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSpanExporter.java index 0384d57f..b179b04a 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSpanExporter.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSpanExporter.java @@ -37,17 +37,17 @@ public CompletableResultCode export(Collection collection) { parentMetadata = Util.buildMetadata(spanData.getParentSpanContext()); } - String entryXTraceId = Util.buildXTraceId(spanData.getSpanContext()); + String w3cContext = Util.W3CContextToHexString(spanData.getSpanContext()); String spanName = spanData.getKind().toString() + "." + spanData.getName(); - Metadata spanMetadata = new Metadata(entryXTraceId); + Metadata spanMetadata = new Metadata(w3cContext); spanMetadata.randomizeOpID(); //get around the metadata logic, this op id is not used Event entryEvent; if (parentMetadata != null) { - entryEvent = new EventImpl(parentMetadata, entryXTraceId, true); + entryEvent = new EventImpl(parentMetadata, w3cContext, true); } else { - entryEvent = new EventImpl(null, entryXTraceId, false); + entryEvent = new EventImpl(null, w3cContext, false); } if (!spanData.getParentSpanContext().isValid() || spanData.getParentSpanContext().isRemote()) { //then a root span of this service From 5c63e641b17341ecbbee168e02a8fd7acb26f4dd Mon Sep 17 00:00:00 2001 From: jiwen624 Date: Wed, 6 Oct 2021 09:53:11 -0700 Subject: [PATCH 15/21] add tracestate as attribute --- .../extensions/AppOpticsContextPropagator.java | 5 +++++ .../opentelemetry/extensions/AppOpticsSampler.java | 12 ++---------- .../opentelemetry/extensions/TraceStateKey.java | 12 ++++++++++++ 3 files changed, 19 insertions(+), 10 deletions(-) create mode 100644 custom/src/main/java/com/appoptics/opentelemetry/extensions/TraceStateKey.java diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagator.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagator.java index 8b3f4230..c6a301c4 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagator.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagator.java @@ -96,6 +96,11 @@ public Context extract(Context context, @Nullable C carrier, TextMapGetter!key.equals(SW_TRACESTATE_KEY)) - .collect(Collectors.joining(",")); - if (!upstreamVendors.isEmpty()) { - additionalAttributesBuilder.put(SW_UPSTREAM_VENDORS, upstreamVendors); - } + additionalAttributesBuilder.put(SW_UPSTREAM_TRACESTATE, parentContext.get(TraceStateKey.KEY)); } return TraceStateSamplingResult.wrap(samplingResult, additionalAttributesBuilder.build()); } diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/TraceStateKey.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/TraceStateKey.java new file mode 100644 index 00000000..111c6f4e --- /dev/null +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/TraceStateKey.java @@ -0,0 +1,12 @@ +package com.appoptics.opentelemetry.extensions; + +import com.tracelytics.joboe.XTraceOptions; +import io.opentelemetry.context.ContextKey; + +import javax.annotation.concurrent.Immutable; + +@Immutable +public class TraceStateKey { + static final ContextKey KEY = ContextKey.named("tracestate-original-value"); + +} From b2c2efb45f09a2533bf082ae3995e46cff6dc2a8 Mon Sep 17 00:00:00 2001 From: jiwen624 Date: Wed, 6 Oct 2021 12:31:40 -0700 Subject: [PATCH 16/21] update attributes key name --- .../opentelemetry/core/Constants.java | 13 ++-- .../appoptics/opentelemetry/core/Util.java | 8 +-- .../AppOpticsContextPropagator.java | 62 +++++++++++++++---- .../AppOpticsInboundMetricsSpanProcessor.java | 2 +- .../AppOpticsProfilingSpanProcessor.java | 4 +- .../extensions/AppOpticsSampler.java | 51 +++++++-------- .../extensions/AppOpticsSpanExporter.java | 8 +-- .../annotation/AppOpticsAnnotationTracer.java | 17 +++-- .../instrumentation/AoStatementTracer.java | 2 +- 9 files changed, 103 insertions(+), 64 deletions(-) diff --git a/core-bootstrap/src/main/java/com/appoptics/opentelemetry/core/Constants.java b/core-bootstrap/src/main/java/com/appoptics/opentelemetry/core/Constants.java index 765ad20a..de4beb23 100644 --- a/core-bootstrap/src/main/java/com/appoptics/opentelemetry/core/Constants.java +++ b/core-bootstrap/src/main/java/com/appoptics/opentelemetry/core/Constants.java @@ -1,10 +1,13 @@ package com.appoptics.opentelemetry.core; public interface Constants { - String AO_INTERNAL_ATTRIBUTE_PREFIX = "ao.internal."; - String AO_DETAILED_TRACING = AO_INTERNAL_ATTRIBUTE_PREFIX + "detailedTracing"; - String AO_METRICS = AO_INTERNAL_ATTRIBUTE_PREFIX + "metrics"; - String AO_SAMPLER = AO_INTERNAL_ATTRIBUTE_PREFIX + "sampler"; - String AO_KEY_PREFIX = "ao."; + String SW_KEY_PREFIX = "sw."; String OT_KEY_PREFIX = "ot."; + String SW_INTERNAL_ATTRIBUTE_PREFIX = SW_KEY_PREFIX + "internal."; + String SW_DETAILED_TRACING = SW_INTERNAL_ATTRIBUTE_PREFIX + "detailedTracing"; + String SW_METRICS = SW_INTERNAL_ATTRIBUTE_PREFIX + "metrics"; + String SW_SAMPLER = SW_INTERNAL_ATTRIBUTE_PREFIX + "sampler"; + String W3C_KEY_PREFIX = "w3c."; + String SW_UPSTREAM_TRACESTATE = SW_KEY_PREFIX + W3C_KEY_PREFIX + "tracestate"; + String SW_PARENT_ID = SW_KEY_PREFIX + "parentid"; } diff --git a/core-bootstrap/src/main/java/com/appoptics/opentelemetry/core/Util.java b/core-bootstrap/src/main/java/com/appoptics/opentelemetry/core/Util.java index e814b252..b62301ee 100644 --- a/core-bootstrap/src/main/java/com/appoptics/opentelemetry/core/Util.java +++ b/core-bootstrap/src/main/java/com/appoptics/opentelemetry/core/Util.java @@ -138,8 +138,8 @@ public static void setSpanAttributes(Span span, Map attributes) { for (Map.Entry entry : attributes.entrySet()) { Object value = entry.getValue(); String key = entry.getKey(); - if (!key.startsWith(AO_KEY_PREFIX)) { - key = AO_KEY_PREFIX + key; + if (!key.startsWith(SW_KEY_PREFIX)) { + key = SW_KEY_PREFIX + key; } if (value instanceof String) { span.setAttribute(key, (String) value); @@ -169,8 +169,8 @@ public static void setSpanAttributes(SpanBuilder spanBuilder, Map att for (Map.Entry entry : attributes.entrySet()) { Object value = entry.getValue(); String key = entry.getKey(); - if (!key.startsWith(AO_KEY_PREFIX)) { - key = AO_KEY_PREFIX + key; + if (!key.startsWith(SW_KEY_PREFIX)) { + key = SW_KEY_PREFIX + key; } if (value instanceof String) { diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagator.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagator.java index c6a301c4..648421a1 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagator.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagator.java @@ -15,6 +15,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; public class AppOpticsContextPropagator implements TextMapPropagator { @@ -27,8 +28,9 @@ public class AppOpticsContextPropagator implements TextMapPropagator { Collections.unmodifiableList(Arrays.asList(TRACE_PARENT, TRACE_STATE, HeaderConstants.XTRACE_HEADER)); private static final int TRACESTATE_MAX_SIZE = 512; private static final int TRACESTATE_MAX_MEMBERS = 32; - private static final char TRACESTATE_KEY_VALUE_DELIMITER = '='; - private static final char TRACESTATE_ENTRY_DELIMITER = ','; + private static final int OVERSIZE_ENTRY_LENGTH = 129; + private static final String TRACESTATE_KEY_VALUE_DELIMITER = "="; + private static final String TRACESTATE_ENTRY_DELIMITER = ","; @Override public Collection fields() { @@ -52,18 +54,8 @@ public void inject(Context context, @Nullable C carrier, TextMapSetter se //update trace state too: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#tracestate //https://www.w3.org/TR/trace-context/#mutating-the-tracestate-field TraceState traceState = spanContext.getTraceState(); - StringBuilder traceStateBuilder = new StringBuilder(TRACESTATE_MAX_SIZE); String swTraceStateValue = spanContext.getSpanId() + "-" + (spanContext.isSampled() ? "01" : "00"); - traceStateBuilder.append(TRACE_STATE_APPOPTICS_KEY).append(TRACESTATE_KEY_VALUE_DELIMITER).append(swTraceStateValue); - AtomicInteger count = new AtomicInteger(1); - traceState.forEach( - (key, value) -> { - if (!TRACE_STATE_APPOPTICS_KEY.equals(key) && count.getAndIncrement() <= TRACESTATE_MAX_MEMBERS) { - traceStateBuilder.append(TRACESTATE_ENTRY_DELIMITER); - traceStateBuilder.append(key).append(TRACESTATE_KEY_VALUE_DELIMITER).append(value); - } - }); - setter.set(carrier, TRACE_STATE, traceStateBuilder.toString()); + setter.set(carrier, TRACE_STATE, updateTraceState(traceState, swTraceStateValue)); String traceOptions = context.get(TriggerTraceContextKey.XTRACE_OPTIONS); String traceOptionsSignature = context.get(TriggerTraceContextKey.XTRACE_OPTIONS_SIGNATURE); @@ -75,6 +67,50 @@ public void inject(Context context, @Nullable C carrier, TextMapSetter se } } + /** + * Update tracestate with the new SW tracestate value and do some truncation if needed. + * @param traceState + * @param swTraceStateValue + * @return + */ + private String updateTraceState(TraceState traceState, String swTraceStateValue) { + StringBuilder traceStateBuilder = new StringBuilder(TRACESTATE_MAX_SIZE); + traceStateBuilder.append(TRACE_STATE_APPOPTICS_KEY).append(TRACESTATE_KEY_VALUE_DELIMITER).append(swTraceStateValue); + AtomicInteger count = new AtomicInteger(1); + + // calculate current length of the tracestate + AtomicInteger traceStateLength = new AtomicInteger(0); + traceState.forEach( + (key, value) -> { + if (!TRACE_STATE_APPOPTICS_KEY.equals(key)) { + traceStateLength.addAndGet(key.length()); + traceStateLength.addAndGet(TRACESTATE_KEY_VALUE_DELIMITER.length()); + traceStateLength.addAndGet(value.length()); + traceStateLength.addAndGet(TRACESTATE_ENTRY_DELIMITER.length()); + } + } + ); + + AtomicBoolean truncateLargeEntry = new AtomicBoolean(traceStateLength.get() + traceStateBuilder.length() > TRACESTATE_MAX_SIZE); + traceState.forEach( + (key, value) -> { + if (!TRACE_STATE_APPOPTICS_KEY.equals(key) + && count.get() < TRACESTATE_MAX_MEMBERS + && traceStateBuilder.length() + TRACESTATE_ENTRY_DELIMITER.length() + key.length() + TRACESTATE_KEY_VALUE_DELIMITER.length() + value.length() <= TRACESTATE_MAX_SIZE) { + if (key.length() + TRACESTATE_KEY_VALUE_DELIMITER.length() + value.length() >= OVERSIZE_ENTRY_LENGTH + && truncateLargeEntry.get()) { + truncateLargeEntry.set(false); // only truncate one oversize entry as SW tracestate entry is smaller than OVERSIZE_ENTRY_LENGTH + } else { + traceStateBuilder.append(TRACESTATE_ENTRY_DELIMITER) + .append(key) + .append(TRACESTATE_KEY_VALUE_DELIMITER) + .append(value); + count.incrementAndGet(); + } + } + }); + return traceStateBuilder.toString(); + } /** * Extract context from the carrier, first scanning for appoptics x-trace header. * If not found, try the w3c `tracestate` diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsInboundMetricsSpanProcessor.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsInboundMetricsSpanProcessor.java index a3059c15..43e5aad8 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsInboundMetricsSpanProcessor.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsInboundMetricsSpanProcessor.java @@ -29,7 +29,7 @@ * Span processor to record inbound metrics */ public class AppOpticsInboundMetricsSpanProcessor implements SpanProcessor { - private static final AttributeKey AO_METRICS_KEY = AttributeKey.booleanKey(Constants.AO_METRICS); + private static final AttributeKey AO_METRICS_KEY = AttributeKey.booleanKey(Constants.SW_METRICS); public static final OpenTelemetryInboundMeasurementReporter measurementReporter = new OpenTelemetryInboundMeasurementReporter(); public static final OpenTelemetryInboundHistogramReporter histogramReporter = new OpenTelemetryInboundHistogramReporter(); diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsProfilingSpanProcessor.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsProfilingSpanProcessor.java index 5dd4601f..9c7d956f 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsProfilingSpanProcessor.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsProfilingSpanProcessor.java @@ -36,9 +36,9 @@ public void onStart(Context parentContext, ReadWriteSpan span) { if (PROFILER_ENABLED) { Metadata metadata = Util.buildMetadata(span.getSpanContext()); Profiler.addProfiledThread(Thread.currentThread(), metadata, metadata.getTraceId()); - span.setAttribute(AO_KEY_PREFIX + "ProfileSpans", 1); + span.setAttribute(SW_KEY_PREFIX + "ProfileSpans", 1); } else { - span.setAttribute(AO_KEY_PREFIX + "ProfileSpans", -1); //profiler disabled + span.setAttribute(SW_KEY_PREFIX + "ProfileSpans", -1); //profiler disabled } } } diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java index 406bcc91..1283ea1f 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java @@ -28,31 +28,29 @@ */ @AutoService(Sampler.class) public class AppOpticsSampler implements Sampler { - private static final String SW_UPSTREAM_TRACESTATE = "ao.tracestate"; - private static final String SW_PARENT_ID = "ao.SWParentID"; private final SamplingResult PARENT_SAMPLED = SamplingResult.create(SamplingDecision.RECORD_AND_SAMPLE, Attributes.of( - AttributeKey.booleanKey(Constants.AO_DETAILED_TRACING), true, - AttributeKey.booleanKey(Constants.AO_METRICS), true, - AttributeKey.booleanKey(Constants.AO_SAMPLER), true)); + AttributeKey.booleanKey(Constants.SW_DETAILED_TRACING), true, + AttributeKey.booleanKey(Constants.SW_METRICS), true, + AttributeKey.booleanKey(Constants.SW_SAMPLER), true)); private final SamplingResult PARENT_NOT_SAMPLED = SamplingResult.create(SamplingDecision.DROP, Attributes.of( - AttributeKey.booleanKey(Constants.AO_DETAILED_TRACING), false, - AttributeKey.booleanKey(Constants.AO_METRICS), false, - AttributeKey.booleanKey(Constants.AO_SAMPLER), true)); + AttributeKey.booleanKey(Constants.SW_DETAILED_TRACING), false, + AttributeKey.booleanKey(Constants.SW_METRICS), false, + AttributeKey.booleanKey(Constants.SW_SAMPLER), true)); private final SamplingResult METRICS_ONLY = SamplingResult.create(SamplingDecision.RECORD_ONLY, Attributes.of( - AttributeKey.booleanKey(Constants.AO_DETAILED_TRACING), false, - AttributeKey.booleanKey(Constants.AO_METRICS), true, - AttributeKey.booleanKey(Constants.AO_SAMPLER), true + AttributeKey.booleanKey(Constants.SW_DETAILED_TRACING), false, + AttributeKey.booleanKey(Constants.SW_METRICS), true, + AttributeKey.booleanKey(Constants.SW_SAMPLER), true )); private final SamplingResult NOT_TRACED = SamplingResult.create(SamplingDecision.DROP, Attributes.of( - AttributeKey.booleanKey(Constants.AO_DETAILED_TRACING), false, - AttributeKey.booleanKey(Constants.AO_METRICS), false, - AttributeKey.booleanKey(Constants.AO_SAMPLER), true)); + AttributeKey.booleanKey(Constants.SW_DETAILED_TRACING), false, + AttributeKey.booleanKey(Constants.SW_METRICS), false, + AttributeKey.booleanKey(Constants.SW_SAMPLER), true)); @Override public SamplingResult shouldSample(Context parentContext, String traceId, String name, SpanKind spanKind, Attributes attributes, List parentLinks) { @@ -83,12 +81,15 @@ public SamplingResult shouldSample(Context parentContext, String traceId, String parentId = swVal.split("-")[0]; } if (parentSpanContext.isRemote() && parentId != null) { - additionalAttributesBuilder.put(SW_PARENT_ID, parentId); + additionalAttributesBuilder.put(Constants.SW_PARENT_ID, parentId); } } if (parentSpanContext.isRemote() && !traceState.isEmpty()) { - additionalAttributesBuilder.put(SW_UPSTREAM_TRACESTATE, parentContext.get(TraceStateKey.KEY)); + String traceStateValue = parentContext.get(TraceStateKey.KEY); + if (traceStateValue != null) { + additionalAttributesBuilder.put(Constants.SW_UPSTREAM_TRACESTATE, traceStateValue); + } } return TraceStateSamplingResult.wrap(samplingResult, additionalAttributesBuilder.build()); } @@ -112,7 +113,7 @@ private String getResource(Attributes attributes) { @Override public String getDescription() { - return "AppOptics Sampler"; + return "Solarwinds NH Sampler"; } private SamplingResult toOtSamplingResult(TraceDecision aoTraceDecision) { @@ -121,14 +122,14 @@ private SamplingResult toOtSamplingResult(TraceDecision aoTraceDecision) { if (aoTraceDecision.isSampled()) { SamplingDecision samplingDecision = SamplingDecision.RECORD_AND_SAMPLE; AttributesBuilder aoAttributesBuilder = Attributes.builder(); - aoAttributesBuilder.put(Constants.AO_KEY_PREFIX + "SampleRate", aoTraceDecision.getTraceConfig().getSampleRate()); - aoAttributesBuilder.put(Constants.AO_KEY_PREFIX + "SampleSource", aoTraceDecision.getTraceConfig().getSampleRateSourceValue()); - aoAttributesBuilder.put(Constants.AO_KEY_PREFIX + "BucketRate", aoTraceDecision.getTraceConfig().getBucketRate(aoTraceDecision.getRequestType().getBucketType())); - aoAttributesBuilder.put(Constants.AO_KEY_PREFIX + "BucketCapacity", aoTraceDecision.getTraceConfig().getBucketCapacity(aoTraceDecision.getRequestType().getBucketType())); - aoAttributesBuilder.put(Constants.AO_KEY_PREFIX + "RequestType", aoTraceDecision.getRequestType().name()); - aoAttributesBuilder.put(Constants.AO_DETAILED_TRACING, aoTraceDecision.isSampled()); - aoAttributesBuilder.put(Constants.AO_METRICS, aoTraceDecision.isReportMetrics()); - aoAttributesBuilder.put(Constants.AO_SAMPLER, true); //mark that it has been sampled by us + aoAttributesBuilder.put(Constants.SW_KEY_PREFIX + "SampleRate", aoTraceDecision.getTraceConfig().getSampleRate()); + aoAttributesBuilder.put(Constants.SW_KEY_PREFIX + "SampleSource", aoTraceDecision.getTraceConfig().getSampleRateSourceValue()); + aoAttributesBuilder.put(Constants.SW_KEY_PREFIX + "BucketRate", aoTraceDecision.getTraceConfig().getBucketRate(aoTraceDecision.getRequestType().getBucketType())); + aoAttributesBuilder.put(Constants.SW_KEY_PREFIX + "BucketCapacity", aoTraceDecision.getTraceConfig().getBucketCapacity(aoTraceDecision.getRequestType().getBucketType())); + aoAttributesBuilder.put(Constants.SW_KEY_PREFIX + "RequestType", aoTraceDecision.getRequestType().name()); + aoAttributesBuilder.put(Constants.SW_DETAILED_TRACING, aoTraceDecision.isSampled()); + aoAttributesBuilder.put(Constants.SW_METRICS, aoTraceDecision.isReportMetrics()); + aoAttributesBuilder.put(Constants.SW_SAMPLER, true); //mark that it has been sampled by us result = SamplingResult.create(samplingDecision, aoAttributesBuilder.build()); } else { diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSpanExporter.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSpanExporter.java index b179b04a..020c0683 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSpanExporter.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSpanExporter.java @@ -17,7 +17,7 @@ * Span exporter to be used with the OpenTelemetry auto agent */ public class AppOpticsSpanExporter implements SpanExporter { - private static final AttributeKey AO_SAMPLER_KEY = AttributeKey.booleanKey(com.appoptics.opentelemetry.core.Constants.AO_SAMPLER); + private static final AttributeKey AO_SAMPLER_KEY = AttributeKey.booleanKey(com.appoptics.opentelemetry.core.Constants.SW_SAMPLER); private AppOpticsSpanExporter(String serviceKey) { @@ -144,7 +144,7 @@ private static Map, Object> filterAttributes(Attributes inputAtt Map, Object> result = new HashMap<>(); for (Map.Entry, Object> keyValue : inputAttributes.asMap().entrySet()) { AttributeKey key = keyValue.getKey(); - if (!key.getKey().startsWith(com.appoptics.opentelemetry.core.Constants.AO_INTERNAL_ATTRIBUTE_PREFIX)) { + if (!key.getKey().startsWith(com.appoptics.opentelemetry.core.Constants.SW_INTERNAL_ATTRIBUTE_PREFIX)) { result.put(key, keyValue.getValue()); } } @@ -193,8 +193,8 @@ private Map getEventKvs(Attributes inputAttributes) { } //Add all attributes as KVs, but add/remove prefix based on type - if (attributeKey.startsWith(com.appoptics.opentelemetry.core.Constants.AO_KEY_PREFIX)) { - attributeKey = attributeKey.substring(com.appoptics.opentelemetry.core.Constants.AO_KEY_PREFIX.length()); + if (attributeKey.startsWith(com.appoptics.opentelemetry.core.Constants.SW_KEY_PREFIX)) { + attributeKey = attributeKey.substring(com.appoptics.opentelemetry.core.Constants.SW_KEY_PREFIX.length()); } else { attributeKey = Constants.OT_KEY_PREFIX + attributeKey; } diff --git a/instrumentation/appoptics-annotation/src/main/java/com/appoptics/opentelemetry/instrumentation/annotation/AppOpticsAnnotationTracer.java b/instrumentation/appoptics-annotation/src/main/java/com/appoptics/opentelemetry/instrumentation/annotation/AppOpticsAnnotationTracer.java index da287425..61b9fc9d 100644 --- a/instrumentation/appoptics-annotation/src/main/java/com/appoptics/opentelemetry/instrumentation/annotation/AppOpticsAnnotationTracer.java +++ b/instrumentation/appoptics-annotation/src/main/java/com/appoptics/opentelemetry/instrumentation/annotation/AppOpticsAnnotationTracer.java @@ -7,7 +7,6 @@ import com.appoptics.api.ext.LogMethod; import com.appoptics.api.ext.ProfileMethod; -import com.appoptics.api.ext.impl.SdkUtil; import com.appoptics.opentelemetry.core.Constants; import com.appoptics.opentelemetry.core.Util; import com.tracelytics.joboe.EventValueConverter; @@ -47,12 +46,12 @@ public Context startSpan(Context parentContext, LogMethod annotation, Method met Span span = spanBuilder(parentContext, operationName, kind).startSpan(); - span.setAttribute(Constants.AO_KEY_PREFIX + "Class", method.getDeclaringClass().getName()); - span.setAttribute(Constants.AO_KEY_PREFIX + "Method", method.getName()); + span.setAttribute(Constants.SW_KEY_PREFIX + "Class", method.getDeclaringClass().getName()); + span.setAttribute(Constants.SW_KEY_PREFIX + "Method", method.getName()); if (annotation.backTrace()) { - span.setAttribute(Constants.AO_KEY_PREFIX + "Backtrace", BackTraceUtil.backTraceToString(BackTraceUtil.getBackTrace(1))); + span.setAttribute(Constants.SW_KEY_PREFIX + "Backtrace", BackTraceUtil.backTraceToString(BackTraceUtil.getBackTrace(1))); } return parentContext.with(span); } @@ -64,9 +63,9 @@ public Context startSpan(Context parentContext, ProfileMethod annotation, Method Span span = spanBuilder(parentContext, operationName, kind).startSpan(); - span.setAttribute(Constants.AO_KEY_PREFIX + "Class", method.getDeclaringClass().getName()); - span.setAttribute(Constants.AO_KEY_PREFIX + "FunctionName", method.getName()); - span.setAttribute(Constants.AO_KEY_PREFIX + "Signature", method.toGenericString()); //slightly different from the method signature before, but this is more readable + span.setAttribute(Constants.SW_KEY_PREFIX + "Class", method.getDeclaringClass().getName()); + span.setAttribute(Constants.SW_KEY_PREFIX + "FunctionName", method.getName()); + span.setAttribute(Constants.SW_KEY_PREFIX + "Signature", method.toGenericString()); //slightly different from the method signature before, but this is more readable if (method.getDeclaringClass().getProtectionDomain() != null) { CodeSource codeSource = method.getDeclaringClass().getProtectionDomain().getCodeSource(); @@ -75,14 +74,14 @@ public Context startSpan(Context parentContext, ProfileMethod annotation, Method if (location != null) { String file = location.getFile(); if (file != null && !"".equals(file)) { - span.setAttribute(Constants.AO_KEY_PREFIX + "File", file); + span.setAttribute(Constants.SW_KEY_PREFIX + "File", file); } } } } if (annotation.backTrace()) { - span.setAttribute(Constants.AO_KEY_PREFIX + "Backtrace", BackTraceUtil.backTraceToString(BackTraceUtil.getBackTrace(1))); + span.setAttribute(Constants.SW_KEY_PREFIX + "Backtrace", BackTraceUtil.backTraceToString(BackTraceUtil.getBackTrace(1))); } return parentContext.with(span); } diff --git a/instrumentation/jdbc/src/main/java/com/appoptics/opentelemetry/instrumentation/AoStatementTracer.java b/instrumentation/jdbc/src/main/java/com/appoptics/opentelemetry/instrumentation/AoStatementTracer.java index 3c05d58c..936faf57 100644 --- a/instrumentation/jdbc/src/main/java/com/appoptics/opentelemetry/instrumentation/AoStatementTracer.java +++ b/instrumentation/jdbc/src/main/java/com/appoptics/opentelemetry/instrumentation/AoStatementTracer.java @@ -21,7 +21,7 @@ public static void writeStackTrace(Context context) { if (span.getSpanContext().isSampled()) { String backTraceString = BackTraceUtil.backTraceToString(BackTraceUtil.getBackTrace(1)); - span.setAttribute(Constants.AO_KEY_PREFIX + "Backtrace", backTraceString); + span.setAttribute(Constants.SW_KEY_PREFIX + "Backtrace", backTraceString); } } From 2ff8362e1b8c0e2baf1578fffee25a292ffcc2eb Mon Sep 17 00:00:00 2001 From: jiwen624 Date: Thu, 7 Oct 2021 16:32:28 -0700 Subject: [PATCH 17/21] update parent_id key name --- .../main/java/com/appoptics/opentelemetry/core/Constants.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-bootstrap/src/main/java/com/appoptics/opentelemetry/core/Constants.java b/core-bootstrap/src/main/java/com/appoptics/opentelemetry/core/Constants.java index de4beb23..bd40effe 100644 --- a/core-bootstrap/src/main/java/com/appoptics/opentelemetry/core/Constants.java +++ b/core-bootstrap/src/main/java/com/appoptics/opentelemetry/core/Constants.java @@ -9,5 +9,5 @@ public interface Constants { String SW_SAMPLER = SW_INTERNAL_ATTRIBUTE_PREFIX + "sampler"; String W3C_KEY_PREFIX = "w3c."; String SW_UPSTREAM_TRACESTATE = SW_KEY_PREFIX + W3C_KEY_PREFIX + "tracestate"; - String SW_PARENT_ID = SW_KEY_PREFIX + "parentid"; + String SW_PARENT_ID = SW_KEY_PREFIX + "parent_id"; } From 1435c9e9267bb48fc9e042889fd96701d8791343 Mon Sep 17 00:00:00 2001 From: jiwen624 Date: Tue, 12 Oct 2021 17:17:10 -0700 Subject: [PATCH 18/21] do not remove ao prefix --- .../extensions/AppOpticsSpanExporter.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSpanExporter.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSpanExporter.java index 020c0683..e8ad90e4 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSpanExporter.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSpanExporter.java @@ -30,7 +30,7 @@ static Builder newBuilder(String serviceKey) { @Override public CompletableResultCode export(Collection collection) { for (SpanData spanData : collection) { - if (spanData.hasEnded() && Boolean.TRUE == spanData.getAttributes().get(AO_SAMPLER_KEY)) { + if (spanData.hasEnded()) { try { Metadata parentMetadata = null; if (spanData.getParentSpanContext().isValid()) { @@ -193,11 +193,12 @@ private Map getEventKvs(Attributes inputAttributes) { } //Add all attributes as KVs, but add/remove prefix based on type - if (attributeKey.startsWith(com.appoptics.opentelemetry.core.Constants.SW_KEY_PREFIX)) { - attributeKey = attributeKey.substring(com.appoptics.opentelemetry.core.Constants.SW_KEY_PREFIX.length()); - } else { - attributeKey = Constants.OT_KEY_PREFIX + attributeKey; - } + // TODO: remove it +// if (attributeKey.startsWith(com.appoptics.opentelemetry.core.Constants.SW_KEY_PREFIX)) { +// attributeKey = attributeKey.substring(com.appoptics.opentelemetry.core.Constants.SW_KEY_PREFIX.length()); +// } else { +// attributeKey = Constants.OT_KEY_PREFIX + attributeKey; +// } tags.put(attributeKey, attributeValue); } return tags; From 78748b7e1701ab1847bc62990e85275eeec2fc63 Mon Sep 17 00:00:00 2001 From: jiwen624 Date: Mon, 25 Oct 2021 13:58:19 -0700 Subject: [PATCH 19/21] update appoptics dependencies --- agent/build.gradle | 4 ++-- appoptics-opentelemetry-sdk/build.gradle | 18 ++++-------------- build.gradle | 3 ++- core-bootstrap/build.gradle | 4 ++-- custom/build.gradle | 4 ++-- .../appoptics-annotation/build.gradle | 2 +- instrumentation/jdbc/build.gradle | 2 +- .../spring/spring-webmvc-3.1/build.gradle | 2 +- sdk-extensions-bootstrap/build.gradle | 4 ++-- sdk-extensions/build.gradle | 4 ++-- 10 files changed, 19 insertions(+), 28 deletions(-) diff --git a/agent/build.gradle b/agent/build.gradle index 91f0c598..b470e6ba 100644 --- a/agent/build.gradle +++ b/agent/build.gradle @@ -16,8 +16,8 @@ dependencies { customShadow project(path: ":instrumentation", configuration: "shadow") implementation project(path: ":core-bootstrap") implementation "io.opentelemetry.javaagent:opentelemetry-javaagent:${versions.opentelemetryJavaagent}:all" - implementation "com.appoptics.agent.java:core:${versions.appoptics}" - implementation "com.appoptics.agent.java:metrics:${versions.appoptics}" + implementation "com.appoptics.agent.java:core:${versions.appopticsCore}" + implementation "com.appoptics.agent.java:metrics:${versions.appopticsMetrics}" } CopySpec isolateSpec() { diff --git a/appoptics-opentelemetry-sdk/build.gradle b/appoptics-opentelemetry-sdk/build.gradle index 8a1bce4b..8a7b4c1d 100644 --- a/appoptics-opentelemetry-sdk/build.gradle +++ b/appoptics-opentelemetry-sdk/build.gradle @@ -6,23 +6,13 @@ group = "com.appoptics.agent.java" dependencies { compileOnly("io.opentelemetry:opentelemetry-sdk:${versions.opentelemetry}") compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-bootstrap:${versions.opentelemetryJavaagentAlpha}") - compileOnly "com.appoptics.agent.java:core:${versions.appoptics}" - compileOnly "com.appoptics.agent.java:metrics:${versions.appoptics}" + compileOnly "com.appoptics.agent.java:core:${versions.appopticsCore}" + compileOnly "com.appoptics.agent.java:metrics:${versions.appopticsMetrics}" compileOnly project(":custom") compileOnly project(":core-bootstrap") testImplementation "junit:junit:4.10" - testImplementation "com.appoptics.agent.java:core:${versions.appoptics}" - testImplementation "com.appoptics.agent.java:metrics:${versions.appoptics}" - - - -// implementation "io.opentelemetry.javaagent:opentelemetry-javaagent-api:1.1.0-alpha" -// implementation "io.opentelemetry.javaagent:opentelemetry-javaagent-tooling:1.1.0-alpha" -// implementation "io.opentelemetry.instrumentation:opentelemetry-instrumentation-api:1.1.0-alpha" -// implementation "com.google.guava:guava:30.1-jre" //why - -// compileOnly "com.appoptics.agent.java:appoptics-opentelemetry-sdk:6.23.0" -// implementation "com.appoptics.agent.java:appoptics-opentelemetry-java-extensions:6.23.0" + testImplementation "com.appoptics.agent.java:core:${versions.appopticsCore}" + testImplementation "com.appoptics.agent.java:metrics:${versions.appopticsMetrics}" } diff --git a/build.gradle b/build.gradle index 495e3453..9f9b0444 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,8 @@ subprojects { // opentelemetryJavaagent: "1.1.0", bytebuddy : "1.10.18", guava : "30.1-jre", - appoptics : "6.24.1" + appopticsCore : "7.0.0", + appopticsMetrics : "7.0.0" ] versions.opentelemetryAlpha = "${versions.opentelemetry}-alpha" versions.opentelemetryJavaagentAlpha = "${versions.opentelemetryJavaagent}-alpha" diff --git a/core-bootstrap/build.gradle b/core-bootstrap/build.gradle index 24e664ec..3e7a6c30 100644 --- a/core-bootstrap/build.gradle +++ b/core-bootstrap/build.gradle @@ -11,7 +11,7 @@ dependencies { compileOnly("org.checkerframework:checker-qual:3.13.0") compileOnly "org.slf4j:slf4j-api:1.6.2" - compileOnly "com.appoptics.agent.java:core:${versions.appoptics}" - compileOnly "com.appoptics.agent.java:metrics:${versions.appoptics}" + compileOnly "com.appoptics.agent.java:core:${versions.appopticsCore}" + compileOnly "com.appoptics.agent.java:metrics:${versions.appopticsMetrics}" } diff --git a/custom/build.gradle b/custom/build.gradle index c6ba5dd9..a8c0f2c0 100644 --- a/custom/build.gradle +++ b/custom/build.gradle @@ -18,8 +18,8 @@ dependencies { implementation project(path: ":core-bootstrap") implementation "org.slf4j:slf4j-api:1.6.2" - compileOnly "com.appoptics.agent.java:core:${versions.appoptics}" - compileOnly "com.appoptics.agent.java:metrics:${versions.appoptics}" + compileOnly "com.appoptics.agent.java:core:${versions.appopticsCore}" + compileOnly "com.appoptics.agent.java:metrics:${versions.appopticsMetrics}" compileOnly "com.google.auto.service:auto-service-annotations:1.0-rc6" annotationProcessor "com.google.auto.service:auto-service:1.0-rc6" diff --git a/instrumentation/appoptics-annotation/build.gradle b/instrumentation/appoptics-annotation/build.gradle index 3358685e..e44c0430 100644 --- a/instrumentation/appoptics-annotation/build.gradle +++ b/instrumentation/appoptics-annotation/build.gradle @@ -7,7 +7,7 @@ apply from: "$rootDir/gradle/instrumentation.gradle" dependencies { compileOnly "io.opentelemetry.instrumentation:opentelemetry-instrumentation-api:${versions.opentelemetryJavaagentAlpha}" - compileOnly "com.appoptics.agent.java:core:${versions.appoptics}" + compileOnly "com.appoptics.agent.java:core:${versions.appopticsCore}" compileOnly project(":appoptics-opentelemetry-sdk") compileOnly project(":custom") compileOnly project(":core-bootstrap") diff --git a/instrumentation/jdbc/build.gradle b/instrumentation/jdbc/build.gradle index d4fdb2ca..1cfaec57 100644 --- a/instrumentation/jdbc/build.gradle +++ b/instrumentation/jdbc/build.gradle @@ -26,5 +26,5 @@ dependencies { testImplementation "org.eclipse.jetty:jetty-server:8.0.0.v20110901" testImplementation "org.eclipse.jetty:jetty-servlet:8.0.0.v20110901" - compileOnly "com.appoptics.agent.java:core:${versions.appoptics}" + compileOnly "com.appoptics.agent.java:core:${versions.appopticsCore}" } diff --git a/instrumentation/spring/spring-webmvc-3.1/build.gradle b/instrumentation/spring/spring-webmvc-3.1/build.gradle index 2ee602c8..794ed452 100644 --- a/instrumentation/spring/spring-webmvc-3.1/build.gradle +++ b/instrumentation/spring/spring-webmvc-3.1/build.gradle @@ -30,7 +30,7 @@ dependencies { compileOnly "org.springframework:spring-webmvc:3.1.0.RELEASE" compileOnly "io.opentelemetry.instrumentation:opentelemetry-instrumentation-api:${versions.opentelemetryJavaagentAlpha}" - compileOnly "com.appoptics.agent.java:core:${versions.appoptics}" + compileOnly "com.appoptics.agent.java:core:${versions.appopticsCore}" compileOnly "javax.servlet:javax.servlet-api:3.1.0" } diff --git a/sdk-extensions-bootstrap/build.gradle b/sdk-extensions-bootstrap/build.gradle index 9ae30686..aa4b4c0f 100644 --- a/sdk-extensions-bootstrap/build.gradle +++ b/sdk-extensions-bootstrap/build.gradle @@ -6,8 +6,8 @@ plugins { apply from: "$rootDir/gradle/shadow.gradle" dependencies { - runtimeOnly "com.appoptics.agent.java:core:${versions.appoptics}" - runtimeOnly "com.appoptics.agent.java:metrics:${versions.appoptics}" + runtimeOnly "com.appoptics.agent.java:core:${versions.appopticsCore}" + runtimeOnly "com.appoptics.agent.java:metrics:${versions.appopticsMetrics}" } diff --git a/sdk-extensions/build.gradle b/sdk-extensions/build.gradle index a529f076..364ee0b4 100644 --- a/sdk-extensions/build.gradle +++ b/sdk-extensions/build.gradle @@ -16,8 +16,8 @@ dependencies { implementation project(":custom") //core and metrics will be made available in jar from sdk-extensions-bootstrap, appended to bootstrap via `-Xbootclasspath/a:` - compileOnly "com.appoptics.agent.java:core:${versions.appoptics}" - compileOnly "com.appoptics.agent.java:metrics:${versions.appoptics}" + compileOnly "com.appoptics.agent.java:core:${versions.appopticsCore}" + compileOnly "com.appoptics.agent.java:metrics:${versions.appopticsMetrics}" } tasks { From 24e8bdf398a2b07f1a313576a8d82e37bab61ab5 Mon Sep 17 00:00:00 2001 From: jiwen624 Date: Wed, 27 Oct 2021 13:59:13 -0700 Subject: [PATCH 20/21] update w3c trace context header name --- .../opentelemetry/extensions/AppOpticsContextPropagator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagator.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagator.java index 648421a1..f88bf4e2 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagator.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsContextPropagator.java @@ -25,7 +25,7 @@ public class AppOpticsContextPropagator implements TextMapPropagator { static final String X_TRACE_OPTIONS = "X-Trace-Options"; static final String X_TRACE_OPTIONS_SIGNATURE = "X-Trace-Options-Signature"; private static final List FIELDS = - Collections.unmodifiableList(Arrays.asList(TRACE_PARENT, TRACE_STATE, HeaderConstants.XTRACE_HEADER)); + Collections.unmodifiableList(Arrays.asList(TRACE_PARENT, TRACE_STATE, HeaderConstants.W3C_TRACE_CONTEXT_HEADER)); private static final int TRACESTATE_MAX_SIZE = 512; private static final int TRACESTATE_MAX_MEMBERS = 32; private static final int OVERSIZE_ENTRY_LENGTH = 129; From a053fb59ea67d3f3353bf5c9acac9b5c58be8baf Mon Sep 17 00:00:00 2001 From: jiwen624 Date: Thu, 28 Oct 2021 10:16:38 -0700 Subject: [PATCH 21/21] minor tweak to extensions --- .../opentelemetry/extensions/AppOpticsSampler.java | 2 +- .../opentelemetry/extensions/AppOpticsSpanExporter.java | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java index 1283ea1f..92147ae9 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSampler.java @@ -134,7 +134,7 @@ private SamplingResult toOtSamplingResult(TraceDecision aoTraceDecision) { result = SamplingResult.create(samplingDecision, aoAttributesBuilder.build()); } else { if (aoTraceDecision.isReportMetrics()) { - result = METRICS_ONLY; // is this correct? probably not... + result = METRICS_ONLY; } } return result; diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSpanExporter.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSpanExporter.java index e8ad90e4..25ae31df 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSpanExporter.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/AppOpticsSpanExporter.java @@ -17,8 +17,6 @@ * Span exporter to be used with the OpenTelemetry auto agent */ public class AppOpticsSpanExporter implements SpanExporter { - private static final AttributeKey AO_SAMPLER_KEY = AttributeKey.booleanKey(com.appoptics.opentelemetry.core.Constants.SW_SAMPLER); - private AppOpticsSpanExporter(String serviceKey) { } @@ -192,13 +190,6 @@ private Map getEventKvs(Attributes inputAttributes) { tags.put(tagKey, attributeValue); } - //Add all attributes as KVs, but add/remove prefix based on type - // TODO: remove it -// if (attributeKey.startsWith(com.appoptics.opentelemetry.core.Constants.SW_KEY_PREFIX)) { -// attributeKey = attributeKey.substring(com.appoptics.opentelemetry.core.Constants.SW_KEY_PREFIX.length()); -// } else { -// attributeKey = Constants.OT_KEY_PREFIX + attributeKey; -// } tags.put(attributeKey, attributeValue); } return tags;