Skip to content

Commit eb167f1

Browse files
committed
Only add service name dimension if the service is actually defined.
1 parent 05fe15e commit eb167f1

File tree

5 files changed

+73
-17
lines changed

5 files changed

+73
-17
lines changed

powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/MetricsLoggerFactory.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414

1515
package software.amazon.lambda.powertools.metrics;
1616

17-
import software.amazon.lambda.powertools.metrics.model.DimensionSet;
18-
17+
import software.amazon.lambda.powertools.common.internal.LambdaConstants;
1918
import software.amazon.lambda.powertools.common.internal.LambdaHandlerProcessor;
19+
import software.amazon.lambda.powertools.metrics.model.DimensionSet;
2020
import software.amazon.lambda.powertools.metrics.provider.EmfMetricsProvider;
2121
import software.amazon.lambda.powertools.metrics.provider.MetricsProvider;
2222

@@ -45,7 +45,11 @@ public static synchronized MetricsLogger getMetricsLogger() {
4545
metricsLogger.setNamespace(envNamespace);
4646
}
4747

48-
metricsLogger.setDefaultDimensions(DimensionSet.of("Service", LambdaHandlerProcessor.serviceName()));
48+
// Only set Service dimension if it's not the default undefined value
49+
String serviceName = LambdaHandlerProcessor.serviceName();
50+
if (!LambdaConstants.SERVICE_UNDEFINED.equals(serviceName)) {
51+
metricsLogger.setDefaultDimensions(DimensionSet.of("Service", serviceName));
52+
}
4953
}
5054

5155
return metricsLogger;

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

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
import com.amazonaws.services.lambda.runtime.Context;
2727

28+
import software.amazon.lambda.powertools.common.internal.LambdaConstants;
2829
import software.amazon.lambda.powertools.common.internal.LambdaHandlerProcessor;
2930
import software.amazon.lambda.powertools.metrics.Metrics;
3031
import software.amazon.lambda.powertools.metrics.MetricsLogger;
@@ -70,12 +71,10 @@ public Object around(ProceedingJoinPoint pjp,
7071
logger.setNamespace(metrics.namespace());
7172
}
7273

