Skip to content

Commit f741035

Browse files
committed
Fix issue when function name is not set.
1 parent 015c763 commit f741035

3 files changed

Lines changed: 73 additions & 21 deletions

File tree

docs/core/metrics.md

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,21 @@ If you would like to suppress metrics output during your unit tests, you can use
558558

559559
When unit testing your code, you can run assertions against the output generated by the `Metrics` Singleton. For the `EmfMetricsLogger`, you can assert the generated JSON blob following the [CloudWatch EMF specification](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Embedded_Metric_Format.html) against your expected output.
560560

561+
Make sure to set a test metrics namespace and service name to run assertions against metrics. For example, by setting the following environment variables in your tests:
562+
563+
```xml
564+
<plugin>
565+
<groupId>org.apache.maven.plugins</groupId>
566+
<artifactId>maven-surefire-plugin</artifactId>
567+
<configuration>
568+
<environmentVariables>
569+
<POWERTOOLS_SERVICE_NAME>TestService</POWERTOOLS_SERVICE_NAME>
570+
<POWERTOOLS_METRICS_NAMESPACE>TestNamespace</POWERTOOLS_METRICS_NAMESPACE>
571+
</environmentVariables>
572+
</configuration>
573+
</plugin>
574+
```
575+
561576
Consider the following example where we redirect the standard output to a custom `PrintStream`. We use the Jackson library to parse the EMF output into a `JsonNode` and run assertions against that.
562577

