Skip to content

Commit

Permalink
Add logger and split config
Browse files Browse the repository at this point in the history
  • Loading branch information
luneo7 committed Jun 15, 2021
1 parent 870fabc commit 7af08fb
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@
public class OpenTelemetrySamplerConfigTest {
@RegisterExtension
static final QuarkusUnitTest unitTest = new QuarkusUnitTest()
.overrideConfigKey("quarkus.opentelemetry.tracer.sampler", "traceidratio")
.overrideConfigKey("quarkus.opentelemetry.tracer.sampler", "ratio")
.overrideConfigKey("quarkus.opentelemetry.tracer.sampler.ratio", "0.5")
.overrideConfigKey("quarkus.opentelemetry.tracer.sampler.parent-based", "false")
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClass(TestUtil.class));

@Inject
Expand Down
Original file line number Diff line number Diff line change
@@ -1,46 +1,96 @@
package io.quarkus.opentelemetry.runtime.tracing;

import java.util.Collections;
import java.util.Map;
import java.util.function.BiConsumer;

import org.jboss.logging.Logger;

import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;

/**
* Class enabling Quarkus to instantiate a {@link io.opentelemetry.api.trace.TracerProvider}
* during static initialization and set a {@link Attributes} delegate during runtime initialization.
*/
public class DelayedAttributes implements Attributes {
private static final Logger log = Logger.getLogger(DelayedAttributes.class);
private boolean warningLogged = false;

private Attributes delegate;

/**
* Set the actual {@link Attributes} to use as the delegate.
*
* @param delegate Properly constructed {@link Attributes}.
*/
public void setAttributesDelegate(Attributes delegate) {
this.delegate = delegate;
}

@Override
public <T> T get(AttributeKey<T> attributeKey) {
if (delegate == null) {
logDelegateNotFound();
return null;
}
return delegate.get(attributeKey);
}

@Override
public void forEach(BiConsumer<? super AttributeKey<?>, ? super Object> biConsumer) {
if (delegate == null) {
logDelegateNotFound();
return;
}
delegate.forEach(biConsumer);
}

@Override
public int size() {
if (delegate == null) {
logDelegateNotFound();
return 0;
}
return delegate.size();
}

@Override
public boolean isEmpty() {
if (delegate == null) {
logDelegateNotFound();
return true;
}
return delegate.isEmpty();
}

@Override
public Map<AttributeKey<?>, Object> asMap() {
if (delegate == null) {
logDelegateNotFound();
return Collections.emptyMap();
}
return delegate.asMap();
}

@Override
public AttributesBuilder toBuilder() {
if (delegate == null) {
logDelegateNotFound();
return Attributes.builder();
}
return delegate.toBuilder();
}

/**
* If we haven't previously logged an error,
* log an error about a missing {@code delegate} and set {@code warningLogged=true}
*/
private void logDelegateNotFound() {
if (!warningLogged) {
log.warn("No Attributes delegate specified, no action taken.");
warningLogged = true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,31 @@

import java.util.List;

import org.jboss.logging.Logger;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context;
import io.opentelemetry.sdk.trace.data.LinkData;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import io.opentelemetry.sdk.trace.samplers.SamplingDecision;
import io.opentelemetry.sdk.trace.samplers.SamplingResult;

/**
* Class enabling Quarkus to instantiate a {@link io.opentelemetry.api.trace.TracerProvider}
* during static initialization and set a {@link Sampler} delegate during runtime initialization.
*/
public class LateBoundSampler implements Sampler {
private static final Logger log = Logger.getLogger(LateBoundSampler.class);
private boolean warningLogged = false;

private Sampler delegate;

/**
* Set the actual {@link Sampler} to use as the delegate.
*
* @param delegate Properly constructed {@link Sampler}.
*/
public void setSamplerDelegate(Sampler delegate) {
this.delegate = delegate;
}
Expand All @@ -23,11 +38,30 @@ public SamplingResult shouldSample(Context parentContext,
SpanKind spanKind,
Attributes attributes,
List<LinkData> parentLinks) {
if (delegate == null) {
logDelegateNotFound();
return SamplingResult.create(SamplingDecision.RECORD_AND_SAMPLE);
}
return delegate.shouldSample(parentContext, traceId, name, spanKind, attributes, parentLinks);
}

@Override
public String getDescription() {
if (delegate == null) {
logDelegateNotFound();
return "";
}
return delegate.getDescription();
}

/**
* If we haven't previously logged an error,
* log an error about a missing {@code delegate} and set {@code warningLogged=true}
*/
private void logDelegateNotFound() {
if (!warningLogged) {
log.warn("No Sampler delegate specified, no action taken.");
warningLogged = true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ public void setupSampler(TracerRuntimeConfig config) {
lateBoundSampler.setSamplerDelegate(samplerBean.get());
} else {
// Define Sampler using config
lateBoundSampler.setSamplerDelegate(TracerUtil.mapSampler(config.sampler, config.samplerRatio));
lateBoundSampler.setSamplerDelegate(TracerUtil.mapSampler(config.sampler));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.List;
import java.util.Optional;

import io.quarkus.runtime.annotations.ConfigGroup;
import io.quarkus.runtime.annotations.ConfigItem;
import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;
Expand All @@ -18,23 +19,36 @@ public class TracerRuntimeConfig {
@ConfigItem
Optional<List<String>> resourceAttributes;

/**
* The sampler to use for tracing
* <p>
* Valid values are {@code always_off, always_on, parentbased_always_off,
* parentbased_always_on, parentbased_traceidratio, traceidratio}.
* <p>
* Defaults to {@code parentbased_always_on}.
*/
@ConfigItem(defaultValue = "parentbased_always_on")
public String sampler;
/** Config for sampler */
public SamplerConfig sampler;

/**
* The sampler ratio to use for tracing.
* <p>
* Only supported by the {@code parentbased_traceidratio, traceidratio}
* samplers.
*/
@ConfigItem(name = "sampler.ratio")
public Optional<Double> samplerRatio;
@ConfigGroup
public static class SamplerConfig {
/**
* The sampler to use for tracing
* <p>
* Valid values are {@code off, on, ratio}.
* <p>
* Defaults to {@code on}.
*/
@ConfigItem(name = ConfigItem.PARENT, defaultValue = "on")
public String samplerName;

/**
* The sampler ratio to use for tracing.z
* <p>
* Only supported by the {@code ratio} sampler.
*/
public Optional<Double> ratio;

/**
* If the sampler to use for tracing is parent based
* <p>
* Valid values are {@code true, false}.
* <p>
* Defaults to {@code true}.
*/
@ConfigItem(defaultValue = "true")
public Boolean parentBased;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,26 @@ public static Resource mapResourceAttributes(List<String> resourceAttributes) {
return Resource.create(attributesBuilder.build());
}

public static Sampler mapSampler(String sampler, Optional<Double> ratio) {
switch (sampler) {
case "always_on":
private static Sampler getBaseSampler(String samplerName, Optional<Double> ratio) {
switch (samplerName) {
case "on":
return Sampler.alwaysOn();
case "always_off":
case "off":
return Sampler.alwaysOff();
case "traceidratio":
case "ratio":
return Sampler.traceIdRatioBased(ratio.orElse(1.0d));
case "parentbased_always_on":
return Sampler.parentBased(Sampler.alwaysOn());
case "parentbased_always_off":
return Sampler.parentBased(Sampler.alwaysOff());
case "parentbased_traceidratio":
return Sampler.parentBased(Sampler.traceIdRatioBased(ratio.orElse(1.0d)));
default:
throw new IllegalArgumentException("Unrecognized value for sampler: " + sampler);
throw new IllegalArgumentException("Unrecognized value for sampler: " + samplerName);
}
}

public static Sampler mapSampler(TracerRuntimeConfig.SamplerConfig samplerConfig) {
Sampler sampler = getBaseSampler(samplerConfig.samplerName, samplerConfig.ratio);

if (samplerConfig.parentBased) {
return Sampler.parentBased(sampler);
}

return sampler;
}
}

0 comments on commit 7af08fb

Please sign in to comment.