Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion custom/src/test/resources/sdk-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ attribute_limits:
# Configure text map context propagators.
propagator:
# Configure the set of propagators to include in the composite text map propagator.
composite: [ tracecontext, baggage, swo/contextPropagator ]
composite:
- tracecontext:
- baggage:
- swo_tracestate:
- swo_xtraceoptions:

# Configure tracer provider.
tracer_provider:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class SolarwindsContextPropagatorProvider implements ConfigurablePropagat

@Override
public TextMapPropagator getPropagator(ConfigProperties config) {
return new SolarwindsContextPropagator();
return TextMapPropagator.composite(new TraceStatePropagator(), new TraceOptionsPropagator());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* © SolarWinds Worldwide, LLC. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.solarwinds.opentelemetry.extensions;

import com.solarwinds.joboe.sampling.XtraceOptions;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.propagation.TextMapGetter;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.context.propagation.TextMapSetter;
import java.util.Collection;
import java.util.Collections;

public class TraceOptionsPropagator implements TextMapPropagator {
static final String X_TRACE_OPTIONS = "X-Trace-Options";
static final String X_TRACE_OPTIONS_SIGNATURE = "X-Trace-Options-Signature";

@Override
public Collection<String> fields() {
return Collections.emptyList();
Comment thread
cleverchuk marked this conversation as resolved.
}

/**
* Injects the x-trace-options and its signature into the carrier with values provided by current
* context
*
* @param context trace context
* @param carrier the input to the method being instrumented. Usually a request of some kind
* @param setter the object that knows how to inject data into carrier using preconfigured keys
*/
@Override
public <C> void inject(Context context, C carrier, TextMapSetter<C> setter) {
if (carrier == null || !Span.fromContext(context).getSpanContext().isValid()) {
return;
}

final String traceOptions = context.get(TriggerTraceContextKey.XTRACE_OPTIONS);
final String traceOptionsSignature =
context.get(TriggerTraceContextKey.XTRACE_OPTIONS_SIGNATURE);

if (traceOptions != null) {
setter.set(carrier, X_TRACE_OPTIONS, traceOptions);
}

if (traceOptionsSignature != null) {
setter.set(carrier, X_TRACE_OPTIONS_SIGNATURE, traceOptionsSignature);
}
}

/**
* Extracts x-trace-options and its signature from carrier and populates the extracted data into
* the current trace context.
*
* @param context trace context
* @param carrier the input to the method being instrumented. Usually a request of some kind
* @param getter the object that knows how to extract data from carrier using preconfigured keys
* @return updated context
*/
@Override
public <C> Context extract(Context context, C carrier, TextMapGetter<C> getter) {
final String traceOptions = getter.get(carrier, X_TRACE_OPTIONS);
final String traceOptionsSignature = getter.get(carrier, X_TRACE_OPTIONS_SIGNATURE);

final 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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import static com.solarwinds.opentelemetry.extensions.SamplingUtil.SW_XTRACE_OPTIONS_RESP_KEY;

import com.solarwinds.joboe.sampling.XtraceOptions;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanContext;
import io.opentelemetry.api.trace.TraceState;
Expand All @@ -33,13 +32,11 @@
import java.util.Map;
import java.util.Set;

public class SolarwindsContextPropagator implements TextMapPropagator {
public class TraceStatePropagator implements TextMapPropagator {
private static final String SWI_TRACE_STATE_KEY = "sw";
static final String TRACE_PARENT = "traceparent";
static final String TRACE_STATE = "tracestate";
static final String W3C_TRACE_CONTEXT_HEADER = "sw.trace_context";
static final String X_TRACE_OPTIONS = "X-Trace-Options";
static final String X_TRACE_OPTIONS_SIGNATURE = "X-Trace-Options-Signature";
private static final List<String> FIELDS =
Collections.unmodifiableList(
Arrays.asList(TRACE_PARENT, TRACE_STATE, W3C_TRACE_CONTEXT_HEADER));
Expand All @@ -55,8 +52,8 @@ public Collection<String> fields() {
}

/**
* Injects the both the Solarwinds x-trace ID and the updated w3c `tracestate` with our x-trace ID
* prepended into the carrier with values provided by current context
* Injects the updated w3c `tracestate` with our x-trace ID prepended into the carrier with values
* provided by current context
*
* @param context trace context
* @param carrier the input to the method being instrumented. Usually a request of some kind
Expand All @@ -75,16 +72,6 @@ public <C> void inject(Context context, C carrier, TextMapSetter<C> setter) {
final String swTraceStateValue =
spanContext.getSpanId() + "-" + spanContext.getTraceFlags().asHex();
setter.set(carrier, TRACE_STATE, updateTraceState(traceState, swTraceStateValue));

final String traceOptions = context.get(TriggerTraceContextKey.XTRACE_OPTIONS);
final String traceOptionsSignature =
context.get(TriggerTraceContextKey.XTRACE_OPTIONS_SIGNATURE);
if (traceOptions != null) {
setter.set(carrier, X_TRACE_OPTIONS, traceOptions);
}
if (traceOptionsSignature != null) {
setter.set(carrier, X_TRACE_OPTIONS_SIGNATURE, traceOptionsSignature);
}
}

/**
Expand Down Expand Up @@ -146,12 +133,13 @@ private String updateTraceState(TraceState traceState, String swTraceStateValue)
}
}
}

return traceStateBuilder.toString();
}

/**
* Extracts x-trace-options and tracestate from carrier and populates the extracted data into the
* current trace context.
* Extracts tracestate from carrier and populates the extracted data into the current trace
* context.
*
* @param context trace context
* @param carrier the input to the method being instrumented. Usually a request of some kind
Expand All @@ -160,27 +148,16 @@ private String updateTraceState(TraceState traceState, String swTraceStateValue)
*/
@Override
public <C> Context extract(Context context, C carrier, TextMapGetter<C> getter) {
final String traceOptions = getter.get(carrier, X_TRACE_OPTIONS);
final String traceOptionsSignature = getter.get(carrier, X_TRACE_OPTIONS_SIGNATURE);
final 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);
}
}

final String traceState = getter.get(carrier, TRACE_STATE);
if (traceState != null) {
boolean anyMatch =
Arrays.stream(traceState.split(",")).anyMatch(info -> !info.startsWith("sw="));

if (anyMatch) {
context = context.with(TraceStateKey.KEY, traceState);
}
}

return context;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
import io.opentelemetry.sdk.autoconfigure.declarativeconfig.model.MetricReaderModel;
import io.opentelemetry.sdk.autoconfigure.declarativeconfig.model.OpenTelemetryConfigurationModel;
import io.opentelemetry.sdk.autoconfigure.declarativeconfig.model.PeriodicMetricReaderModel;
import io.opentelemetry.sdk.autoconfigure.declarativeconfig.model.PropagatorModel;
import io.opentelemetry.sdk.autoconfigure.declarativeconfig.model.PushMetricExporterModel;
import io.opentelemetry.sdk.autoconfigure.declarativeconfig.model.SamplerModel;
import io.opentelemetry.sdk.autoconfigure.declarativeconfig.model.SpanExporterModel;
Expand Down Expand Up @@ -98,13 +97,6 @@ public void customize(DeclarativeConfigurationCustomizer customizer) {
addLogExporter(configurationModel);
}

PropagatorModel propagatorModel = configurationModel.getPropagator();
if (propagatorModel == null) {
propagatorModel = new PropagatorModel();
configurationModel.setPropagator(propagatorModel);
}

addContextPropagators(propagatorModel);
return configurationModel;
});
}
Expand Down Expand Up @@ -172,18 +164,6 @@ private void addSampler(TracerProviderModel model) {
}
}

