Skip to content

Commit 4416578

Browse files
authored
Fix metric expressions with @return (#10178)
When compiling the metric expression using @return synthetic variable, the type of @return was not propagated correctly and the generic Object type was used instead which prevent to call length() when this is a String. Fix also reporting errors as ProbeSatus by returning Error status when instrumenting.
1 parent 7055fd6 commit 4416578

File tree

4 files changed

+43
-2
lines changed

4 files changed

+43
-2
lines changed

dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/MetricInstrumenter.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ public class MetricInstrumenter extends Instrumenter {
8282
private final MetricProbe metricProbe;
8383
private int durationStartVar = -1;
8484
private LabelNode durationStartLabel;
85+
private InstrumentationResult.Status status = InstrumentationResult.Status.INSTALLED;
8586

8687
public MetricInstrumenter(
8788
MetricProbe metricProbe,
@@ -116,7 +117,13 @@ public InstrumentationResult.Status instrument() {
116117
throw new IllegalArgumentException(
117118
"Invalid evaluateAt attribute: " + definition.getEvaluateAt());
118119
}
119-
return InstrumentationResult.Status.INSTALLED;
120+
return status;
121+
}
122+
123+
@Override
124+
protected void reportError(String message) {
125+
super.reportError(message);
126+
status = InstrumentationResult.Status.ERROR;
120127
}
121128

122129
private void addFinallyHandler(LabelNode endLabel) {
@@ -185,7 +192,7 @@ protected InsnList getBeforeReturnInsnList(AbstractInsnNode node) {
185192
case Opcodes.ARETURN:
186193
storeOpCode = Opcodes.ASTORE;
187194
loadOpCode = Opcodes.ALOAD;
188-
returnType = OBJECT_TYPE;
195+
returnType = Type.getReturnType(this.methodNode.desc);
189196
break;
190197
default:
191198
throw new UnsupportedOperationException("Unsupported opcode: " + node.getOpcode());

dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/MetricProbesInstrumentationTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,25 @@ public void methodSyntheticReturnGaugeMetric() throws IOException, URISyntaxExce
399399
assertArrayEquals(new String[] {METRIC_PROBEID_TAG}, listener.lastTags);
400400
}
401401

402+
@Test
403+
public void methodSyntheticReturnLenGaugeMetric() throws IOException, URISyntaxException {
404+
final String CLASS_NAME = "com.datadog.debugger.CapturedSnapshot32";
405+
String METRIC_NAME = "syn_gauge";
406+
MetricProbe metricProbe =
407+
createMetricBuilder(METRIC_ID, METRIC_NAME, GAUGE)
408+
.where(CLASS_NAME, "processArg", "(String)")
409+
.valueScript(new ValueScript(DSL.len(DSL.ref("@return")), "len(@return)"))
410+
.evaluateAt(MethodLocation.EXIT)
411+
.build();
412+
MetricForwarderListener listener = installMetricProbes(metricProbe);
413+
Class<?> testClass = compileAndLoadClass(CLASS_NAME);
414+
int result = Reflect.on(testClass).call("main", "foobar").get();
415+
assertEquals(42, result);
416+
assertTrue(listener.gauges.containsKey(METRIC_NAME));
417+
assertEquals(6, listener.gauges.get(METRIC_NAME).longValue());
418+
assertArrayEquals(new String[] {METRIC_PROBEID_TAG}, listener.lastTags);
419+
}
420+
402421
@Test
403422
public void methodSyntheticReturnInvalidType() throws IOException, URISyntaxException {
404423
final String CLASS_NAME = "CapturedSnapshot06";
-229 Bytes
Binary file not shown.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.datadog.debugger;
2+
3+
public class CapturedSnapshot32 {
4+
public static int main(String arg) throws Exception {
5+
arg = processArg(arg);
6+
return 42;
7+
}
8+
9+
public static String processArg(String arg) {
10+
if (arg.startsWith("-")) {
11+
arg = arg.substring(1);
12+
}
13+
return arg;
14+
}
15+
}

0 commit comments

Comments
 (0)