All Downloads are FREE. Search and download functionalities are using the official Maven repository.

datadog.trace.api.IdGenerationStrategy Maven / Gradle / Ivy

There is a newer version: 1.42.2
Show newest version
package datadog.trace.api;

import static java.lang.Long.MAX_VALUE;

import java.security.SecureRandom;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicLong;

/**
 * Strategy for generating trace ids and span ids.
 *
 * 

The reason this is not an ENUM is to allow future changes that are crosscutting and * configuration based, for example 128 bit trace ids et.c., without changing the public API. */ public abstract class IdGenerationStrategy { protected final boolean traceId128BitGenerationEnabled; private IdGenerationStrategy(boolean traceId128BitGenerationEnabled) { this.traceId128BitGenerationEnabled = traceId128BitGenerationEnabled; } public static IdGenerationStrategy fromName(String name) { return fromName(name, false); } public static IdGenerationStrategy fromName(String name, boolean traceId128BitGenerationEnabled) { switch (name.toUpperCase()) { case "RANDOM": return new Random(traceId128BitGenerationEnabled); case "SEQUENTIAL": return new Sequential(traceId128BitGenerationEnabled); case "SECURE_RANDOM": return new SRandom(traceId128BitGenerationEnabled); default: return null; } } public DDTraceId generateTraceId() { return this.traceId128BitGenerationEnabled ? DD128bTraceId.from(generateHighOrderBits(), getNonZeroPositiveLong()) : DD64bTraceId.from(getNonZeroPositiveLong()); } public long generateSpanId() { return getNonZeroPositiveLong(); } protected abstract long getNonZeroPositiveLong(); protected long generateHighOrderBits() { long timestamp = System.currentTimeMillis() / 1000; return timestamp << 32; } static final class Random extends IdGenerationStrategy { private Random(boolean traceId128BitGenerationEnabled) { super(traceId128BitGenerationEnabled); } @Override protected long getNonZeroPositiveLong() { return ThreadLocalRandom.current().nextLong(0, MAX_VALUE) + 1; } } static final class Sequential extends IdGenerationStrategy { private final AtomicLong id; private Sequential(boolean traceId128BitGenerationEnabled) { super(traceId128BitGenerationEnabled); this.id = new AtomicLong(0); } @Override public DDTraceId generateTraceId() { // Only use 64-bit TraceId to use incremental values only return DD64bTraceId.from(getNonZeroPositiveLong()); } @Override protected long getNonZeroPositiveLong() { return this.id.incrementAndGet(); } } @FunctionalInterface interface ThrowingSupplier { T get() throws Throwable; } static final class SRandom extends IdGenerationStrategy { private final SecureRandom secureRandom; SRandom(boolean traceId128BitGenerationEnabled) { this(traceId128BitGenerationEnabled, SecureRandom::getInstanceStrong); } SRandom(boolean traceId128BitGenerationEnabled, ThrowingSupplier supplier) { super(traceId128BitGenerationEnabled); try { secureRandom = supplier.get(); } catch (Throwable e) { throw new ExceptionInInitializerError(e); } } @Override protected long getNonZeroPositiveLong() { long value = secureRandom.nextLong() & MAX_VALUE; while (value == 0) { value = secureRandom.nextLong() & MAX_VALUE; } return value; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy