Skip to content

Commit 74aaadb

Browse files
committed
Added Statistic Set
1 parent e2a28ae commit 74aaadb

File tree

9 files changed

+646
-22
lines changed

9 files changed

+646
-22
lines changed

src/main/java/software/amazon/cloudwatchlogs/emf/logger/MetricsLogger.java

Lines changed: 95 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import software.amazon.cloudwatchlogs.emf.exception.InvalidMetricException;
3131
import software.amazon.cloudwatchlogs.emf.exception.InvalidNamespaceException;
3232
import software.amazon.cloudwatchlogs.emf.exception.InvalidTimestampException;
33+
import software.amazon.cloudwatchlogs.emf.model.AggregationType;
3334
import software.amazon.cloudwatchlogs.emf.model.DimensionSet;
3435
import software.amazon.cloudwatchlogs.emf.model.MetricsContext;
3536
import software.amazon.cloudwatchlogs.emf.model.StorageResolution;
@@ -45,6 +46,7 @@ public class MetricsLogger {
4546
private MetricsContext context;
4647
private CompletableFuture<Environment> environmentFuture;
4748
private EnvironmentProvider environmentProvider;
49+
@Getter @Setter private volatile AggregationType defaultAggregationType = AggregationType.NONE;
4850
/**
4951
* This lock is used to create an internal sync context for flush() method in multi-threaded
5052
* situations. Flush() acquires write lock, other methods (accessing mutable shared data with
@@ -191,18 +193,23 @@ public MetricsLogger resetDimensions(boolean useDefault) {
191193
* @param value is the value of the metric
192194
* @param unit is the unit of the metric value
193195
* @param storageResolution is the resolution of the metric
196+
* @param aggregationType is the aggregation type of the metric
194197
* @see <a
195198
* href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/publishingMetrics.html#high-resolution-metrics">CloudWatch
196199
* High Resolution Metrics</a>
197200
* @return the current logger
198201
* @throws InvalidMetricException if the metric is invalid
199202
*/
200203
public MetricsLogger putMetric(
201-
String key, double value, Unit unit, StorageResolution storageResolution)
204+
String key,
205+
double value,
206+
Unit unit,
207+
StorageResolution storageResolution,
208+
AggregationType aggregationType)
202209
throws InvalidMetricException {
203210
rwl.readLock().lock();
204211
try {
205-
this.context.putMetric(key, value, unit, storageResolution);
212+
this.context.putMetric(key, value, unit, storageResolution, aggregationType);
206213
return this;
207214
} finally {
208215
rwl.readLock().unlock();
@@ -225,7 +232,7 @@ public MetricsLogger putMetric(
225232
*/
226233
public MetricsLogger putMetric(String key, double value, StorageResolution storageResolution)
227234
throws InvalidMetricException {
228-
this.putMetric(key, value, Unit.NONE, storageResolution);
235+
this.putMetric(key, value, Unit.NONE, storageResolution, defaultAggregationType);
229236
return this;
230237
}
231238

@@ -242,7 +249,7 @@ public MetricsLogger putMetric(String key, double value, StorageResolution stora
242249
*/
243250
public MetricsLogger putMetric(String key, double value, Unit unit)
244251
throws InvalidMetricException {
245-
this.putMetric(key, value, unit, StorageResolution.STANDARD);
252+
this.putMetric(key, value, unit, StorageResolution.STANDARD, defaultAggregationType);
246253
return this;
247254
}
248255

@@ -257,7 +264,90 @@ public MetricsLogger putMetric(String key, double value, Unit unit)
257264
* @throws InvalidMetricException if the metric is invalid
258265
*/
259266
public MetricsLogger putMetric(String key, double value) throws InvalidMetricException {
260-
this.putMetric(key, value, Unit.NONE, StorageResolution.STANDARD);
267+
this.putMetric(key, value, Unit.NONE, StorageResolution.STANDARD, defaultAggregationType);
268+
return this;
269+
}
270+
271+
/**
272+
* Put a metric value. This value will be emitted to CloudWatch Metrics asynchronously and does
273+
* not contribute to your account TPS limits. The value will also be available in your
274+
* CloudWatch Logs
275+
*
276+
* @param key is the name of the metric
277+
* @param value is the value of the metric
278+
* @param unit is the unit of the metric value
279+
* @param storageResolution is the resolution of the metric
280+
* @see <a
281+
* href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/publishingMetrics.html#high-resolution-metrics">CloudWatch
282+
* High Resolution Metrics</a>
283+
* @return the current logger
284+
* @throws InvalidMetricException if the metric is invalid
285+
*/
286+
public MetricsLogger putMetric(
287+
String key, double value, Unit unit, StorageResolution storageResolution)
288+
throws InvalidMetricException {
289+
this.putMetric(key, value, Unit.NONE, storageResolution, defaultAggregationType);
290+
return this;
291+
}
292+
293+
/**
294+
* Put a metric value. This value will be emitted to CloudWatch Metrics asynchronously and does
295+
* not contribute to your account TPS limits. The value will also be available in your
296+
* CloudWatch Logs
297+
*
298+
* @param key is the name of the metric
299+
* @param value is the value of the metric
300+
* @param storageResolution is the resolution of the metric
301+
* @param aggregationType is the aggregation type of the metric
302+
* @see <a
303+
* href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/publishingMetrics.html#high-resolution-metrics">CloudWatch
304+
* High Resolution Metrics</a>
305+
* @return the current logger
306+
* @throws InvalidMetricException if the metric is invalid
307+
*/
308+
public MetricsLogger putMetric(
309+
String key,
310+
double value,
311+
StorageResolution storageResolution,
312+
AggregationType aggregationType)
313+
throws InvalidMetricException {
314+
this.putMetric(key, value, Unit.NONE, storageResolution, aggregationType);
315+
return this;
316+
}
317+
318+
/**
319+
* Put a metric value. This value will be emitted to CloudWatch Metrics asynchronously and does
320+
* not contribute to your account TPS limits. The value will also be available in your
321+
* CloudWatch Logs
322+
*
323+
* @param key is the name of the metric
324+
* @param value is the value of the metric
325+
* @param unit is the unit of the metric value
326+
* @param aggregationType is the aggregation type of the metric
327+
* @return the current logger
328+
* @throws InvalidMetricException if the metric is invalid
329+
*/
330+
public MetricsLogger putMetric(
331+
String key, double value, Unit unit, AggregationType aggregationType)
332+
throws InvalidMetricException {
333+
this.putMetric(key, value, unit, StorageResolution.STANDARD, aggregationType);
334+
return this;
335+
}
336+
337+
/**
338+
* Put a metric value. This value will be emitted to CloudWatch Metrics asynchronously and does
339+
* not contribute to your account TPS limits. The value will also be available in your
340+
* CloudWatch Logs
341+
*
342+
* @param key the name of the metric
343+
* @param value the value of the metric
344+
* @param aggregationType is the aggregation type of the metric
345+
* @return the current logger
346+
* @throws InvalidMetricException if the metric is invalid
347+
*/
348+
public MetricsLogger putMetric(String key, double value, AggregationType aggregationType)
349+
throws InvalidMetricException {
350+
this.putMetric(key, value, Unit.NONE, StorageResolution.STANDARD, aggregationType);
261351
return this;
262352
}
263353

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package software.amazon.cloudwatchlogs.emf.model;
18+
19+
public enum AggregationType {
20+
NONE(60),
21+
STATISTIC_SET(1),
22+
UNKNOWN_TO_SDK_VERSION(-1);
23+
24+
private final int value;
25+
26+
AggregationType(final int newValue) {
27+
value = newValue;
28+
}
29+
30+
public int getValue() {
31+
return this.value;
32+
}
33+
}

src/main/java/software/amazon/cloudwatchlogs/emf/model/Metric.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import com.fasterxml.jackson.annotation.JsonProperty;
2121
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
2222
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
23-
2423
import lombok.Getter;
2524
import software.amazon.cloudwatchlogs.emf.serializers.StorageResolutionFilter;
2625
import software.amazon.cloudwatchlogs.emf.serializers.StorageResolutionSerializer;

src/main/java/software/amazon/cloudwatchlogs/emf/model/MetricDirective.java

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,28 +68,44 @@ void putDimensionSet(DimensionSet dimensionSet) {
6868

6969
// Helper method for testing putMetric()
7070
void putMetric(String key, double value) {
71-
putMetric(key, value, Unit.NONE, StorageResolution.STANDARD);
71+
putMetric(key, value, Unit.NONE, StorageResolution.STANDARD, AggregationType.NONE);
7272
}
7373

7474
// Helper method for testing putMetric()
7575
void putMetric(String key, double value, Unit unit) {
76-
putMetric(key, value, unit, StorageResolution.STANDARD);
76+
putMetric(key, value, unit, StorageResolution.STANDARD, AggregationType.NONE);
7777
}
7878

7979
// Helper method for testing serialization
8080
void putMetric(String key, double value, StorageResolution storageResolution) {
81-
putMetric(key, value, Unit.NONE, storageResolution);
81+
putMetric(key, value, Unit.NONE, storageResolution, AggregationType.NONE);
8282
}
8383

84-
void putMetric(String key, double value, Unit unit, StorageResolution storageResolution) {
84+
void putMetric(
85+
String key,
86+
double value,
87+
Unit unit,
88+
StorageResolution storageResolution,
89+
AggregationType aggregationType) {
8590
metrics.compute(
8691
key,
8792
(k, v) -> {
8893
if (v == null) {
89-
MetricDefinitionBuilder tmp =
90-
new MetricDefinitionBuilder(unit, storageResolution, value);
91-
tmp.setName(key);
92-
return (Metric) tmp;
94+
Metric metric;
95+
switch (aggregationType) {
96+
case STATISTIC_SET:
97+
StatisticSetBuilder statisticSet =
98+
new StatisticSetBuilder(unit, storageResolution);
99+
statisticSet.addValue(value);
100+
metric = statisticSet;
101+
break;
102+
case NONE:
103+
default:
104+
metric =
105+
new MetricDefinitionBuilder(unit, storageResolution, value);
106+
}
107+
metric.setName(key);
108+
return metric;
93109
} else if (v instanceof MetricBuilder) {
94110
((MetricBuilder) v).addValue(value);
95111
return v;

src/main/java/software/amazon/cloudwatchlogs/emf/model/MetricsContext.java

Lines changed: 101 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ public class MetricsContext {
4343
private MetricDirective metricDirective;
4444
private final Map<String, StorageResolution> metricNameAndResolutionMap =
4545
new ConcurrentHashMap<>();
46+
private final Map<String, AggregationType> metricNameAndAggregationMap =
47+
new ConcurrentHashMap<>();
4648

4749
public MetricsContext() {
4850
this(new RootNode());
@@ -112,6 +114,40 @@ public boolean hasDefaultDimensions() {
112114
return !getDefaultDimensions().getDimensionKeys().isEmpty();
113115
}
114116

117+
/**
118+
* Add a metric measurement to the context. Multiple calls using the same key will be stored as
119+
* an array of scalar values.
120+
*
121+
* <pre>{@code
122+
* metricContext.putMetric("Latency", 100, Unit.MILLISECONDS, StorageResolution.HIGH, AggregationType.NONE)
123+
* }</pre>
124+
*
125+
* @param key Name of the metric
126+
* @param value Value of the metric
127+
* @param unit The unit of the metric
128+
* @param storageResolution The resolution of the metric
129+
* @throws InvalidMetricException if the metric is invalid
130+
*/
131+
public void putMetric(
132+
String key,
133+
double value,
134+
Unit unit,
135+
StorageResolution storageResolution,
136+
AggregationType aggregationType)
137+
throws InvalidMetricException {
138+
Validator.validateMetric(
139+
key,
140+
value,
141+
unit,
142+
storageResolution,
143+
aggregationType,
144+
metricNameAndResolutionMap,
145+
metricNameAndAggregationMap);
146+
metricDirective.putMetric(key, value, unit, storageResolution, aggregationType);
147+
metricNameAndResolutionMap.put(key, storageResolution);
148+
metricNameAndAggregationMap.put(key, aggregationType);
149+
}
150+
115151
/**
116152
* Add a metric measurement to the context. Multiple calls using the same key will be stored as
117153
* an array of scalar values.
@@ -128,10 +164,9 @@ public boolean hasDefaultDimensions() {
128164
*/
129165
public void putMetric(String key, double value, Unit unit, StorageResolution storageResolution)
130166
throws InvalidMetricException {
131-
Validator.validateMetric(key, value, unit, storageResolution, metricNameAndResolutionMap);
132-
metricDirective.putMetric(key, value, unit, storageResolution);
133-
metricNameAndResolutionMap.put(key, storageResolution);
167+
putMetric(key, value, unit, storageResolution, AggregationType.NONE);
134168
}
169+
135170
/**
136171
* Add a metric measurement to the context with a storage resolution but without a unit.
137172
* Multiple calls using the same key will be stored as an array of scalar values.
@@ -147,7 +182,7 @@ public void putMetric(String key, double value, Unit unit, StorageResolution sto
147182
*/
148183
public void putMetric(String key, double value, StorageResolution storageResolution)
149184
throws InvalidMetricException {
150-
putMetric(key, value, Unit.NONE, storageResolution);
185+
putMetric(key, value, Unit.NONE, storageResolution, AggregationType.NONE);
151186
}
152187

153188
/**
@@ -164,7 +199,67 @@ public void putMetric(String key, double value, StorageResolution storageResolut
164199
* @throws InvalidMetricException if the metric is invalid
165200
*/
166201
public void putMetric(String key, double value, Unit unit) throws InvalidMetricException {
167-
putMetric(key, value, unit, StorageResolution.STANDARD);
202+
putMetric(key, value, unit, StorageResolution.STANDARD, AggregationType.NONE);
203+
}
204+
205+
/**
206+
* Add a metric measurement to the context without a unit Multiple calls using the same key will
207+
* be stored as an array of scalar values.
208+
*
209+
* <pre>{@code
210+
* metricContext.putMetric("Count", 10, AggregationType.NONE)
211+
* }</pre>
212+
*
213+
* @param key Name of the metric
214+
* @param value Value of the metric
215+
* @param aggregationType The aggregation type of the metric
216+
* @throws InvalidMetricException if the metric is invalid
217+
*/
218+
public void putMetric(String key, double value, AggregationType aggregationType)
219+
throws InvalidMetricException {
220+
putMetric(key, value, Unit.NONE, StorageResolution.STANDARD, aggregationType);
221+
}
222+
223+
/**
224+
* Add a metric measurement to the context with a storage resolution but without a unit.
225+
* Multiple calls using the same key will be stored as an array of scalar values.
226+
*
227+
* <pre>{@code
228+
* metricContext.putMetric("Latency", 100, StorageResolution.HIGH, AggregationType.NONE)
229+
* }</pre>
230+
*
231+
* @param key Name of the metric
232+
* @param value Value of the metric
233+
* @param storageResolution The resolution of the metric
234+
* @param aggregationType The aggregation type of the metric
235+
* @throws InvalidMetricException if the metric is invalid
236+
*/
237+
public void putMetric(
238+
String key,
239+
double value,
240+
StorageResolution storageResolution,
241+
AggregationType aggregationType)
242+
throws InvalidMetricException {
243+
putMetric(key, value, Unit.NONE, storageResolution, aggregationType);
244+
}
245+
246+
/**
247+
* Add a metric measurement to the context without a storage resolution. Multiple calls using
248+
* the same key will be stored as an array of scalar values.
249+
*
250+
* <pre>{@code
251+
* metricContext.putMetric("Latency", 100, Unit.MILLISECONDS, AggregationType.NONE)
252+
* }</pre>
253+
*
254+
* @param key Name of the metric
255+
* @param value Value of the metric
256+
* @param unit The unit of the metric
257+
* @param aggregationType The aggregation type of the metric
258+
* @throws InvalidMetricException if the metric is invalid
259+
*/
260+
public void putMetric(String key, double value, Unit unit, AggregationType aggregationType)
261+
throws InvalidMetricException {
262+
putMetric(key, value, unit, StorageResolution.STANDARD, aggregationType);
168263
}
169264

170265
/**
@@ -180,7 +275,7 @@ public void putMetric(String key, double value, Unit unit) throws InvalidMetricE
180275
* @throws InvalidMetricException if the metric is invalid
181276
*/
182277
public void putMetric(String key, double value) throws InvalidMetricException {
183-
putMetric(key, value, Unit.NONE, StorageResolution.STANDARD);
278+
putMetric(key, value, Unit.NONE, StorageResolution.STANDARD, AggregationType.NONE);
184279
}
185280

186281
/**

0 commit comments

Comments
 (0)