Skip to content

Commit b083f76

Browse files
Mertics default dimensions (#329)
1 parent 8ee3571 commit b083f76

File tree

8 files changed

+112
-27
lines changed

8 files changed

+112
-27
lines changed

.github/workflows/build-docs.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,6 @@ jobs:
2727
echo "SOURCE_BRANCH=${GITHUB_REF#refs/heads/}" >> $GITHUB_ENV
2828
echo "SOURCE_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
2929
- name: Build docs website
30-
run: make build-docs-website
30+
run: |
31+
echo "GIT_PYTHON_REFRESH=quiet"
32+
make build-docs-website

docs/core/metrics.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ This will be available in CloudWatch Logs to ease operations on high cardinal da
186186

187187
By default, all metrics emitted via module captures `Service` as one of the default dimension. This is either specified via
188188
`POWERTOOLS_SERVICE_NAME` environment variable or via `service` attribute on `Metrics` annotation. If you wish to override the default
189-
Dimension, it can be done via `#!java MetricsUtils.defaultDimensionSet()`.
189+
Dimension, it can be done via `#!java MetricsUtils.defaultDimensions()`.
190190

191191
=== "App.java"
192192

@@ -199,7 +199,7 @@ Dimension, it can be done via `#!java MetricsUtils.defaultDimensionSet()`.
199199
MetricsLogger metricsLogger = MetricsUtils.metricsLogger();
200200
201201
static {
202-
MetricsUtils.defaultDimensionSet(DimensionSet.of("CustomDimension", "booking"));
202+
MetricsUtils.defaultDimensions(DimensionSet.of("CustomDimension", "booking"));
203203
}
204204

205205
@Override

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

+21-6
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
*/
2626
public final class MetricsUtils {
2727
private static final MetricsLogger metricsLogger = new MetricsLogger();
28-
private static DimensionSet defaultDimensionSet;
28+
private static DimensionSet[] defaultDimensions;
2929

3030
private MetricsUtils() {
3131
}
@@ -39,14 +39,29 @@ public static MetricsLogger metricsLogger() {
3939
return metricsLogger;
4040
}
4141

42+
/**
43+
* Configure default dimension to be used by logger.
44+
* By default, @{@link Metrics} annotation captures configured service as a dimension <i>Service</i>
45+
* @param dimensionSets Default value of dimensions set for logger
46+
*/
47+
public static void defaultDimensions(final DimensionSet... dimensionSets) {
48+
MetricsUtils.defaultDimensions = dimensionSets;
49+
}
50+
4251
/**
4352
* Configure default dimension to be used by logger.
4453
* By default, @{@link Metrics} annotation captures configured service as a dimension <i>Service</i>
4554
* @param dimensionSet Default value of dimension set for logger
55+
* @deprecated use {@link #defaultDimensions(DimensionSet...)} instead
56+
*
4657
*/
58+
@Deprecated
4759
public static void defaultDimensionSet(final DimensionSet dimensionSet) {
4860
requireNonNull(dimensionSet, "Null dimension set not allowed");
49-
MetricsUtils.defaultDimensionSet = dimensionSet;
61+
62+
if(dimensionSet.getDimensionKeys().size() > 0) {
63+
defaultDimensions(dimensionSet);
64+
}
5065
}
5166

5267

@@ -105,12 +120,12 @@ public static void withSingleMetric(final String name,
105120
}
106121
}
107122

108-
public static DimensionSet defaultDimensionSet() {
109-
return defaultDimensionSet;
123+
public static DimensionSet[] getDefaultDimensions() {
124+
return defaultDimensions;
110125
}
111126

112127
public static boolean hasDefaultDimension() {
113-
return null != defaultDimensionSet && defaultDimensionSet.getDimensionKeys().size() > 0;
128+
return null != defaultDimensions;
114129
}
115130

116131
private static void captureRequestAndTraceId(MetricsLogger metricsLogger) {
@@ -137,7 +152,7 @@ private static MetricsLogger logger() {
137152
MetricsContext metricsContext = new MetricsContext();
138153

139154
if (hasDefaultDimension()) {
140-
metricsContext.setDefaultDimensions(defaultDimensionSet());
155+
metricsContext.setDimensions(defaultDimensions);
141156
}
142157

143158
return new MetricsLogger(new EnvironmentProvider(), metricsContext);

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import software.amazon.cloudwatchlogs.emf.model.Unit;
1313
import software.amazon.lambda.powertools.core.internal.LambdaHandlerProcessor;
1414
import software.amazon.lambda.powertools.metrics.Metrics;
15+
import software.amazon.lambda.powertools.metrics.MetricsUtils;
1516
import software.amazon.lambda.powertools.metrics.ValidationException;
1617

1718
import static software.amazon.cloudwatchlogs.emf.model.MetricsLoggerHelper.dimensionsCount;
@@ -23,7 +24,6 @@
2324
import static software.amazon.lambda.powertools.core.internal.LambdaHandlerProcessor.placedOnRequestHandler;
2425
import static software.amazon.lambda.powertools.core.internal.LambdaHandlerProcessor.placedOnStreamHandler;
2526
import static software.amazon.lambda.powertools.core.internal.LambdaHandlerProcessor.serviceName;
26-
import static software.amazon.lambda.powertools.metrics.MetricsUtils.defaultDimensionSet;
2727
import static software.amazon.lambda.powertools.metrics.MetricsUtils.hasDefaultDimension;
2828
import static software.amazon.lambda.powertools.metrics.MetricsUtils.metricsLogger;
2929

@@ -125,10 +125,10 @@ public static void refreshMetricsContext(Metrics metrics) {
125125
f.setAccessible(true);
126126
MetricsContext context = new MetricsContext();
127127

128-
DimensionSet defaultDimensionSet = hasDefaultDimension() ? defaultDimensionSet()
129-
: DimensionSet.of("Service", service(metrics));
128+
DimensionSet[] defaultDimensions = hasDefaultDimension() ? MetricsUtils.getDefaultDimensions()
129+
: new DimensionSet[]{DimensionSet.of("Service", service(metrics))};
130130

131-
context.setDefaultDimensions(defaultDimensionSet);
131+
context.setDimensions(defaultDimensions);
132132

133133
f.set(metricsLogger(), context);
134134
} catch (NoSuchFieldException | IllegalAccessException e) {

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ void singleMetricsCaptureUtilityWithDefaultDimension() {
5252
mocked.when(() -> SystemWrapper.getenv("AWS_EMF_ENVIRONMENT")).thenReturn("Lambda");
5353
internalWrapper.when(() -> getenv("_X_AMZN_TRACE_ID")).thenReturn("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1\"");
5454

55-
MetricsUtils.defaultDimensionSet(DimensionSet.of("Service", "Booking"));
55+
MetricsUtils.defaultDimensions(DimensionSet.of("Service", "Booking"));
5656

5757
MetricsUtils.withSingleMetric("Metric1", 1, Unit.COUNT, "test",
5858
metricsLogger -> {});

powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/handlers/PowertoolsMetricsEnabledDefaultDimensionHandler.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
import software.amazon.cloudwatchlogs.emf.model.Unit;
88
import software.amazon.lambda.powertools.metrics.Metrics;
99

10-
import static software.amazon.lambda.powertools.metrics.MetricsUtils.defaultDimensionSet;
10+
import static software.amazon.lambda.powertools.metrics.MetricsUtils.defaultDimensions;
1111
import static software.amazon.lambda.powertools.metrics.MetricsUtils.metricsLogger;
1212
import static software.amazon.lambda.powertools.metrics.MetricsUtils.withSingleMetric;
1313

1414
public class PowertoolsMetricsEnabledDefaultDimensionHandler implements RequestHandler<Object, Object> {
1515

1616
static {
17-
defaultDimensionSet(DimensionSet.of("CustomDimension", "booking"));
17+
defaultDimensions(DimensionSet.of("CustomDimension", "booking"));
1818
}
1919

2020
@Override
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package software.amazon.lambda.powertools.metrics.handlers;
2+
3+
import com.amazonaws.services.lambda.runtime.Context;
4+
import com.amazonaws.services.lambda.runtime.RequestHandler;
5+
import software.amazon.cloudwatchlogs.emf.logger.MetricsLogger;
6+
import software.amazon.cloudwatchlogs.emf.model.Unit;
7+
import software.amazon.lambda.powertools.metrics.Metrics;
8+
import software.amazon.lambda.powertools.metrics.MetricsUtils;
9+
10+
import static software.amazon.lambda.powertools.metrics.MetricsUtils.metricsLogger;
11+
import static software.amazon.lambda.powertools.metrics.MetricsUtils.withSingleMetric;
12+
13+
public class PowertoolsMetricsEnabledDefaultNoDimensionHandler implements RequestHandler<Object, Object> {
14+
15+
static {
16+
MetricsUtils.defaultDimensions();
17+
}
18+
19+
@Override
20+
@Metrics(namespace = "ExampleApplication", service = "booking")
21+
public Object handleRequest(Object input, Context context) {
22+
MetricsLogger metricsLogger = metricsLogger();
23+
metricsLogger.putMetric("Metric1", 1, Unit.BYTES);
24+
25+
withSingleMetric("Metric2", 1, Unit.COUNT, log -> {});
26+
27+
return null;
28+
}
29+
}

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

+50-11
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import software.amazon.lambda.powertools.metrics.ValidationException;
2525
import software.amazon.lambda.powertools.metrics.handlers.PowertoolsMetricsColdStartEnabledHandler;
2626
import software.amazon.lambda.powertools.metrics.handlers.PowertoolsMetricsEnabledDefaultDimensionHandler;
27+
import software.amazon.lambda.powertools.metrics.handlers.PowertoolsMetricsEnabledDefaultNoDimensionHandler;
2728
import software.amazon.lambda.powertools.metrics.handlers.PowertoolsMetricsEnabledHandler;
2829
import software.amazon.lambda.powertools.metrics.handlers.PowertoolsMetricsEnabledStreamHandler;
2930
import software.amazon.lambda.powertools.metrics.handlers.PowertoolsMetricsExceptionWhenNoMetricsHandler;
@@ -49,7 +50,6 @@ public class LambdaMetricsAspectTest {
4950
private final PrintStream originalOut = System.out;
5051
private final ObjectMapper mapper = new ObjectMapper();
5152
private RequestHandler<Object, Object> requestHandler;
52-
private RequestStreamHandler streamHandler;
5353

5454

5555
@BeforeAll
@@ -80,7 +80,7 @@ public void metricsWithoutColdStart() {
8080
mocked.when(() -> SystemWrapper.getenv("AWS_EMF_ENVIRONMENT")).thenReturn("Lambda");
8181
internalWrapper.when(() -> getenv("_X_AMZN_TRACE_ID")).thenReturn("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1\"");
8282

83-
MetricsUtils.defaultDimensionSet(new DimensionSet());
83+
MetricsUtils.defaultDimensions(null);
8484
requestHandler = new PowertoolsMetricsEnabledHandler();
8585
requestHandler.handleRequest("input", context);
8686

@@ -154,14 +154,53 @@ public void metricsWithDefaultDimensionSpecified() {
154154
}
155155
}
156156

157+
@Test
158+
public void metricsWithDefaultNoDimensionSpecified() {
159+
try (MockedStatic<SystemWrapper> mocked = mockStatic(SystemWrapper.class);
160+
MockedStatic<software.amazon.lambda.powertools.core.internal.SystemWrapper> internalWrapper = mockStatic(software.amazon.lambda.powertools.core.internal.SystemWrapper.class)) {
161+
162+
mocked.when(() -> SystemWrapper.getenv("AWS_EMF_ENVIRONMENT")).thenReturn("Lambda");
163+
internalWrapper.when(() -> getenv("_X_AMZN_TRACE_ID")).thenReturn("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1\"");
164+
165+
requestHandler = new PowertoolsMetricsEnabledDefaultNoDimensionHandler();
166+
167+
requestHandler.handleRequest("input", context);
168+
169+
assertThat(out.toString().split("\n"))
170+
.hasSize(2)
171+
.satisfies(s -> {
172+
Map<String, Object> logAsJson = readAsJson(s[0]);
173+
174+
assertThat(logAsJson)
175+
.containsEntry("Metric2", 1.0)
176+
.containsKey("_aws")
177+
.containsEntry("xray_trace_id", "1-5759e988-bd862e3fe1be46a994272793")
178+
.containsEntry("function_request_id", "123ABC");
179+
180+
Map<String, Object> aws = (Map<String, Object>) logAsJson.get("_aws");
181+
182+
assertThat(aws.get("CloudWatchMetrics"))
183+
.asString()
184+
.contains("Namespace=ExampleApplication");
185+
186+
logAsJson = readAsJson(s[1]);
187+
188+
assertThat(logAsJson)
189+
.containsEntry("Metric1", 1.0)
190+
.containsEntry("function_request_id", "123ABC")
191+
.containsKey("_aws");
192+
});
193+
}
194+
}
195+
157196
@Test
158197
public void metricsWithColdStart() {
159198

160199
try (MockedStatic<SystemWrapper> mocked = mockStatic(SystemWrapper.class)) {
161200

162201
mocked.when(() -> SystemWrapper.getenv("AWS_EMF_ENVIRONMENT")).thenReturn("Lambda");
163202

164-
MetricsUtils.defaultDimensionSet(new DimensionSet());
203+
MetricsUtils.defaultDimensions(null);
165204
requestHandler = new PowertoolsMetricsColdStartEnabledHandler();
166205

167206
requestHandler.handleRequest("input", context);
@@ -196,7 +235,7 @@ public void noColdStartMetricsWhenColdStartDone() {
196235
try (MockedStatic<SystemWrapper> mocked = mockStatic(SystemWrapper.class)) {
197236
mocked.when(() -> SystemWrapper.getenv("AWS_EMF_ENVIRONMENT")).thenReturn("Lambda");
198237

199-
MetricsUtils.defaultDimensionSet(new DimensionSet());
238+
MetricsUtils.defaultDimensions(null);
200239
requestHandler = new PowertoolsMetricsColdStartEnabledHandler();
201240

202241
requestHandler.handleRequest("input", context);
@@ -241,8 +280,8 @@ public void metricsWithStreamHandler() throws IOException {
241280
try (MockedStatic<SystemWrapper> mocked = mockStatic(SystemWrapper.class)) {
242281
mocked.when(() -> SystemWrapper.getenv("AWS_EMF_ENVIRONMENT")).thenReturn("Lambda");
243282

244-
MetricsUtils.defaultDimensionSet(new DimensionSet());
245-
streamHandler = new PowertoolsMetricsEnabledStreamHandler();
283+
MetricsUtils.defaultDimensions(null);
284+
RequestStreamHandler streamHandler = new PowertoolsMetricsEnabledStreamHandler();
246285

247286
streamHandler.handleRequest(new ByteArrayInputStream(new byte[]{}), new ByteArrayOutputStream(), context);
248287

@@ -264,7 +303,7 @@ public void exceptionWhenNoMetricsEmitted() {
264303
try (MockedStatic<SystemWrapper> mocked = mockStatic(SystemWrapper.class)) {
265304
mocked.when(() -> SystemWrapper.getenv("AWS_EMF_ENVIRONMENT")).thenReturn("Lambda");
266305

267-
MetricsUtils.defaultDimensionSet(new DimensionSet());
306+
MetricsUtils.defaultDimensions(null);
268307
requestHandler = new PowertoolsMetricsExceptionWhenNoMetricsHandler();
269308

270309
assertThatExceptionOfType(ValidationException.class)
@@ -279,7 +318,7 @@ public void noExceptionWhenNoMetricsEmitted() {
279318
try (MockedStatic<SystemWrapper> mocked = mockStatic(SystemWrapper.class)) {
280319
mocked.when(() -> SystemWrapper.getenv("AWS_EMF_ENVIRONMENT")).thenReturn("Lambda");
281320

282-
MetricsUtils.defaultDimensionSet(new DimensionSet());
321+
MetricsUtils.defaultDimensions(null);
283322
requestHandler = new PowertoolsMetricsNoExceptionWhenNoMetricsHandler();
284323

285324
requestHandler.handleRequest("input", context);
@@ -299,7 +338,7 @@ public void noExceptionWhenNoMetricsEmitted() {
299338
public void allowWhenNoDimensionsSet() {
300339
try (MockedStatic<SystemWrapper> mocked = mockStatic(SystemWrapper.class)) {
301340
mocked.when(() -> SystemWrapper.getenv("AWS_EMF_ENVIRONMENT")).thenReturn("Lambda");
302-
MetricsUtils.defaultDimensionSet(new DimensionSet());
341+
MetricsUtils.defaultDimensions(null);
303342

304343
requestHandler = new PowertoolsMetricsNoDimensionsHandler();
305344
requestHandler.handleRequest("input", context);
@@ -321,7 +360,7 @@ public void exceptionWhenTooManyDimensionsSet() {
321360
try (MockedStatic<SystemWrapper> mocked = mockStatic(SystemWrapper.class)) {
322361
mocked.when(() -> SystemWrapper.getenv("AWS_EMF_ENVIRONMENT")).thenReturn("Lambda");
323362

324-
MetricsUtils.defaultDimensionSet(new DimensionSet());
363+
MetricsUtils.defaultDimensions(null);
325364

326365
requestHandler = new PowertoolsMetricsTooManyDimensionsHandler();
327366

@@ -336,7 +375,7 @@ public void metricsPublishedEvenHandlerThrowsException() {
336375
try (MockedStatic<SystemWrapper> mocked = mockStatic(SystemWrapper.class)) {
337376
mocked.when(() -> SystemWrapper.getenv("AWS_EMF_ENVIRONMENT")).thenReturn("Lambda");
338377

339-
MetricsUtils.defaultDimensionSet(new DimensionSet());
378+
MetricsUtils.defaultDimensions(null);
340379
requestHandler = new PowertoolsMetricsWithExceptionInHandler();
341380

342381
assertThatExceptionOfType(IllegalStateException.class)

0 commit comments

Comments
 (0)