Skip to content

Commit ae423ca

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

14 files changed

+861
-61
lines changed

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

+114-29
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,74 +194,156 @@ 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();
209217
}
210218
}
211219

212220
/**
213-
* Put a metric value. This value will be emitted to CloudWatch Metrics asynchronously and does
214-
* not contribute to your account TPS limits. The value will also be available in your
215-
* CloudWatch Logs
221+
* Unit defaults to NONE
216222
*
217-
* @param key is the name of the metric
218-
* @param value is the value of the metric
219-
* @param storageResolution is the resolution of the metric
220-
* @see <a
221-
* href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/publishingMetrics.html#high-resolution-metrics">CloudWatch
222-
* High Resolution Metrics</a>
223-
* @return the current logger
224-
* @throws InvalidMetricException if the metric is invalid
223+
* <p>AggregationType defaults to the default AggregationType of this logger
224+
*
225+
* @see MetricsLogger#putMetric(String key, double value, Unit unit, StorageResolution
226+
* storageResolution, AggregationType aggregationType) putMetric(String key, double value,
227+
* Unit unit, StorageResolution storageResolution, AggregationType aggregationType)
225228
*/
226229
public MetricsLogger putMetric(String key, double value, StorageResolution storageResolution)
227230
throws InvalidMetricException {
228-
this.putMetric(key, value, Unit.NONE, storageResolution);
231+
this.putMetric(key, value, Unit.NONE, storageResolution, this.defaultAggregationType);
229232
return this;
230233
}
231234

232235
/**
233-
* Put a metric value. This value will be emitted to CloudWatch Metrics asynchronously and does
234-
* not contribute to your account TPS limits. The value will also be available in your
235-
* CloudWatch Logs
236+
* Unit defaults to NONE
236237
*
237-
* @param key is the name of the metric
238-
* @param value is the value of the metric
239-
* @param unit is the unit of the metric value
240-
* @return the current logger
241-
* @throws InvalidMetricException if the metric is invalid
238+
* <p>StorageResolution defaults to STANDARD
239+
*
240+
* <p>AggregationType defaults to the default AggregationType of this logger
241+
*
242+
* @see MetricsLogger#putMetric(String key, double value, Unit unit, StorageResolution
243+
* storageResolution, AggregationType aggregationType) putMetric(String key, double value,
244+
* Unit unit, StorageResolution storageResolution, AggregationType aggregationType)
242245
*/
243246
public MetricsLogger putMetric(String key, double value, Unit unit)
244247
throws InvalidMetricException {
245-
this.putMetric(key, value, unit, StorageResolution.STANDARD);
248+
this.putMetric(key, value, unit, StorageResolution.STANDARD, this.defaultAggregationType);
246249
return this;
247250
}
248251

