|
14 | 14 | */ |
15 | 15 | package software.amazon.cloudformation.metrics; |
16 | 16 |
|
| 17 | +import com.google.common.collect.Sets; |
17 | 18 | import java.time.Instant; |
18 | | -import java.util.ArrayList; |
19 | | -import java.util.HashMap; |
20 | | -import java.util.List; |
21 | | -import java.util.Map; |
| 19 | +import java.util.EnumSet; |
| 20 | +import java.util.HashSet; |
| 21 | +import java.util.Set; |
22 | 22 | import software.amazon.awssdk.services.cloudwatch.CloudWatchClient; |
23 | 23 | import software.amazon.awssdk.services.cloudwatch.model.Dimension; |
24 | 24 | import software.amazon.awssdk.services.cloudwatch.model.MetricDatum; |
@@ -57,86 +57,83 @@ public void publishExceptionMetric(final Instant timestamp, |
57 | 57 | final Action action, |
58 | 58 | final Throwable e, |
59 | 59 | final HandlerErrorCode handlerErrorCode) { |
60 | | - Map<String, String> dimensions = new HashMap<>(); |
61 | | - dimensions.put(Metric.DIMENSION_KEY_ACTION_TYPE, action == null ? "NO_ACTION" : action.name()); |
62 | | - dimensions.put(Metric.DIMENSION_KEY_EXCEPTION_TYPE, e.getClass().toString()); |
63 | | - dimensions.put(Metric.DIMENSION_KEY_RESOURCE_TYPE, this.getResourceTypeName()); |
64 | | - dimensions.put(Metric.DIMENSION_KEY_HANDLER_ERROR_CODE, handlerErrorCode.name()); |
65 | | - |
66 | | - publishMetric(Metric.METRIC_NAME_HANDLER_EXCEPTION, dimensions, StandardUnit.COUNT, 1.0, timestamp); |
| 60 | + publishBulkMetrics(MetricDatum.builder().timestamp(timestamp).metricName(Metric.METRIC_NAME_HANDLER_EXCEPTION) |
| 61 | + .unit(StandardUnit.COUNT).value(1.0) |
| 62 | + .dimensions(Sets.newHashSet( |
| 63 | + Dimension.builder().name(Metric.DIMENSION_KEY_ACTION_TYPE).value(action == null ? "NO_ACTION" : action.name()) |
| 64 | + .build(), |
| 65 | + Dimension.builder().name(Metric.DIMENSION_KEY_EXCEPTION_TYPE).value(e.getClass().toString()).build(), |
| 66 | + Dimension.builder().name(Metric.DIMENSION_KEY_RESOURCE_TYPE).value(this.getResourceTypeName()).build(), |
| 67 | + Dimension.builder().name(Metric.DIMENSION_KEY_HANDLER_ERROR_CODE).value(handlerErrorCode.name()).build())) |
| 68 | + .build()); |
67 | 69 | } |
68 | 70 |
|
69 | 71 | @Override |
70 | | - public void publishExceptionByErrorCodeMetric(final Instant timestamp, |
71 | | - final Action action, |
72 | | - final HandlerErrorCode handlerErrorCode, |
73 | | - final boolean thrown) { |
74 | | - Map<String, String> dimensions = new HashMap<>(); |
75 | | - dimensions.put(Metric.DIMENSION_KEY_ACTION_TYPE, action == null ? "NO_ACTION" : action.name()); |
76 | | - dimensions.put(Metric.DIMENSION_KEY_HANDLER_ERROR_CODE, handlerErrorCode.name()); |
77 | | - |
78 | | - publishMetric(Metric.METRIC_NAME_HANDLER_EXCEPTION_BY_ERROR_CODE, dimensions, StandardUnit.COUNT, thrown ? 1.0 : 0.0, |
79 | | - timestamp); |
80 | | - } |
81 | | - |
82 | | - public void publishExceptionCountMetric(final Instant timestamp, final Action action, final boolean thrown) { |
83 | | - Map<String, String> dimensions = new HashMap<>(); |
84 | | - dimensions.put(Metric.DIMENSION_KEY_ACTION_TYPE, action == null ? "NO_ACTION" : action.name()); |
85 | | - |
86 | | - publishMetric(Metric.METRIC_NAME_HANDLER_EXCEPTION_BY_EXCEPTION_COUNT, dimensions, StandardUnit.COUNT, thrown ? 1.0 : 0.0, |
87 | | - timestamp); |
| 72 | + public void publishExceptionByErrorCodeAndCountBulkMetrics(final Instant timestamp, |
| 73 | + final Action action, |
| 74 | + final HandlerErrorCode handlerErrorCode) { |
| 75 | + Set<MetricDatum> bulkData = new HashSet<>(); |
| 76 | + |
| 77 | + // By Error Code dimensions |
| 78 | + |
| 79 | + EnumSet.allOf(HandlerErrorCode.class).forEach( |
| 80 | + errorCode -> bulkData.add(MetricDatum.builder().metricName(Metric.METRIC_NAME_HANDLER_EXCEPTION_BY_ERROR_CODE) |
| 81 | + .unit(StandardUnit.COUNT).value(errorCode == handlerErrorCode ? 1.0 : 0.0) |
| 82 | + .dimensions(Sets.newHashSet( |
| 83 | + Dimension.builder().name(Metric.DIMENSION_KEY_ACTION_TYPE).value(action == null ? "NO_ACTION" : action.name()) |
| 84 | + .build(), |
| 85 | + Dimension.builder().name(Metric.DIMENSION_KEY_HANDLER_ERROR_CODE).value(errorCode.name()).build())) |
| 86 | + .timestamp(timestamp).build())); |
| 87 | + |
| 88 | + // By Count dimensions |
| 89 | + bulkData.add(MetricDatum.builder().metricName(Metric.METRIC_NAME_HANDLER_EXCEPTION_BY_EXCEPTION_COUNT) |
| 90 | + .unit(StandardUnit.COUNT).value(handlerErrorCode == null ? 0.0 : 1.0).dimensions(Dimension.builder() |
| 91 | + .name(Metric.DIMENSION_KEY_ACTION_TYPE).value(action == null ? "NO_ACTION" : action.name()).build()) |
| 92 | + .timestamp(timestamp).build()); |
| 93 | + |
| 94 | + publishBulkMetrics(bulkData.toArray(new MetricDatum[bulkData.size()])); |
88 | 95 | } |
89 | 96 |
|
90 | 97 | @Override |
91 | 98 | public void publishProviderLogDeliveryExceptionMetric(final Instant timestamp, final Throwable e) { |
92 | | - Map<String, String> dimensions = new HashMap<>(); |
93 | | - dimensions.put(Metric.DIMENSION_KEY_ACTION_TYPE, "ProviderLogDelivery"); |
94 | | - dimensions.put(Metric.DIMENSION_KEY_EXCEPTION_TYPE, e.getClass().toString()); |
95 | | - dimensions.put(Metric.DIMENSION_KEY_RESOURCE_TYPE, this.getResourceTypeName()); |
96 | | - |
97 | | - publishMetric(Metric.METRIC_NAME_HANDLER_EXCEPTION, dimensions, StandardUnit.COUNT, 1.0, timestamp); |
| 99 | + publishBulkMetrics( |
| 100 | + MetricDatum.builder().metricName(Metric.METRIC_NAME_HANDLER_EXCEPTION).unit(StandardUnit.COUNT).value(1.0) |
| 101 | + .dimensions(Sets.newHashSet( |
| 102 | + Dimension.builder().name(Metric.DIMENSION_KEY_ACTION_TYPE).value("ProviderLogDelivery").build(), |
| 103 | + Dimension.builder().name(Metric.DIMENSION_KEY_EXCEPTION_TYPE).value(e.getClass().toString()).build(), |
| 104 | + Dimension.builder().name(Metric.DIMENSION_KEY_RESOURCE_TYPE).value(this.getResourceTypeName()).build())) |
| 105 | + .timestamp(timestamp).build()); |
98 | 106 | } |
99 | 107 |
|
100 | 108 | @Override |
101 | 109 | public void publishInvocationMetric(final Instant timestamp, final Action action) { |
102 | | - Map<String, String> dimensions = new HashMap<>(); |
103 | | - dimensions.put(Metric.DIMENSION_KEY_ACTION_TYPE, action == null ? "NO_ACTION" : action.name()); |
104 | | - dimensions.put(Metric.DIMENSION_KEY_RESOURCE_TYPE, this.getResourceTypeName()); |
105 | | - |
106 | | - publishMetric(Metric.METRIC_NAME_HANDLER_INVOCATION_COUNT, dimensions, StandardUnit.COUNT, 1.0, timestamp); |
| 110 | + publishBulkMetrics( |
| 111 | + MetricDatum.builder().metricName(Metric.METRIC_NAME_HANDLER_INVOCATION_COUNT).unit(StandardUnit.COUNT).value(1.0) |
| 112 | + .dimensions(Sets.newHashSet( |
| 113 | + Dimension.builder().name(Metric.DIMENSION_KEY_ACTION_TYPE).value(action == null ? "NO_ACTION" : action.name()) |
| 114 | + .build(), |
| 115 | + Dimension.builder().name(Metric.DIMENSION_KEY_RESOURCE_TYPE).value(this.getResourceTypeName()).build())) |
| 116 | + .timestamp(timestamp).build()); |
107 | 117 | } |
108 | 118 |
|
109 | 119 | @Override |
110 | 120 | public void publishDurationMetric(final Instant timestamp, final Action action, final long milliseconds) { |
111 | | - Map<String, String> dimensions = new HashMap<>(); |
112 | | - dimensions.put(Metric.DIMENSION_KEY_ACTION_TYPE, action == null ? "NO_ACTION" : action.name()); |
113 | | - dimensions.put(Metric.DIMENSION_KEY_RESOURCE_TYPE, this.getResourceTypeName()); |
114 | | - |
115 | | - publishMetric(Metric.METRIC_NAME_HANDLER_DURATION, dimensions, StandardUnit.MILLISECONDS, (double) milliseconds, |
116 | | - timestamp); |
| 121 | + publishBulkMetrics(MetricDatum.builder().metricName(Metric.METRIC_NAME_HANDLER_DURATION).unit(StandardUnit.MILLISECONDS) |
| 122 | + .value((double) milliseconds) |
| 123 | + .dimensions(Sets.newHashSet( |
| 124 | + Dimension.builder().name(Metric.DIMENSION_KEY_ACTION_TYPE).value(action == null ? "NO_ACTION" : action.name()) |
| 125 | + .build(), |
| 126 | + Dimension.builder().name(Metric.DIMENSION_KEY_RESOURCE_TYPE).value(this.getResourceTypeName()).build())) |
| 127 | + .timestamp(timestamp).build()); |
117 | 128 | } |
118 | 129 |
|
119 | | - private void publishMetric(final String metricName, |
120 | | - final Map<String, String> dimensionData, |
121 | | - final StandardUnit unit, |
122 | | - final Double value, |
123 | | - final Instant timestamp) { |
| 130 | + private void publishBulkMetrics(final MetricDatum... metricData) { |
124 | 131 | assert cloudWatchClient != null : "CloudWatchEventsClient was not initialised. You must call refreshClient() first."; |
125 | 132 |
|
126 | | - List<Dimension> dimensions = new ArrayList<>(); |
127 | | - for (Map.Entry<String, String> kvp : dimensionData.entrySet()) { |
128 | | - Dimension dimension = Dimension.builder().name(kvp.getKey()).value(kvp.getValue()).build(); |
129 | | - dimensions.add(dimension); |
130 | | - } |
131 | | - |
132 | | - MetricDatum metricDatum = MetricDatum.builder().metricName(metricName).unit(unit).value(value).dimensions(dimensions) |
133 | | - .timestamp(timestamp).build(); |
134 | | - |
135 | | - PutMetricDataRequest putMetricDataRequest = PutMetricDataRequest.builder() |
136 | | - .namespace(String.format("%s/%s", Metric.METRIC_NAMESPACE_ROOT, resourceNamespace)).metricData(metricDatum).build(); |
137 | | - |
138 | 133 | try { |
139 | | - this.cloudWatchClient.putMetricData(putMetricDataRequest); |
| 134 | + this.cloudWatchClient.putMetricData( |
| 135 | + PutMetricDataRequest.builder().namespace(String.format("%s/%s", Metric.METRIC_NAMESPACE_ROOT, resourceNamespace)) |
| 136 | + .metricData(metricData).build()); |
140 | 137 | } catch (final Exception e) { |
141 | 138 | log(String.format("An error occurred while publishing metrics: %s", e.getMessage())); |
142 | 139 | } |
|
0 commit comments