From 873086bfd33d4ada3f32ff8f56485198d56de079 Mon Sep 17 00:00:00 2001 From: Felix Barnsteiner Date: Tue, 20 Mar 2018 07:18:11 +0100 Subject: [PATCH 1/2] Implement sampling (closes #3) Signed-off-by: Felix Barnsteiner --- .../apm/impl/AbstractReporterBenchmark.java | 3 +- .../apm/configuration/CoreConfiguration.java | 14 +++- .../co/elastic/apm/impl/ElasticApmTracer.java | 21 ++++-- .../apm/impl/sampling/ConstantSampler.java | 29 +++++++++ .../apm/impl/sampling/ProbabilitySampler.java | 30 +++++++++ .../co/elastic/apm/impl/sampling/Sampler.java | 28 ++++++++ .../co/elastic/apm/impl/transaction/Span.java | 1 + .../apm/impl/transaction/Transaction.java | 5 +- .../apm/impl/transaction/TransactionId.java | 5 ++ .../apm/configuration/SpyConfiguration.java | 4 +- .../apm/impl/ElasticApmTracerTest.java | 15 +++++ .../TransactionPayloadJsonSchemaTest.java | 3 +- .../impl/sampling/ProbabilitySamplerTest.java | 64 +++++++++++++++++++ 13 files changed, 211 insertions(+), 11 deletions(-) create mode 100644 apm-agent-core/src/main/java/co/elastic/apm/impl/sampling/ConstantSampler.java create mode 100644 apm-agent-core/src/main/java/co/elastic/apm/impl/sampling/ProbabilitySampler.java create mode 100644 apm-agent-core/src/main/java/co/elastic/apm/impl/sampling/Sampler.java create mode 100644 apm-agent-core/src/test/java/co/elastic/apm/impl/sampling/ProbabilitySamplerTest.java diff --git a/apm-agent-benchmarks/src/main/java/co/elastic/apm/impl/AbstractReporterBenchmark.java b/apm-agent-benchmarks/src/main/java/co/elastic/apm/impl/AbstractReporterBenchmark.java index 7eea5cad1b..d830032093 100644 --- a/apm-agent-benchmarks/src/main/java/co/elastic/apm/impl/AbstractReporterBenchmark.java +++ b/apm-agent-benchmarks/src/main/java/co/elastic/apm/impl/AbstractReporterBenchmark.java @@ -10,6 +10,7 @@ import co.elastic.apm.impl.payload.Service; import co.elastic.apm.impl.payload.SystemInfo; import co.elastic.apm.impl.payload.TransactionPayload; +import co.elastic.apm.impl.sampling.ConstantSampler; import co.elastic.apm.impl.stacktrace.StacktraceFactory; import co.elastic.apm.impl.transaction.Span; import co.elastic.apm.impl.transaction.Transaction; @@ -69,7 +70,7 @@ public void setUp() throws Exception { payload = new TransactionPayload(process, service, system); for (int i = 0; i < reporterConfiguration.getMaxQueueSize(); i++) { Transaction t = new Transaction(); - t.start(tracer, 0, true); + t.start(tracer, 0, ConstantSampler.of(true)); fillTransaction(t); payload.getTransactions().add(t); } diff --git a/apm-agent-core/src/main/java/co/elastic/apm/configuration/CoreConfiguration.java b/apm-agent-core/src/main/java/co/elastic/apm/configuration/CoreConfiguration.java index 16936844fb..1bbb9e71ec 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/configuration/CoreConfiguration.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/configuration/CoreConfiguration.java @@ -57,6 +57,16 @@ public class CoreConfiguration extends ConfigurationOptionProvider { "To reduce overhead and storage requirements, you can set the sample rate to a value between 0.0 and 1.0. " + "We still record overall time and the result for unsampled transactions, but no context information, tags, or spans.") .dynamic(true) + .addValidator(new ConfigurationOption.Validator() { + @Override + public void assertValid(Double value) { + if (value != null) { + if (value < 0 || value > 1) { + throw new IllegalArgumentException("The sample rate must be between 0 and 1"); + } + } + } + }) .buildWithDefault(1.0); private final ConfigurationOption transactionMaxSpans = ConfigurationOption.integerOption() @@ -87,8 +97,8 @@ public String getEnvironment() { return environment.get(); } - public double getSampleRate() { - return sampleRate.get(); + public ConfigurationOption getSampleRate() { + return sampleRate; } public int getTransactionMaxSpans() { diff --git a/apm-agent-core/src/main/java/co/elastic/apm/impl/ElasticApmTracer.java b/apm-agent-core/src/main/java/co/elastic/apm/impl/ElasticApmTracer.java index cfd168af76..89ab2d78ef 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/impl/ElasticApmTracer.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/impl/ElasticApmTracer.java @@ -6,6 +6,9 @@ import co.elastic.apm.configuration.CoreConfiguration; import co.elastic.apm.configuration.PrefixingConfigurationSourceWrapper; import co.elastic.apm.impl.error.ErrorCapture; +import co.elastic.apm.impl.sampling.ConstantSampler; +import co.elastic.apm.impl.sampling.ProbabilitySampler; +import co.elastic.apm.impl.sampling.Sampler; import co.elastic.apm.impl.stacktrace.Stacktrace; import co.elastic.apm.impl.stacktrace.StacktraceConfiguration; import co.elastic.apm.impl.stacktrace.StacktraceFactory; @@ -21,6 +24,7 @@ import com.blogspot.mydailyjava.weaklockfree.DetachedThreadLocal; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.stagemonitor.configuration.ConfigurationOption; import org.stagemonitor.configuration.ConfigurationOptionProvider; import org.stagemonitor.configuration.ConfigurationRegistry; import org.stagemonitor.configuration.source.EnvironmentVariableConfigurationSource; @@ -28,6 +32,7 @@ import org.stagemonitor.configuration.source.SimpleSource; import org.stagemonitor.configuration.source.SystemPropertyConfigurationSource; +import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.ServiceLoader; import java.util.concurrent.TimeUnit; @@ -56,6 +61,7 @@ public class ElasticApmTracer implements Tracer { private final CoreConfiguration coreConfiguration; private final Transaction noopTransaction; private final Span noopSpan; + private Sampler sampler; ElasticApmTracer(ConfigurationRegistry configurationRegistry, Reporter reporter, StacktraceFactory stacktraceFactory) { this.configurationRegistry = configurationRegistry; @@ -91,9 +97,15 @@ public Stacktrace createInstance() { } }); coreConfiguration = configurationRegistry.getConfig(CoreConfiguration.class); - noopTransaction = new Transaction().withName("noop").withType("noop").start(this, 0, false); + noopTransaction = new Transaction().withName("noop").withType("noop").start(this, 0, ConstantSampler.of(false)); noopSpan = new Span().withName("noop").withType("noop").start(this, noopTransaction, null, 0, true); - + sampler = ProbabilitySampler.of(coreConfiguration.getSampleRate().get()); + coreConfiguration.getSampleRate().addChangeListener(new ConfigurationOption.ChangeListener() { + @Override + public void onChange(ConfigurationOption configurationOption, Double oldValue, Double newValue) { + sampler = ProbabilitySampler.of(newValue); + } + }); } public static Builder builder() { @@ -121,13 +133,14 @@ ElasticApmTracer register() { return this; } + @Nonnull @Override public Transaction startTransaction() { Transaction transaction; if (!coreConfiguration.isActive()) { transaction = noopTransaction; } else { - transaction = transactionPool.createInstance().start(this, System.nanoTime(), true); + transaction = transactionPool.createInstance().start(this, System.nanoTime(), sampler); } currentTransaction.set(transaction); return transaction; @@ -143,6 +156,7 @@ public Span currentSpan() { return currentSpan.get(); } + @Nonnull @Override public Span startSpan() { Transaction transaction = currentTransaction(); @@ -167,7 +181,6 @@ private Span createRealSpan(Transaction transaction) { transaction.getSpanCount().getDropped().increment(); } else { dropped = false; - transaction.addSpan(span); } span.start(this, transaction, currentSpan(), System.nanoTime(), dropped); return span; diff --git a/apm-agent-core/src/main/java/co/elastic/apm/impl/sampling/ConstantSampler.java b/apm-agent-core/src/main/java/co/elastic/apm/impl/sampling/ConstantSampler.java new file mode 100644 index 0000000000..6264dd9165 --- /dev/null +++ b/apm-agent-core/src/main/java/co/elastic/apm/impl/sampling/ConstantSampler.java @@ -0,0 +1,29 @@ +package co.elastic.apm.impl.sampling; + +import co.elastic.apm.impl.transaction.TransactionId; + +public class ConstantSampler implements Sampler { + + private static final Sampler TRUE = new ConstantSampler(true); + private static final Sampler FALSE = new ConstantSampler(false); + + private final boolean decision; + + private ConstantSampler(boolean decision) { + this.decision = decision; + } + + public static Sampler of(boolean decision) { + if (decision) { + return TRUE; + } else { + return FALSE; + } + } + + @Override + + public boolean isSampled(TransactionId transactionId) { + return decision; + } +} diff --git a/apm-agent-core/src/main/java/co/elastic/apm/impl/sampling/ProbabilitySampler.java b/apm-agent-core/src/main/java/co/elastic/apm/impl/sampling/ProbabilitySampler.java new file mode 100644 index 0000000000..be4174bbb4 --- /dev/null +++ b/apm-agent-core/src/main/java/co/elastic/apm/impl/sampling/ProbabilitySampler.java @@ -0,0 +1,30 @@ +package co.elastic.apm.impl.sampling; + +import co.elastic.apm.impl.transaction.TransactionId; + +public class ProbabilitySampler implements Sampler { + + private final long lowerBound; + private final long higherBound; + + public static Sampler of(double samplingRate) { + if (samplingRate == 1) { + return ConstantSampler.of(true); + } + if (samplingRate == 0) { + return ConstantSampler.of(false); + } + return new ProbabilitySampler(samplingRate); + } + + private ProbabilitySampler(double samplingRate) { + higherBound = (long) (Long.MAX_VALUE * samplingRate); + lowerBound = -higherBound; + } + + @Override + public boolean isSampled(TransactionId transactionId) { + final long mostSignificantBits = transactionId.getMostSignificantBits(); + return mostSignificantBits > lowerBound && mostSignificantBits < higherBound; + } +} diff --git a/apm-agent-core/src/main/java/co/elastic/apm/impl/sampling/Sampler.java b/apm-agent-core/src/main/java/co/elastic/apm/impl/sampling/Sampler.java new file mode 100644 index 0000000000..ae8d9ad0ae --- /dev/null +++ b/apm-agent-core/src/main/java/co/elastic/apm/impl/sampling/Sampler.java @@ -0,0 +1,28 @@ +package co.elastic.apm.impl.sampling; + +import co.elastic.apm.impl.transaction.TransactionId; + +/** + * A sampler is responsible for determining whether a {@link co.elastic.apm.api.Transaction} should be sampled. + *

+ * In contrast other tracing systems, + * in Elastic APM, + * non-sampled {@link co.elastic.apm.api.Transaction}s do get reported to the APM server. + * However, + * to keep the size at a minimum, + * the reported {@link co.elastic.apm.api.Transaction} only contains the transaction name, + * the duration and the id. + * Also, + * {@link co.elastic.apm.api.Span}s of non sampled {@link co.elastic.apm.api.Transaction}s are not reported. + *

+ */ +public interface Sampler { + + /** + * Determines whether the given transaction should be sampled. + * + * @param transactionId The id of the transaction. + * @return The sampling decision. + */ + boolean isSampled(TransactionId transactionId); +} diff --git a/apm-agent-core/src/main/java/co/elastic/apm/impl/transaction/Span.java b/apm-agent-core/src/main/java/co/elastic/apm/impl/transaction/Span.java index d15ffd963f..1252d8f2eb 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/impl/transaction/Span.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/impl/transaction/Span.java @@ -79,6 +79,7 @@ public Span start(ElasticApmTracer tracer, Transaction transaction, @Nullable Sp if (sampled) { start = (nanoTime - transaction.getDuration()) / MS_IN_NANOS; duration = nanoTime; + transaction.addSpan(this); } return this; } diff --git a/apm-agent-core/src/main/java/co/elastic/apm/impl/transaction/Transaction.java b/apm-agent-core/src/main/java/co/elastic/apm/impl/transaction/Transaction.java index 7d48ec6390..cfc0357fd1 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/impl/transaction/Transaction.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/impl/transaction/Transaction.java @@ -2,6 +2,7 @@ import co.elastic.apm.impl.ElasticApmTracer; import co.elastic.apm.impl.context.Context; +import co.elastic.apm.impl.sampling.Sampler; import co.elastic.apm.objectpool.Recyclable; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonInclude; @@ -86,12 +87,12 @@ public class Transaction implements Recyclable, co.elastic.apm.api.Transaction { @JsonProperty("sampled") private boolean sampled; - public Transaction start(ElasticApmTracer tracer, long startTimestampNanos, boolean sampled) { + public Transaction start(ElasticApmTracer tracer, long startTimestampNanos, Sampler sampler) { this.tracer = tracer; this.duration = startTimestampNanos; - this.sampled = sampled; this.timestamp.setTime(System.currentTimeMillis()); this.id.setToRandomValue(); + this.sampled = sampler.isSampled(id); return this; } diff --git a/apm-agent-core/src/main/java/co/elastic/apm/impl/transaction/TransactionId.java b/apm-agent-core/src/main/java/co/elastic/apm/impl/transaction/TransactionId.java index a96e44db29..eab0851bbd 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/impl/transaction/TransactionId.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/impl/transaction/TransactionId.java @@ -6,6 +6,7 @@ import java.io.IOException; import java.io.OutputStream; +import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Random; import java.util.UUID; @@ -29,6 +30,10 @@ public void setToRandomValue(Random random) { random.nextBytes(data); } + public void setValue(long mostSignificantBits, long leastSignificantBits) { + ByteBuffer.wrap(data).putLong(mostSignificantBits).putLong(leastSignificantBits); + } + @Override public void resetState() { for (int i = 0; i < data.length; i++) { diff --git a/apm-agent-core/src/test/java/co/elastic/apm/configuration/SpyConfiguration.java b/apm-agent-core/src/test/java/co/elastic/apm/configuration/SpyConfiguration.java index 1ca6e9c04c..f54a56bc3e 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/configuration/SpyConfiguration.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/configuration/SpyConfiguration.java @@ -10,6 +10,8 @@ public class SpyConfiguration { + public static final String CONFIG_SOURCE_NAME = "test config source"; + /** * Creates a configuration registry where all {@link ConfigurationOptionProvider}s are wrapped with * {@link org.mockito.Mockito#spy(Object)} @@ -24,7 +26,7 @@ public static ConfigurationRegistry createSpyConfig() { builder.addOptionProvider(spy(options)); } return builder - .addConfigSource(SimpleSource.forTest("service_name", "elastic-apm-test")) + .addConfigSource(new SimpleSource(CONFIG_SOURCE_NAME).add("service_name", "elastic-apm-test")) .build(); } } diff --git a/apm-agent-core/src/test/java/co/elastic/apm/impl/ElasticApmTracerTest.java b/apm-agent-core/src/test/java/co/elastic/apm/impl/ElasticApmTracerTest.java index 832b8805e1..3393a95e37 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/impl/ElasticApmTracerTest.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/impl/ElasticApmTracerTest.java @@ -14,6 +14,8 @@ import org.junit.jupiter.api.Test; import org.stagemonitor.configuration.ConfigurationRegistry; +import java.io.IOException; + import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.when; @@ -195,4 +197,17 @@ void testDisableMidTransaction() { assertThat(reporter.getFirstTransaction()).isSameAs(transaction); } + + @Test + void testSamplingNone() throws IOException { + config.getConfig(CoreConfiguration.class).getSampleRate().update(0.0, SpyConfiguration.CONFIG_SOURCE_NAME); + try (Transaction transaction = tracerImpl.startTransaction()) { + transaction.setUser("1", "jon.doe@example.com", "jondoe"); + try (Span span = tracerImpl.startSpan()) { + } + } + assertThat(reporter.getTransactions()).hasSize(1); + assertThat(reporter.getFirstTransaction().getSpans()).hasSize(0); + assertThat(reporter.getFirstTransaction().getContext().getUser().getEmail()).isNull(); + } } diff --git a/apm-agent-core/src/test/java/co/elastic/apm/impl/payload/TransactionPayloadJsonSchemaTest.java b/apm-agent-core/src/test/java/co/elastic/apm/impl/payload/TransactionPayloadJsonSchemaTest.java index 505448393b..28a59e6ecb 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/impl/payload/TransactionPayloadJsonSchemaTest.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/impl/payload/TransactionPayloadJsonSchemaTest.java @@ -1,6 +1,7 @@ package co.elastic.apm.impl.payload; import co.elastic.apm.impl.ElasticApmTracer; +import co.elastic.apm.impl.sampling.ConstantSampler; import co.elastic.apm.impl.transaction.Span; import co.elastic.apm.impl.transaction.Transaction; import com.fasterxml.jackson.databind.ObjectMapper; @@ -35,7 +36,7 @@ private TransactionPayload createPayloadWithRequiredValues() { private Transaction createTransactionWithRequiredValues() { Transaction t = new Transaction(); - t.start(mock(ElasticApmTracer.class), 0, true); + t.start(mock(ElasticApmTracer.class), 0, ConstantSampler.of(true)); t.setType("type"); t.getContext().getRequest().withMethod("GET"); Span s = new Span(); diff --git a/apm-agent-core/src/test/java/co/elastic/apm/impl/sampling/ProbabilitySamplerTest.java b/apm-agent-core/src/test/java/co/elastic/apm/impl/sampling/ProbabilitySamplerTest.java new file mode 100644 index 0000000000..ee7b1e4b9b --- /dev/null +++ b/apm-agent-core/src/test/java/co/elastic/apm/impl/sampling/ProbabilitySamplerTest.java @@ -0,0 +1,64 @@ +package co.elastic.apm.impl.sampling; + +import co.elastic.apm.impl.transaction.TransactionId; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class ProbabilitySamplerTest { + + public static final int ITERATIONS = 1_000_000; + public static final int DELTA = (int) (ITERATIONS * 0.01); + public static final double SAMPLING_RATE = 0.5; + private Sampler sampler; + + @BeforeEach + void setUp() { + sampler = ProbabilitySampler.of(SAMPLING_RATE); + } + + @Test + void isSampledEmpiricalTest() { + int sampledTransactions = 0; + TransactionId id = new TransactionId(); + for (int i = 0; i < ITERATIONS; i++) { + id.setToRandomValue(); + if (sampler.isSampled(id)) { + sampledTransactions++; + } + } + assertThat(sampledTransactions).isBetween((int) (SAMPLING_RATE * ITERATIONS - DELTA), (int) (SAMPLING_RATE * ITERATIONS + DELTA)); + } + + @Test + void testSamplingUpperBoundary() { + long upperBound = Long.MAX_VALUE / 2; + final TransactionId transactionId = new TransactionId(); + + transactionId.setValue(upperBound - 1, 0); + assertThat(ProbabilitySampler.of(0.5).isSampled(transactionId)).isTrue(); + + transactionId.setValue(upperBound, 0); + assertThat(ProbabilitySampler.of(0.5).isSampled(transactionId)).isTrue(); + + transactionId.setValue(upperBound + 1, 0); + assertThat(ProbabilitySampler.of(0.5).isSampled(transactionId)).isFalse(); + } + + @Test + void testSamplingLowerBoundary() { + long lowerBound = -Long.MAX_VALUE / 2; + final TransactionId transactionId = new TransactionId(); + + transactionId.setValue(lowerBound + 1, 0); + assertThat(ProbabilitySampler.of(0.5).isSampled(transactionId)).isTrue(); + + transactionId.setValue(lowerBound, 0); + assertThat(ProbabilitySampler.of(0.5).isSampled(transactionId)).isTrue(); + + transactionId.setValue(lowerBound - 1, 0); + assertThat(ProbabilitySampler.of(0.5).isSampled(transactionId)).isFalse(); + } + +} From 3ac211ab2ecbc24a2c20664a1a79806be9d27fef Mon Sep 17 00:00:00 2001 From: Felix Barnsteiner Date: Wed, 21 Mar 2018 14:51:07 +0100 Subject: [PATCH 2/2] add docs --- .../apm/impl/sampling/ConstantSampler.java | 4 +++- .../apm/impl/sampling/ProbabilitySampler.java | 24 +++++++++++++++++++ .../co/elastic/apm/impl/sampling/Sampler.java | 9 +++---- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/apm-agent-core/src/main/java/co/elastic/apm/impl/sampling/ConstantSampler.java b/apm-agent-core/src/main/java/co/elastic/apm/impl/sampling/ConstantSampler.java index 6264dd9165..8446895291 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/impl/sampling/ConstantSampler.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/impl/sampling/ConstantSampler.java @@ -2,6 +2,9 @@ import co.elastic.apm.impl.transaction.TransactionId; +/** + * This is a implementation of {@link Sampler} which always returns the same sampling decision. + */ public class ConstantSampler implements Sampler { private static final Sampler TRUE = new ConstantSampler(true); @@ -22,7 +25,6 @@ public static Sampler of(boolean decision) { } @Override - public boolean isSampled(TransactionId transactionId) { return decision; } diff --git a/apm-agent-core/src/main/java/co/elastic/apm/impl/sampling/ProbabilitySampler.java b/apm-agent-core/src/main/java/co/elastic/apm/impl/sampling/ProbabilitySampler.java index be4174bbb4..e168a2a232 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/impl/sampling/ProbabilitySampler.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/impl/sampling/ProbabilitySampler.java @@ -2,6 +2,30 @@ import co.elastic.apm.impl.transaction.TransactionId; +/** + * This implementation of {@link Sampler} samples based on a sampling probability (or sampling rate) between 0.0 and 1.0. + *

+ * A sampling rate of 0.5 means that 50% of all transactions should be {@linkplain Sampler sampled}. + *

+ *

+ * Implementation notes: + *

+ *

+ * We are taking advantage of the fact, that the {@link TransactionId} is randomly generated. + * So instead of generating another random number, + * we just see if the long value returned by {@link TransactionId#getMostSignificantBits()} + * falls into the range between the lowerBound and the higherBound. + * This is a visual representation of the mechanism with a sampling rate of 0.5 (=50%): + *

+ * Long.MIN_VALUE        0                     Long.MAX_VALUE
+ * v                     v                     v
+ * [----------[----------|----------]----------]
+ *            ^                     ^
+ *            lowerBound            higherBound = Long.MAX_VALUE * samplingRate
+ *            = Long.MAX_VALUE * samplingRate * -1
+ * 
+ *

+ */ public class ProbabilitySampler implements Sampler { private final long lowerBound; diff --git a/apm-agent-core/src/main/java/co/elastic/apm/impl/sampling/Sampler.java b/apm-agent-core/src/main/java/co/elastic/apm/impl/sampling/Sampler.java index ae8d9ad0ae..b57785efd6 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/impl/sampling/Sampler.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/impl/sampling/Sampler.java @@ -1,19 +1,20 @@ package co.elastic.apm.impl.sampling; +import co.elastic.apm.api.Transaction; import co.elastic.apm.impl.transaction.TransactionId; /** - * A sampler is responsible for determining whether a {@link co.elastic.apm.api.Transaction} should be sampled. + * A sampler is responsible for determining whether a {@link Transaction} should be sampled. *

* In contrast other tracing systems, * in Elastic APM, - * non-sampled {@link co.elastic.apm.api.Transaction}s do get reported to the APM server. + * non-sampled {@link Transaction}s do get reported to the APM server. * However, * to keep the size at a minimum, - * the reported {@link co.elastic.apm.api.Transaction} only contains the transaction name, + * the reported {@link Transaction} only contains the transaction name, * the duration and the id. * Also, - * {@link co.elastic.apm.api.Span}s of non sampled {@link co.elastic.apm.api.Transaction}s are not reported. + * {@link co.elastic.apm.api.Span}s of non sampled {@link Transaction}s are not reported. *

*/ public interface Sampler {