Skip to content

Commit bc1896c

Browse files
jdohertyjeromevdl
authored andcommitted
adding validation for tracing annotation keys
1 parent de547d0 commit bc1896c

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

powertools-tracing/pom.xml

+11
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@
4848
</developer>
4949
</developers>
5050

51+
<properties>
52+
<logback.version>1.2.11</logback.version>
53+
</properties>
54+
5155
<distributionManagement>
5256
<snapshotRepository>
5357
<id>ossrh</id>
@@ -115,6 +119,13 @@
115119
<artifactId>assertj-core</artifactId>
116120
<scope>test</scope>
117121
</dependency>
122+
<dependency>
123+
<groupId>ch.qos.logback</groupId>
124+
<artifactId>logback-classic</artifactId>
125+
<version>${logback.version}</version>
126+
<scope>test</scope>
127+
</dependency>
128+
118129
</dependencies>
119130

120131
<build>

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

+11
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,15 @@
2121
import com.amazonaws.xray.entities.Subsegment;
2222
import com.fasterxml.jackson.databind.ObjectMapper;
2323
import java.util.function.Consumer;
24+
import org.slf4j.Logger;
25+
import org.slf4j.LoggerFactory;
2426

2527
/**
2628
* A class of helper functions to add additional functionality and ease
2729
* of use.
2830
*/
2931
public final class TracingUtils {
32+
private static final Logger LOG = LoggerFactory.getLogger(TracingUtils.class);
3033
private static ObjectMapper objectMapper;
3134

3235
/**
@@ -36,6 +39,7 @@ public final class TracingUtils {
3639
* @param value the value of the annotation
3740
*/
3841
public static void putAnnotation(String key, String value) {
42+
validateAnnotationKey(key);
3943
AWSXRay.getCurrentSubsegmentOptional()
4044
.ifPresent(segment -> segment.putAnnotation(key, value));
4145
}
@@ -47,10 +51,17 @@ public static void putAnnotation(String key, String value) {
4751
* @param value the value of the annotation
4852
*/
4953
public static void putAnnotation(String key, Number value) {
54+
validateAnnotationKey(key);
5055
AWSXRay.getCurrentSubsegmentOptional()
5156
.ifPresent(segment -> segment.putAnnotation(key, value));
5257
}
5358

59+
private static void validateAnnotationKey(String key) {
60+
if (!key.matches("^[a-zA-Z0-9_]+$")) {
61+
LOG.warn("ignoring annotation with unsupported characters in key: {}", key);
62+
}
63+
}
64+
5465
/**
5566
* Put an annotation to the current subsegment with a Boolean value.
5667
*

powertools-tracing/src/test/java/software/amazon/lambda/powertools/tracing/TracingUtilsTest.java

+48
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,18 @@
2020
import static org.mockito.Mockito.verify;
2121
import static software.amazon.lambda.powertools.tracing.TracingUtils.withEntitySubsegment;
2222

23+
import ch.qos.logback.classic.Level;
24+
import ch.qos.logback.classic.Logger;
25+
import ch.qos.logback.classic.spi.ILoggingEvent;
26+
import ch.qos.logback.core.read.ListAppender;
2327
import com.amazonaws.services.lambda.runtime.Context;
2428
import com.amazonaws.xray.AWSXRay;
2529
import com.amazonaws.xray.entities.Entity;
30+
import java.util.List;
2631
import org.junit.jupiter.api.AfterEach;
2732
import org.junit.jupiter.api.BeforeEach;
2833
import org.junit.jupiter.api.Test;
34+
import org.slf4j.LoggerFactory;
2935

3036
class TracingUtilsTest {
3137

@@ -123,6 +129,48 @@ void shouldInvokeCodeBlockWrappedWithinSubsegment() {
123129
});
124130
}
125131

132+
@Test
133+
void shouldEmitNoLogWarnIfValidCharacterInKey() {
134+
AWSXRay.beginSubsegment("subSegment");
135+
Logger logger = (Logger) LoggerFactory.getLogger(TracingUtils.class);
136+
137+
// create and start a ListAppender
138+
ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
139+
listAppender.start();
140+
141+
// add the appender to the logger
142+
logger.addAppender(listAppender);
143+
144+
TracingUtils.putAnnotation("stringKey", "val");
145+
146+
List<ILoggingEvent> logsList = listAppender.list;
147+
assertThat(AWSXRay.getTraceEntity().getAnnotations())
148+
.hasSize(1)
149+
.contains(
150+
entry("stringKey", "val")
151+
);
152+
assertThat(logsList.size()).isZero();
153+
}
154+
155+
@Test
156+
void shouldEmitLogWarnIfInvalidCharacterInKey() {
157+
AWSXRay.beginSubsegment("subSegment");
158+
Logger logger = (Logger) LoggerFactory.getLogger(TracingUtils.class);
159+
160+
// create and start a ListAppender
161+
ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
162+
listAppender.start();
163+
164+
// add the appender to the logger
165+
logger.addAppender(listAppender);
166+
String inputKey = "stringKey with spaces";
167+
TracingUtils.putAnnotation(inputKey, "val");
168+
169+
List<ILoggingEvent> logsList = listAppender.list;
170+
assertThat(logsList.get(0).getLevel()).isEqualTo(Level.WARN);
171+
assertThat(logsList.get(0).getMessage()).isEqualTo("ignoring annotation with unsupported characters in key: {}",inputKey);
172+
}
173+
126174
@Test
127175
void shouldInvokeCodeBlockWrappedWithinNamespacedSubsegment() {
128176
Context test = mock(Context.class);

0 commit comments

Comments
 (0)