Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,6 @@
import org.slf4j.LoggerFactory;

public class DebuggerProductChangesListener implements ProductListener {
public static final int MAX_ALLOWED_TRIGGER_PROBES = 100;
public static final int MAX_ALLOWED_METRIC_PROBES = 100;
public static final int MAX_ALLOWED_LOG_PROBES = 100;
public static final int MAX_ALLOWED_SPAN_PROBES = 100;
public static final int MAX_ALLOWED_SPAN_DECORATION_PROBES = 100;
public static final String LOG_PROBE_PREFIX = "logProbe_";
public static final String METRIC_PROBE_PREFIX = "metricProbe_";
public static final String SPAN_PROBE_PREFIX = "spanProbe_";
Expand Down Expand Up @@ -161,55 +156,25 @@ public void commit(PollingRateHinter pollingRateHinter) {

static class DefinitionBuilder {
private final Collection<ProbeDefinition> definitions = new ArrayList<>();
private int triggerProbeCount = 0;
private int metricProbeCount = 0;
private int logProbeCount = 0;
private int spanProbeCount = 0;
private int spanDecorationProbeCount = 0;

void add(MetricProbe probe) {
if (metricProbeCount >= MAX_ALLOWED_METRIC_PROBES) {
LOGGER.debug("Max allowed metric probes reached, ignoring new probe: {}", probe);
return;
}
definitions.add(probe);
metricProbeCount++;
}

void add(LogProbe probe) {
if (logProbeCount >= MAX_ALLOWED_LOG_PROBES) {
LOGGER.debug("Max allowed log probes reached, ignoring new probe: {}", probe);
return;
}
definitions.add(probe);
logProbeCount++;
}

void add(SpanProbe probe) {
if (spanProbeCount >= MAX_ALLOWED_SPAN_PROBES) {
LOGGER.debug("Max allowed span probes reached, ignoring new probe: {}", probe);
return;
}
definitions.add(probe);
spanProbeCount++;
}

void add(TriggerProbe probe) {
if (triggerProbeCount >= MAX_ALLOWED_TRIGGER_PROBES) {
LOGGER.debug("Max allowed trigger probes reached, ignoring new probe: {}", probe);
return;
}
definitions.add(probe);
triggerProbeCount++;
}

void add(SpanDecorationProbe probe) {
if (spanDecorationProbeCount >= MAX_ALLOWED_SPAN_DECORATION_PROBES) {
LOGGER.debug("Max allowed span decoration probes reached, ignoring new probe: {}", probe);
return;
}
definitions.add(probe);
spanDecorationProbeCount++;
}

void addAll(Collection<ProbeDefinition> newDefinitions) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,20 @@ public TagValue getValue() {
public String toString() {
return "Tag{" + "name='" + name + '\'' + ", value=" + value + '}';
}

@Generated
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
Tag tag = (Tag) o;
return Objects.equals(name, tag.name) && Objects.equals(value, tag.value);
}

@Generated
@Override
public int hashCode() {
return Objects.hash(name, value);
}
}

public static class Decoration {
Expand All @@ -108,6 +122,20 @@ public List<Tag> getTags() {
public String toString() {
return "Decoration{" + "when=" + when + ", tags=" + tags + '}';
}

@Generated
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
Decoration that = (Decoration) o;
return Objects.equals(when, that.when) && Objects.equals(tags, that.tags);
}

@Generated
@Override
public int hashCode() {
return Objects.hash(when, tags);
}
}

private final TargetSpan targetSpan;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
package com.datadog.debugger.agent;

import static com.datadog.debugger.agent.DebuggerProductChangesListener.MAX_ALLOWED_LOG_PROBES;
import static com.datadog.debugger.agent.DebuggerProductChangesListener.MAX_ALLOWED_METRIC_PROBES;
import static com.datadog.debugger.agent.DebuggerProductChangesListener.MAX_ALLOWED_SPAN_DECORATION_PROBES;
import static com.datadog.debugger.agent.DebuggerProductChangesListener.MAX_ALLOWED_SPAN_PROBES;
import static com.datadog.debugger.util.LogProbeTestHelper.parseTemplate;
import static datadog.remoteconfig.PollingHinterNoop.NOOP;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
Expand All @@ -19,8 +15,11 @@
import com.datadog.debugger.probe.ProbeDefinition;
import com.datadog.debugger.probe.SpanDecorationProbe;
import com.datadog.debugger.probe.SpanProbe;
import com.datadog.debugger.probe.TriggerProbe;
import com.datadog.debugger.probe.Where;
import datadog.remoteconfig.state.ParsedConfigKey;
import datadog.trace.api.Config;
import datadog.trace.bootstrap.debugger.ProbeId;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
Expand Down Expand Up @@ -133,6 +132,9 @@ public void testMultipleSingleProbesConfigurations() {
MetricProbe metricProbe = createMetricProbe(UUID.randomUUID().toString());
LogProbe logProbe = createLogProbe(UUID.randomUUID().toString());
SpanProbe spanProbe = createSpanProbe(UUID.randomUUID().toString());
SpanDecorationProbe spanDecorationProbe =
createSpanDecorationProbe(UUID.randomUUID().toString());
TriggerProbe triggerProbe = createTriggerProbe(UUID.randomUUID().toString());

acceptMetricProbe(listener, metricProbe);
listener.commit(NOOP);
Expand All @@ -146,16 +148,40 @@ public void testMultipleSingleProbesConfigurations() {
listener.commit(NOOP);
assertDefinitions(acceptor.getDefinitions(), metricProbe, logProbe, spanProbe);

acceptSpanDecorationProbe(listener, spanDecorationProbe);
listener.commit(NOOP);
assertDefinitions(
acceptor.getDefinitions(), metricProbe, logProbe, spanProbe, spanDecorationProbe);

acceptTriggerProbe(listener, triggerProbe);
listener.commit(NOOP);
assertDefinitions(
acceptor.getDefinitions(),
metricProbe,
logProbe,
spanProbe,
spanDecorationProbe,
triggerProbe);

removeMetricProbe(listener, metricProbe);
listener.commit(NOOP);
assertDefinitions(acceptor.getDefinitions(), logProbe, spanProbe);
assertDefinitions(
acceptor.getDefinitions(), logProbe, spanProbe, spanDecorationProbe, triggerProbe);

removeLogProbe(listener, logProbe);
listener.commit(NOOP);
assertDefinitions(acceptor.getDefinitions(), spanProbe);
assertDefinitions(acceptor.getDefinitions(), spanProbe, spanDecorationProbe, triggerProbe);

removeSpanProbe(listener, spanProbe);
listener.commit(NOOP);
assertDefinitions(acceptor.getDefinitions(), spanDecorationProbe, triggerProbe);

removeSpanDecorationProbe(listener, spanDecorationProbe);
listener.commit(NOOP);
assertDefinitions(acceptor.getDefinitions(), triggerProbe);

removeTriggerProbe(listener, triggerProbe);
listener.commit(NOOP);
assertTrue(acceptor.getDefinitions().isEmpty());
}

Expand All @@ -170,13 +196,17 @@ public void testMergeConfigWithSingleProbe() {
MetricProbe metricProbe = createMetricProbe("345");
LogProbe logProbe = createLogProbe("567");
SpanProbe spanProbe = createSpanProbe("890");
SpanDecorationProbe spanDecorationProbe = createSpanDecorationProbe("891");
TriggerProbe triggerProbe = createTriggerProbe("892");

Configuration config =
Configuration.builder()
.setService(SERVICE_NAME)
.add(metricProbe)
.add(logProbe)
.add(spanProbe)
.add(spanDecorationProbe)
.add(triggerProbe)
.add(new LogProbe.Sampling(3.0))
.addDenyList(createFilteredList())
.build();
Expand All @@ -185,7 +215,13 @@ public void testMergeConfigWithSingleProbe() {
acceptConfig(listener, config, UUID.randomUUID().toString());
listener.commit(NOOP);
assertDefinitions(
acceptor.getDefinitions(), logProbeWithSnapshot, metricProbe, logProbe, spanProbe);
acceptor.getDefinitions(),
logProbeWithSnapshot,
metricProbe,
logProbe,
spanProbe,
spanDecorationProbe,
triggerProbe);
}

@Test
Expand All @@ -197,74 +233,6 @@ public void badConfigIDFailsToAccept() throws IOException {
assertNull(acceptor.definitions);
}

@Test
public void maxLogProbes() {
SimpleAcceptor acceptor = new SimpleAcceptor();
DebuggerProductChangesListener listener =
new DebuggerProductChangesListener(tracerConfig, acceptor);
for (int i = 0; i < 200; i++) {
LogProbe probe =
LogProbe.builder()
.probeId(String.valueOf(i), 0)
.where("java.lang.String", "concat" + i)
.build();
acceptLogProbe(listener, probe);
}
listener.commit(NOOP);
assertEquals(MAX_ALLOWED_LOG_PROBES, acceptor.getDefinitions().size());
}

@Test
public void maxMetricProbes() {
SimpleAcceptor acceptor = new SimpleAcceptor();
DebuggerProductChangesListener listener =
new DebuggerProductChangesListener(tracerConfig, acceptor);
for (int i = 0; i < 200; i++) {
MetricProbe probe =
MetricProbe.builder()
.probeId(String.valueOf(i), 0)
.where("java.lang.String", "concat" + i)
.build();
acceptMetricProbe(listener, probe);
}
listener.commit(NOOP);
assertEquals(MAX_ALLOWED_METRIC_PROBES, acceptor.getDefinitions().size());
}

@Test
public void maxSpanProbes() {
SimpleAcceptor acceptor = new SimpleAcceptor();
DebuggerProductChangesListener listener =
new DebuggerProductChangesListener(tracerConfig, acceptor);
for (int i = 0; i < 200; i++) {
SpanProbe probe =
SpanProbe.builder()
.probeId(String.valueOf(i), 0)
.where("java.lang.String", "concat" + i)
.build();
acceptSpanProbe(listener, probe);
}
listener.commit(NOOP);
assertEquals(MAX_ALLOWED_SPAN_PROBES, acceptor.getDefinitions().size());
}

@Test
public void maxSpanDecorationProbes() {
SimpleAcceptor acceptor = new SimpleAcceptor();
DebuggerProductChangesListener listener =
new DebuggerProductChangesListener(tracerConfig, acceptor);
for (int i = 0; i < 200; i++) {
SpanDecorationProbe probe =
SpanDecorationProbe.builder()
.probeId(String.valueOf(i), 0)
.where("java.lang.String", "concat" + i)
.build();
acceptSpanDecorationProbe(listener, probe);
}
listener.commit(NOOP);
assertEquals(MAX_ALLOWED_SPAN_DECORATION_PROBES, acceptor.getDefinitions().size());
}

@Test
public void parsingException() throws IOException {
SimpleAcceptor acceptor = new SimpleAcceptor();
Expand Down Expand Up @@ -320,6 +288,12 @@ byte[] toContent(SpanDecorationProbe probe) {
.getBytes(StandardCharsets.UTF_8);
}

byte[] toContent(TriggerProbe probe) {
return DebuggerProductChangesListener.Adapter.TRIGGER_PROBE_JSON_ADAPTER
.toJson(probe)
.getBytes(StandardCharsets.UTF_8);
}

void acceptConfig(
DebuggerProductChangesListener listener, Configuration config, String configId) {
assertDoesNotThrow(() -> listener.accept(createConfigKey(configId), toContent(config), NOOP));
Expand Down Expand Up @@ -361,10 +335,28 @@ void acceptSpanDecorationProbe(
createConfigKey("spanDecorationProbe_" + probe.getId()), toContent(probe), NOOP));
}

void acceptTriggerProbe(DebuggerProductChangesListener listener, TriggerProbe probe) {
assertDoesNotThrow(
() ->
listener.accept(
createConfigKey("triggerProbe_" + probe.getId()), toContent(probe), NOOP));
}

void removeSpanProbe(DebuggerProductChangesListener listener, SpanProbe probe) {
assertDoesNotThrow(() -> listener.remove(createConfigKey("spanProbe_" + probe.getId()), NOOP));
}

void removeSpanDecorationProbe(
DebuggerProductChangesListener listener, SpanDecorationProbe probe) {
assertDoesNotThrow(
() -> listener.remove(createConfigKey("spanDecorationProbe_" + probe.getId()), NOOP));
}

void removeTriggerProbe(DebuggerProductChangesListener listener, TriggerProbe probe) {
assertDoesNotThrow(
() -> listener.remove(createConfigKey("triggerProbe_" + probe.getId()), NOOP));
}

LogProbe createLogProbeWithSnapshot(String id) {
return LogProbe.builder()
.probeId(id, 0)
Expand Down Expand Up @@ -397,6 +389,18 @@ SpanProbe createSpanProbe(String id) {
.build();
}

SpanDecorationProbe createSpanDecorationProbe(String id) {
return SpanDecorationProbe.builder()
.probeId(id, 0)
.where(null, null, null, 1966, "src/main/java/java/lang/String.java")
.targetSpan(SpanDecorationProbe.TargetSpan.ACTIVE)
.build();
}

TriggerProbe createTriggerProbe(String id) {
return new TriggerProbe(new ProbeId(id, 0), Where.of("java.lang.String", "indexOf", null));
}

Configuration.FilterList createFilteredList() {
return new Configuration.FilterList(
Collections.singletonList("datadog"), Collections.singletonList("class1"));
Expand Down