Skip to content

Commit 2411d1e

Browse files
author
Meshwa Savalia
committed
Modified metrics validation logic and minor fixes
1 parent f434897 commit 2411d1e

File tree

10 files changed

+57
-16
lines changed

10 files changed

+57
-16
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ The `MetricsLogger` is the interface you will use to publish embedded metrics.
9292
- MetricsLogger **putMetric**(String key, double value, Unit unit)
9393
- MetricsLogger **putMetric**(String key, double value)
9494

95-
Adds a new metric to the current logger context. Multiple metrics using the same key will be appended to an array of values. Multiple metrics cannot have same key but different storage resolution. The Embedded Metric Format supports a maximum of 100 values per key.
95+
Adds a new metric to the current logger context. Multiple metrics using the same key will be appended to an array of values. Multiple metrics cannot have same key and different storage resolution. The Embedded Metric Format supports a maximum of 100 values per key.
9696

9797
Requirements:
9898

canarytests/agent/src/main/java/emf/canary/ECSRunnable.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import software.amazon.cloudwatchlogs.emf.exception.InvalidNamespaceException;
99
import software.amazon.cloudwatchlogs.emf.logger.MetricsLogger;
1010
import software.amazon.cloudwatchlogs.emf.model.DimensionSet;
11+
import software.amazon.cloudwatchlogs.emf.model.StorageResolution;
1112
import software.amazon.cloudwatchlogs.emf.model.Unit;
1213

