Skip to content

Commit

Permalink
Merge pull request #1393 from DataDog/xgouchet/RUMM-3194/add_tracer_s…
Browse files Browse the repository at this point in the history
…ampling_rate

RUMM-3194 add tracer sampling rate
  • Loading branch information
xgouchet authored Apr 18, 2023
2 parents a3f9c38 + 2edc280 commit ef757a7
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ object AndroidConfig {

// this is temporary, until we bump min sdk. Compose requires min sdk 21.
const val MIN_SDK_FOR_COMPOSE = 21
const val MIN_SDK_FOR_WEAR = 23
const val BUILD_TOOLS_VERSION = "33.0.0"

val VERSION = Version(1, 19, 0, Version.Type.Snapshot)
Expand Down
1 change: 1 addition & 0 deletions dd-sdk-android/apiSurface
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,7 @@ class com.datadog.android.tracing.AndroidTracer : com.datadog.opentracing.DDTrac
fun setPartialFlushThreshold(Int): Builder
fun addGlobalTag(String, String): Builder
fun setBundleWithRumEnabled(Boolean): Builder
fun setSamplingRate(Double): Builder
companion object
fun logThrowable(io.opentracing.Span, Throwable)
fun logErrorMessage(io.opentracing.Span, String)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,15 @@ public class RateByServiceSampler implements Sampler, PrioritySampler {

private static final double DEFAULT_RATE = 1.0;

private volatile Map<String, RateSampler> serviceRates =
unmodifiableMap(singletonMap(DEFAULT_KEY, createRateSampler(DEFAULT_RATE)));
private volatile Map<String, RateSampler> serviceRates;

public RateByServiceSampler() {
this(DEFAULT_RATE);
}

public RateByServiceSampler(Double defaultSampleRate) {
this.serviceRates = singletonMap(DEFAULT_KEY, createRateSampler(defaultSampleRate));
}

@Override
public boolean sample(final DDSpan span) {
Expand Down Expand Up @@ -68,7 +75,6 @@ private static String getSpanEnv(final DDSpan span) {
return null == span.getTags().get("env") ? "" : String.valueOf(span.getTags().get("env"));
}


private RateSampler createRateSampler(final double sampleRate) {
final double sanitizedRate;
if (sampleRate < 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ final class Builder {
public static Sampler forConfig(final Config config) {
Sampler sampler;
if (config != null) {

if (config.isPrioritySamplingEnabled()) {
sampler = new RateByServiceSampler();
sampler = new RateByServiceSampler(config.getTraceSampleRate());
} else {
sampler = new AllSampler();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

package com.datadog.android.tracing

import androidx.annotation.FloatRange
import com.datadog.android.Datadog
import com.datadog.android.core.internal.utils.internalLogger
import com.datadog.android.log.LogAttributes
Expand Down Expand Up @@ -92,6 +93,7 @@ class AndroidTracer internal constructor(

private var tracingHeaderTypes: Set<TracingHeaderType> = setOf(TracingHeaderType.DATADOG)
private var bundleWithRumEnabled: Boolean = true
private var samplingRate: Double = DEFAULT_SAMPLING_RATE

// TODO RUMM-0000 should have a nicer call chain
private var serviceName: String? = (Datadog.globalSdkCore as? DatadogCore)
Expand Down Expand Up @@ -193,6 +195,17 @@ class AndroidTracer internal constructor(
return this
}

/**
* Sets the sampling rate of spans.
* @param samplingRate the sampling rate as a percentage between 0 and 100 (default is 100%)
*/
fun setSamplingRate(
@FloatRange(from = 0.0, to = 100.0) samplingRate: Double
): Builder {
this.samplingRate = samplingRate
return this
}

// endregion

// region Internal
Expand All @@ -216,6 +229,10 @@ class AndroidTracer internal constructor(
Config.TAGS,
globalTags.map { "${it.key}:${it.value}" }.joinToString(",")
)
properties.setProperty(
Config.TRACE_SAMPLE_RATE,
(samplingRate / DEFAULT_SAMPLING_RATE).toString()
)

val propagationStyles = tracingHeaderTypes.joinToString(",")
properties.setProperty(Config.PROPAGATION_STYLE_EXTRACT, propagationStyles)
Expand Down Expand Up @@ -248,6 +265,8 @@ class AndroidTracer internal constructor(
// endregion

companion object {
internal const val DEFAULT_SAMPLING_RATE = 100.0

internal const val TRACING_NOT_ENABLED_ERROR_MESSAGE =
"You're trying to create an AndroidTracer instance, " +
"but either the SDK was not initialized or the Tracing feature was " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.whenever
import fr.xgouchet.elmyr.Forge
import fr.xgouchet.elmyr.annotation.DoubleForgery
import fr.xgouchet.elmyr.annotation.Forgery
import fr.xgouchet.elmyr.annotation.LongForgery
import fr.xgouchet.elmyr.annotation.StringForgery
Expand All @@ -48,6 +49,7 @@ import io.opentracing.Span
import io.opentracing.log.Fields
import io.opentracing.util.GlobalTracer
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.offset
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
Expand Down Expand Up @@ -442,6 +444,24 @@ internal class AndroidTracerTest {
.isEqualTo(threshold)
}

@Test
fun `it will build a valid Tracer with sampling rate`(
@DoubleForgery(0.0, 1.0) samplingRate: Double
) {
// Given

// When
val tracer = testedTracerBuilder
.setSamplingRate(samplingRate * 100.0)
.build()
val properties = testedTracerBuilder.properties()

// Then
assertThat(tracer).isNotNull()
assertThat(properties.getProperty(Config.TRACE_SAMPLE_RATE).toDouble())
.isCloseTo(samplingRate, offset(0.005))
}

@Test
fun `it will build a valid Tracer with global tags`(
@StringForgery operation: String,
Expand Down
2 changes: 1 addition & 1 deletion sample/wear/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ android {

defaultConfig {
applicationId = "com.datadog.android.wear.sample"
minSdk = AndroidConfig.MIN_SDK_FOR_COMPOSE
minSdk = AndroidConfig.MIN_SDK_FOR_WEAR
targetSdk = AndroidConfig.TARGET_SDK
versionCode = AndroidConfig.VERSION.code
versionName = AndroidConfig.VERSION.name
Expand Down

1 comment on commit ef757a7

@joshskeen
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Please sign in to comment.