Skip to content

Commit 5bd6139

Browse files
authored
Properly capture lambda payloads for all handler types. (#8264)
* Properly capture lambda payloads for all handler types. * Remove unused import. * Remove non-stream handler test. * Properly create OutputStream for testing.
1 parent 710964d commit 5bd6139

File tree

6 files changed

+45
-36
lines changed

6 files changed

+45
-36
lines changed

dd-java-agent/instrumentation/aws-lambda-handler/src/main/java/datadog/trace/instrumentation/aws/v1/lambda/LambdaHandlerInstrumentation.java

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import static net.bytebuddy.asm.Advice.OnMethodExit;
1111
import static net.bytebuddy.asm.Advice.Origin;
1212
import static net.bytebuddy.asm.Advice.This;
13-
import static net.bytebuddy.implementation.bytecode.assign.Assigner.Typing.DYNAMIC;
1413
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
1514
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
1615

@@ -66,20 +65,14 @@ protected boolean defaultEnabled() {
6665

6766
@Override
6867
public void methodAdvice(MethodTransformer transformer) {
69-
// two args
70-
transformer.applyAdvice(
71-
isMethod()
72-
.and(named("handleRequest"))
73-
.and(takesArgument(1, named("com.amazonaws.services.lambda.runtime.Context"))),
74-
getClass().getName() + "$ExtensionCommunicationAdvice");
75-
// three args (streaming)
68+
// lambda under the hood converts all handlers to streaming handlers via
69+
// lambdainternal.EventHandlerLoader$PojoHandlerAsStreamHandler.handleRequest
70+
// full spec here : https://docs.aws.amazon.com/lambda/latest/dg/java-handler.html
7671
transformer.applyAdvice(
7772
isMethod()
7873
.and(named("handleRequest"))
7974
.and(takesArgument(2, named("com.amazonaws.services.lambda.runtime.Context"))),
8075
getClass().getName() + "$ExtensionCommunicationAdvice");
81-
// full spec here : https://docs.aws.amazon.com/lambda/latest/dg/java-handler.html
82-
8376
}
8477

8578
public static class ExtensionCommunicationAdvice {
@@ -108,7 +101,7 @@ static AgentScope enter(
108101
static void exit(
109102
@Origin String method,
110103
@Enter final AgentScope scope,
111-
@Advice.Return(typing = DYNAMIC) final Object result,
104+
@Advice.Argument(1) final Object result,
112105
@Advice.Thrown final Throwable throwable) {
113106

114107
if (scope == null) {

dd-java-agent/instrumentation/aws-lambda-handler/src/test/groovy/Handler.java

Lines changed: 0 additions & 10 deletions
This file was deleted.

dd-java-agent/instrumentation/aws-lambda-handler/src/test/groovy/LambdaHandlerInstrumentationTest.groovy

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,6 @@ abstract class LambdaHandlerInstrumentationTest extends VersionedNamingTestBase
88
null
99
}
1010

11-
def "test lambda handler"() {
12-
when:
13-
new Handler().handleRequest(null, null)
14-
15-
then:
16-
assertTraces(1) {
17-
trace(1) {
18-
span {
19-
operationName operation()
20-
errored false
21-
}
22-
}
23-
}
24-
}
25-
2611
def "test lambda streaming handler"() {
2712
when:
2813
def input = new ByteArrayInputStream(StandardCharsets.UTF_8.encode("Hello").array())

dd-trace-core/src/main/java/datadog/trace/lambda/LambdaHandler.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import datadog.trace.bootstrap.instrumentation.api.AgentSpanContext;
1111
import datadog.trace.core.CoreTracer;
1212
import java.io.ByteArrayInputStream;
13+
import java.io.ByteArrayOutputStream;
1314
import java.nio.charset.StandardCharsets;
1415
import java.util.Base64;
1516
import okhttp3.ConnectionPool;
@@ -63,6 +64,7 @@ public class LambdaHandler {
6364
private static final JsonAdapter<Object> adapter =
6465
new Moshi.Builder()
6566
.add(ByteArrayInputStream.class, new ReadFromInputStreamJsonAdapter())
67+
.add(ByteArrayOutputStream.class, new ReadFromOutputStreamJsonAdapter())
6668
.add(SkipUnsupportedTypeJsonAdapter.newFactory())
6769
.build()
6870
.adapter(Object.class);
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package datadog.trace.lambda;
2+
3+
import com.squareup.moshi.JsonAdapter;
4+
import com.squareup.moshi.JsonReader;
5+
import com.squareup.moshi.JsonWriter;
6+
import java.io.ByteArrayOutputStream;
7+
import java.io.IOException;
8+
import okio.BufferedSink;
9+
10+
public final class ReadFromOutputStreamJsonAdapter extends JsonAdapter<ByteArrayOutputStream> {
11+
12+
@Override
13+
public ByteArrayOutputStream fromJson(JsonReader reader) throws IOException {
14+
throw new UnsupportedOperationException();
15+
}
16+
17+
@Override
18+
public void toJson(JsonWriter writer, ByteArrayOutputStream outputStream) throws IOException {
19+
if (outputStream != null) {
20+
BufferedSink sink = writer.valueSink();
21+
byte[] bytes = outputStream.toByteArray();
22+
sink.write(bytes);
23+
sink.flush();
24+
}
25+
}
26+
}

dd-trace-core/src/test/groovy/datadog/trace/lambda/LambdaHandlerTest.groovy

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,4 +308,17 @@ class LambdaHandlerTest extends DDCoreSpecification {
308308
then:
309309
result == body
310310
}
311+
312+
def "test moshi toJson OutputStream"() {
313+
given:
314+
def body = "{\"body\":\"bababango\",\"statusCode\":\"200\"}"
315+
def myEvent = new ByteArrayOutputStream()
316+
myEvent.write(body.getBytes(), 0, body.length())
317+
318+
when:
319+
def result = LambdaHandler.writeValueAsString(myEvent)
320+
321+
then:
322+
result == body
323+
}
311324
}

0 commit comments

Comments
 (0)