563578
```java hl_lines="34 39 55-60"
@@ -614,19 +629,30 @@ class MetricsTestExample {
614629

615630
// Then
616631
String emfOutput = outputStreamCaptor.toString().trim();
617-
JsonNode rootNode = objectMapper.readTree(emfOutput);
618-
619-
assertThat(rootNode.has("test-metric")).isTrue();
620-
assertThat(rootNode.get("test-metric").asDouble()).isEqualTo(100.0);
621-
assertThat(rootNode.get("_aws").get("CloudWatchMetrics").get(0).get("Namespace").asText())
622-
.isEqualTo("CustomNamespace");
623-
assertThat(rootNode.has("Service")).isTrue();
624-
assertThat(rootNode.get("Service").asText()).isEqualTo("CustomService");
632+
String[] jsonLines = emfOutput.split("\n");
633+
634+
// First JSON object should be the cold start metric
635+
JsonNode coldStartNode = objectMapper.readTree(jsonLines[0]);
636+
assertThat(coldStartNode.has("ColdStart")).isTrue();
637+
assertThat(coldStartNode.get("ColdStart").asDouble()).isEqualTo(1.0);
638+
assertThat(coldStartNode.get("_aws").get("CloudWatchMetrics").get(0).get("Namespace").asText())
639+
.isEqualTo("TestNamespace");
640+
assertThat(coldStartNode.has("Service")).isTrue();
641+
assertThat(coldStartNode.get("Service").asText()).isEqualTo("TestService");
642+
643+
// Second JSON object should be the regular metric
644+
JsonNode regularNode = objectMapper.readTree(jsonLines[1]);
645+
assertThat(regularNode.has("test-metric")).isTrue();
646+
assertThat(regularNode.get("test-metric").asDouble()).isEqualTo(100.0);
647+
assertThat(regularNode.get("_aws").get("CloudWatchMetrics").get(0).get("Namespace").asText())
648+
.isEqualTo("TestNamespace");
649+
assertThat(regularNode.has("Service")).isTrue();
650+
assertThat(regularNode.get("Service").asText()).isEqualTo("TestService");
625651
}
626652

627653
static class HandlerWithMetricsAnnotation implements RequestHandler<Map<String, Object>, String> {
628654
@Override
629-
@FlushMetrics(namespace = "CustomNamespace", service = "CustomService")
655+
@FlushMetrics(captureColdStart = true)
630656
public String handleRequest(Map<String, Object> input, Context context) {
631657
Metrics metrics = MetricsFactory.getMetricsInstance();
632658
metrics.addMetric("test-metric", 100, MetricUnit.COUNT);

powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/internal/LambdaMetricsAspect.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,9 @@ private void captureColdStartMetricIfEnabled(Context extractedContext, FlushMetr
136136
}
137137

138138
// Add function name
139-
coldStartDimensions.addDimension("FunctionName",
140-
funcName != null ? funcName : extractedContext.getFunctionName());
139+
if (funcName != null) {
140+
coldStartDimensions.addDimension("FunctionName", funcName);
141+
}
141142

142143
metricsInstance.captureColdStartMetric(extractedContext, coldStartDimensions);
143144
}

powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/RequestHandlerTest.java

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import java.io.ByteArrayOutputStream;
66
import java.io.PrintStream;
7+
import java.lang.reflect.Method;
78
import java.util.HashMap;
89
import java.util.Map;
910

@@ -20,6 +21,7 @@
2021
import com.fasterxml.jackson.databind.JsonNode;
2122
import com.fasterxml.jackson.databind.ObjectMapper;
2223

24+
import software.amazon.lambda.powertools.common.internal.LambdaHandlerProcessor;
2325
import software.amazon.lambda.powertools.metrics.model.MetricUnit;
2426

2527
@ExtendWith(MockitoExtension.class)
@@ -34,9 +36,19 @@ class RequestHandlerTest {
3436
private final ObjectMapper objectMapper = new ObjectMapper();
3537

3638
@BeforeEach
37-
void setUp() {
39+
void setUp() throws Exception {
3840
outputStreamCaptor = new ByteArrayOutputStream();
3941
System.setOut(new PrintStream(outputStreamCaptor));
42+
43+
// Reset LambdaHandlerProcessor's SERVICE_NAME
44+
Method resetServiceName = LambdaHandlerProcessor.class.getDeclaredMethod("resetServiceName");
45+
resetServiceName.setAccessible(true);
46+
resetServiceName.invoke(null);
47+
48+
// Reset IS_COLD_START
49+
java.lang.reflect.Field coldStartField = LambdaHandlerProcessor.class.getDeclaredField("IS_COLD_START");
50+
coldStartField.setAccessible(true);
51+
coldStartField.set(null, null);
4052
}
4153

4254
@AfterEach
@@ -54,6 +66,8 @@ void tearDown() throws Exception {
5466
}
5567

5668
@Test
69+
@SetEnvironmentVariable(key = "POWERTOOLS_METRICS_NAMESPACE", value = "TestNamespace")
70+
@SetEnvironmentVariable(key = "POWERTOOLS_SERVICE_NAME", value = "TestService")
5771
void shouldCaptureMetricsFromAnnotatedHandler() throws Exception {
5872
// Given
5973
RequestHandler<Map<String, Object>, String> handler = new HandlerWithMetricsAnnotation();
@@ -64,14 +78,25 @@ void shouldCaptureMetricsFromAnnotatedHandler() throws Exception {
6478

6579
// Then
6680
String emfOutput = outputStreamCaptor.toString().trim();
67-
JsonNode rootNode = objectMapper.readTree(emfOutput);
68-
69-
assertThat(rootNode.has("test-metric")).isTrue();
70-
assertThat(rootNode.get("test-metric").asDouble()).isEqualTo(100.0);
71-
assertThat(rootNode.get("_aws").get("CloudWatchMetrics").get(0).get("Namespace").asText())
72-
.isEqualTo("CustomNamespace");
73-
assertThat(rootNode.has("Service")).isTrue();
74-
assertThat(rootNode.get("Service").asText()).isEqualTo("CustomService");
81+
String[] jsonLines = emfOutput.split("\n");
82+
83+
// First JSON object should be the cold start metric
84+
JsonNode coldStartNode = objectMapper.readTree(jsonLines[0]);
85+
assertThat(coldStartNode.has("ColdStart")).isTrue();
86+
assertThat(coldStartNode.get("ColdStart").asDouble()).isEqualTo(1.0);
87+
assertThat(coldStartNode.get("_aws").get("CloudWatchMetrics").get(0).get("Namespace").asText())
88+
.isEqualTo("TestNamespace");
89+
assertThat(coldStartNode.has("Service")).isTrue();
90+
assertThat(coldStartNode.get("Service").asText()).isEqualTo("TestService");
91+
92+
// Second JSON object should be the regular metric
93+
JsonNode regularNode = objectMapper.readTree(jsonLines[1]);
94+
assertThat(regularNode.has("test-metric")).isTrue();
95+
assertThat(regularNode.get("test-metric").asDouble()).isEqualTo(100.0);
96+
assertThat(regularNode.get("_aws").get("CloudWatchMetrics").get(0).get("Namespace").asText())
97+
.isEqualTo("TestNamespace");
98+
assertThat(regularNode.has("Service")).isTrue();
99+
assertThat(regularNode.get("Service").asText()).isEqualTo("TestService");
75100
}
76101

77102
@SetEnvironmentVariable(key = "POWERTOOLS_METRICS_DISABLED", value = "true")
@@ -91,7 +116,7 @@ void shouldNotCaptureMetricsWhenDisabled() {
91116

92117
static class HandlerWithMetricsAnnotation implements RequestHandler<Map<String, Object>, String> {
93118
@Override
94-
@FlushMetrics(namespace = "CustomNamespace", service = "CustomService")
119+
@FlushMetrics(captureColdStart = true)
95120
public String handleRequest(Map<String, Object> input, Context context) {
96121
Metrics metrics = MetricsFactory.getMetricsInstance();
97122
metrics.addMetric("test-metric", 100, MetricUnit.COUNT);

0 commit comments

Comments
 (0)