Skip to content

Commit d1b2a49

Browse files
committed
Added Statistic Set Metric Type
1 parent 51e2337 commit d1b2a49

14 files changed

+881
-33
lines changed

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

+114-5
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@
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;
35+
import software.amazon.cloudwatchlogs.emf.model.Metric;
3436
import software.amazon.cloudwatchlogs.emf.model.MetricsContext;
3537
import software.amazon.cloudwatchlogs.emf.model.StorageResolution;
3638
import software.amazon.cloudwatchlogs.emf.model.Unit;
@@ -45,6 +47,7 @@ public class MetricsLogger {
4547
private MetricsContext context;
4648
private CompletableFuture<Environment> environmentFuture;
4749
private EnvironmentProvider environmentProvider;
50+
@Getter @Setter private volatile AggregationType defaultAggregationType = AggregationType.NONE;
4851
/**
4952
* This lock is used to create an internal sync context for flush() method in multi-threaded
5053
* situations. Flush() acquires write lock, other methods (accessing mutable shared data with
@@ -191,18 +194,23 @@ public MetricsLogger resetDimensions(boolean useDefault) {
191194
* @param value is the value of the metric
192195
* @param unit is the unit of the metric value
193196
* @param storageResolution is the resolution of the metric
197+
* @param aggregationType is the aggregation type of the metric
194198
* @see <a
195199
* href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/publishingMetrics.html#high-resolution-metrics">CloudWatch
196200
* High Resolution Metrics</a>
197201
* @return the current logger
198202
* @throws InvalidMetricException if the metric is invalid
199203
*/
200204
public MetricsLogger putMetric(
201-
String key, double value, Unit unit, StorageResolution storageResolution)
205+
String key,
206+
double value,
207+
Unit unit,
208+
StorageResolution storageResolution,
209+
AggregationType aggregationType)
202210
throws InvalidMetricException {
203211
rwl.readLock().lock();
204212
try {
205-
this.context.putMetric(key, value, unit, storageResolution);
213+
this.context.putMetric(key, value, unit, storageResolution, aggregationType);
206214
return this;
207215
} finally {
208216
rwl.readLock().unlock();
@@ -225,7 +233,7 @@ public MetricsLogger putMetric(
225233
*/
226234
public MetricsLogger putMetric(String key, double value, StorageResolution storageResolution)
227235
throws InvalidMetricException {
228-
this.putMetric(key, value, Unit.NONE, storageResolution);
236+
this.putMetric(key, value, Unit.NONE, storageResolution, defaultAggregationType);
229237
return this;
230238
}
231239

@@ -242,7 +250,7 @@ public MetricsLogger putMetric(String key, double value, StorageResolution stora
242250
*/
243251
public MetricsLogger putMetric(String key, double value, Unit unit)
244252
throws InvalidMetricException {
245-
this.putMetric(key, value, unit, StorageResolution.STANDARD);
253+
this.putMetric(key, value, unit, StorageResolution.STANDARD, defaultAggregationType);
246254
return this;
247255
}
248256

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

355+
/**
356+
* Set a metric value, if a metric already has the same key it will be overwitten. This value
357+
* will be emitted to CloudWatch Metrics asynchronously and does not contribute to your account
358+
* TPS limits. The value will also be available in your CloudWatch Logs
359+
*
360+
* @param key the name of the metric
361+
* @param value the value of the metric
362+
* @return the current logger
363+
* @throws InvalidMetricException if the metric is invalid
364+
*/
365+
public MetricsLogger setMetric(String key, Metric value) {
366+
return applyReadLock(
367+
() -> {
368+
this.context.setMetric(key, value);
369+
return this;
370+
});
371+
}
372+
264373
/**
265374
* Add a custom key-value pair to the Metadata object.
266375
*
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

+9-2
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,15 @@ public abstract class Metric<V> {
4141
@JsonProperty("Unit")
4242
@JsonSerialize(using = UnitSerializer.class)
4343
@JsonDeserialize(using = UnitDeserializer.class)
44-
protected Unit unit;
44+
protected Unit unit = Unit.NONE;
4545

4646
@JsonProperty("StorageResolution")
4747
@JsonInclude(
4848
value = JsonInclude.Include.CUSTOM,
4949
valueFilter =
5050
StorageResolutionFilter.class) // Do not serialize when valueFilter is true
5151
@JsonSerialize(using = StorageResolutionSerializer.class)
52-
protected StorageResolution storageResolution;
52+
protected StorageResolution storageResolution = StorageResolution.STANDARD;
5353

5454
@JsonIgnore @Getter protected V values;
5555

@@ -58,6 +58,9 @@ protected Object getFormattedValues() {
5858
return this.getValues();
5959
}
6060

61+
/** @return true if the values of this metric are valid, false otherwise. */
62+
public abstract boolean hasValidValues();
63+
6164
/**
6265
* Creates a Metric with the first {@code size} values of the current metric
6366
*
@@ -109,6 +112,10 @@ public T storageResolution(StorageResolution storageResolution) {
109112
return getThis();
110113
}
111114

115+
public boolean hasValidValues() {
116+
return build().hasValidValues();
117+
}
118+
112119
protected Metric getMetricValuesOverSize(int size) {
113120
return build().getMetricValuesOverSize(size);
114121
}

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

+5
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ protected Object getFormattedValues() {
8282
return values.size() == 1 ? values.get(0) : values;
8383
}
8484

85+
@Override
86+
public boolean hasValidValues() {
87+
return values != null && !values.isEmpty();
88+
}
89+
8590
public static class MetricDefinitionBuilder
8691
extends Metric.MetricBuilder<List<Double>, MetricDefinitionBuilder> {
8792

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

+32-7
Original file line numberDiff line numberDiff line change
@@ -69,31 +69,44 @@ void putDimensionSet(DimensionSet dimensionSet) {
6969

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

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

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

85-
void putMetric(String key, double value, Unit unit, StorageResolution storageResolution) {
85+
void putMetric(
86+
String key,
87+
double value,
88+
Unit unit,
89+
StorageResolution storageResolution,
90+
AggregationType aggregationType) {
8691
metrics.compute(
8792
key,
8893
(k, v) -> {
8994
if (v == null) {
90-
MetricDefinition.MetricDefinitionBuilder builder =
91-
MetricDefinition.builder()
95+
switch (aggregationType) {
96+
case STATISTIC_SET:
97+
return StatisticSet.builder()
9298
.name(k)
9399
.unit(unit)
94100
.storageResolution(storageResolution)
95101
.addValue(value);
96-
return builder;
102+
case NONE:
103+
default:
104+
return MetricDefinition.builder()
105+
.name(k)
106+
.unit(unit)
107+
.storageResolution(storageResolution)
108+
.addValue(value);
109+
}
97110
} else if (v instanceof Metric.MetricBuilder) {
98111
((Metric.MetricBuilder) v).addValue(value);
99112
return v;
@@ -106,6 +119,18 @@ void putMetric(String key, double value, Unit unit, StorageResolution storageRes
106119
});
107120
}
108121

122+
/**
123+
* Sets a metric to the given value. If a metric with the same name already exists, it will be
124+
* overwritten.
125+
*
126+
* @param key the name of the metric
127+
* @param value the value of the metric
128+
*/
129+
void setMetric(String key, Metric value) {
130+
value.setName(key);
131+
metrics.put(key, value);
132+
}
133+
109134
@JsonProperty("Metrics")
110135
Collection<Metric> getAllMetrics() {
111136
return metrics.values();

0 commit comments

Comments
 (0)