Skip to content

Commit 6c97349

Browse files
committed
added 0-value for non-exception events by error code
1 parent 1bd0222 commit 6c97349

File tree

5 files changed

+42
-18
lines changed

5 files changed

+42
-18
lines changed

src/main/java/software/amazon/cloudformation/LambdaWrapper.java

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.time.Instant;
3030
import java.util.Arrays;
3131
import java.util.Date;
32+
import java.util.EnumSet;
3233
import java.util.HashMap;
3334
import java.util.List;
3435
import java.util.Map;
@@ -313,7 +314,7 @@ public void handleRequest(final InputStream inputStream, final OutputStream outp
313314
if (handlerResponse.getStatus() == OperationStatus.IN_PROGRESS && !isMutatingAction) {
314315
throw new TerminalException("READ and LIST handlers must return synchronously.");
315316
} else if (handlerResponse.getStatus() != OperationStatus.FAILED) {
316-
this.metricsPublisherProxy.publishExceptionCountMetric(Instant.now(), request.getAction(), false);
317+
publishExceptionCodeAndCountMetric(request.getAction(), handlerResponse.getErrorCode(), false);
317318
}
318319

319320
return handlerResponse;
@@ -349,8 +350,7 @@ public void handleRequest(final InputStream inputStream, final OutputStream outp
349350
}
350351

351352
if (handlerResponse.getStatus() == OperationStatus.FAILED) {
352-
publishExceptionMetric(request.getAction(), new Throwable(handlerResponse.getMessage()),
353-
handlerResponse.getErrorCode());
353+
publishExceptionCodeAndCountMetric(request.getAction(), handlerResponse.getErrorCode(), true);
354354
}
355355

356356
return handlerResponse;
@@ -471,16 +471,29 @@ public abstract ProgressEvent<ResourceT, CallbackT> invokeHandler(AmazonWebServi
471471
private void publishExceptionMetric(final Action action, final Throwable ex, final HandlerErrorCode handlerErrorCode) {
472472
if (this.metricsPublisherProxy != null) {
473473
this.metricsPublisherProxy.publishExceptionMetric(Instant.now(), action, ex, handlerErrorCode);
474-
this.metricsPublisherProxy.publishExceptionByErrorCodeMetric(Instant.now(), action, handlerErrorCode);
475474
// always puts failed events
476-
this.metricsPublisherProxy.publishExceptionCountMetric(Instant.now(), action, true);
475+
publishExceptionCodeAndCountMetric(action, handlerErrorCode, true);
477476
} else {
478477
// Lambda logger is the only fallback if metrics publisher proxy is not
479478
// initialized.
480479
lambdaLogger.log(ex.toString());
481480
}
482481
}
483482

483+
/*
484+
* null-safe exception metrics delivery
485+
*/
486+
private void
487+
publishExceptionCodeAndCountMetric(final Action action, final HandlerErrorCode handlerErrorCode, final boolean thrown) {
488+
EnumSet.allOf(HandlerErrorCode.class).stream()
489+
// publishing 0 value for all (if not thrown) otherwise filtered
490+
.filter(errorCode -> errorCode.equals(handlerErrorCode) || !thrown).forEach(errorCode -> this.metricsPublisherProxy
491+
.publishExceptionByErrorCodeMetric(Instant.now(), action, errorCode, thrown));
492+
// this.metricsPublisherProxy.publishExceptionByErrorCodeMetric(Instant.now(),
493+
// action, handlerErrorCode, thrown);
494+
this.metricsPublisherProxy.publishExceptionCountMetric(Instant.now(), action, thrown);
495+
}
496+
484497
/**
485498
* null-safe logger redirect
486499
*

src/main/java/software/amazon/cloudformation/metrics/MetricsPublisher.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,10 @@ public void publishExceptionMetric(final Instant timestamp,
4242
final HandlerErrorCode handlerErrorCode) {
4343
}
4444

45-
public void
46-
publishExceptionByErrorCodeMetric(final Instant timestamp, final Action action, final HandlerErrorCode handlerErrorCode) {
45+
public void publishExceptionByErrorCodeMetric(final Instant timestamp,
46+
final Action action,
47+
final HandlerErrorCode handlerErrorCode,
48+
final boolean thrown) {
4749
}
4850

4951
public void publishExceptionCountMetric(final Instant timestamp, final Action action, final boolean thrown) {

src/main/java/software/amazon/cloudformation/metrics/MetricsPublisherImpl.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,16 @@ public void publishExceptionMetric(final Instant timestamp,
6767
}
6868

6969
@Override
70-
public void
71-
publishExceptionByErrorCodeMetric(final Instant timestamp, final Action action, final HandlerErrorCode handlerErrorCode) {
70+
public void publishExceptionByErrorCodeMetric(final Instant timestamp,
71+
final Action action,
72+
final HandlerErrorCode handlerErrorCode,
73+
final boolean thrown) {
7274
Map<String, String> dimensions = new HashMap<>();
7375
dimensions.put(Metric.DIMENSION_KEY_ACTION_TYPE, action == null ? "NO_ACTION" : action.name());
7476
dimensions.put(Metric.DIMENSION_KEY_HANDLER_ERROR_CODE, handlerErrorCode.name());
7577

76-
publishMetric(Metric.METRIC_NAME_HANDLER_EXCEPTION_BY_ERROR_CODE, dimensions, StandardUnit.COUNT, 1.0, timestamp);
78+
publishMetric(Metric.METRIC_NAME_HANDLER_EXCEPTION_BY_ERROR_CODE, dimensions, StandardUnit.COUNT, thrown ? 1.0 : 0.0,
79+
timestamp);
7780
}
7881

7982
public void publishExceptionCountMetric(final Instant timestamp, final Action action, final boolean thrown) {

src/main/java/software/amazon/cloudformation/proxy/MetricsPublisherProxy.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@ public void publishExceptionMetric(final Instant timestamp,
3535
.forEach(metricsPublisher -> metricsPublisher.publishExceptionMetric(timestamp, action, e, handlerErrorCode));
3636
}
3737

38-
public void
39-
publishExceptionByErrorCodeMetric(final Instant timestamp, final Action action, final HandlerErrorCode handlerErrorCode) {
40-
metricsPublishers.stream()
41-
.forEach(metricsPublisher -> metricsPublisher.publishExceptionByErrorCodeMetric(timestamp, action, handlerErrorCode));
38+
public void publishExceptionByErrorCodeMetric(final Instant timestamp,
39+
final Action action,
40+
final HandlerErrorCode handlerErrorCode,
41+
final boolean thrown) {
42+
metricsPublishers.stream().forEach(
43+
metricsPublisher -> metricsPublisher.publishExceptionByErrorCodeMetric(timestamp, action, handlerErrorCode, thrown));
4244
}
4345

4446
public void publishExceptionCountMetric(final Instant timestamp, final Action action, final boolean thrown) {

src/test/java/software/amazon/cloudformation/LambdaWrapperTest.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,12 +161,12 @@ public void invokeHandler_nullResponse_returnsFailure(final String requestDataPa
161161
verify(providerMetricsPublisher).publishExceptionMetric(any(Instant.class), any(), any(TerminalException.class),
162162
any(HandlerErrorCode.class));
163163
verify(providerMetricsPublisher).publishExceptionByErrorCodeMetric(any(Instant.class), any(),
164-
any(HandlerErrorCode.class));
164+
any(HandlerErrorCode.class), eq(Boolean.TRUE));
165165
verify(providerMetricsPublisher).publishExceptionCountMetric(any(Instant.class), any(), any(Boolean.class));
166166

167167
// all metrics should be published even on terminal failure
168-
verify(providerMetricsPublisher, times(1)).publishInvocationMetric(any(Instant.class), eq(action));
169-
verify(providerMetricsPublisher, times(1)).publishDurationMetric(any(Instant.class), eq(action), anyLong());
168+
verify(providerMetricsPublisher).publishInvocationMetric(any(Instant.class), eq(action));
169+
verify(providerMetricsPublisher).publishDurationMetric(any(Instant.class), eq(action), anyLong());
170170

171171
// verify that model validation occurred for CREATE/UPDATE/DELETE
172172
if (action == Action.CREATE || action == Action.UPDATE || action == Action.DELETE) {
@@ -402,6 +402,8 @@ public void invokeHandler_InProgress_returnsInProgress(final String requestDataP
402402
// verify output response
403403
verifyHandlerResponse(out, ProgressEvent.<TestModel, TestContext>builder().status(OperationStatus.IN_PROGRESS)
404404
.resourceModel(TestModel.builder().property1("abc").property2(123).build()).build());
405+
verify(providerMetricsPublisher, atLeastOnce()).publishExceptionByErrorCodeMetric(any(Instant.class), eq(action),
406+
any(), eq(Boolean.FALSE));
405407
verify(providerMetricsPublisher).publishExceptionCountMetric(any(Instant.class), eq(action), eq(Boolean.FALSE));
406408
} else {
407409
verifyHandlerResponse(out,
@@ -411,7 +413,7 @@ public void invokeHandler_InProgress_returnsInProgress(final String requestDataP
411413
verify(providerMetricsPublisher).publishExceptionMetric(any(Instant.class), eq(action),
412414
any(TerminalException.class), eq(HandlerErrorCode.InternalFailure));
413415
verify(providerMetricsPublisher).publishExceptionByErrorCodeMetric(any(Instant.class), eq(action),
414-
eq(HandlerErrorCode.InternalFailure));
416+
eq(HandlerErrorCode.InternalFailure), eq(Boolean.TRUE));
415417
verify(providerMetricsPublisher).publishExceptionCountMetric(any(Instant.class), eq(action), eq(Boolean.TRUE));
416418
}
417419

@@ -456,6 +458,8 @@ public void reInvokeHandler_InProgress_returnsInProgress(final String requestDat
456458
// all metrics should be published, once for a single invocation
457459
verify(providerMetricsPublisher).publishInvocationMetric(any(Instant.class), eq(action));
458460
verify(providerMetricsPublisher).publishDurationMetric(any(Instant.class), eq(action), anyLong());
461+
verify(providerMetricsPublisher, atLeastOnce()).publishExceptionByErrorCodeMetric(any(Instant.class), eq(action),
462+
any(), eq(Boolean.FALSE));
459463
verify(providerMetricsPublisher).publishExceptionCountMetric(any(Instant.class), eq(action), eq(Boolean.FALSE));
460464

461465
// validation failure metric should not be published

0 commit comments

Comments
 (0)