Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.1.0] - 2025-02-10

### Added

- Add default dimensions for OTEL metrics.

## [1.0.1] - 2024-09-19

### Changed
Expand All @@ -18,6 +24,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Initial release of the AWS SDK Java OpenTelemetry Metrics library.

[1.1.0]: https://github.com/AppsFlyer/aws-sdk-java-opentelemetry-metrics/compare/aws-sdk-java-opentelemetry-metrics-1.0.1...aws-sdk-java-opentelemetry-metrics-1.1.0

[1.0.1]: https://github.com/AppsFlyer/aws-sdk-java-opentelemetry-metrics/compare/aws-sdk-java-opentelemetry-metrics-1.0.0...aws-sdk-java-opentelemetry-metrics-1.0.1

[1.0.0]: https://github.com/AppsFlyer/aws-sdk-java-opentelemetry-metrics/releases/tag/aws-sdk-java-opentelemetry-metrics-1.0.0
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>com.appsflyer</groupId>
<artifactId>aws-sdk-java-opentelemetry-metrics</artifactId>
<version>1.0.2-SNAPSHOT</version>
<version>1.1.0-SNAPSHOT</version>
<name>AWS SDK Java OpenTelemetry Metrics</name>
<description>OpenTelemetry Metric Publisher for AWS SDK for Java</description>
<url>https://github.com/AppsFlyer/aws-sdk-java-opentelemetry-metrics</url>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
public class OtelMetricPublisher implements MetricPublisher {
private static final Logger log = LoggerFactory.getLogger(OtelMetricPublisher.class);
private static final String DEFAULT_METRIC_PREFIX = "aws.sdk";
private final Attributes baseAttributes;

private final Map<String, Map<Boolean, Map<Integer, Attributes>>> perRequestAttributesCache = new ConcurrentHashMap<>();
private final Map<Attributes, Map<String, Attributes>> perAttemptAttributesCache = new ConcurrentHashMap<>();
Expand All @@ -38,25 +39,31 @@ public class OtelMetricPublisher implements MetricPublisher {
private final Map<String, MetricStrategy> httpMetrics;

public OtelMetricPublisher(OpenTelemetry openTelemetry) {
this(openTelemetry, DEFAULT_METRIC_PREFIX);
this(openTelemetry, DEFAULT_METRIC_PREFIX, ForkJoinPool.commonPool(), Attributes.empty());
}

public OtelMetricPublisher(OpenTelemetry openTelemetry, String metricPrefix) {
this(openTelemetry, metricPrefix, ForkJoinPool.commonPool());
this(openTelemetry, metricPrefix, ForkJoinPool.commonPool(), Attributes.empty());
}

public OtelMetricPublisher(OpenTelemetry openTelemetry, String metricPrefix, Executor executor) {
this(openTelemetry, metricPrefix, executor, Attributes.empty());
}

public OtelMetricPublisher(OpenTelemetry openTelemetry, String metricPrefix,
Executor executor, Attributes baseAttributes) {
Objects.requireNonNull(metricPrefix, "metricPrefix must not be null");
Objects.requireNonNull(openTelemetry, "openTelemetry must not be null");
Objects.requireNonNull(baseAttributes, "baseAttributes must not be null");

if (executor == null) {
log.warn("An executor is not provided. The metrics will be published synchronously on the calling thread.");
}

this.metricPrefix = metricPrefix + ".";
this.executor = executor;
this.baseAttributes = baseAttributes;

Meter meter = openTelemetry.getMeter("aws.sdk");
Meter meter = openTelemetry.getMeter(this.metricPrefix);

perRequestMetrics = initializePerRequestStrategies(meter);
perAttemptMetrics = initializeCoreStrategies(meter);
Expand Down Expand Up @@ -267,6 +274,7 @@ private Attributes toPerRequestAttributes(String operationName, boolean isSucces
.put("request_operation_name", nullSafeOperationName)
.put("request_is_success", isSuccess)
.put("request_retry_count", retryCount)
.putAll(this.baseAttributes)
.build());
}

Expand All @@ -291,4 +299,3 @@ private Attributes toHttpAttributes(Attributes parentAttributes, int httpStatusC
.build());
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.sdk.metrics.data.HistogramData;
Expand Down Expand Up @@ -30,6 +31,8 @@ class OtelMetricPublisherTest {
private ExecutorService executor;
private InMemoryMetricReader metricReader;
private MetricPublisher metricPublisher;
private Attributes baseAttributes;
private static String basePrefix = "custom.prefix";

@BeforeEach
void setUp() {
Expand All @@ -39,6 +42,10 @@ void setUp() {
// Set up an InMemoryMetricReader to capture metrics
metricReader = InMemoryMetricReader.create();

// Setup some base attributes
baseAttributes = Attributes.of(AttributeKey.stringKey("custom.dimension.key.1"), "CustomDimensionValue.1",
AttributeKey.stringKey("custom.dimension.key.2"), "CustomDimensionValue.2");

// Set up the SdkMeterProvider with the metric reader
SdkMeterProvider sdkMeterProvider = SdkMeterProvider.builder()
.registerMetricReader(metricReader)
Expand All @@ -53,7 +60,7 @@ void setUp() {
GlobalOpenTelemetry.set(openTelemetrySdk);

// Create an instance of OtelMetricPublisher
metricPublisher = new OtelMetricPublisher(GlobalOpenTelemetry.get(), "aws.sdk", executor);
metricPublisher = new OtelMetricPublisher(GlobalOpenTelemetry.get(), basePrefix, executor, baseAttributes);
}

@Test
Expand All @@ -75,7 +82,7 @@ public void testPublishMetrics() throws InterruptedException {
assertEquals(1, exportedMetrics.size(), "Expected one metric to be exported");

MetricData metricData = exportedMetrics.get(0);
assertEquals("aws.sdk.api_call_duration", metricData.getName());
assertEquals(basePrefix + ".api_call_duration", metricData.getName());
assertEquals("The total time taken to finish a request (inclusive of all retries)", metricData.getDescription());
assertEquals("ns", metricData.getUnit());

Expand All @@ -90,6 +97,10 @@ public void testPublishMetrics() throws InterruptedException {
assertEquals("GetItem", point.getAttributes().get(AttributeKey.stringKey("request_operation_name")));
assertEquals(true, point.getAttributes().get(AttributeKey.booleanKey("request_is_success")));
assertEquals(0L, point.getAttributes().get(AttributeKey.longKey("request_retry_count")));
assertEquals("CustomDimensionValue.1", point.getAttributes()
.get(AttributeKey.stringKey("custom.dimension.key.1")));
assertEquals("CustomDimensionValue.2", point.getAttributes()
.get(AttributeKey.stringKey("custom.dimension.key.2")));
}

private MetricCollection createMockMetricCollection() {
Expand Down
Loading