73-
// If the default dimensions are larger than 1 or do not contain the "Service" dimension, it means that the
74-
// user overwrote them manually e.g. using MetricsLoggerBuilder. In this case, we don't set the service
75-
// default dimension.
76-
if (!"".equals(metrics.service())
77-
&& logger.getDefaultDimensions().getDimensionKeys().size() <= 1
78-
&& logger.getDefaultDimensions().getDimensionKeys().contains(SERVICE_DIMENSION)) {
74+
// We only overwrite the default dimensions if the user didn't overwrite them previously. This means that
75+
// they are either empty or only contain the default "Service" dimension.
76+
if (!"".equals(metrics.service().trim()) && (logger.getDefaultDimensions().getDimensionKeys().size() <= 1
77+
|| logger.getDefaultDimensions().getDimensionKeys().contains(SERVICE_DIMENSION))) {
7978
logger.setDefaultDimensions(DimensionSet.of(SERVICE_DIMENSION, metrics.service()));
8079
}
8180

@@ -95,12 +94,20 @@ public Object around(ProceedingJoinPoint pjp,
9594
// Get function name from annotation or context
9695
String funcName = functionName(metrics, extractedContext);
9796

98-
// Create dimensions with service and function name
99-
DimensionSet coldStartDimensions = DimensionSet.of(
100-
SERVICE_DIMENSION,
101-
logger.getDefaultDimensions().getDimensions().getOrDefault(SERVICE_DIMENSION,
102-
serviceNameWithFallback(metrics)),
103-
"FunctionName", funcName != null ? funcName : extractedContext.getFunctionName());
97+
DimensionSet coldStartDimensions = new DimensionSet();
98+
99+
// Get service name from logger default dimensions or fallback
100+
String serviceName = logger.getDefaultDimensions().getDimensions().getOrDefault(SERVICE_DIMENSION,
101+
serviceNameWithFallback(metrics));
102+
103+
// Only add service if it is not undefined
104+
if (!LambdaConstants.SERVICE_UNDEFINED.equals(serviceName)) {
105+
coldStartDimensions.addDimension(SERVICE_DIMENSION, serviceName);
106+
}
107+
108+
// Add function name
109+
coldStartDimensions.addDimension("FunctionName",
110+
funcName != null ? funcName : extractedContext.getFunctionName());
104111

105112
logger.captureColdStartMetric(extractedContext, coldStartDimensions);
106113
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,8 @@ void shouldUseDefaultsWhenNoConfiguration() throws Exception {
179179
// Default values should be used
180180
assertThat(rootNode.get("_aws").get("CloudWatchMetrics").get(0).get("Namespace").asText())
181181
.isEqualTo("TestNamespace");
182-
assertThat(rootNode.has("Service")).isTrue();
183-
assertThat(rootNode.get("Service").asText()).isEqualTo("service_undefined");
182+
// Service dimension should not be present when service is undefined
183+
assertThat(rootNode.has("Service")).isFalse();
184184
}
185185

186186
private static class HandlerWithMetricsAnnotation implements RequestHandler<Map<String, Object>, String> {

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,4 +146,21 @@ void shouldThrowExceptionWhenSettingNullProvider() {
146146
.hasMessage("Metrics provider cannot be null");
147147
}
148148

149+
@Test
150+
void shouldNotSetServiceDimensionWhenServiceUndefined() throws Exception {
151+
// Given - no POWERTOOLS_SERVICE_NAME set, so it will use the default undefined value
152+
153+
// When
154+
MetricsLogger metricsLogger = MetricsLoggerFactory.getMetricsLogger();
155+
metricsLogger.setNamespace("TestNamespace");
156+
metricsLogger.addMetric("test-metric", 100, MetricUnit.COUNT);
157+
metricsLogger.flush();
158+
159+
// Then
160+
String emfOutput = outputStreamCaptor.toString().trim();
161+
JsonNode rootNode = objectMapper.readTree(emfOutput);
162+
163+
// Service dimension should not be present
164+
assertThat(rootNode.has("Service")).isFalse();
165+
}
149166
}

powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/internal/LambdaMetricsAspectTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,34 @@ void shouldCaptureColdStartMetricWhenConfigured() throws Exception {
161161
assertThat(metricsNode.has("test-metric")).isTrue();
162162
}
163163

164+
@Test
165+
void shouldNotIncludeServiceDimensionInColdStartMetricWhenServiceUndefined() throws Exception {
166+
// Given - no service name set, so it will use the default undefined value
167+
RequestHandler<Map<String, Object>, String> handler = new HandlerWithColdStartMetricsAnnotation();
168+
Context context = new TestContext();
169+
Map<String, Object> input = new HashMap<>();
170+
171+
// When
172+
handler.handleRequest(input, context);
173+
174+
// Then
175+
String emfOutput = outputStreamCaptor.toString().trim();
176+
String[] emfOutputs = emfOutput.split("\\n");
177+
178+
// There should be two EMF outputs - one for cold start and one for the handler metrics
179+
assertThat(emfOutputs).hasSize(2);
180+
181+
JsonNode coldStartNode = objectMapper.readTree(emfOutputs[0]);
182+
assertThat(coldStartNode.has("ColdStart")).isTrue();
183+
assertThat(coldStartNode.get("ColdStart").asDouble()).isEqualTo(1.0);
184+
185+
// Service dimension should not be present in cold start metrics
186+
assertThat(coldStartNode.has("Service")).isFalse();
187+
188+
// FunctionName dimension should be present
189+
assertThat(coldStartNode.has("FunctionName")).isTrue();
190+
}
191+
164192
@Test
165193
void shouldUseCustomFunctionNameWhenProvidedForColdStartMetric() throws Exception {
166194
// Given

0 commit comments

Comments
 (0)