Merge pull request #863 from DataDog/labbati/non-static-config
Avoid usage of static getters when accessing configuration parameters
This commit is contained in:
		
						commit
						075b30053d
					
				|  | @ -151,7 +151,7 @@ public class JMXFetch { | |||
|         for (final String config : split) { | ||||
|           integrationName.clear(); | ||||
|           integrationName.add(config.replace(".yaml", "")); | ||||
|           if (Config.jmxFetchIntegrationEnabled(integrationName, false)) { | ||||
|           if (Config.get().isJmxFetchIntegrationEnabled(integrationName, false)) { | ||||
|             final URL resource = JMXFetch.class.getResource("metricconfigs/" + config); | ||||
|             result.add(resource.getPath().split("\\.jar!/")[1]); | ||||
|           } | ||||
|  |  | |||
|  | @ -23,16 +23,13 @@ public abstract class BaseDecorator { | |||
|   protected final float traceAnalyticsSampleRate; | ||||
| 
 | ||||
|   protected BaseDecorator() { | ||||
|     Config config = Config.get(); | ||||
|     final String[] instrumentationNames = instrumentationNames(); | ||||
|     traceAnalyticsEnabled = | ||||
|         instrumentationNames.length > 0 | ||||
|             && Config.traceAnalyticsIntegrationEnabled( | ||||
|             && config.isTraceAnalyticsIntegrationEnabled( | ||||
|                 new TreeSet<>(Arrays.asList(instrumentationNames)), traceAnalyticsDefault()); | ||||
|     float rate = 1.0f; | ||||
|     for (final String name : instrumentationNames) { | ||||
|       rate = Config.getFloatSettingFromEnvironment(name + ".analytics.sample-rate", rate); | ||||
|     } | ||||
|     traceAnalyticsSampleRate = rate; | ||||
|     traceAnalyticsSampleRate = config.getInstrumentationAnalyticsSampleRate(instrumentationNames); | ||||
|   } | ||||
| 
 | ||||
|   protected abstract String[] instrumentationNames(); | ||||
|  |  | |||
|  | @ -35,7 +35,7 @@ public abstract class HttpServerDecorator<REQUEST, CONNECTION, RESPONSE> extends | |||
| 
 | ||||
|   @Override | ||||
|   protected boolean traceAnalyticsDefault() { | ||||
|     return Config.getBooleanSettingFromEnvironment(Config.TRACE_ANALYTICS_ENABLED, false); | ||||
|     return Config.get().isTraceAnalyticsEnabled(); | ||||
|   } | ||||
| 
 | ||||
|   public Span onRequest(final Span span, final REQUEST request) { | ||||
|  |  | |||
|  | @ -52,7 +52,7 @@ public interface Instrumenter { | |||
|       instrumentationNames.add(instrumentationName); | ||||
|       instrumentationPrimaryName = instrumentationName; | ||||
| 
 | ||||
|       enabled = Config.integrationEnabled(instrumentationNames, defaultEnabled()); | ||||
|       enabled = Config.get().isIntegrationEnabled(instrumentationNames, defaultEnabled()); | ||||
|       contextProvider = new FieldBackedProvider(this); | ||||
|     } | ||||
| 
 | ||||
|  | @ -212,7 +212,7 @@ public interface Instrumenter { | |||
|     } | ||||
| 
 | ||||
|     protected boolean defaultEnabled() { | ||||
|       return Config.getBooleanSettingFromEnvironment("integrations.enabled", true); | ||||
|       return Config.get().isIntegrationsEnabled(); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -9,7 +9,6 @@ import io.opentracing.tag.Tags | |||
| import spock.lang.Shared | ||||
| import spock.lang.Specification | ||||
| 
 | ||||
| import static datadog.trace.agent.test.utils.ConfigUtils.withSystemProperty | ||||
| import static io.opentracing.log.Fields.ERROR_OBJECT | ||||
| 
 | ||||
| class BaseDecoratorTest extends Specification { | ||||
|  | @ -168,18 +167,24 @@ class BaseDecoratorTest extends Specification { | |||
|     false          | true           | 1.0 | ||||
|   } | ||||
| 
 | ||||
|   def "test analytics rate enabled"() { | ||||
|   def "test analytics rate enabled:#enabled, integration:#integName, sampleRate:#sampleRate"() { | ||||
|     setup: | ||||
|     ConfigUtils.updateConfig { | ||||
|       System.properties.setProperty("dd.${integName}.analytics.enabled", "true") | ||||
|       System.properties.setProperty("dd.${integName}.analytics.sample-rate", "$sampleRate") | ||||
|     } | ||||
| 
 | ||||
|     when: | ||||
|     BaseDecorator dec = withSystemProperty("dd.${integName}.analytics.enabled", "true") { | ||||
|       withSystemProperty("dd.${integName}.analytics.sample-rate", "$sampleRate") { | ||||
|         newDecorator(enabled) | ||||
|       } | ||||
|     } | ||||
|     BaseDecorator dec = newDecorator(enabled) | ||||
| 
 | ||||
|     then: | ||||
|     dec.traceAnalyticsEnabled == expectedEnabled | ||||
|     dec.traceAnalyticsSampleRate == (Float) expectedRate | ||||
| 
 | ||||
|     cleanup: | ||||
|     System.clearProperty("dd.${integName}.analytics.enabled") | ||||
|     System.clearProperty("dd.${integName}.analytics.sample-rate") | ||||
| 
 | ||||
|     where: | ||||
|     enabled | integName | sampleRate | expectedEnabled | expectedRate | ||||
|     false   | ""        | ""         | false           | 1.0 | ||||
|  |  | |||
|  | @ -80,7 +80,9 @@ class DefaultInstrumenterTest extends Specification { | |||
| 
 | ||||
|   def "configure default sys prop as #value"() { | ||||
|     setup: | ||||
|     ConfigUtils.updateConfig { | ||||
|       System.setProperty("dd.integrations.enabled", value) | ||||
|     } | ||||
|     def target = new TestDefaultInstrumenter("test") | ||||
|     target.instrument(new AgentBuilder.Default()) | ||||
| 
 | ||||
|  | @ -98,6 +100,7 @@ class DefaultInstrumenterTest extends Specification { | |||
|   def "configure default env var as #value"() { | ||||
|     setup: | ||||
|     environmentVariables.set("DD_INTEGRATIONS_ENABLED", value) | ||||
|     ConfigUtils.resetConfig() | ||||
|     def target = new TestDefaultInstrumenter("test") | ||||
|     target.instrument(new AgentBuilder.Default()) | ||||
| 
 | ||||
|  |  | |||
|  | @ -22,8 +22,7 @@ public abstract class AbstractExecutorInstrumentation extends Instrumenter.Defau | |||
| 
 | ||||
|   public static final String EXEC_NAME = "java_concurrent"; | ||||
| 
 | ||||
|   private static final boolean TRACE_ALL_EXECUTORS = | ||||
|       Config.getBooleanSettingFromEnvironment("trace.executors.all", false); | ||||
|   private static final boolean TRACE_ALL_EXECUTORS = Config.get().isTraceExecutorsAll(); | ||||
| 
 | ||||
|   /** | ||||
|    * Only apply executor instrumentation to whitelisted executors. To apply to all executors, use | ||||
|  | @ -85,8 +84,7 @@ public abstract class AbstractExecutorInstrumentation extends Instrumenter.Defau | |||
|         "com.google.common.util.concurrent.MoreExecutors$ScheduledListeningDecorator", | ||||
|       }; | ||||
| 
 | ||||
|       final Set<String> executors = | ||||
|           new HashSet<>(Config.getListSettingFromEnvironment("trace.executors", "")); | ||||
|       final Set<String> executors = new HashSet<>(Config.get().getTraceExecutors()); | ||||
|       executors.addAll(Arrays.asList(whitelist)); | ||||
| 
 | ||||
|       WHITELISTED_EXECUTORS = Collections.unmodifiableSet(executors); | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| import datadog.opentracing.DDSpan | ||||
| import datadog.opentracing.scopemanager.ContinuableScope | ||||
| import datadog.trace.agent.test.AgentTestRunner | ||||
| import datadog.trace.agent.test.utils.ConfigUtils | ||||
| import datadog.trace.api.Trace | ||||
| import datadog.trace.bootstrap.instrumentation.java.concurrent.CallableWrapper | ||||
| import datadog.trace.bootstrap.instrumentation.java.concurrent.RunnableWrapper | ||||
|  | @ -25,8 +26,10 @@ import java.util.concurrent.TimeoutException | |||
| class ExecutorInstrumentationTest extends AgentTestRunner { | ||||
| 
 | ||||
|   static { | ||||
|     ConfigUtils.updateConfig { | ||||
|       System.setProperty("dd.trace.executors", "ExecutorInstrumentationTest\$CustomThreadPoolExecutor") | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   @Shared | ||||
|   def executeRunnable = { e, c -> e.execute((Runnable) c) } | ||||
|  |  | |||
|  | @ -34,8 +34,7 @@ public class MDCInjectionInstrumentation extends Instrumenter.Default { | |||
| 
 | ||||
|   @Override | ||||
|   protected boolean defaultEnabled() { | ||||
|     return Config.getBooleanSettingFromEnvironment( | ||||
|         Config.LOGS_INJECTION_ENABLED, Config.DEFAULT_LOGS_INJECTION_ENABLED); | ||||
|     return Config.get().isLogsInjectionEnabled(); | ||||
|   } | ||||
| 
 | ||||
|   @Override | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| import datadog.trace.agent.test.AgentTestRunner | ||||
| import datadog.trace.agent.test.utils.ConfigUtils | ||||
| import datadog.trace.api.CorrelationIdentifier | ||||
| import io.opentracing.Scope | ||||
| import io.opentracing.util.GlobalTracer | ||||
|  | @ -8,8 +9,10 @@ import java.util.concurrent.atomic.AtomicReference | |||
| 
 | ||||
| class Slf4jMDCTest extends AgentTestRunner { | ||||
|   static { | ||||
|     ConfigUtils.updateConfig { | ||||
|       System.setProperty("dd.logs.injection", "true") | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   def "mdc shows trace and span ids for active scope"() { | ||||
|     when: | ||||
|  |  | |||
|  | @ -47,7 +47,7 @@ public final class TraceAnnotationsInstrumentation extends Instrumenter.Default | |||
|   public TraceAnnotationsInstrumentation() { | ||||
|     super("trace", "trace-annotation"); | ||||
| 
 | ||||
|     final String configString = Config.getSettingFromEnvironment(Config.TRACE_ANNOTATIONS, null); | ||||
|     final String configString = Config.get().getTraceAnnotations(); | ||||
|     if (configString == null) { | ||||
|       additionalTraceAnnotations = | ||||
|           Collections.unmodifiableSet(Sets.<String>newHashSet(DEFAULT_ANNOTATIONS)); | ||||
|  |  | |||
|  | @ -47,7 +47,7 @@ public class TraceConfigInstrumentation implements Instrumenter { | |||
|   private final Map<String, Set<String>> classMethodsToTrace; | ||||
| 
 | ||||
|   public TraceConfigInstrumentation() { | ||||
|     final String configString = Config.getSettingFromEnvironment(Config.TRACE_METHODS, null); | ||||
|     final String configString = Config.get().getTraceMethods(); | ||||
|     if (configString == null || configString.trim().isEmpty()) { | ||||
|       classMethodsToTrace = Collections.emptyMap(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,18 +1,19 @@ | |||
| import datadog.trace.agent.test.AgentTestRunner | ||||
| import datadog.trace.agent.test.utils.ConfigUtils | ||||
| import datadog.trace.instrumentation.trace_annotation.TraceAnnotationsInstrumentation | ||||
| import dd.test.trace.annotation.SayTracedHello | ||||
| 
 | ||||
| import java.util.concurrent.Callable | ||||
| 
 | ||||
| import static datadog.trace.agent.test.utils.ConfigUtils.withSystemProperty | ||||
| import static datadog.trace.instrumentation.trace_annotation.TraceAnnotationsInstrumentation.DEFAULT_ANNOTATIONS | ||||
| 
 | ||||
| class ConfiguredTraceAnnotationsTest extends AgentTestRunner { | ||||
| 
 | ||||
|   static { | ||||
|     // nr annotation not included here, so should be disabled. | ||||
|     ConfigUtils.updateConfig { | ||||
|       System.setProperty("dd.trace.annotations", "package.Class\$Name;${OuterClass.InterestingMethod.name}") | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   def specCleanup() { | ||||
|     System.clearProperty("dd.trace.annotations") | ||||
|  | @ -46,12 +47,16 @@ class ConfiguredTraceAnnotationsTest extends AgentTestRunner { | |||
| 
 | ||||
|   def "test configuration #value"() { | ||||
|     setup: | ||||
|     def config = withSystemProperty("dd.trace.annotations", value) { | ||||
|       new TraceAnnotationsInstrumentation().additionalTraceAnnotations | ||||
|     ConfigUtils.updateConfig { | ||||
|       if (value) { | ||||
|         System.properties.setProperty("dd.trace.annotations", value) | ||||
|       } else { | ||||
|         System.clearProperty("dd.trace.annotations") | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     expect: | ||||
|     config == expected.toSet() | ||||
|     new TraceAnnotationsInstrumentation().additionalTraceAnnotations == expected.toSet() | ||||
| 
 | ||||
|     where: | ||||
|     value                               | expected | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| import datadog.opentracing.decorators.ErrorFlag | ||||
| import datadog.trace.agent.test.AgentTestRunner | ||||
| import datadog.trace.agent.test.utils.ConfigUtils | ||||
| import datadog.trace.api.Trace | ||||
| import dd.test.trace.annotation.SayTracedHello | ||||
| import io.opentracing.tag.Tags | ||||
|  | @ -9,8 +10,10 @@ import java.util.concurrent.Callable | |||
| class TraceAnnotationsTest extends AgentTestRunner { | ||||
| 
 | ||||
|   static { | ||||
|     ConfigUtils.updateConfig { | ||||
|       System.clearProperty("dd.trace.annotations") | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   def "test simple case annotations"() { | ||||
|     setup: | ||||
|  |  | |||
|  | @ -1,19 +1,22 @@ | |||
| import datadog.trace.agent.test.AgentTestRunner | ||||
| import datadog.trace.agent.test.utils.ConfigUtils | ||||
| import datadog.trace.instrumentation.trace_annotation.TraceConfigInstrumentation | ||||
| 
 | ||||
| import java.util.concurrent.Callable | ||||
| 
 | ||||
| import static datadog.trace.agent.test.utils.ConfigUtils.withSystemProperty | ||||
| 
 | ||||
| class TraceConfigTest extends AgentTestRunner { | ||||
| 
 | ||||
|   static { | ||||
|     ConfigUtils.updateConfig { | ||||
|       System.setProperty("dd.trace.methods", "package.ClassName[method1,method2];${ConfigTracedCallable.name}[call]") | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   def specCleanup() { | ||||
|     ConfigUtils.updateConfig { | ||||
|       System.clearProperty("dd.trace.methods") | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   class ConfigTracedCallable implements Callable<String> { | ||||
|     @Override | ||||
|  | @ -42,14 +45,19 @@ class TraceConfigTest extends AgentTestRunner { | |||
| 
 | ||||
|   def "test configuration #value"() { | ||||
|     setup: | ||||
|     def config = null | ||||
|     withSystemProperty("dd.trace.methods", value) { | ||||
|       def instrumentation = new TraceConfigInstrumentation() | ||||
|       config = instrumentation.classMethodsToTrace | ||||
|     ConfigUtils.updateConfig { | ||||
|       if (value) { | ||||
|         System.properties.setProperty("dd.trace.methods", value) | ||||
|       } else { | ||||
|         System.clearProperty("dd.trace.methods") | ||||
|       } | ||||
|     } | ||||
|     expect: | ||||
| 
 | ||||
|     config == expected | ||||
|     expect: | ||||
|     new TraceConfigInstrumentation().classMethodsToTrace == expected | ||||
| 
 | ||||
|     cleanup: | ||||
|     System.clearProperty("dd.trace.methods") | ||||
| 
 | ||||
|     where: | ||||
|     value                                                           | expected | ||||
|  |  | |||
|  | @ -20,22 +20,7 @@ class ConfigUtils { | |||
|   private static class ConfigInstance { | ||||
|     // Wrapped in a static class to lazy load. | ||||
|     static final FIELD = Config.getDeclaredField("INSTANCE") | ||||
|   } | ||||
| 
 | ||||
|   // TODO: ideally all users of this should switch to using Config object (and withConfigOverride) instead. | ||||
|   @Deprecated | ||||
|   @SneakyThrows | ||||
|   static <T extends Object> Object withSystemProperty(final String name, final String value, final Callable<T> r) { | ||||
|     if (value == null) { | ||||
|       System.clearProperty(name) | ||||
|     } else { | ||||
|       System.setProperty(name, value) | ||||
|     } | ||||
|     try { | ||||
|       return r.call() | ||||
|     } finally { | ||||
|       System.clearProperty(name) | ||||
|     } | ||||
|     static final RUNTIME_ID_FIELD = Config.getDeclaredField("runtimeId") | ||||
|   } | ||||
| 
 | ||||
|   @SneakyThrows | ||||
|  | @ -59,19 +44,48 @@ class ConfigUtils { | |||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Calling will reset the runtimeId too, so it might cause problems around runtimeId verification. | ||||
|    * Provides an callback to set up the testing environment and reset the global configuration after system properties and envs are set. | ||||
|    * | ||||
|    * @param r | ||||
|    * @return | ||||
|    */ | ||||
|   static updateConfig(final Callable r) { | ||||
|     makeConfigInstanceModifiable() | ||||
|     r.call() | ||||
|     resetConfig() | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Reset the global configuration. Please note that Runtime ID is preserved to the pre-existing value. | ||||
|    */ | ||||
|   static void resetConfig() { | ||||
|     // Ensure the class was retransformed properly in AgentTestRunner.makeConfigInstanceModifiable() | ||||
|     // Ensure the class was re-transformed properly in AgentTestRunner.makeConfigInstanceModifiable() | ||||
|     assert Modifier.isPublic(ConfigInstance.FIELD.getModifiers()) | ||||
|     assert Modifier.isStatic(ConfigInstance.FIELD.getModifiers()) | ||||
|     assert Modifier.isVolatile(ConfigInstance.FIELD.getModifiers()) | ||||
|     assert !Modifier.isFinal(ConfigInstance.FIELD.getModifiers()) | ||||
| 
 | ||||
|     ConfigInstance.FIELD.set(null, new Config()) | ||||
|     assert Modifier.isPublic(ConfigInstance.RUNTIME_ID_FIELD.getModifiers()) | ||||
|     assert !Modifier.isStatic(ConfigInstance.RUNTIME_ID_FIELD.getModifiers()) | ||||
|     assert Modifier.isVolatile(ConfigInstance.RUNTIME_ID_FIELD.getModifiers()) | ||||
|     assert !Modifier.isFinal(ConfigInstance.RUNTIME_ID_FIELD.getModifiers()) | ||||
| 
 | ||||
|     def previousConfig = ConfigInstance.FIELD.get(null) | ||||
|     def newConfig = new Config() | ||||
|     ConfigInstance.FIELD.set(null, newConfig) | ||||
|     if (previousConfig != null) { | ||||
|       ConfigInstance.RUNTIME_ID_FIELD.set(newConfig, ConfigInstance.RUNTIME_ID_FIELD.get(previousConfig)) | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // Keep track of config instance already made modifiable | ||||
|   private static isConfigInstanceModifiable = false | ||||
| 
 | ||||
|   static void makeConfigInstanceModifiable() { | ||||
|     if (isConfigInstanceModifiable) { | ||||
|       return | ||||
|     } | ||||
| 
 | ||||
|     def instrumentation = ByteBuddyAgent.install() | ||||
|     final transformer = | ||||
|       new AgentBuilder.Default() | ||||
|  | @ -81,14 +95,21 @@ class ConfigUtils { | |||
|         .with( | ||||
|           new AgentBuilder.LocationStrategy.Simple( | ||||
|             ClassFileLocator.ForClassLoader.ofSystemLoader())) | ||||
|         .ignore(none()) // Allow transforming boostrap classes | ||||
|         .ignore(none()) // Allow transforming bootstrap classes | ||||
|         .type(named("datadog.trace.api.Config")) | ||||
|         .transform { builder, typeDescription, classLoader, module -> | ||||
|           builder | ||||
|             .field(named("INSTANCE")) | ||||
|             .transform(Transformer.ForField.withModifiers(PUBLIC, STATIC, VOLATILE)) | ||||
|         } | ||||
|         // Making runtimeId modifiable so that it can be preserved when resetting config in tests | ||||
|         .transform { builder, typeDescription, classLoader, module -> | ||||
|           builder | ||||
|             .field(named("runtimeId")) | ||||
|             .transform(Transformer.ForField.withModifiers(PUBLIC, VOLATILE)) | ||||
|         } | ||||
|         .installOn(instrumentation) | ||||
|     isConfigInstanceModifiable = true | ||||
| 
 | ||||
|     final field = ConfigInstance.FIELD | ||||
|     assert Modifier.isPublic(field.getModifiers()) | ||||
|  | @ -96,6 +117,12 @@ class ConfigUtils { | |||
|     assert Modifier.isVolatile(field.getModifiers()) | ||||
|     assert !Modifier.isFinal(field.getModifiers()) | ||||
| 
 | ||||
|     final runtimeIdField = ConfigInstance.RUNTIME_ID_FIELD | ||||
|     assert Modifier.isPublic(runtimeIdField.getModifiers()) | ||||
|     assert !Modifier.isStatic(ConfigInstance.RUNTIME_ID_FIELD.getModifiers()) | ||||
|     assert Modifier.isVolatile(runtimeIdField.getModifiers()) | ||||
|     assert !Modifier.isFinal(runtimeIdField.getModifiers()) | ||||
| 
 | ||||
|     // No longer needed (Unless class gets retransformed somehow). | ||||
|     instrumentation.removeTransformer(transformer) | ||||
|   } | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ import com.google.common.reflect.ClassPath | |||
| import datadog.trace.agent.test.AgentTestRunner | ||||
| import datadog.trace.agent.test.SpockRunner | ||||
| import datadog.trace.agent.test.utils.ClasspathUtils | ||||
| import datadog.trace.agent.test.utils.ConfigUtils | ||||
| import datadog.trace.agent.test.utils.GlobalTracerUtils | ||||
| import datadog.trace.agent.tooling.Constants | ||||
| import io.opentracing.Span | ||||
|  | @ -10,7 +11,6 @@ import spock.lang.Shared | |||
| 
 | ||||
| import java.lang.reflect.Field | ||||
| 
 | ||||
| import static datadog.trace.agent.test.utils.ConfigUtils.resetConfig | ||||
| import static datadog.trace.agent.test.utils.TraceUtils.runUnderTrace | ||||
| import static datadog.trace.api.Config.TRACE_CLASSES_EXCLUDE | ||||
| 
 | ||||
|  | @ -23,8 +23,9 @@ class AgentTestRunnerTest extends AgentTestRunner { | |||
|   private Class sharedSpanClass | ||||
| 
 | ||||
|   static { | ||||
|     ConfigUtils.updateConfig { | ||||
|       System.setProperty("dd." + TRACE_CLASSES_EXCLUDE, "config.exclude.packagename.*, config.exclude.SomeClass,config.exclude.SomeClass\$NestedClass") | ||||
|     resetConfig() | ||||
|     } | ||||
| 
 | ||||
|     // when test class initializes, opentracing should be set up, but not the agent. | ||||
|     OT_LOADER = io.opentracing.Tracer.getClassLoader() | ||||
|  |  | |||
|  | @ -38,6 +38,7 @@ public class Config { | |||
|   public static final String SERVICE_NAME = "service.name"; | ||||
|   public static final String SERVICE = "service"; | ||||
|   public static final String TRACE_ENABLED = "trace.enabled"; | ||||
|   public static final String INTEGRATIONS_ENABLED = "integrations.enabled"; | ||||
|   public static final String WRITER_TYPE = "writer.type"; | ||||
|   public static final String AGENT_HOST = "agent.host"; | ||||
|   public static final String TRACE_AGENT_PORT = "trace.agent.port"; | ||||
|  | @ -51,6 +52,8 @@ public class Config { | |||
|   public static final String JMX_TAGS = "trace.jmx.tags"; | ||||
|   public static final String TRACE_ANALYTICS_ENABLED = "trace.analytics.enabled"; | ||||
|   public static final String TRACE_ANNOTATIONS = "trace.annotations"; | ||||
|   public static final String TRACE_EXECUTORS_ALL = "trace.executors.all"; | ||||
|   public static final String TRACE_EXECUTORS = "trace.executors"; | ||||
|   public static final String TRACE_METHODS = "trace.methods"; | ||||
|   public static final String TRACE_CLASSES_EXCLUDE = "trace.classes.exclude"; | ||||
|   public static final String TRACE_REPORT_HOSTNAME = "trace.report-hostname"; | ||||
|  | @ -84,6 +87,7 @@ public class Config { | |||
|   public static final String DEFAULT_SERVICE_NAME = "unnamed-java-app"; | ||||
| 
 | ||||
|   private static final boolean DEFAULT_TRACE_ENABLED = true; | ||||
|   public static final boolean DEFAULT_INTEGRATIONS_ENABLED = true; | ||||
|   public static final String DD_AGENT_WRITER_TYPE = "DDAgentWriter"; | ||||
|   public static final String LOGGING_WRITER_TYPE = "LoggingWriter"; | ||||
|   private static final String DEFAULT_AGENT_WRITER_TYPE = DD_AGENT_WRITER_TYPE; | ||||
|  | @ -115,6 +119,12 @@ public class Config { | |||
|   private static final String SPLIT_BY_SPACE_OR_COMMA_REGEX = "[,\\s]+"; | ||||
| 
 | ||||
|   private static final boolean DEFAULT_TRACE_REPORT_HOSTNAME = false; | ||||
|   private static final String DEFAULT_TRACE_ANNOTATIONS = null; | ||||
|   private static final boolean DEFAULT_TRACE_EXECUTORS_ALL = false; | ||||
|   private static final String DEFAULT_TRACE_EXECUTORS = ""; | ||||
|   private static final String DEFAULT_TRACE_METHODS = null; | ||||
|   public static final boolean DEFAULT_TRACE_ANALYTICS_ENABLED = false; | ||||
|   public static final float DEFAULT_ANALYTICS_SAMPLE_RATE = 1.0f; | ||||
| 
 | ||||
|   public enum PropagationStyle { | ||||
|     DATADOG, | ||||
|  | @ -132,6 +142,7 @@ public class Config { | |||
| 
 | ||||
|   @Getter private final String serviceName; | ||||
|   @Getter private final boolean traceEnabled; | ||||
|   @Getter private final boolean integrationsEnabled; | ||||
|   @Getter private final String writerType; | ||||
|   @Getter private final String agentHost; | ||||
|   @Getter private final int agentPort; | ||||
|  | @ -167,6 +178,15 @@ public class Config { | |||
| 
 | ||||
|   @Getter private final boolean reportHostName; | ||||
| 
 | ||||
|   @Getter private final String traceAnnotations; | ||||
| 
 | ||||
|   @Getter private final String traceMethods; | ||||
| 
 | ||||
|   @Getter private final boolean traceExecutorsAll; | ||||
|   @Getter private final List<String> traceExecutors; | ||||
| 
 | ||||
|   @Getter private final boolean traceAnalyticsEnabled; | ||||
| 
 | ||||
|   // Read order: System Properties -> Env Variables, [-> default value] | ||||
|   // Visible for testing | ||||
|   Config() { | ||||
|  | @ -175,6 +195,8 @@ public class Config { | |||
|     serviceName = getSettingFromEnvironment(SERVICE_NAME, DEFAULT_SERVICE_NAME); | ||||
| 
 | ||||
|     traceEnabled = getBooleanSettingFromEnvironment(TRACE_ENABLED, DEFAULT_TRACE_ENABLED); | ||||
|     integrationsEnabled = | ||||
|         getBooleanSettingFromEnvironment(INTEGRATIONS_ENABLED, DEFAULT_INTEGRATIONS_ENABLED); | ||||
|     writerType = getSettingFromEnvironment(WRITER_TYPE, DEFAULT_AGENT_WRITER_TYPE); | ||||
|     agentHost = getSettingFromEnvironment(AGENT_HOST, DEFAULT_AGENT_HOST); | ||||
|     agentPort = | ||||
|  | @ -254,6 +276,18 @@ public class Config { | |||
|     reportHostName = | ||||
|         getBooleanSettingFromEnvironment(TRACE_REPORT_HOSTNAME, DEFAULT_TRACE_REPORT_HOSTNAME); | ||||
| 
 | ||||
|     traceAnnotations = getSettingFromEnvironment(TRACE_ANNOTATIONS, DEFAULT_TRACE_ANNOTATIONS); | ||||
| 
 | ||||
|     traceMethods = getSettingFromEnvironment(TRACE_METHODS, DEFAULT_TRACE_METHODS); | ||||
| 
 | ||||
|     traceExecutorsAll = | ||||
|         getBooleanSettingFromEnvironment(TRACE_EXECUTORS_ALL, DEFAULT_TRACE_EXECUTORS_ALL); | ||||
| 
 | ||||
|     traceExecutors = getListSettingFromEnvironment(TRACE_EXECUTORS, DEFAULT_TRACE_EXECUTORS); | ||||
| 
 | ||||
|     traceAnalyticsEnabled = | ||||
|         getBooleanSettingFromEnvironment(TRACE_ANALYTICS_ENABLED, DEFAULT_TRACE_ANALYTICS_ENABLED); | ||||
| 
 | ||||
|     log.debug("New instance: {}", this); | ||||
|   } | ||||
| 
 | ||||
|  | @ -264,6 +298,8 @@ public class Config { | |||
|     serviceName = properties.getProperty(SERVICE_NAME, parent.serviceName); | ||||
| 
 | ||||
|     traceEnabled = getPropertyBooleanValue(properties, TRACE_ENABLED, parent.traceEnabled); | ||||
|     integrationsEnabled = | ||||
|         getPropertyBooleanValue(properties, INTEGRATIONS_ENABLED, parent.integrationsEnabled); | ||||
|     writerType = properties.getProperty(WRITER_TYPE, parent.writerType); | ||||
|     agentHost = properties.getProperty(AGENT_HOST, parent.agentHost); | ||||
|     agentPort = | ||||
|  | @ -347,6 +383,17 @@ public class Config { | |||
|     reportHostName = | ||||
|         getPropertyBooleanValue(properties, TRACE_REPORT_HOSTNAME, parent.reportHostName); | ||||
| 
 | ||||
|     traceAnnotations = properties.getProperty(TRACE_ANNOTATIONS, parent.traceAnnotations); | ||||
| 
 | ||||
|     traceMethods = properties.getProperty(TRACE_METHODS, parent.traceMethods); | ||||
| 
 | ||||
|     traceExecutorsAll = | ||||
|         getPropertyBooleanValue(properties, TRACE_EXECUTORS_ALL, parent.traceExecutorsAll); | ||||
|     traceExecutors = getPropertyListValue(properties, TRACE_EXECUTORS, parent.traceExecutors); | ||||
| 
 | ||||
|     traceAnalyticsEnabled = | ||||
|         getPropertyBooleanValue(properties, TRACE_ANALYTICS_ENABLED, parent.traceAnalyticsEnabled); | ||||
| 
 | ||||
|     log.debug("New instance: {}", this); | ||||
|   } | ||||
| 
 | ||||
|  | @ -388,6 +435,20 @@ public class Config { | |||
|     return Collections.unmodifiableMap(result); | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Returns the sample rate for the specified instrumentation or {@link | ||||
|    * #DEFAULT_ANALYTICS_SAMPLE_RATE} if none specified. | ||||
|    */ | ||||
|   public float getInstrumentationAnalyticsSampleRate(String... aliases) { | ||||
|     for (final String alias : aliases) { | ||||
|       Float rate = getFloatSettingFromEnvironment(alias + ".analytics.sample-rate", null); | ||||
|       if (null != rate) { | ||||
|         return rate; | ||||
|       } | ||||
|     } | ||||
|     return DEFAULT_ANALYTICS_SAMPLE_RATE; | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Return a map of tags required by the datadog backend to link runtime metrics (i.e. jmx) and | ||||
|    * traces. | ||||
|  | @ -404,6 +465,18 @@ public class Config { | |||
|     return Collections.unmodifiableMap(result); | ||||
|   } | ||||
| 
 | ||||
|   public boolean isIntegrationEnabled( | ||||
|       final SortedSet<String> integrationNames, final boolean defaultEnabled) { | ||||
|     return integrationEnabled(integrationNames, defaultEnabled); | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * @deprecated This method should only be used internally. Use the instance getter instead {@link | ||||
|    *     #isIntegrationEnabled(SortedSet, boolean)}. | ||||
|    * @param integrationNames | ||||
|    * @param defaultEnabled | ||||
|    * @return | ||||
|    */ | ||||
|   public static boolean integrationEnabled( | ||||
|       final SortedSet<String> integrationNames, final boolean defaultEnabled) { | ||||
|     // If default is enabled, we want to enable individually, | ||||
|  | @ -421,6 +494,18 @@ public class Config { | |||
|     return anyEnabled; | ||||
|   } | ||||
| 
 | ||||
|   public boolean isJmxFetchIntegrationEnabled( | ||||
|       final SortedSet<String> integrationNames, final boolean defaultEnabled) { | ||||
|     return jmxFetchIntegrationEnabled(integrationNames, defaultEnabled); | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * @deprecated This method should only be used internally. Use the instance getter instead {@link | ||||
|    *     #isJmxFetchIntegrationEnabled(SortedSet, boolean)}. | ||||
|    * @param integrationNames | ||||
|    * @param defaultEnabled | ||||
|    * @return | ||||
|    */ | ||||
|   public static boolean jmxFetchIntegrationEnabled( | ||||
|       final SortedSet<String> integrationNames, final boolean defaultEnabled) { | ||||
|     // If default is enabled, we want to enable individually, | ||||
|  | @ -438,6 +523,18 @@ public class Config { | |||
|     return anyEnabled; | ||||
|   } | ||||
| 
 | ||||
|   public boolean isTraceAnalyticsIntegrationEnabled( | ||||
|       final SortedSet<String> integrationNames, final boolean defaultEnabled) { | ||||
|     return traceAnalyticsIntegrationEnabled(integrationNames, defaultEnabled); | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * @deprecated This method should only be used internally. Use the instance getter instead {@link | ||||
|    *     #isTraceAnalyticsIntegrationEnabled(SortedSet, boolean)}. | ||||
|    * @param integrationNames | ||||
|    * @param defaultEnabled | ||||
|    * @return | ||||
|    */ | ||||
|   public static boolean traceAnalyticsIntegrationEnabled( | ||||
|       final SortedSet<String> integrationNames, final boolean defaultEnabled) { | ||||
|     // If default is enabled, we want to enable individually, | ||||
|  | @ -463,6 +560,7 @@ public class Config { | |||
|    * @param name | ||||
|    * @param defaultValue | ||||
|    * @return | ||||
|    * @deprecated This method should only be used internally. Use the explicit getter instead. | ||||
|    */ | ||||
|   public static String getSettingFromEnvironment(final String name, final String defaultValue) { | ||||
|     final String completeName = PREFIX + name; | ||||
|  | @ -472,6 +570,7 @@ public class Config { | |||
|     return value == null ? defaultValue : value; | ||||
|   } | ||||
| 
 | ||||
|   /** @deprecated This method should only be used internally. Use the explicit getter instead. */ | ||||
|   private static Map<String, String> getMapSettingFromEnvironment( | ||||
|       final String name, final String defaultValue) { | ||||
|     return parseMap(getSettingFromEnvironment(name, defaultValue), PREFIX + name); | ||||
|  | @ -480,6 +579,8 @@ public class Config { | |||
|   /** | ||||
|    * Calls {@link #getSettingFromEnvironment(String, String)} and converts the result to a list by | ||||
|    * splitting on `,`. | ||||
|    * | ||||
|    * @deprecated This method should only be used internally. Use the explicit getter instead. | ||||
|    */ | ||||
|   public static List<String> getListSettingFromEnvironment( | ||||
|       final String name, final String defaultValue) { | ||||
|  | @ -488,6 +589,8 @@ public class Config { | |||
| 
 | ||||
|   /** | ||||
|    * Calls {@link #getSettingFromEnvironment(String, String)} and converts the result to a Boolean. | ||||
|    * | ||||
|    * @deprecated This method should only be used internally. Use the explicit getter instead. | ||||
|    */ | ||||
|   public static Boolean getBooleanSettingFromEnvironment( | ||||
|       final String name, final Boolean defaultValue) { | ||||
|  | @ -497,6 +600,8 @@ public class Config { | |||
| 
 | ||||
|   /** | ||||
|    * Calls {@link #getSettingFromEnvironment(String, String)} and converts the result to a Float. | ||||
|    * | ||||
|    * @deprecated This method should only be used internally. Use the explicit getter instead. | ||||
|    */ | ||||
|   public static Float getFloatSettingFromEnvironment(final String name, final Float defaultValue) { | ||||
|     final String value = getSettingFromEnvironment(name, null); | ||||
|  |  | |||
|  | @ -455,7 +455,7 @@ class ConfigTest extends Specification { | |||
|     System.setProperty("dd.integration.disabled-prop.enabled", "false") | ||||
| 
 | ||||
|     expect: | ||||
|     Config.integrationEnabled(integrationNames, defaultEnabled) == expected | ||||
|     Config.get().isIntegrationEnabled(integrationNames, defaultEnabled) == expected | ||||
| 
 | ||||
|     where: | ||||
|     names                          | defaultEnabled | expected | ||||
|  | @ -489,7 +489,7 @@ class ConfigTest extends Specification { | |||
|     System.setProperty("dd.jmxfetch.disabled-prop.enabled", "false") | ||||
| 
 | ||||
|     expect: | ||||
|     Config.jmxFetchIntegrationEnabled(integrationNames, defaultEnabled) == expected | ||||
|     Config.get().isJmxFetchIntegrationEnabled(integrationNames, defaultEnabled) == expected | ||||
| 
 | ||||
|     where: | ||||
|     names                          | defaultEnabled | expected | ||||
|  | @ -523,7 +523,7 @@ class ConfigTest extends Specification { | |||
|     System.setProperty("dd.disabled-prop.analytics.enabled", "false") | ||||
| 
 | ||||
|     expect: | ||||
|     Config.traceAnalyticsIntegrationEnabled(integrationNames, defaultEnabled) == expected | ||||
|     Config.get().isTraceAnalyticsIntegrationEnabled(integrationNames, defaultEnabled) == expected | ||||
| 
 | ||||
|     where: | ||||
|     names                          | defaultEnabled | expected | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue