From 9e32782de3a2ab7e4d6bd37d29b624bab0ea2095 Mon Sep 17 00:00:00 2001
From: yibole
Date: Tue, 31 Dec 2024 16:47:24 -0800
Subject: [PATCH] End to end test passed
---
.../emf-metric-publisher/pom.xml | 5 +
.../publishers/emf/EmfMetricPublisher.java | 10 +-
.../emf/internal/MetricEmfConverter.java | 221 ++++++++++--------
.../src/main/resources/log4j2.properties | 38 +++
.../emf/EmfMetricPublisherTest.java | 3 -
.../emf/internal/MetricEmfConverterTest.java | 52 +++--
6 files changed, 209 insertions(+), 120 deletions(-)
create mode 100644 metric-publishers/emf-metric-publisher/src/main/resources/log4j2.properties
diff --git a/metric-publishers/emf-metric-publisher/pom.xml b/metric-publishers/emf-metric-publisher/pom.xml
index 9a48033fc6d7..77a8160c48a4 100644
--- a/metric-publishers/emf-metric-publisher/pom.xml
+++ b/metric-publishers/emf-metric-publisher/pom.xml
@@ -65,6 +65,11 @@
${awsjavasdk.version}
compile
+
+ org.apache.logging.log4j
+ log4j-slf4j-impl
+ 2.20.0
+
software.amazon.awssdk
sdk-core
diff --git a/metric-publishers/emf-metric-publisher/src/main/java/software/amazon/awssdk/metrics/publishers/emf/EmfMetricPublisher.java b/metric-publishers/emf-metric-publisher/src/main/java/software/amazon/awssdk/metrics/publishers/emf/EmfMetricPublisher.java
index 7cdb4c6a0d3c..d11668a5cdd5 100644
--- a/metric-publishers/emf-metric-publisher/src/main/java/software/amazon/awssdk/metrics/publishers/emf/EmfMetricPublisher.java
+++ b/metric-publishers/emf-metric-publisher/src/main/java/software/amazon/awssdk/metrics/publishers/emf/EmfMetricPublisher.java
@@ -23,6 +23,7 @@
import software.amazon.awssdk.annotations.Immutable;
import software.amazon.awssdk.annotations.SdkPublicApi;
import software.amazon.awssdk.annotations.ThreadSafe;
+import software.amazon.awssdk.core.metrics.CoreMetric;
import software.amazon.awssdk.metrics.MetricCategory;
import software.amazon.awssdk.metrics.MetricCollection;
import software.amazon.awssdk.metrics.MetricLevel;
@@ -50,6 +51,13 @@
* monitoring and alerting.
*
*
+ *
+ * // Create a CloudWatchMetricPublisher using a custom namespace.
+ * MetricPublisher metricPublisher = EmfMetricPublisher.builder()
+ * .namespace("MyApplication")
+ * .build();
+ *
+ *
*
* @see MetricPublisher The base interface for metric publishers
* @see MetricCollection For the collection of metrics to be published
@@ -135,7 +143,7 @@ public Builder namespace(String namespace) {
* this
* publisher.
*
- * If this is not specified, [] will be used.
+ *
If this is not specified, {@link CoreMetric#SERVICE_ID} and {@link CoreMetric#OPERATION_NAME} will be used.
*/
public Builder dimensions(Collection> dimensions) {
this.dimensions = new ArrayList<>(dimensions);
diff --git a/metric-publishers/emf-metric-publisher/src/main/java/software/amazon/awssdk/metrics/publishers/emf/internal/MetricEmfConverter.java b/metric-publishers/emf-metric-publisher/src/main/java/software/amazon/awssdk/metrics/publishers/emf/internal/MetricEmfConverter.java
index 6165708d61c1..7adf04916624 100644
--- a/metric-publishers/emf-metric-publisher/src/main/java/software/amazon/awssdk/metrics/publishers/emf/internal/MetricEmfConverter.java
+++ b/metric-publishers/emf-metric-publisher/src/main/java/software/amazon/awssdk/metrics/publishers/emf/internal/MetricEmfConverter.java
@@ -33,23 +33,15 @@
import software.amazon.awssdk.utils.Logger;
/**
- * # MetricEmfConverter
-
- * Converts metrics into Amazon CloudWatch Embedded Metric Format (EMF).
- * This internal class handles the transformation of various metric types
- * into EMF-compatible format.
-
- * ## Configuration
- * The converter is initialized with an `EmfMetricConfiguration` that defines:
- * - Metric categories to process
- * - Other EMF-specific settings
-
- * ## Implementation Notes
- * - Boolean values are converted to numeric values (1.0 for true, 0.0 for false)
- * - Null values are converted to 0.0
- * - Very small numeric values (below 0.0001) are normalized to 0.0
- * - Duration values are converted to milliseconds
+ * Converts {@link MetricCollection} into List of Amazon CloudWatch Embedded Metric Format (EMF) Strings.
+ *
+ * This class is responsible for transforming {@link MetricCollection} into the EMF format required by CloudWatch.
+ * It handles the conversion of different metric types and ensures the output conforms to EMF specifications.
+ *
*
+ *
+ * @see
+ * CloudWatch Embedded Metric Format Specification
* @see EmfMetricConfiguration
*/
@SdkInternalApi
@@ -73,48 +65,14 @@ public MetricEmfConverter(EmfMetricConfiguration config) {
}
/**
- * Processes and normalizes metric values for EMF formatting.
- * The method handles various input types and normalizes them according to EMF requirements:
- * - `null` : 0.0
- * - `Boolean` : 1.0 (true) or 0.0 (false)
- * - `Duration` : milliseconds value
- * - `Double`: normalized to 0.0 if below threshold
- *
- * @param mRecord The metric record to process
- */
- private void processAndWriteValue(JsonWriter jsonWriter, MetricRecord> mRecord) {
- Object value = mRecord.value();
- Class> valueClass = mRecord.metric().valueClass();
-
- if (value == null) {
- jsonWriter.writeValue(0.0);
- } else if (Boolean.class.isAssignableFrom(valueClass)) {
- jsonWriter.writeValue(value.equals(true) ? 1.0 : 0.0);
- } else if (Duration.class.isAssignableFrom(valueClass)) {
- Duration duration = (Duration) value;
- double millisValue = duration.toMillis();
- jsonWriter.writeValue(millisValue);
- } else if (Double.class.isAssignableFrom(valueClass)) {
- double doubleValue = (Double) value;
- if (Math.abs(doubleValue) < ZERO_THRESHOLD) {
- jsonWriter.writeValue(0.0);
- } else {
- jsonWriter.writeValue(doubleValue);
- }
- } else if (Integer.class.isAssignableFrom(valueClass)) {
- jsonWriter.writeValue((Integer) value);
- } else if (Long.class.isAssignableFrom(valueClass)) {
- jsonWriter.writeValue((Long) value);
- }
- }
-
- /**
- * # Convert SDK Metrics to EMF Format
+ *
+ * Convert SDK Metrics to EMF Format.
* Transforms a collection of SDK metrics into CloudWatch's Embedded Metric Format (EMF).
* The method processes standard SDK measurements and structures them according to
* CloudWatch's EMF specification.
- * ## Example Output
- * ```json
+ *
+ * Example Output
+ *
* {
* "_aws": {
* "Timestamp": 1672963200,
@@ -126,10 +84,10 @@ private void processAndWriteValue(JsonWriter jsonWriter, MetricRecord> mRecord
* }]
* }]
* },
- * "ServiceId": "XXXXXXXXXXXXX",
+ * "ServiceId": "DynamoDB",
* "AvailableConcurrency": 5
* }
- * ```
+ *
*
* @param metricCollection Collection of SDK metrics to be converted
* @return List of EMF-formatted metrics ready for CloudWatch
@@ -168,6 +126,48 @@ public List convertMetricCollectionToEmf(MetricCollection metricCollecti
return createEmfStrings(aggregatedMetrics);
}
+ /**
+ * Processes and normalizes metric values for EMF formatting.
+ * The method handles various input types and normalizes them according to EMF requirements:
+ * Value Conversion Rules:
+ *
+ * - Numbers (Integer, Long, Double, etc.) are converted to their native numeric format
+ * - Duration values are converted to milliseconds
+ * - Date/Time values are converted to epoch milliseconds
+ * - Null values are omitted from the output
+ * - Boolean values are converted to 1 (true) or 0 (false)
+ * - Non-Dimension metrics with non-numeric values are omitted from the output
+ *
+ *
+ * @param mRecord The metric record to process
+ */
+ private void processAndWriteValue(JsonWriter jsonWriter, MetricRecord> mRecord) {
+ Object value = mRecord.value();
+ Class> valueClass = mRecord.metric().valueClass();
+
+ if (value == null) {
+ return;
+ }
+ if (Boolean.class.isAssignableFrom(valueClass)) {
+ jsonWriter.writeValue(value.equals(true) ? 1.0 : 0.0);
+ } else if (Duration.class.isAssignableFrom(valueClass)) {
+ Duration duration = (Duration) value;
+ double millisValue = duration.toMillis();
+ jsonWriter.writeValue(millisValue);
+ } else if (Double.class.isAssignableFrom(valueClass)) {
+ double doubleValue = (Double) value;
+ if (Math.abs(doubleValue) < ZERO_THRESHOLD) {
+ jsonWriter.writeValue(0.0);
+ } else {
+ jsonWriter.writeValue(doubleValue);
+ }
+ } else if (Integer.class.isAssignableFrom(valueClass)) {
+ jsonWriter.writeValue((Integer) value);
+ } else if (Long.class.isAssignableFrom(valueClass)) {
+ jsonWriter.writeValue((Long) value);
+ }
+ }
+
private List createEmfStrings(Map>> aggregatedMetrics) {
List emfStrings = new ArrayList<>();
Map>> currentMetricBatch = new HashMap<>();
@@ -179,8 +179,9 @@ private List createEmfStrings(Map>> aggrega
if (records.size() > 100) {
records = records.subList(0, 100);
+ int size = records.size();
logger.warn(() -> "Some AWS SDK client-side metric data have been dropped because it exceeds the cloudwatch "
- + "requirements.");
+ + "requirements. There are " + size + " values for metric " + metricName);
}
if (currentMetricNames.size() >= 100) {
@@ -190,7 +191,7 @@ private List createEmfStrings(Map>> aggrega
}
currentMetricBatch.put(metricName, records);
- if (!String.class.isAssignableFrom(records.get(0).metric().valueClass())) {
+ if (!isStringMetric(records.get(0))) {
currentMetricNames.put(metricName, records.get(0).metric().valueClass());
}
@@ -222,7 +223,7 @@ private void writeAwsObject(JsonWriter jsonWriter, Map> metricN
jsonWriter.writeFieldName("Timestamp");
- jsonWriter.writeValue(clock.instant());
+ jsonWriter.writeValue(clock.instant().toEpochMilli());
jsonWriter.writeFieldName("LogGroupName");
@@ -266,54 +267,86 @@ private void writeMetricDefinitionArray(JsonWriter jsonWriter, Map writeMetricDefinition(jsonWriter, name, type));
- // Write metric definitions
- metricNames.forEach((name, type) -> {
- jsonWriter.writeStartObject();
- jsonWriter.writeFieldName("Name");
- jsonWriter.writeValue(name);
+ jsonWriter.writeEndArray();
+ }
- String unit = getMetricUnit(type);
- if (unit != null) {
- jsonWriter.writeFieldName("Unit");
- jsonWriter.writeValue(unit);
- }
+ private void writeMetricDefinition(JsonWriter jsonWriter, String name, Class> type) {
+ jsonWriter.writeStartObject();
+ jsonWriter.writeFieldName("Name");
+ jsonWriter.writeValue(name);
- jsonWriter.writeEndObject();
- });
+ String unit = getMetricUnit(type);
+ if (unit != null) {
+ jsonWriter.writeFieldName("Unit");
+ jsonWriter.writeValue(unit);
+ }
- jsonWriter.writeEndArray();
+ jsonWriter.writeEndObject();
}
-
private void writeMetricValues(JsonWriter jsonWriter, Map>> metrics) {
- for (Map.Entry>> entry : metrics.entrySet()) {
- String metricName = entry.getKey();
- List> records = entry.getValue();
-
+ metrics.forEach((metricName, records) -> {
+ if (records.isEmpty()) {
+ return;
+ }
if (isDimension(metricName)) {
- jsonWriter.writeFieldName(metricName);
- jsonWriter.writeValue((String) records.get(0).value());
+ writeDimensionValue(jsonWriter, metricName, records);
} else {
- if (records.get(0).value() instanceof String) {
- continue;
- }
- if (records.size() == 1) {
- jsonWriter.writeFieldName(metricName);
- processAndWriteValue(jsonWriter, records.get(0));
- } else {
- jsonWriter.writeFieldName(metricName);
- jsonWriter.writeStartArray();
- for (MetricRecord> mRecord: records) {
- processAndWriteValue(jsonWriter, mRecord);
- }
- jsonWriter.writeEndArray();
- }
+ writeMetricRecord(jsonWriter, metricName, records);
}
+ });
+ }
+
+ private void writeDimensionValue(JsonWriter jsonWriter, String metricName, List> records) {
+ if (records.get(0).value() == null) {
+ return;
+ }
+
+ jsonWriter.writeFieldName(metricName);
+ jsonWriter.writeValue((String) records.get(0).value());
+ }
+
+ private void writeMetricRecord(JsonWriter jsonWriter, String metricName, List> records) {
+ MetricRecord> firstRecord = records.get(0);
+
+ if (!isNumericMetric(firstRecord) || (records.size() == 1 && firstRecord.value() == null)) {
+ return;
+ }
+
+ jsonWriter.writeFieldName(metricName);
+
+ if (records.size() == 1) {
+ processAndWriteValue(jsonWriter, firstRecord);
+ } else {
+ writeMetricArray(jsonWriter, records);
+ }
+ }
+
+ private boolean isStringMetric(MetricRecord> mRecord) {
+ return String.class.isAssignableFrom(mRecord.metric().valueClass());
+ }
+
+ private boolean isNumericMetric(MetricRecord> mRecord) {
+ return Integer.class.isAssignableFrom(mRecord.metric().valueClass())
+ || Boolean.class.isAssignableFrom(mRecord.metric().valueClass())
+ || Long.class.isAssignableFrom(mRecord.metric().valueClass())
+ || Duration.class.isAssignableFrom(mRecord.metric().valueClass())
+ || Double.class.isAssignableFrom(mRecord.metric().valueClass());
+ }
+
+
+ private void writeMetricArray(JsonWriter jsonWriter, List> records) {
+ jsonWriter.writeStartArray();
+ for (MetricRecord> mRecord : records) {
+ processAndWriteValue(jsonWriter, mRecord);
}
+ jsonWriter.writeEndArray();
}
+
private boolean isDimension(String metricName) {
return metricName != null && config.getDimensionStrings().contains(metricName);
}
diff --git a/metric-publishers/emf-metric-publisher/src/main/resources/log4j2.properties b/metric-publishers/emf-metric-publisher/src/main/resources/log4j2.properties
new file mode 100644
index 000000000000..ea24f17148e6
--- /dev/null
+++ b/metric-publishers/emf-metric-publisher/src/main/resources/log4j2.properties
@@ -0,0 +1,38 @@
+#
+# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License").
+# You may not use this file except in compliance with the License.
+# A copy of the License is located at
+#
+# http://aws.amazon.com/apache2.0
+#
+# or in the "license" file accompanying this file. This file is distributed
+# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+# express or implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+status = warn
+
+appender.console.type = Console
+appender.console.name = ConsoleAppender
+appender.console.layout.type = PatternLayout
+appender.console.layout.pattern = %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n%throwable
+
+rootLogger.level = info
+rootLogger.appenderRef.stdout.ref = ConsoleAppender
+
+# Uncomment below to enable more specific logging
+#
+#logger.sdk.name = software.amazon.awssdk
+#logger.sdk.level = debug
+#
+#logger.request.name = software.amazon.awssdk.request
+#logger.request.level = debug
+#
+#logger.apache.name = org.apache.http.wire
+#logger.apache.level = debug
+#
+#logger.netty.name = io.netty.handler.logging
+#logger.netty.level = debug
\ No newline at end of file
diff --git a/metric-publishers/emf-metric-publisher/src/test/java/software/amazon/awssdk/metrics/publishers/emf/EmfMetricPublisherTest.java b/metric-publishers/emf-metric-publisher/src/test/java/software/amazon/awssdk/metrics/publishers/emf/EmfMetricPublisherTest.java
index 09e29d805dc7..ed9e2a2b5142 100644
--- a/metric-publishers/emf-metric-publisher/src/test/java/software/amazon/awssdk/metrics/publishers/emf/EmfMetricPublisherTest.java
+++ b/metric-publishers/emf-metric-publisher/src/test/java/software/amazon/awssdk/metrics/publishers/emf/EmfMetricPublisherTest.java
@@ -61,7 +61,4 @@ void Publish_EmptyMetrics() {
assertThat(loggedEvents()).hasSize(4);
}
-
-
-
}
diff --git a/metric-publishers/emf-metric-publisher/src/test/java/software/amazon/awssdk/metrics/publishers/emf/internal/MetricEmfConverterTest.java b/metric-publishers/emf-metric-publisher/src/test/java/software/amazon/awssdk/metrics/publishers/emf/internal/MetricEmfConverterTest.java
index 42545f3fa2ca..f2b3f5cbe698 100644
--- a/metric-publishers/emf-metric-publisher/src/test/java/software/amazon/awssdk/metrics/publishers/emf/internal/MetricEmfConverterTest.java
+++ b/metric-publishers/emf-metric-publisher/src/test/java/software/amazon/awssdk/metrics/publishers/emf/internal/MetricEmfConverterTest.java
@@ -59,11 +59,10 @@ void setUp() {
@Test
void ConvertMetricCollectionToEMF_EmptyCollection() {
List emfLogs = metricEmfConverterDefault.convertMetricCollectionToEmf(MetricCollector.create("test").collect());
- for (String emfLog : emfLogs) {
- assertThat(emfLog).isEqualTo("{\"_aws\":{\"Timestamp\":12345.678,\"LogGroupName\":\"my_log_group_name\","
+
+ assertThat(emfLogs).containsOnly("{\"_aws\":{\"Timestamp\":12345678,\"LogGroupName\":\"my_log_group_name\","
+ "\"CloudWatchMetrics\":[{\"Namespace\":\"AwsSdk/JavaSdk2\",\"Dimensions\":[[]],"
+ "\"Metrics\":[]}]}}");
- }
}
@Test
@@ -74,10 +73,9 @@ void ConvertMetricCollectionToEMF_MultipleMetrics(){
metricCollector.reportMetric(HttpMetric.CONCURRENCY_ACQUIRE_DURATION, java.time.Duration.ofMillis(100));
List emfLogs = metricEmfConverterDefault.convertMetricCollectionToEmf(metricCollector.collect());
- for (String emfLog : emfLogs) {
- assertThat(emfLog).isEqualTo("{\"_aws\":{\"Timestamp\":12345.678,\"LogGroupName\":\"my_log_group_name\",\"CloudWatchMetrics\":[{\"Namespace\":\"AwsSdk/JavaSdk2\",\"Dimensions\":[[]],\"Metrics\":[{\"Name\":\"AvailableConcurrency\"},{\"Name\":\"ConcurrencyAcquireDuration\",\"Unit\":\"Milliseconds\"}]}]},\"AvailableConcurrency\":5,\"ConcurrencyAcquireDuration\":100.0}");
-
- }
+ assertThat(emfLogs).containsOnly("{\"_aws\":{\"Timestamp\":12345678,\"LogGroupName\":\"my_log_group_name\","
+ + "\"CloudWatchMetrics\":[{\"Namespace\":\"AwsSdk/JavaSdk2\",\"Dimensions\":[[]],\"Metrics\":[{\"Name\":\"AvailableConcurrency\"},"
+ + "{\"Name\":\"ConcurrencyAcquireDuration\",\"Unit\":\"Milliseconds\"}]}]},\"AvailableConcurrency\":5,\"ConcurrencyAcquireDuration\":100.0}");
}
@@ -90,15 +88,12 @@ void ConvertMetricCollectionToEMF_Dimensions(){
metricCollector.reportMetric(HttpMetric.HTTP_STATUS_CODE, 404);
List emfLogs = metricEmfConverterDefault.convertMetricCollectionToEmf(metricCollector.collect());
- for (String emfLog : emfLogs) {
- assertThat(emfLog).isEqualTo("{\"_aws\":{\"Timestamp\":12345.678,\"LogGroupName\":\"my_log_group_name\","
+ assertThat(emfLogs).containsOnly("{\"_aws\":{\"Timestamp\":12345678,\"LogGroupName\":\"my_log_group_name\","
+ "\"CloudWatchMetrics\":[{\"Namespace\":\"AwsSdk/JavaSdk2\","
+ "\"Dimensions\":[[\"OperationName\"]],"
+ "\"Metrics\":[{\"Name\":\"AvailableConcurrency\"}]}]},"
+ "\"AvailableConcurrency\":5,"
+ "\"OperationName\":\"operationName\"}");
-
- }
}
@Test
@@ -107,12 +102,9 @@ void ConvertMetricCollectionToEMF_metricCategory(){
metricCollector.reportMetric(HttpMetric.AVAILABLE_CONCURRENCY, 5);
List emfLogs = metricEmfConverterCustom.convertMetricCollectionToEmf(metricCollector.collect());
- for (String emfLog : emfLogs) {
- assertThat(emfLog).isEqualTo("{\"_aws\":{\"Timestamp\":12345.678,\"LogGroupName\":\"my_log_group_name\",\"CloudWatchMetrics\":[{\"Namespace\":"
+ assertThat(emfLogs).containsOnly("{\"_aws\":{\"Timestamp\":12345678,\"LogGroupName\":\"my_log_group_name\",\"CloudWatchMetrics\":[{\"Namespace\":"
+ "\"AwsSdk/Test/JavaSdk2\",\"Dimensions\":[[]],"
+ "\"Metrics\":[{\"Name\":\"AvailableConcurrency\"}]}]},\"AvailableConcurrency\":5}");
-
- }
}
@Test
@@ -122,12 +114,9 @@ void ConvertMetricCollectionToEMF_metricLevel(){
metricCollector.reportMetric(HttpMetric.HTTP_STATUS_CODE, 404);
List emfLogs = metricEmfConverterCustom.convertMetricCollectionToEmf(metricCollector.collect());
- for (String emfLog : emfLogs) {
- assertThat(emfLog).isEqualTo("{\"_aws\":{\"Timestamp\":12345.678,\"LogGroupName\":\"my_log_group_name\","
+ assertThat(emfLogs).containsOnly("{\"_aws\":{\"Timestamp\":12345678,\"LogGroupName\":\"my_log_group_name\","
+ "\"CloudWatchMetrics\":[{\"Namespace\":\"AwsSdk/Test/JavaSdk2\""
+ ",\"Dimensions\":[[]],\"Metrics\":[{\"Name\":\"AvailableConcurrency\"},{\"Name\":\"HttpStatusCode\"}]}]},\"AvailableConcurrency\":5,\"HttpStatusCode\":404}");
-
- }
}
@@ -145,16 +134,35 @@ void ConvertMetricCollectionToEMF_MultiChildCollections(){
childMetricCollector2.reportMetric(HttpMetric.CONCURRENCY_ACQUIRE_DURATION, java.time.Duration.ofMillis(200));
List emfLogs = metricEmfConverterDefault.convertMetricCollectionToEmf(metricCollector.collect());
- for (String emfLog : emfLogs) {
- assertThat(emfLog).isEqualTo("{\"_aws\":{\"Timestamp\":12345.678,\"LogGroupName\":\"my_log_group_name\","
+ assertThat(emfLogs).containsOnly("{\"_aws\":{\"Timestamp\":12345678,\"LogGroupName\":\"my_log_group_name\","
+ "\"CloudWatchMetrics\""
+ ":[{\"Namespace\":\"AwsSdk/JavaSdk2\",\"Dimensions\":[[]],"
+ "\"Metrics\":[{\"Name\":\"AvailableConcurrency\"},"
+ "{\"Name\":\"ConcurrencyAcquireDuration\",\"Unit\":\"Milliseconds\"}]}]},\"AvailableConcurrency\":5,\"ConcurrencyAcquireDuration\":"
+ "[100.0,200.0]}");
+ }
+ @Test
+ void ConvertMetricCollectionToEMF_OverSizedRecords(){
+
+ MetricCollector metricCollector = MetricCollector.create("test");
+ metricCollector.reportMetric(HttpMetric.HTTP_CLIENT_NAME, "apache-http-client");
+ metricCollector.reportMetric(HttpMetric.AVAILABLE_CONCURRENCY, 5);
+
+ for (int i = 0; i < 120; i++) {
+ MetricCollector childMetricCollector = metricCollector.createChild("child" + i);
+ childMetricCollector.reportMetric(HttpMetric.CONCURRENCY_ACQUIRE_DURATION, java.time.Duration.ofMillis(100+i));
}
- }
+ List emfLogs = metricEmfConverterDefault.convertMetricCollectionToEmf(metricCollector.collect());
+
+ assertThat(emfLogs).containsOnly("{\"_aws\":{\"Timestamp\":12345678,\"LogGroupName\":\"my_log_group_name\",\"CloudWatchMetrics\":[{\"Namespace\":\"AwsSdk/JavaSdk2\","
+ + "\"Dimensions\":[[]],\"Metrics\":[{\"Name\":\"AvailableConcurrency\"},{\"Name\":\"ConcurrencyAcquireDuration\",\"Unit\":\"Milliseconds\"}]}]},\"AvailableConcurrency\":5,"
+ + "\"ConcurrencyAcquireDuration\":[100.0,101.0,102.0,103.0,104.0,105.0,106.0,107.0,108.0,109.0,110.0,111.0,112.0,113.0,114.0,115.0,116.0,117.0,118.0,119.0,120.0,121.0,122.0,"
+ + "123.0,124.0,125.0,126.0,127.0,128.0,129.0,130.0,131.0,132.0,133.0,134.0,135.0,136.0,137.0,138.0,139.0,140.0,141.0,142.0,143.0,144.0,145.0,146.0,147.0,148.0,149.0,150.0,151.0,"
+ + "152.0,153.0,154.0,155.0,156.0,157.0,158.0,159.0,160.0,161.0,162.0,163.0,164.0,165.0,166.0,167.0,168.0,169.0,170.0,171.0,172.0,173.0,174.0,175.0,176.0,177.0,178.0,179.0,180.0,181.0,"
+ + "182.0,183.0,184.0,185.0,186.0,187.0,188.0,189.0,190.0,191.0,192.0,193.0,194.0,195.0,196.0,197.0,198.0,199.0]}");
+
+ }
}
\ No newline at end of file