249252
/**
250-
* Put a metric value. This value will be emitted to CloudWatch Metrics asynchronously and does
251-
* not contribute to your account TPS limits. The value will also be available in your
252-
* CloudWatch Logs
253+
* Unit defaults to NONE
254+
*
255+
* <p>StorageResolution defaults to STANDARD
256+
*
257+
* <p>AggregationType defaults to the default AggregationType of this logger
258+
*
259+
* @see MetricsLogger#putMetric(String key, double value, Unit unit, StorageResolution
260+
* storageResolution, AggregationType aggregationType) putMetric(String key, double value,
261+
* Unit unit, StorageResolution storageResolution, AggregationType aggregationType)
262+
*/
263+
public MetricsLogger putMetric(String key, double value) throws InvalidMetricException {
264+
this.putMetric(
265+
key, value, Unit.NONE, StorageResolution.STANDARD, this.defaultAggregationType);
266+
return this;
267+
}
268+
269+
/**
270+
* AggregationType defaults to the default AggregationType of this logger
271+
*
272+
* @see MetricsLogger#putMetric(String key, double value, Unit unit, StorageResolution
273+
* storageResolution, AggregationType aggregationType) putMetric(String key, double value,
274+
* Unit unit, StorageResolution storageResolution, AggregationType aggregationType)
275+
*/
276+
public MetricsLogger putMetric(
277+
String key, double value, Unit unit, StorageResolution storageResolution)
278+
throws InvalidMetricException {
279+
this.putMetric(key, value, Unit.NONE, storageResolution, this.defaultAggregationType);
280+
return this;
281+
}
282+
283+
/**
284+
* StorageResolution defaults to STANDARD
285+
*
286+
* <p>AggregationType defaults to the default AggregationType of this logger
287+
*
288+
* @see MetricsLogger#putMetric(String key, double value, Unit unit, StorageResolution
289+
* storageResolution, AggregationType aggregationType) putMetric(String key, double value,
290+
* Unit unit, StorageResolution storageResolution, AggregationType aggregationType)
291+
*/
292+
public MetricsLogger putMetric(
293+
String key,
294+
double value,
295+
StorageResolution storageResolution,
296+
AggregationType aggregationType)
297+
throws InvalidMetricException {
298+
this.putMetric(key, value, Unit.NONE, storageResolution, aggregationType);
299+
return this;
300+
}
301+
302+
/**
303+
* StorageResolution defaults to STANDARD
304+
*
305+
* @see MetricsLogger#putMetric(String key, double value, Unit unit, StorageResolution
306+
* storageResolution, AggregationType aggregationType) putMetric(String key, double value,
307+
* Unit unit, StorageResolution storageResolution, AggregationType aggregationType)
308+
*/
309+
public MetricsLogger putMetric(
310+
String key, double value, Unit unit, AggregationType aggregationType)
311+
throws InvalidMetricException {
312+
this.putMetric(key, value, unit, StorageResolution.STANDARD, aggregationType);
313+
return this;
314+
}
315+
316+
/**
317+
* Unit defaults to NONE
318+
*
319+
* <p>StorageResolution defaults to STANDARD
320+
*
321+
* @see MetricsLogger#putMetric(String key, double value, Unit unit, StorageResolution
322+
* storageResolution, AggregationType aggregationType) putMetric(String key, double value,
323+
* Unit unit, StorageResolution storageResolution, AggregationType aggregationType)
324+
*/
325+
public MetricsLogger putMetric(String key, double value, AggregationType aggregationType)
326+
throws InvalidMetricException {
327+
this.putMetric(key, value, Unit.NONE, StorageResolution.STANDARD, aggregationType);
328+
return this;
329+
}
330+
331+
/**
332+
* Set a metric value, if a metric already has the same key it will be overwitten. This value
333+
* will be emitted to CloudWatch Metrics asynchronously and does not contribute to your account
334+
* TPS limits. The value will also be available in your CloudWatch Logs
253335
*
254336
* @param key the name of the metric
255337
* @param value the value of the metric
256338
* @return the current logger
257339
* @throws InvalidMetricException if the metric is invalid
258340
*/
259-
public MetricsLogger putMetric(String key, double value) throws InvalidMetricException {
260-
this.putMetric(key, value, Unit.NONE, StorageResolution.STANDARD);
261-
return this;
341+
public MetricsLogger setMetric(String key, Metric value) {
342+
return applyReadLock(
343+
() -> {
344+
this.context.setMetric(key, value);
345+
return this;
346+
});
262347
}
263348

264349
/**
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

+34-11
Original file line numberDiff line numberDiff line change
@@ -69,31 +69,42 @@ 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()
92-
.name(k)
93-
.unit(unit)
94-
.storageResolution(storageResolution)
95-
.addValue(value);
96-
return builder;
95+
Metric.MetricBuilder builder;
96+
switch (aggregationType) {
97+
case STATISTIC_SET:
98+
builder = StatisticSet.builder();
99+
break;
100+
case NONE:
101+
default:
102+
builder = MetricDefinition.builder();
103+
}
104+
return builder.name(k)
105+
.unit(unit)
106+
.storageResolution(storageResolution)
107+
.addValue(value);
97108
} else if (v instanceof Metric.MetricBuilder) {
98109
((Metric.MetricBuilder) v).addValue(value);
99110
return v;
@@ -106,6 +117,18 @@ void putMetric(String key, double value, Unit unit, StorageResolution storageRes
106117
});
107118
}
108119

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

0 commit comments

Comments
 (0)