Skip to content

Commit 4d2e562

Browse files
authored
feat(crac): Support CRaC and priming of powertools tracing (#2345)
* fix: cold start only on on-demand invocation * fix: cold start only on on-demand invocation * fix: cold start only on on-demand invocation * mvn clean test is successful * reversed the sqllite changes * fix: priming for powertools-tracing * reverted OS specific changes * mvn clean test is successful * reversed the sqllite changes * fix: priming for powertools-tracing * reverted OS specific changes * resolved testing issues * resolved testing issues * resolved testing issues * resolved testing issues * resolved testing issues * incorporated comments * Update pom.xml
1 parent 54fe0be commit 4d2e562

File tree

6 files changed

+6134
-1
lines changed

6 files changed

+6134
-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.init(); // 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.init(); // 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: 41 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>
@@ -80,6 +84,11 @@
8084
</dependency>
8185

8286
<!-- Test dependencies -->
87+
<dependency>
88+
<groupId>org.mockito</groupId>
89+
<artifactId>mockito-core</artifactId>
90+
<scope>test</scope>
91+
</dependency>
8392
<dependency>
8493
<groupId>org.junit.jupiter</groupId>
8594
<artifactId>junit-jupiter-api</artifactId>
@@ -144,8 +153,33 @@
144153
</build>
145154

146155
<profiles>
156+
<profile>
157+
<id>generate-classesloaded-file</id>
158+
<build>
159+
<plugins>
160+
<plugin>
161+
<groupId>org.apache.maven.plugins</groupId>
162+
<artifactId>maven-surefire-plugin</artifactId>
163+
<configuration>
164+
<argLine>
165+
-Xlog:class+load=info:classesloaded.txt
166+
--add-opens java.base/java.util=ALL-UNNAMED
167+
--add-opens java.base/java.lang=ALL-UNNAMED
168+
</argLine>
169+
</configuration>
170+
</plugin>
171+
</plugins>
172+
</build>
173+
</profile>
147174
<profile>
148175
<id>generate-graalvm-files</id>
176+
<dependencies>
177+
<dependency>
178+
<groupId>org.mockito</groupId>
179+
<artifactId>mockito-subclass</artifactId>
180+
<scope>test</scope>
181+
</dependency>
182+
</dependencies>
149183
<build>
150184
<plugins>
151185
<plugin>
@@ -165,6 +199,13 @@
165199
</profile>
166200
<profile>
167201
<id>graalvm-native</id>
202+
<dependencies>
203+
<dependency>
204+
<groupId>org.mockito</groupId>
205+
<artifactId>mockito-subclass</artifactId>
206+
<scope>test</scope>
207+
</dependency>
208+
</dependencies>
168209
<build>
169210
<plugins>
170211
<plugin>

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

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,37 @@
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+
45+
public static void init() {
46+
// Placeholder method used to enable SnapStart priming. Users need a direct reference to this class in order for the CRaC hooks to execute.
47+
new TracingUtils();
48+
}
49+
3550
/**
3651
* Put an annotation to the current subsegment with a String value.
3752
*
@@ -192,4 +207,15 @@ public static void defaultObjectMapper(ObjectMapper objectMapper) {
192207
public static ObjectMapper objectMapper() {
193208
return objectMapper;
194209
}
210+
211+
@Override
212+
public void beforeCheckpoint(Context<? extends Resource> context) throws Exception {
213+
init();
214+
ClassPreLoader.preloadClasses();
215+
}
216+
217+
@Override
218+
public void afterRestore(Context<? extends Resource> context) throws Exception {
219+
// This is a no-op, as we don't need to do anything after restore
220+
}
195221
}

0 commit comments

Comments
 (0)