1314
import java.lang.management.ManagementFactory;
@@ -46,7 +47,7 @@ public void run() {
4647
try {
4748
logger.putMetric("Invoke", 1, Unit.COUNT);
4849
logger.putMetric("Memory.HeapTotal", heapTotal, Unit.COUNT);
49-
logger.putMetric("Memory.HeapUsed", heapUsed, Unit.COUNT);
50+
logger.putMetric("Memory.HeapUsed", heapUsed, Unit.COUNT, StorageResolution.HIGH);
5051
logger.putMetric("Memory.JVMUsedTotal", heapUsed + nonHeapUsed, Unit.COUNT);
5152
} catch (InvalidMetricException e) {
5253
System.out.println(e);

examples/ecs-firelens/src/main/java/App.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public static void main(String[] args) throws Exception {
4040
MetricsLogger logger = new MetricsLogger();
4141
logger.setNamespace("FargateEMF");
4242
logger.putMetric("Latency", 63, Unit.MILLISECONDS);
43-
logger.putMetric("LatencyInHighResolution", 65, Unit.MILLISECONDS, StorageResolution.HIGH);
43+
logger.putMetric("CPU Utilization", 87, Unit.PERCENT, StorageResolution.HIGH);
4444
logger.flush();
4545
HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
4646
int portNumber = 8000;
@@ -77,7 +77,6 @@ public void handle(HttpExchange he) throws IOException {
7777
logger.putProperty("Url", he.getRequestURI());
7878
try {
7979
logger.putMetric("ProcessingTime", System.currentTimeMillis() - time, Unit.MILLISECONDS);
80-
logger.putMetric("ProcessingTimeInHighResolution", System.currentTimeMillis() - time, Unit.MILLISECONDS, StorageResolution.HIGH);
8180
} catch (InvalidMetricException e) {
8281
System.out.println(e);
8382
}

examples/lambda/src/main/java/Handler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public String handleRequest(Map<String, String> event, Context context) {
2121
try {
2222
logger.putDimensions(DimensionSet.of("Service", "Aggregator"));
2323
logger.putMetric("ProcessingLatency", 100, Unit.MILLISECONDS);
24-
logger.putMetric("ProcessingLatencyInHighResolution", 101, Unit.MILLISECONDS, StorageResolution.HIGH);
24+
logger.putMetric("CPU Utilization", 87, Unit.PERCENT, StorageResolution.HIGH);
2525
} catch (InvalidDimensionException | InvalidMetricException | DimensionSetExceededException e) {
2626
System.out.println(e);
2727
}

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
import software.amazon.cloudwatchlogs.emf.model.StorageResolution;
3636
import software.amazon.cloudwatchlogs.emf.model.Unit;
3737
import software.amazon.cloudwatchlogs.emf.sinks.ISink;
38-
import software.amazon.cloudwatchlogs.emf.util.Validator;
3938

4039
/**
4140
* A metrics logger. Use this interface to publish logs to CloudWatch Logs and extract metrics to
@@ -94,7 +93,6 @@ public void flush() {
9493
configureContextForEnvironment(context, environment);
9594
sink.accept(context);
9695
context = context.createCopyWithContext(flushPreserveDimensions);
97-
Validator.metricNameAndResolutionMap.clear();
9896
} finally {
9997
rwl.writeLock().unlock();
10098
}
@@ -193,6 +191,9 @@ public MetricsLogger resetDimensions(boolean useDefault) {
193191
* @param value is the value of the metric
194192
* @param unit is the unit of the metric value
195193
* @param storageResolution is the resolution of the metric
194+
* @see <a
195+
* href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/publishingMetrics.html#high-resolution-metrics">CloudWatch
196+
* High Resolution Metrics</a>
196197
* @return the current logger
197198
* @throws InvalidMetricException if the metric is invalid
198199
*/
@@ -216,6 +217,9 @@ public MetricsLogger putMetric(
216217
* @param key is the name of the metric
217218
* @param value is the value of the metric
218219
* @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>
219223
* @return the current logger
220224
* @throws InvalidMetricException if the metric is invalid
221225
*/

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public class MetricsContext {
3434
@Getter private final RootNode rootNode;
3535

3636
private MetricDirective metricDirective;
37+
private final Map<String, String> metricNameAndResolutionMap = new HashMap<>();
3738

3839
public MetricsContext() {
3940
this(new RootNode());
@@ -119,7 +120,7 @@ public boolean hasDefaultDimensions() {
119120
*/
120121
public void putMetric(String key, double value, Unit unit, StorageResolution storageResolution)
121122
throws InvalidMetricException {
122-
Validator.validateMetric(key, value, unit, storageResolution);
123+
Validator.validateMetric(key, value, unit, storageResolution, metricNameAndResolutionMap);
123124
metricDirective.putMetric(key, value, unit, storageResolution);
124125
}
125126
/**

src/main/java/software/amazon/cloudwatchlogs/emf/serializers/StorageResolutionFilter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ public class StorageResolutionFilter {
77
@Override
88
public boolean equals(Object obj) {
99

10-
if (obj == null || !(obj instanceof StorageResolution)) {
10+
if (!(obj instanceof StorageResolution)) {
1111
return false;
1212
}
1313
return (obj.toString().equals("STANDARD"));

src/main/java/software/amazon/cloudwatchlogs/emf/util/Validator.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package software.amazon.cloudwatchlogs.emf.util;
1818

1919
import java.time.Instant;
20-
import java.util.HashMap;
2120
import java.util.Map;
2221
import org.apache.commons.lang3.StringUtils;
2322
import software.amazon.cloudwatchlogs.emf.Constants;
@@ -26,7 +25,6 @@
2625
import software.amazon.cloudwatchlogs.emf.model.Unit;
2726

2827
public class Validator {
29-
public static Map<String, String> metricNameAndResolutionMap = new HashMap<>();
3028

3129
private Validator() {
3230
throw new IllegalStateException("Utility class");
@@ -94,10 +92,15 @@ public static void validateDimensionSet(String dimensionName, String dimensionVa
9492
* @param value Metric value
9593
* @param unit Metric unit
9694
* @param storageResolution Metric resolution
95+
* @param metricNameAndResolutionMap Map to validate Metric
9796
* @throws InvalidMetricException if metric is invalid
9897
*/
9998
public static void validateMetric(
100-
String name, double value, Unit unit, StorageResolution storageResolution)
99+
String name,
100+
double value,
101+
Unit unit,
102+
StorageResolution storageResolution,
103+
Map<String, String> metricNameAndResolutionMap)
101104
throws InvalidMetricException {
102105

103106
if (name == null || name.trim().isEmpty()) {
@@ -126,8 +129,7 @@ public static void validateMetric(
126129
}
127130

128131
if (metricNameAndResolutionMap.containsKey(name)) {
129-
String resolutionOfMetric = metricNameAndResolutionMap.get(name);
130-
if (!resolutionOfMetric.equals(storageResolution.toString())) {
132+
if (!metricNameAndResolutionMap.get(name).equals(storageResolution.toString())) {
131133
throw new InvalidMetricException(
132134
"Resolution for metrics "
133135
+ name

src/test/java/software/amazon/cloudwatchlogs/emf/logger/MetricsLoggerTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,16 @@ void whenPutMetric_withNullStorageResolution_thenThrowInvalidMetricException() {
361361
() -> logger.putMetric("test", 1, (StorageResolution) null));
362362
}
363363

364+
@Test
365+
void whenPutMetric_withSameMetricDifferentStorageResolutionAfterFlush_thenAllow()
366+
throws InvalidMetricException {
367+
logger.putMetric("Count", 1);
368+
logger.flush();
369+
logger.putMetric("Count", 1.0, StorageResolution.HIGH);
370+
logger.flush();
371+
assertTrue(sink.getLogEvents().get(0).contains("StorageResolution"));
372+
}
373+
364374
@Test
365375
void whenPutMetric_withDifferentStorageResolution_thenThrowInvalidMetricException() {
366376
assertThrows(

src/test/java/software/amazon/cloudwatchlogs/emf/model/MetricDefinitionTest.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,27 @@ public void testThrowExceptionIfNameIsNull() {
3131
new MetricDefinition(null);
3232
}
3333

34+
@Test
35+
public void testSerializeMetricDefinitionWithoutUnitWithStorageResolution()
36+
throws JsonProcessingException {
37+
ObjectMapper objectMapper = new ObjectMapper();
38+
MetricDefinition metricDefinition =
39+
new MetricDefinition("Time", StorageResolution.HIGH, 10);
40+
String metricString = objectMapper.writeValueAsString(metricDefinition);
41+
42+
assertEquals("{\"Name\":\"Time\",\"Unit\":\"None\",\"StorageResolution\":1}", metricString);
43+
}
44+
45+
@Test
46+
public void testSerializeMetricDefinitionWithUnitWithoutStorageResolution()
47+
throws JsonProcessingException {
48+
ObjectMapper objectMapper = new ObjectMapper();
49+
MetricDefinition metricDefinition = new MetricDefinition("Time", Unit.MILLISECONDS, 10);
50+
String metricString = objectMapper.writeValueAsString(metricDefinition);
51+
52+
assertEquals("{\"Name\":\"Time\",\"Unit\":\"Milliseconds\"}", metricString);
53+
}
54+
3455
@Test
3556
public void testSerializeMetricDefinitionWithoutUnit() throws JsonProcessingException {
3657
ObjectMapper objectMapper = new ObjectMapper();
@@ -43,10 +64,13 @@ public void testSerializeMetricDefinitionWithoutUnit() throws JsonProcessingExce
4364
@Test
4465
public void testSerializeMetricDefinition() throws JsonProcessingException {
4566
ObjectMapper objectMapper = new ObjectMapper();
46-
MetricDefinition metricDefinition = new MetricDefinition("Time", Unit.MILLISECONDS, 10);
67+
MetricDefinition metricDefinition =
68+
new MetricDefinition("Time", Unit.MILLISECONDS, StorageResolution.HIGH, 10);
4769
String metricString = objectMapper.writeValueAsString(metricDefinition);
4870

49-
assertEquals("{\"Name\":\"Time\",\"Unit\":\"Milliseconds\"}", metricString);
71+
assertEquals(
72+
"{\"Name\":\"Time\",\"Unit\":\"Milliseconds\",\"StorageResolution\":1}",
73+
metricString);
5074
}
5175

5276
@Test

0 commit comments

Comments
 (0)