Skip to content

Commit d8ae46b

Browse files
authored
Added Statistic Set Metric Type (#150)
1 parent 51e2337 commit d8ae46b

14 files changed

+967
-102
lines changed

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

+135-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.LIST;
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,177 @@ 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
216221
*
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
222+
*
223+
* <ul>
224+
* <li>Unit defaults to NONE
225+
* <li>AggregationType defaults to the default AggregationType of this logger
226+
* </ul>
227+
*
228+
* @see MetricsLogger#putMetric(String key, double value, Unit unit, StorageResolution
229+
* storageResolution, AggregationType aggregationType) putMetric(String key, double value,
230+
* Unit unit, StorageResolution storageResolution, AggregationType aggregationType)
225231
*/
226232
public MetricsLogger putMetric(String key, double value, StorageResolution storageResolution)
227233
throws InvalidMetricException {
228-
this.putMetric(key, value, Unit.NONE, storageResolution);
234+
this.putMetric(key, value, Unit.NONE, storageResolution, this.defaultAggregationType);
229235
return this;
230236
}
231237

232238
/**
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
236239
*
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
240+
*
241+
* <ul>
242+
* <li>StorageResolution defaults to STANDARD
243+
* <li>AggregationType defaults to the default AggregationType of this logger
244+
* </ul>
245+
*
246+
* @see MetricsLogger#putMetric(String key, double value, Unit unit, StorageResolution
247+
* storageResolution, AggregationType aggregationType) putMetric(String key, double value,
248+
* Unit unit, StorageResolution storageResolution, AggregationType aggregationType)
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, this.defaultAggregationType);
246253
return this;
247254
}
248255

249256
/**
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
257+
*
258+
*
259+
* <ul>
260+
* <li>StorageResolution defaults to STANDARD
261+
* <li>Unit defaults to NONE
262+
* <li>AggregationType defaults to the default AggregationType of this logger
263+
* </ul>
264+
*
265+
* @see MetricsLogger#putMetric(String key, double value, Unit unit, StorageResolution
266+
* storageResolution, AggregationType aggregationType) putMetric(String key, double value,
267+
* Unit unit, StorageResolution storageResolution, AggregationType aggregationType)
268+
*/
269+
public MetricsLogger putMetric(String key, double value) throws InvalidMetricException {
270+
this.putMetric(
271+
key, value, Unit.NONE, StorageResolution.STANDARD, this.defaultAggregationType);
272+
return this;
273+
}
274+
275+
/**
276+
*
277+
*
278+
* <ul>
279+
* <li>AggregationType defaults to the default AggregationType of this logger
280+
* </ul>
281+
*
282+
* @see MetricsLogger#putMetric(String key, double value, Unit unit, StorageResolution
283+
* storageResolution, AggregationType aggregationType) putMetric(String key, double value,
284+
* Unit unit, StorageResolution storageResolution, AggregationType aggregationType)
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, this.defaultAggregationType);
290+
return this;
291+
}
292+
293+
/**
294+
*
295+
*
296+
* <ul>
297+
* <li>StorageResolution defaults to STANDARD
298+
* <li>AggregationType defaults to the default AggregationType of this logger
299+
* </ul>
300+
*
301+
* @see MetricsLogger#putMetric(String key, double value, Unit unit, StorageResolution
302+
* storageResolution, AggregationType aggregationType) putMetric(String key, double value,
303+
* Unit unit, StorageResolution storageResolution, AggregationType aggregationType)
304+
*/
305+
public MetricsLogger putMetric(
306+
String key,
307+
double value,
308+
StorageResolution storageResolution,
309+
AggregationType aggregationType)
310+
throws InvalidMetricException {
311+
this.putMetric(key, value, Unit.NONE, storageResolution, aggregationType);
312+
return this;
313+
}
314+
315+
/**
316+
*
317+
*
318+
* <ul>
319+
* <li>StorageResolution defaults to STANDARD
320+
* </ul>
321+
*
322+
* @see MetricsLogger#putMetric(String key, double value, Unit unit, StorageResolution
323+
* storageResolution, AggregationType aggregationType) putMetric(String key, double value,
324+
* Unit unit, StorageResolution storageResolution, AggregationType aggregationType)
325+
*/
326+
public MetricsLogger putMetric(
327+
String key, double value, Unit unit, AggregationType aggregationType)
328+
throws InvalidMetricException {
329+
this.putMetric(key, value, unit, StorageResolution.STANDARD, aggregationType);
330+
return this;
331+
}
332+
333+
/**
334+
*
335+
*
336+
* <ul>
337+
* <li>StorageResolution defaults to STANDARD
338+
* <li>Unit defaults to NONE
339+
* </ul>
340+
*
341+
* @see MetricsLogger#putMetric(String key, double value, Unit unit, StorageResolution
342+
* storageResolution, AggregationType aggregationType) putMetric(String key, double value,
343+
* Unit unit, StorageResolution storageResolution, AggregationType aggregationType)
344+
*/
345+
public MetricsLogger putMetric(String key, double value, AggregationType aggregationType)
346+
throws InvalidMetricException {
347+
this.putMetric(key, value, Unit.NONE, StorageResolution.STANDARD, aggregationType);
348+
return this;
349+
}
350+
351+
/**
352+
* Set a metric value, if a metric already has the same key it will be overwitten. This value
353+
* will be emitted to CloudWatch Metrics asynchronously and does not contribute to your account
354+
* TPS limits. The value will also be available in your CloudWatch Logs
253355
*
254356
* @param key the name of the metric
255357
* @param value the value of the metric
256358
* @return the current logger
257359
* @throws InvalidMetricException if the metric is invalid
258360
*/
259-
public MetricsLogger putMetric(String key, double value) throws InvalidMetricException {
260-
this.putMetric(key, value, Unit.NONE, StorageResolution.STANDARD);
261-
return this;
361+
public MetricsLogger setMetric(String key, Metric value) throws InvalidMetricException {
362+
try {
363+
this.context.setMetric(key, value);
364+
return this;
365+
} finally {
366+
rwl.readLock().unlock();
367+
}
262368
}
263369

264370
/**
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+
LIST(0),
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

+26-20
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.fasterxml.jackson.annotation.JsonProperty;
2222
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
2323
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
24+
import java.util.LinkedList;
2425
import lombok.AccessLevel;
2526
import lombok.Getter;
2627
import lombok.NonNull;
@@ -41,15 +42,15 @@ public abstract class Metric<V> {
4142
@JsonProperty("Unit")
4243
@JsonSerialize(using = UnitSerializer.class)
4344
@JsonDeserialize(using = UnitDeserializer.class)
44-
protected Unit unit;
45+
protected Unit unit = Unit.NONE;
4546

4647
@JsonProperty("StorageResolution")
4748
@JsonInclude(
4849
value = JsonInclude.Include.CUSTOM,
4950
valueFilter =
5051
StorageResolutionFilter.class) // Do not serialize when valueFilter is true
5152
@JsonSerialize(using = StorageResolutionSerializer.class)
52-
protected StorageResolution storageResolution;
53+
protected StorageResolution storageResolution = StorageResolution.STANDARD;
5354

5455
@JsonIgnore @Getter protected V values;
5556

@@ -58,23 +59,20 @@ protected Object getFormattedValues() {
5859
return this.getValues();
5960
}
6061

61-
/**
62-
* Creates a Metric with the first {@code size} values of the current metric
63-
*
64-
* @param size the maximum size of the returned metric's values
65-
* @return a Metric with the first {@code size} values of the current metric.
66-
*/
67-
protected abstract Metric getMetricValuesUnderSize(int size);
62+
/** @return true if the values of this metric are valid, false otherwise. */
63+
public abstract boolean hasValidValues();
64+
65+
/** @return true if the values of this metric are oversized for CloudWatch Logs */
66+
protected abstract boolean isOversized();
6867

6968
/**
70-
* Creates a Metric all metrics after the first {@code size} values of the current metric. If
71-
* there are less than {@code size} values, null is returned.
69+
* Creates a list of new Metrics based off the values in this metric split in so that they are
70+
* small enough that CWL will not drop the message values
7271
*
73-
* @param size the maximum size of the returned metric's values
74-
* @return a Metric with the all metrics after the first {@code size} values of the current
75-
* metric. If there are less than {@code size} values, null is returned.
72+
* @return a list of metrics based off of the values of this metric that aren't too large for
73+
* CWL
7674
*/
77-
protected abstract Metric getMetricValuesOverSize(int size);
75+
protected abstract LinkedList<Metric> serialize();
7876

7977
public abstract static class MetricBuilder<V, T extends MetricBuilder<V, T>> extends Metric<V> {
8078

@@ -92,7 +90,7 @@ public abstract static class MetricBuilder<V, T extends MetricBuilder<V, T>> ext
9290
*
9391
* @return the built metric
9492
*/
95-
abstract Metric build();
93+
abstract Metric<V> build();
9694

9795
protected T name(@NonNull String name) {
9896
this.name = name;
@@ -109,16 +107,24 @@ public T storageResolution(StorageResolution storageResolution) {
109107
return getThis();
110108
}
111109

112-
protected Metric getMetricValuesOverSize(int size) {
113-
return build().getMetricValuesOverSize(size);
110+
@Override
111+
public boolean hasValidValues() {
112+
return build().hasValidValues();
114113
}
115114

116-
protected Metric getMetricValuesUnderSize(int size) {
117-
return build().getMetricValuesUnderSize(size);
115+
@Override
116+
protected LinkedList<Metric> serialize() {
117+
return build().serialize();
118118
}
119119

120+
@Override
120121
protected Object getFormattedValues() {
121122
return build().getFormattedValues();
122123
}
124+
125+
@Override
126+
protected boolean isOversized() {
127+
return build().isOversized();
128+
}
123129
}
124130
}

0 commit comments

Comments
 (0)