Skip to content

Commit 758914d

Browse files
author
Pankaj Agrawal
committed
Initial implementation of tracing support
1 parent 7efdbc0 commit 758914d

File tree

6 files changed

+123
-0
lines changed

6 files changed

+123
-0
lines changed

example/HelloWorldFunction/src/main/java/helloworld/App.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
import org.apache.logging.log4j.Logger;
1717
import software.aws.lambda.logging.PowerLogger;
1818
import software.aws.lambda.logging.PowerToolsLogging;
19+
import software.aws.lambda.tracing.PowerToolTracing;
20+
import software.aws.lambda.tracing.PowerTracer;
1921

2022
/**
2123
* Handler for requests to Lambda function.
@@ -25,6 +27,7 @@ public class App implements RequestHandler<APIGatewayProxyRequestEvent, APIGatew
2527
Logger log = LogManager.getLogger();
2628

2729
@PowerToolsLogging(logEvent = true)
30+
@PowerToolTracing
2831
public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) {
2932
Map<String, String> headers = new HashMap<>();
3033
headers.put("Content-Type", "application/json");
@@ -37,6 +40,7 @@ public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEv
3740
try {
3841
final String pageContents = this.getPageContents("https://checkip.amazonaws.com");
3942
log.info(pageContents);
43+
PowerTracer.putAnnotation("Test", "New");
4044
String output = String.format("{ \"message\": \"hello world\", \"location\": \"%s\" }", pageContents);
4145

4246
log.info("After output");
@@ -50,8 +54,10 @@ public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEv
5054
}
5155
}
5256

57+
@PowerToolTracing(namespace = "getPageContents")
5358
private String getPageContents(String address) throws IOException {
5459
URL url = new URL(address);
60+
PowerTracer.putMetadata("getPageContents", address);
5561
try (BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()))) {
5662
return br.lines().collect(Collectors.joining(System.lineSeparator()));
5763
}

example/template.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Resources:
2121
Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object
2222
Variables:
2323
PARAM1: VALUE
24+
Tracing: Active
2425
Events:
2526
HelloWorld:
2627
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
@@ -35,6 +36,7 @@ Resources:
3536
Handler: helloworld.AppStream::handleRequest
3637
Runtime: java8
3738
MemorySize: 512
39+
Tracing: Active
3840
Environment:
3941
Variables:
4042
PARAM1: VALUE

pom.xml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,32 @@
8383
<artifactId>aspectjrt</artifactId>
8484
<version>${aspectj.version}</version>
8585
</dependency>
86+
<dependency>
87+
<groupId>com.amazonaws</groupId>
88+
<artifactId>aws-xray-recorder-sdk-core</artifactId>
89+
<version>2.4.0</version>
90+
</dependency>
91+
<dependency>
92+
<groupId>com.amazonaws</groupId>
93+
<artifactId>aws-xray-recorder-sdk-aws-sdk</artifactId>
94+
<version>2.4.0</version>
95+
</dependency>
96+
<dependency>
97+
<groupId>com.amazonaws</groupId>
98+
<artifactId>aws-xray-recorder-sdk-aws-sdk-instrumentor</artifactId>
99+
<version>2.4.0</version>
100+
</dependency>
101+
<dependency>
102+
<groupId>com.amazonaws</groupId>
103+
<artifactId>aws-xray-recorder-sdk-aws-sdk-v2</artifactId>
104+
<version>2.4.0</version>
105+
</dependency>
106+
<dependency>
107+
<groupId>com.amazonaws</groupId>
108+
<artifactId>aws-xray-recorder-sdk-aws-sdk-v2-instrumentor</artifactId>
109+
<version>2.4.0</version>
110+
</dependency>
111+
86112

87113
<!-- Test dependencies -->
88114
<dependency>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package software.aws.lambda.tracing;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
@Retention(RetentionPolicy.RUNTIME)
9+
@Target(ElementType.METHOD)
10+
public @interface PowerToolTracing {
11+
String namespace() default "";
12+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package software.aws.lambda.tracing;
2+
3+
import com.amazonaws.xray.AWSXRay;
4+
import com.amazonaws.xray.entities.Entity;
5+
6+
public final class PowerTracer {
7+
private static final String SERVICE_NAME = System.getProperty("POWERTOOLS_SERVICE_NAME", "");
8+
9+
public static void carryForwardCurrentSegment(Entity entity) {
10+
AWSXRay.getGlobalRecorder().setTraceEntity(entity);
11+
}
12+
13+
public static void putAnnotation(String key, String value) {
14+
AWSXRay.getCurrentSubsegmentOptional()
15+
.ifPresent(segment -> segment.putAnnotation(key, value));
16+
}
17+
18+
public static void putMetadata(String key, Object value) {
19+
putMetadata(SERVICE_NAME, key, value);
20+
}
21+
22+
public static void putMetadata(String namespace, String key, Object value) {
23+
AWSXRay.getCurrentSubsegmentOptional()
24+
.ifPresent(segment -> segment.putMetadata(namespace, key, value));
25+
}
26+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package software.aws.lambda.tracing.internal;
2+
3+
import com.amazonaws.xray.AWSXRay;
4+
import com.amazonaws.xray.entities.Subsegment;
5+
import com.fasterxml.jackson.databind.ObjectMapper;
6+
import org.aspectj.lang.ProceedingJoinPoint;
7+
import org.aspectj.lang.annotation.Around;
8+
import org.aspectj.lang.annotation.Aspect;
9+
import org.aspectj.lang.annotation.Pointcut;
10+
import software.aws.lambda.tracing.PowerToolTracing;
11+
12+
@Aspect
13+
public final class LambdaTracingAspect {
14+
static Boolean IS_COLD_START = null;
15+
private static final ObjectMapper mapper = new ObjectMapper();
16+
17+
@Pointcut("@annotation(powerToolsTracing)")
18+
public void callAt(PowerToolTracing powerToolsTracing) {
19+
}
20+
21+
@Around(value = "callAt(powerToolsTracing) && execution(@PowerToolTracing * *.*(..))", argNames = "pjp,powerToolsTracing")
22+
public Object around(ProceedingJoinPoint pjp,
23+
PowerToolTracing powerToolsTracing) throws Throwable {
24+
Object[] proceedArgs = pjp.getArgs();
25+
Subsegment segment;
26+
27+
segment = AWSXRay.beginSubsegment("## " + pjp.getSignature().getName());
28+
29+
if (placedOnHandlerMethod(pjp)) {
30+
segment.putAnnotation("ColdStart", IS_COLD_START == null);
31+
}
32+
33+
IS_COLD_START = false;
34+
35+
try {
36+
Object proceed = pjp.proceed(proceedArgs);
37+
segment.putMetadata(powerToolsTracing.namespace(), pjp.getSignature().getName() + " response", proceed);
38+
return proceed;
39+
} catch (Exception e) {
40+
segment.putMetadata(powerToolsTracing.namespace(), pjp.getSignature().getName() + " error", e);
41+
throw e;
42+
} finally {
43+
AWSXRay.endSubsegment();
44+
}
45+
}
46+
47+
// TODO enrich to check more like inherited class
48+
private boolean placedOnHandlerMethod(ProceedingJoinPoint pjp) {
49+
return "handleRequest".equals(pjp.getSignature().getName());
50+
}
51+
}

0 commit comments

Comments
 (0)