Skip to content

Commit d0e7a4c

Browse files
committed
fix: priming for powertools-tracing
1 parent 5b47395 commit d0e7a4c

File tree

5 files changed

+6094
-1
lines changed

5 files changed

+6094
-1
lines changed

docs/core/tracing.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,3 +447,52 @@ Below is an example configuration needed for each test case.
447447
// test logic
448448
}
449449
```
450+
## Advanced
451+
452+
### Lambda SnapStart priming
453+
454+
The Tracing utility integrates with AWS Lambda SnapStart to improve restore durations. To make sure the SnapStart priming logic of this utility runs correctly, you need an explicit reference to `TracingUtils` in your code to allow the library to register before SnapStart takes a memory snapshot. Learn more about what priming is in this [blog post](https://aws.amazon.com/blogs/compute/optimizing-cold-start-performance-of-aws-lambda-using-advanced-priming-strategies-with-snapstart/){target="_blank"}.
455+
456+
If you don't set a custom `TracingUtils` in your code yet, make sure to reference `TracingUtils` in your Lambda handler initialization code. This can be done by adding one of the following lines to your handler class:
457+
458+
=== "Constructor"
459+
460+
```java hl_lines="7"
461+
import software.amazon.lambda.powertools.validation.Validation;
462+
import software.amazon.lambda.powertools.validation.ValidationConfig;
463+
464+
public class MyFunctionHandler implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
465+
466+
public MyFunctionHandler() {
467+
TracingUtils.putAnnotation("init", "priming"); // Ensure TracingUtils is loaded for SnapStart
468+
}
469+
470+
@Override
471+
@Validation(inboundSchema = "classpath:/schema_in.json", outboundSchema = "classpath:/schema_out.json")
472+
public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent input, Context context) {
473+
// ...
474+
return something;
475+
}
476+
}
477+
```
478+
479+
=== "Static Initializer"
480+
481+
```java hl_lines="7"
482+
import software.amazon.lambda.powertools.validation.Validation;
483+
import software.amazon.lambda.powertools.validation.ValidationConfig;
484+
485+
public class MyFunctionHandler implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
486+
487+
static {
488+
TracingUtils.putAnnotation("init", "priming"); // Ensure TracingUtils is loaded for SnapStart
489+
}
490+
491+
@Override
492+
@Validation(inboundSchema = "classpath:/schema_in.json", outboundSchema = "classpath:/schema_out.json")
493+
public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent input, Context context) {
494+
// ...
495+
return something;
496+
}
497+
}
498+
```

powertools-tracing/pom.xml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
</description>
3434

3535
<dependencies>
36+
<dependency>
37+
<groupId>org.crac</groupId>
38+
<artifactId>crac</artifactId>
39+
</dependency>
3640
<dependency>
3741
<groupId>org.aspectj</groupId>
3842
<artifactId>aspectjrt</artifactId>
@@ -130,6 +134,24 @@
130134
</dependencies>
131135

132136
<profiles>
137+
<profile>
138+
<id>generate-classesloaded-file</id>
139+
<build>
140+
<plugins>
141+
<plugin>
142+
<groupId>org.apache.maven.plugins</groupId>
143+
<artifactId>maven-surefire-plugin</artifactId>
144+
<configuration>
145+
<argLine>
146+
-Xlog:class+load=info:classesloaded.txt
147+
--add-opens java.base/java.util=ALL-UNNAMED
148+
--add-opens java.base/java.lang=ALL-UNNAMED
149+
</argLine>
150+
</configuration>
151+
</plugin>
152+
</plugins>
153+
</build>
154+
</profile>
133155
<profile>
134156
<id>generate-graalvm-files</id>
135157
<build>

powertools-tracing/src/main/java/software/amazon/lambda/powertools/tracing/TracingUtils.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,32 @@
1616

1717
import static software.amazon.lambda.powertools.common.internal.LambdaHandlerProcessor.serviceName;
1818

19+
import org.crac.Context;
20+
import org.crac.Core;
21+
import org.crac.Resource;
1922
import com.amazonaws.xray.AWSXRay;
2023
import com.amazonaws.xray.entities.Entity;
2124
import com.amazonaws.xray.entities.Subsegment;
2225
import com.fasterxml.jackson.databind.ObjectMapper;
2326
import java.util.function.Consumer;
2427
import org.slf4j.Logger;
2528
import org.slf4j.LoggerFactory;
29+
import software.amazon.lambda.powertools.common.internal.ClassPreLoader;
2630

2731
/**
2832
* A class of helper functions to add additional functionality and ease
2933
* of use.
3034
*/
31-
public final class TracingUtils {
35+
public final class TracingUtils implements Resource{
3236
private static final Logger LOG = LoggerFactory.getLogger(TracingUtils.class);
3337
private static ObjectMapper objectMapper;
3438

39+
private static final TracingUtils INSTANCE = new TracingUtils();
40+
41+
static {
42+
Core.getGlobalContext().register(INSTANCE);
43+
}
44+
3545
/**
3646
* Put an annotation to the current subsegment with a String value.
3747
*
@@ -192,4 +202,15 @@ public static void defaultObjectMapper(ObjectMapper objectMapper) {
192202
public static ObjectMapper objectMapper() {
193203
return objectMapper;
194204
}
205+
206+
@Override
207+
public void beforeCheckpoint(Context<? extends Resource> context) throws Exception {
208+
new TracingUtils();
209+
ClassPreLoader.preloadClasses();
210+
}
211+
212+
@Override
213+
public void afterRestore(Context<? extends Resource> context) throws Exception {
214+
215+
}
195216
}

0 commit comments

Comments
 (0)