private void addContextPropagators(PropagatorModel model) {
String compositeList = model.getCompositeList();
if (compositeList != null) {
model.setCompositeList(
String.format("%s,%s", compositeList, ContextPropagatorComponentProvider.COMPONENT_NAME));
} else {
model.setCompositeList(
String.format(
"tracecontext,baggage,%s", ContextPropagatorComponentProvider.COMPONENT_NAME));
}
}

private void addSpanExporter(OpenTelemetryConfigurationModel model) {
TracerProviderModel tracerProvider = Objects.requireNonNull(model.getTracerProvider());
List<SpanProcessorModel> processors = tracerProvider.getProcessors();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@
package com.solarwinds.opentelemetry.extensions.config.provider;

import com.google.auto.service.AutoService;
import com.solarwinds.opentelemetry.extensions.SolarwindsContextPropagator;
import com.solarwinds.opentelemetry.extensions.TraceOptionsPropagator;
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;

@AutoService(ComponentProvider.class)
public class ContextPropagatorComponentProvider implements ComponentProvider {
public class TraceOptionsComponentProvider implements ComponentProvider {

public static final String COMPONENT_NAME = "swo/contextPropagator";
public static final String COMPONENT_NAME = "swo_xtraceoptions";

@Override
public Class<TextMapPropagator> getType() {
Expand All @@ -39,6 +39,6 @@ public String getName() {

@Override
public TextMapPropagator create(DeclarativeConfigProperties declarativeConfigProperties) {
return new SolarwindsContextPropagator();
return new TraceOptionsPropagator();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* © SolarWinds Worldwide, LLC. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.solarwinds.opentelemetry.extensions.config.provider;

import com.google.auto.service.AutoService;
import com.solarwinds.opentelemetry.extensions.TraceStatePropagator;
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;

@AutoService(ComponentProvider.class)
public class TraceStateComponentProvider implements ComponentProvider {

public static final String COMPONENT_NAME = "swo_tracestate";

@Override
public Class<TextMapPropagator> getType() {
return TextMapPropagator.class;
}

@Override
public String getName() {
return COMPONENT_NAME;
}

@Override
public TextMapPropagator create(DeclarativeConfigProperties declarativeConfigProperties) {
return new TraceStatePropagator();
}
}
Loading
Loading