Skip to content

Commit 4a5a11b

Browse files
authored
refactor: consistent naming of powertools tracing and initial docs. (#48)
1 parent 7fcd7f7 commit 4a5a11b

File tree

15 files changed

+214
-76
lines changed

15 files changed

+214
-76
lines changed

docs/content/core/logger.mdx renamed to docs/content/core/logging.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: Logger
2+
title: Logging
33
description: Core utility
44
---
55

docs/content/core/tracer.mdx

-12
This file was deleted.

docs/content/core/tracing.mdx

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
title: Tracing
3+
description: Core utility
4+
---
5+
6+
import Note from "../../src/components/Note"
7+
8+
Powertools tracing is an opinionated thin wrapper for [AWS X-Ray Java SDK](https://github.com/aws/aws-xray-sdk-java/)
9+
a provides functionality to reduce the overhead of performing common tracing tasks.
10+
11+
** Key Features
12+
13+
* Capture cold start as annotation, and responses as well as full exceptions as metadata
14+
* Helper methods to improve the developer experience of creating new X-Ray subsegments.
15+
* Better developer experience when developing with multiple threads.
16+
17+
Initialization
18+
Your AWS Lambda function must have permission to send traces to AWS X-Ray - Here is an example using AWS Serverless Application Model (SAM)
19+
20+
```yaml:title=template.yaml
21+
Resources:
22+
HelloWorldFunction:
23+
Type: AWS::Serverless::Function
24+
Properties:
25+
...
26+
Runtime: java8
27+
28+
Tracing: Active
29+
Environment:
30+
Variables:
31+
POWERTOOLS_SERVICE_NAME: example
32+
```
33+
34+
The Powertools service name is used as the X-Ray namespace. This can be set using the environment variable
35+
`POWERTOOLS_SERVICE_NAME`
36+
37+
To enable Powertools tracing to your function add the @PowertoolsTracing annotation to your handleRequest method.
38+
39+
```java
40+
public class App implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
41+
42+
@PowertoolsTracing
43+
public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent input, Context context) {
44+
...
45+
}
46+
```
47+
48+
By default this annotation will automatically record method responses and exceptions. To disable these features set the
49+
parameter to false in the annotation.
50+
51+
```java
52+
public class App implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
53+
54+
@PowertoolsTracing(captureError = false, captureResponse = false)
55+
public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent input, Context context) {
56+
...
57+
}
58+
```

docs/gatsby-config.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ module.exports = {
2323
'index'
2424
],
2525
'Core utilities': [
26-
'core/tracer',
27-
'core/logger'
26+
'core/logging',
27+
'core/tracing'
2828
]
2929
},
3030
navConfig: {

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
import org.apache.logging.log4j.Logger;
1111
import software.amazon.lambda.powertools.logging.PowertoolsLogger;
1212
import software.amazon.lambda.powertools.logging.PowertoolsLogging;
13-
import software.amazon.lambda.powertools.tracing.PowerToolsTracing;
1413
import software.amazon.lambda.powertools.tracing.PowerTracer;
14+
import software.amazon.lambda.powertools.tracing.PowertoolsTracing;
1515

1616
import java.io.BufferedReader;
1717
import java.io.IOException;
@@ -32,7 +32,7 @@ public class App implements RequestHandler<APIGatewayProxyRequestEvent, APIGatew
3232
Logger log = LogManager.getLogger();
3333

3434
@PowertoolsLogging(logEvent = true)
35-
@PowerToolsTracing
35+
@PowertoolsTracing(captureError = false, captureResponse = false)
3636
public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) {
3737
Map<String, String> headers = new HashMap<>();
3838

@@ -90,13 +90,13 @@ private void threadOption2() throws InterruptedException {
9090
anotherThread.join();
9191
}
9292

93-
@PowerToolsTracing
93+
@PowertoolsTracing
9494
private void log() {
9595
log.info("inside threaded logging for function");
9696
}
9797

9898

99-
@PowerToolsTracing(namespace = "getPageContents", captureResponse = false, captureError = false)
99+
@PowertoolsTracing(namespace = "getPageContents", captureResponse = false, captureError = false)
100100
private String getPageContents(String address) throws IOException {
101101
URL url = new URL(address);
102102
putMetadata("getPageContents", address);

powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/PowertoolsLogging.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
*
2525
* <p>{@code PowertoolsLogging} provides an opinionated logger with output structured as JSON.</p>
2626
*
27-
* <p>{@code PowertoolsLogging} should be used with handleRequest method of a class
27+
* <p>{@code PowertoolsLogging} should be used with the handleRequest method of a class
2828
* which implements either
2929
* {@code com.amazonaws.services.lambda.runtime.RequestHandler} or
3030
* {@code com.amazonaws.services.lambda.runtime.RequestStreamHandler}.</p>

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

-27
This file was deleted.

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

+72-2
Original file line numberDiff line numberDiff line change
@@ -13,47 +13,117 @@
1313
*/
1414
package software.amazon.lambda.powertools.tracing;
1515

16-
import java.util.function.Consumer;
17-
1816
import com.amazonaws.xray.AWSXRay;
1917
import com.amazonaws.xray.entities.Entity;
2018
import com.amazonaws.xray.entities.Subsegment;
2119

20+
import java.util.function.Consumer;
21+
2222
import static software.amazon.lambda.powertools.core.internal.LambdaHandlerProcessor.serviceName;
2323

24+
/**
25+
* A class of helper functions to add additional functionality and ease
26+
* of use.
27+
*
28+
*/
2429
public final class PowerTracer {
2530

31+
/**
32+
* Put an annotation to the current subsegment.
33+
*
34+
* @param key the key of the annotation
35+
* @param value the value of the annotation
36+
*/
2637
public static void putAnnotation(String key, String value) {
2738
AWSXRay.getCurrentSubsegmentOptional()
2839
.ifPresent(segment -> segment.putAnnotation(key, value));
2940
}
3041

42+
/**
43+
* Put additional metadata for the current subsegment.
44+
*
45+
* The namespace used will be the namespace of the current subsegment if it
46+
* is set else it will follow the namespace process as described in
47+
* {@link PowertoolsTracing}
48+
*
49+
* @param key the key of the metadata
50+
* @param value the value of the metadata
51+
*/
3152
public static void putMetadata(String key, Object value) {
3253
String namespace = AWSXRay.getCurrentSubsegmentOptional()
3354
.map(Subsegment::getNamespace).orElse(serviceName());
3455

3556
putMetadata(namespace, key, value);
3657
}
3758

59+
/**
60+
* Put additional metadata for the current subsegment.
61+
*
62+
* @param namespace the namespace of the metadata
63+
* @param key the key of the metadata
64+
* @param value the value of the metadata
65+
*/
3866
public static void putMetadata(String namespace, String key, Object value) {
3967
AWSXRay.getCurrentSubsegmentOptional()
4068
.ifPresent(segment -> segment.putMetadata(namespace, key, value));
4169
}
4270

71+
/**
72+
* Adds a new subsegment around the passed consumer. This also provides access to
73+
* the newly created subsegment.
74+
*
75+
* The namespace used follows the flow as described in {@link PowertoolsTracing}
76+
*
77+
* This method is intended for use with multi-threaded programming where the
78+
* context is lost between threads.
79+
*
80+
* @param name the name of the subsegment
81+
* @param entity the current x-ray context
82+
* @param subsegment the x-ray subsegment for the wrapped consumer
83+
*/
4384
public static void withEntitySubsegment(String name, Entity entity, Consumer<Subsegment> subsegment) {
4485
AWSXRay.setTraceEntity(entity);
4586
withEntitySubsegment(serviceName(), name, entity, subsegment);
4687
}
4788

89+
/**
90+
* Adds a new subsegment around the passed consumer. This also provides access to
91+
* the newly created subsegment.
92+
*
93+
* This method is intended for use with multi-threaded programming where the
94+
* context is lost between threads.
95+
*
96+
* @param namespace the namespace of the subsegment
97+
* @param name the name of the subsegment
98+
* @param entity the current x-ray context
99+
* @param subsegment the x-ray subsegment for the wrapped consumer
100+
*/
48101
public static void withEntitySubsegment(String namespace, String name, Entity entity, Consumer<Subsegment> subsegment) {
49102
AWSXRay.setTraceEntity(entity);
50103
withSubsegment(namespace, name, subsegment);
51104
}
52105

106+
/**
107+
* Adds a new subsegment around the passed consumer. This also provides access to
108+
* the newly created subsegment.
109+
*
110+
* The namespace used follows the flow as described in {@link PowertoolsTracing}
111+
*
112+
* @param name the name of the subsegment
113+
* @param subsegment the x-ray subsegment for the wrapped consumer
114+
*/
53115
public static void withSubsegment(String name, Consumer<Subsegment> subsegment) {
54116
withSubsegment(serviceName(), name, subsegment);
55117
}
56118

119+
/**
120+
* Adds a new subsegment around the passed consumer. This also provides access to
121+
* the newly created subsegment.
122+
*
123+
* @param namespace the namespace for the subsegment
124+
* @param name the name of the subsegment
125+
* @param subsegment the x-ray subsegment for the wrapped consumer
126+
*/
57127
public static void withSubsegment(String namespace, String name, Consumer<Subsegment> subsegment) {
58128
Subsegment segment = AWSXRay.beginSubsegment("## " + name);
59129
segment.setNamespace(namespace);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright 2020 Amazon.com, Inc. or its affiliates.
3+
* Licensed under the Apache License, Version 2.0 (the
4+
* "License"); you may not use this file except in compliance
5+
* with the License. You may obtain a copy of the License at
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
* limitations under the License.
12+
*
13+
*/
14+
package software.amazon.lambda.powertools.tracing;
15+
16+
import java.lang.annotation.ElementType;
17+
import java.lang.annotation.Retention;
18+
import java.lang.annotation.RetentionPolicy;
19+
import java.lang.annotation.Target;
20+
21+
/**
22+
* {@code PowertoolsTracing} is used to signal that the annotated method should
23+
* be extended with the Powertools tracing functionality.
24+
*
25+
* <p>{@code PowertoolsTracing} provides functionality to reduce the overhead
26+
* of performing common tracing tasks.</p>
27+
*
28+
* <p>{@code PowertoolsTracing} should be used with the handleRequest method of a class
29+
* which implements either
30+
* {@code com.amazonaws.services.lambda.runtime.RequestHandler} or
31+
* {@code com.amazonaws.services.lambda.runtime.RequestStreamHandler}.</p>
32+
*
33+
* <p>By default {@code PowertoolsTracing} will capture responses and add them
34+
* to a sub segment named after the method.</p>
35+
*
36+
* <p>To disable this functionality you can specify {@code @PowertoolsTracing( captureRespones = false)}</p>
37+
*
38+
* <p>By default {@code PowertoolsTracing} will capture errors and add them
39+
* to a sub segment named after the method.</p>
40+
*
41+
* <p>To disable this functionality you can specify {@code @PowertoolsTracing( captureError = false)}</p>
42+
*e
43+
* <p>All traces have a namespace set. If {@code @PowertoolsTracing( namespace = "ExampleService")} is set
44+
* this takes precedent over any value set in the environment variable {@code POWER_TOOLS_SERVICE_NAME}.
45+
* If both are undefined then the value will default to {@code service_undefined}</p>
46+
*/
47+
@Retention(RetentionPolicy.RUNTIME)
48+
@Target(ElementType.METHOD)
49+
public @interface PowertoolsTracing {
50+
String namespace() default "";
51+
boolean captureResponse() default true;
52+
boolean captureError() default true;
53+
}

powertools-tracing/src/main/java/software/amazon/lambda/powertools/tracing/internal/LambdaTracingAspect.java

+7-11
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import org.aspectj.lang.annotation.Around;
2020
import org.aspectj.lang.annotation.Aspect;
2121
import org.aspectj.lang.annotation.Pointcut;
22-
import software.amazon.lambda.powertools.tracing.PowerToolsTracing;
22+
import software.amazon.lambda.powertools.tracing.PowertoolsTracing;
2323

2424
import static software.amazon.lambda.powertools.core.internal.LambdaHandlerProcessor.coldStartDone;
2525
import static software.amazon.lambda.powertools.core.internal.LambdaHandlerProcessor.isColdStart;
@@ -33,25 +33,21 @@ public final class LambdaTracingAspect {
3333

3434
@SuppressWarnings({"EmptyMethod", "unused"})
3535
@Pointcut("@annotation(powerToolsTracing)")
36-
public void callAt(PowerToolsTracing powerToolsTracing) {
36+
public void callAt(PowertoolsTracing powerToolsTracing) {
3737
}
3838

39-
@Around(value = "callAt(powerToolsTracing) && execution(@PowerToolsTracing * *.*(..))", argNames = "pjp,powerToolsTracing")
39+
@Around(value = "callAt(powerToolsTracing) && execution(@PowertoolsTracing * *.*(..))", argNames = "pjp,powerToolsTracing")
4040
public Object around(ProceedingJoinPoint pjp,
41-
PowerToolsTracing powerToolsTracing) throws Throwable {
41+
PowertoolsTracing powerToolsTracing) throws Throwable {
4242
Object[] proceedArgs = pjp.getArgs();
43-
Subsegment segment;
4443

45-
segment = AWSXRay.beginSubsegment("## " + pjp.getSignature().getName());
44+
Subsegment segment = AWSXRay.beginSubsegment("## " + pjp.getSignature().getName());
4645
segment.setNamespace(namespace(powerToolsTracing));
4746

48-
boolean placedOnHandlerMethod = placedOnHandlerMethod(pjp);
49-
50-
if (placedOnHandlerMethod) {
47+
if (placedOnHandlerMethod(pjp)) {
5148
segment.putAnnotation("ColdStart", isColdStart() == null);
5249
}
5350

54-
5551
try {
5652
Object methodReturn = pjp.proceed(proceedArgs);
5753
if (powerToolsTracing.captureResponse()) {
@@ -70,7 +66,7 @@ public Object around(ProceedingJoinPoint pjp,
7066
}
7167
}
7268

73-
private String namespace(PowerToolsTracing powerToolsTracing) {
69+
private String namespace(PowertoolsTracing powerToolsTracing) {
7470
return powerToolsTracing.namespace().isEmpty() ? serviceName() : powerToolsTracing.namespace();
7571
}
7672

0 commit comments

Comments
 (0)