Merge pull request #719 from DataDog/tyler/trace-analytics-config
Trace Analytics Config
This commit is contained in:
commit
875d491638
|
@ -10,6 +10,8 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
import java.util.TreeSet;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.datadog.jmxfetch.App;
|
import org.datadog.jmxfetch.App;
|
||||||
|
@ -116,9 +118,11 @@ public class JMXFetch {
|
||||||
final String configs = IOUtils.toString(metricConfigsStream, StandardCharsets.UTF_8);
|
final String configs = IOUtils.toString(metricConfigsStream, StandardCharsets.UTF_8);
|
||||||
final String[] split = configs.split("\n");
|
final String[] split = configs.split("\n");
|
||||||
final List<String> result = new ArrayList<>(split.length);
|
final List<String> result = new ArrayList<>(split.length);
|
||||||
|
final SortedSet<String> integrationName = new TreeSet<>();
|
||||||
for (final String config : split) {
|
for (final String config : split) {
|
||||||
if (Config.integrationEnabled(
|
integrationName.clear();
|
||||||
Collections.singleton(config.replace(".yaml", "")), false)) {
|
integrationName.add(config.replace(".yaml", ""));
|
||||||
|
if (Config.integrationEnabled(integrationName, false)) {
|
||||||
final URL resource = JMXFetch.class.getResource("metricconfigs/" + config);
|
final URL resource = JMXFetch.class.getResource("metricconfigs/" + config);
|
||||||
result.add(resource.getPath().split("\\.jar!/")[1]);
|
result.add(resource.getPath().split("\\.jar!/")[1]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,10 +11,10 @@ import datadog.trace.api.Config;
|
||||||
import java.security.ProtectionDomain;
|
import java.security.ProtectionDomain;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.SortedSet;
|
||||||
|
import java.util.TreeSet;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||||
import net.bytebuddy.description.method.MethodDescription;
|
import net.bytebuddy.description.method.MethodDescription;
|
||||||
|
@ -39,7 +39,7 @@ public interface Instrumenter {
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
abstract class Default implements Instrumenter {
|
abstract class Default implements Instrumenter {
|
||||||
private final Set<String> instrumentationNames;
|
private final SortedSet<String> instrumentationNames;
|
||||||
private final String instrumentationPrimaryName;
|
private final String instrumentationPrimaryName;
|
||||||
private final InstrumentationContextProvider contextProvider;
|
private final InstrumentationContextProvider contextProvider;
|
||||||
protected final boolean enabled;
|
protected final boolean enabled;
|
||||||
|
@ -48,7 +48,7 @@ public interface Instrumenter {
|
||||||
getClass().getPackage() == null ? "" : getClass().getPackage().getName();
|
getClass().getPackage() == null ? "" : getClass().getPackage().getName();
|
||||||
|
|
||||||
public Default(final String instrumentationName, final String... additionalNames) {
|
public Default(final String instrumentationName, final String... additionalNames) {
|
||||||
instrumentationNames = new HashSet<>(Arrays.asList(additionalNames));
|
instrumentationNames = new TreeSet<>(Arrays.asList(additionalNames));
|
||||||
instrumentationNames.add(instrumentationName);
|
instrumentationNames.add(instrumentationName);
|
||||||
instrumentationPrimaryName = instrumentationName;
|
instrumentationPrimaryName = instrumentationName;
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.SortedSet;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
@ -44,6 +44,7 @@ public class Config {
|
||||||
public static final String GLOBAL_TAGS = "trace.global.tags";
|
public static final String GLOBAL_TAGS = "trace.global.tags";
|
||||||
public static final String SPAN_TAGS = "trace.span.tags";
|
public static final String SPAN_TAGS = "trace.span.tags";
|
||||||
public static final String JMX_TAGS = "trace.jmx.tags";
|
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_ANNOTATIONS = "trace.annotations";
|
||||||
public static final String TRACE_METHODS = "trace.methods";
|
public static final String TRACE_METHODS = "trace.methods";
|
||||||
public static final String HEADER_TAGS = "trace.header.tags";
|
public static final String HEADER_TAGS = "trace.header.tags";
|
||||||
|
@ -260,7 +261,7 @@ public class Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean integrationEnabled(
|
public static boolean integrationEnabled(
|
||||||
final Set<String> integrationNames, final boolean defaultEnabled) {
|
final SortedSet<String> integrationNames, final boolean defaultEnabled) {
|
||||||
// If default is enabled, we want to enable individually,
|
// If default is enabled, we want to enable individually,
|
||||||
// if default is disabled, we want to disable individually.
|
// if default is disabled, we want to disable individually.
|
||||||
boolean anyEnabled = defaultEnabled;
|
boolean anyEnabled = defaultEnabled;
|
||||||
|
@ -276,6 +277,24 @@ public class Config {
|
||||||
return anyEnabled;
|
return anyEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean traceAnalyticsIntegrationEnabled(
|
||||||
|
final SortedSet<String> integrationNames, final boolean defaultEnabled) {
|
||||||
|
// If default is enabled, we want to enable individually,
|
||||||
|
// if default is disabled, we want to disable individually.
|
||||||
|
boolean anyEnabled = defaultEnabled;
|
||||||
|
for (final String name : integrationNames) {
|
||||||
|
final boolean configEnabled =
|
||||||
|
getBooleanSettingFromEnvironment(
|
||||||
|
"integration." + name + ".analytics.enabled", defaultEnabled);
|
||||||
|
if (defaultEnabled) {
|
||||||
|
anyEnabled &= configEnabled;
|
||||||
|
} else {
|
||||||
|
anyEnabled |= configEnabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return anyEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method that takes the name, adds a "dd." prefix then checks for System Properties of
|
* Helper method that takes the name, adds a "dd." prefix then checks for System Properties of
|
||||||
* that name. If none found, the name is converted to an Environment Variable and used to check
|
* that name. If none found, the name is converted to an Environment Variable and used to check
|
||||||
|
@ -316,6 +335,18 @@ public class Config {
|
||||||
return value == null ? defaultValue : Boolean.valueOf(value);
|
return value == null ? defaultValue : Boolean.valueOf(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls {@link #getSettingFromEnvironment(String, String)} and converts the result to a Float.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* @param defaultValue
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Float getFloatSettingFromEnvironment(final String name, final Float defaultValue) {
|
||||||
|
final String value = getSettingFromEnvironment(name, null);
|
||||||
|
return value == null ? defaultValue : Float.valueOf(value);
|
||||||
|
}
|
||||||
|
|
||||||
private static Integer getIntegerSettingFromEnvironment(
|
private static Integer getIntegerSettingFromEnvironment(
|
||||||
final String name, final Integer defaultValue) {
|
final String name, final Integer defaultValue) {
|
||||||
final String value = getSettingFromEnvironment(name, null);
|
final String value = getSettingFromEnvironment(name, null);
|
||||||
|
|
|
@ -14,5 +14,6 @@ public class DDTags {
|
||||||
public static final String ERROR_TYPE = "error.type"; // string representing the type of the error
|
public static final String ERROR_TYPE = "error.type"; // string representing the type of the error
|
||||||
public static final String ERROR_STACK = "error.stack"; // human readable version of the stack
|
public static final String ERROR_STACK = "error.stack"; // human readable version of the stack
|
||||||
|
|
||||||
public static final String EVENT_SAMPLE_RATE = "_dd1.sr.eausr";
|
public static final String ANALYTICS_SAMPLE_RATE = "_dd1.sr.eausr";
|
||||||
|
@Deprecated public static final String EVENT_SAMPLE_RATE = ANALYTICS_SAMPLE_RATE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -312,7 +312,41 @@ class ConfigTest extends Specification {
|
||||||
["test-prop", "disabled-prop"] | true | false
|
["test-prop", "disabled-prop"] | true | false
|
||||||
["disabled-env", "test-env"] | true | false
|
["disabled-env", "test-env"] | true | false
|
||||||
|
|
||||||
integrationNames = names.toSet()
|
integrationNames = new TreeSet<>(names)
|
||||||
|
}
|
||||||
|
|
||||||
|
def "verify integration trace analytics config"() {
|
||||||
|
setup:
|
||||||
|
environmentVariables.set("DD_INTEGRATION_ORDER_ANALYTICS_ENABLED", "false")
|
||||||
|
environmentVariables.set("DD_INTEGRATION_TEST_ENV_ANALYTICS_ENABLED", "true")
|
||||||
|
environmentVariables.set("DD_INTEGRATION_DISABLED_ENV_ANALYTICS_ENABLED", "false")
|
||||||
|
|
||||||
|
System.setProperty("dd.integration.order.analytics.enabled", "true")
|
||||||
|
System.setProperty("dd.integration.test-prop.analytics.enabled", "true")
|
||||||
|
System.setProperty("dd.integration.disabled-prop.analytics.enabled", "false")
|
||||||
|
|
||||||
|
expect:
|
||||||
|
Config.traceAnalyticsIntegrationEnabled(integrationNames, defaultEnabled) == expected
|
||||||
|
|
||||||
|
where:
|
||||||
|
names | defaultEnabled | expected
|
||||||
|
[] | true | true
|
||||||
|
[] | false | false
|
||||||
|
["invalid"] | true | true
|
||||||
|
["invalid"] | false | false
|
||||||
|
["test-prop"] | false | true
|
||||||
|
["test-env"] | false | true
|
||||||
|
["disabled-prop"] | true | false
|
||||||
|
["disabled-env"] | true | false
|
||||||
|
["other", "test-prop"] | false | true
|
||||||
|
["other", "test-env"] | false | true
|
||||||
|
["order"] | false | true
|
||||||
|
["test-prop", "disabled-prop"] | false | true
|
||||||
|
["disabled-env", "test-env"] | false | true
|
||||||
|
["test-prop", "disabled-prop"] | true | false
|
||||||
|
["disabled-env", "test-env"] | true | false
|
||||||
|
|
||||||
|
integrationNames = new TreeSet<>(names)
|
||||||
}
|
}
|
||||||
|
|
||||||
def "verify mapping configs on tracer"() {
|
def "verify mapping configs on tracer"() {
|
||||||
|
|
|
@ -3,16 +3,16 @@ package datadog.opentracing.decorators;
|
||||||
import datadog.opentracing.DDSpanContext;
|
import datadog.opentracing.DDSpanContext;
|
||||||
import datadog.trace.api.DDTags;
|
import datadog.trace.api.DDTags;
|
||||||
|
|
||||||
public class EventSampleRateDecorator extends AbstractDecorator {
|
public class AnalyticsSampleRateDecorator extends AbstractDecorator {
|
||||||
public EventSampleRateDecorator() {
|
public AnalyticsSampleRateDecorator() {
|
||||||
super();
|
super();
|
||||||
setMatchingTag(DDTags.EVENT_SAMPLE_RATE);
|
setMatchingTag(DDTags.ANALYTICS_SAMPLE_RATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldSetTag(final DDSpanContext context, final String tag, final Object value) {
|
public boolean shouldSetTag(final DDSpanContext context, final String tag, final Object value) {
|
||||||
if (value instanceof Number) {
|
if (value instanceof Number) {
|
||||||
context.setMetric(DDTags.EVENT_SAMPLE_RATE, (Number) value);
|
context.setMetric(DDTags.ANALYTICS_SAMPLE_RATE, (Number) value);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
|
@ -11,7 +11,7 @@ public class DDDecoratorsFactory {
|
||||||
new DBStatementAsResourceName(),
|
new DBStatementAsResourceName(),
|
||||||
new DBTypeDecorator(),
|
new DBTypeDecorator(),
|
||||||
new ErrorFlag(),
|
new ErrorFlag(),
|
||||||
new EventSampleRateDecorator(),
|
new AnalyticsSampleRateDecorator(),
|
||||||
new OperationDecorator(),
|
new OperationDecorator(),
|
||||||
new PeerServiceDecorator(),
|
new PeerServiceDecorator(),
|
||||||
new ResourceNameDecorator(),
|
new ResourceNameDecorator(),
|
||||||
|
|
Loading…
Reference in New Issue