From 0ef19291c23f1909fda73fa7040547a3d3eebac8 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Thu, 5 Aug 2021 16:58:49 -0400 Subject: [PATCH] Swap old Metrics API for currently specified Metrics API (#3423) * Update the API to the latest SDK specification. * API updates to other sdk areas. * First half of SDK updates for API. Passing off to other cmoputer. * Get SDK compiling again. * Get tests compiling again (and failing). * Fix bad copy-paste error. * Get all SDK tests passing. * More fixes to builds across SDK impls. * Remove unecessary publics * more fixes for new API. * spotless fixes. * Make tests for metric points order independent. * Restore readme. * Fix readmes. * Add noop meter provider tests for code coverage. * Add code coverage for assertion library. * Fix wierd test failure that gradle cache is preventing me from seeing locally. * Fix javadoc/spelling comments from review. * Remove marker interfaces. * Switch from atomic ref to volatile. * Fixes from review. * Apply suggestions from code review Co-authored-by: John Watson * Fixes from review. * Fixes from review. * Update OTLP HTTP exporter to use new metrics api Co-authored-by: John Watson --- api/metrics/README.md | 5 +- api/metrics/build.gradle.kts | 1 + .../api/metrics/AsynchronousInstrument.java | 32 - .../AsynchronousInstrumentBuilder.java | 24 - .../api/metrics/BatchRecorder.java | 85 --- .../api/metrics/BoundDoubleCounter.java | 29 +- .../api/metrics/BoundDoubleHistogram.java | 39 ++ .../api/metrics/BoundDoubleUpDownCounter.java | 29 +- .../api/metrics/BoundDoubleValueRecorder.java | 23 - .../api/metrics/BoundLongCounter.java | 30 +- .../api/metrics/BoundLongHistogram.java | 39 ++ .../api/metrics/BoundLongUpDownCounter.java | 30 +- .../api/metrics/BoundLongValueRecorder.java | 23 - .../metrics/BoundSynchronousInstrument.java | 16 - .../api/metrics/DefaultMeter.java | 661 ------------------ .../api/metrics/DefaultMeterBuilder.java | 29 - .../api/metrics/DefaultMeterProvider.java | 30 - .../api/metrics/DoubleCounter.java | 71 +- .../api/metrics/DoubleCounterBuilder.java | 36 +- .../api/metrics/DoubleGaugeBuilder.java | 39 ++ .../api/metrics/DoubleHistogram.java | 51 ++ .../api/metrics/DoubleHistogramBuilder.java | 36 + .../api/metrics/DoubleSumObserver.java | 49 -- .../api/metrics/DoubleSumObserverBuilder.java | 24 - .../api/metrics/DoubleUpDownCounter.java | 74 +- .../metrics/DoubleUpDownCounterBuilder.java | 36 +- .../api/metrics/DoubleUpDownSumObserver.java | 49 -- .../DoubleUpDownSumObserverBuilder.java | 24 - .../api/metrics/DoubleValueObserver.java | 45 -- .../metrics/DoubleValueObserverBuilder.java | 24 - .../api/metrics/DoubleValueRecorder.java | 74 -- .../metrics/DoubleValueRecorderBuilder.java | 18 - .../api/metrics/GlobalMeterProvider.java | 69 +- .../opentelemetry/api/metrics/Instrument.java | 13 - .../api/metrics/InstrumentBuilder.java | 36 - .../api/metrics/LongCounter.java | 70 +- .../api/metrics/LongCounterBuilder.java | 37 +- .../api/metrics/LongGaugeBuilder.java | 39 ++ .../api/metrics/LongHistogram.java | 51 ++ .../api/metrics/LongHistogramBuilder.java | 35 + .../api/metrics/LongSumObserver.java | 49 -- .../api/metrics/LongSumObserverBuilder.java | 24 - .../api/metrics/LongUpDownCounter.java | 74 +- .../api/metrics/LongUpDownCounterBuilder.java | 36 +- .../api/metrics/LongUpDownSumObserver.java | 49 -- .../metrics/LongUpDownSumObserverBuilder.java | 24 - .../api/metrics/LongValueObserver.java | 45 -- .../api/metrics/LongValueObserverBuilder.java | 24 - .../api/metrics/LongValueRecorder.java | 74 -- .../api/metrics/LongValueRecorderBuilder.java | 18 - .../io/opentelemetry/api/metrics/Meter.java | 185 +---- .../api/metrics/MeterBuilder.java | 4 +- .../api/metrics/MeterProvider.java | 44 +- .../metrics/ObservableDoubleMeasurement.java | 26 + .../metrics/ObservableLongMeasurement.java | 26 + .../api/metrics/ObservableMeasurement.java | 13 + .../api/metrics/SynchronousInstrument.java | 34 - .../metrics/SynchronousInstrumentBuilder.java | 12 - .../api/metrics/common/ArrayBackedLabels.java | 31 - .../common/ArrayBackedLabelsBuilder.java | 33 - .../api/metrics/common/Labels.java | 122 ---- .../api/metrics/common/LabelsBuilder.java | 19 - .../metrics/internal/MetricsStringUtils.java | 31 - .../api/metrics/internal/NoopMeter.java | 434 ++++++++++++ .../metrics/internal/NoopMeterProvider.java | 45 ++ .../api/metrics/internal/package-info.java | 15 - .../api/metrics/BatchRecorderTest.java | 103 --- .../api/metrics/DefaultMeterTest.java | 26 - .../api/metrics/DoubleCounterTest.java | 120 ---- .../api/metrics/DoubleSumObserverTest.java | 80 --- .../api/metrics/DoubleUpDownCounterTest.java | 101 --- .../metrics/DoubleUpDownSumObserverTest.java | 83 --- .../api/metrics/DoubleValueObserverTest.java | 82 --- .../api/metrics/DoubleValueRecorderTest.java | 101 --- .../api/metrics/LongCounterTest.java | 120 ---- .../api/metrics/LongSumObserverTest.java | 82 --- .../api/metrics/LongUpDownCounterTest.java | 100 --- .../metrics/LongUpDownSumObserverTest.java | 83 --- .../api/metrics/LongValueObserverTest.java | 84 --- .../api/metrics/LongValueRecorderTest.java | 102 --- .../api/metrics/common/LabelsTest.java | 151 ---- .../internal/MetricsStringUtilsTest.java | 27 - .../internal/NoopMeterProviderTest.java | 31 + .../api/metrics/internal/NoopMeterTest.java | 268 +++++++ .../otlp/http/trace/OtlpHttpSpanExporter.java | 20 +- .../otlp/trace/OtlpGrpcSpanExporter.java | 28 +- .../sdk/autoconfigure/PrometheusTest.java | 8 +- .../sdk/logging/export/BatchLogProcessor.java | 17 +- ...cutorServiceSpanProcessorCpuBenchmark.java | 9 +- ...iceSpanProcessorDroppedSpansBenchmark.java | 9 +- ...viceSpanProcessorMultiThreadBenchmark.java | 9 +- .../trace/ExecutorServiceSpanProcessor.java | 30 +- .../metrics/DoubleSummaryDataAssert.java | 29 + .../metrics/DoubleSummaryPointDataAssert.java | 39 ++ .../assertj/metrics/MetricAssertions.java | 12 + .../assertj/metrics/MetricDataAssert.java | 18 + .../assertj/metrics/MetricAssertionsTest.java | 57 ++ sdk/metrics/README.md | 15 + .../sdk/metrics/MetricsBenchmarks.java | 9 +- .../metrics/MetricsTestOperationBuilder.java | 80 +-- ...ctDoubleAsynchronousInstrumentBuilder.java | 49 -- .../sdk/metrics/AbstractInstrument.java | 48 -- .../metrics/AbstractInstrumentBuilder.java | 109 +++ ...ractLongAsynchronousInstrumentBuilder.java | 49 -- .../AbstractSynchronousInstrument.java | 4 +- .../AbstractSynchronousInstrumentBuilder.java | 41 -- .../AsynchronousInstrumentAccumulator.java | 60 +- .../sdk/metrics/BatchRecorderSdk.java | 154 ---- .../sdk/metrics/DoubleCounterSdk.java | 64 +- .../sdk/metrics/DoubleSumObserverSdk.java | 34 +- .../sdk/metrics/DoubleUpDownCounterSdk.java | 67 +- .../metrics/DoubleUpDownSumObserverSdk.java | 34 +- .../sdk/metrics/DoubleValueObserverSdk.java | 47 +- .../sdk/metrics/DoubleValueRecorderSdk.java | 69 +- .../opentelemetry/sdk/metrics/Instrument.java | 14 + .../sdk/metrics/InstrumentProcessor.java | 6 +- .../sdk/metrics/LongCounterSdk.java | 64 +- .../sdk/metrics/LongSumObserverSdk.java | 33 +- .../sdk/metrics/LongUpDownCounterSdk.java | 67 +- .../sdk/metrics/LongUpDownSumObserverSdk.java | 34 +- .../sdk/metrics/LongValueObserverSdk.java | 47 +- .../sdk/metrics/LongValueRecorderSdk.java | 74 +- .../opentelemetry/sdk/metrics/SdkMeter.java | 89 +-- .../sdk/metrics/SdkMeterProvider.java | 13 - .../SynchronousInstrumentAccumulator.java | 8 +- .../AbstractMinMaxSumCountAggregator.java | 4 +- .../sdk/metrics/aggregator/Aggregator.java | 4 +- .../metrics/aggregator/CountAggregator.java | 4 +- .../aggregator/DoubleHistogramAggregator.java | 4 +- .../aggregator/DoubleLastValueAggregator.java | 4 +- .../aggregator/DoubleSumAggregator.java | 4 +- .../aggregator/LongLastValueAggregator.java | 4 +- .../metrics/aggregator/LongSumAggregator.java | 4 +- .../metrics/aggregator/MetricDataUtils.java | 32 +- .../MinMaxSumCountAccumulation.java | 6 +- .../metrics/processor/LabelsProcessor.java | 4 +- .../processor/NoopLabelsProcessor.java | 4 +- .../sdk/metrics/view/InstrumentSelector.java | 4 +- .../AbstractInstrumentBuilderTest.java | 135 ---- ...AsynchronousInstrumentAccumulatorTest.java | 12 +- .../sdk/metrics/BatchRecorderSdkTest.java | 235 ------- .../sdk/metrics/DoubleCounterSdkTest.java | 49 +- .../sdk/metrics/DoubleSumObserverSdkTest.java | 33 +- .../metrics/DoubleUpDownCounterSdkTest.java | 44 +- .../DoubleUpDownSumObserverSdkTest.java | 33 +- .../metrics/DoubleValueObserverSdkTest.java | 22 +- .../metrics/DoubleValueRecorderSdkTest.java | 227 +++--- .../sdk/metrics/LongCounterSdkTest.java | 51 +- .../sdk/metrics/LongSumObserverSdkTest.java | 30 +- .../sdk/metrics/LongUpDownCounterSdkTest.java | 39 +- .../metrics/LongUpDownSumObserverSdkTest.java | 30 +- .../sdk/metrics/LongValueObserverSdkTest.java | 24 +- .../sdk/metrics/LongValueRecorderSdkTest.java | 218 +++--- .../sdk/metrics/SdkMeterProviderTest.java | 145 ++-- .../sdk/metrics/SdkMeterRegistryTest.java | 22 +- .../sdk/metrics/SdkMeterTest.java | 285 ++++---- .../SynchronousInstrumentAccumulatorTest.java | 19 +- .../aggregator/CountAggregatorTest.java | 5 +- .../DoubleHistogramAggregatorTest.java | 4 +- .../DoubleLastValueAggregatorTest.java | 3 +- .../DoubleMinMaxSumCountAggregatorTest.java | 4 +- .../aggregator/DoubleSumAggregatorTest.java | 3 +- .../LongLastValueAggregatorTest.java | 3 +- .../LongMinMaxSumCountAggregatorTest.java | 4 +- .../aggregator/LongSumAggregatorTest.java | 3 +- .../MinMaxSumCountAccumulationTest.java | 5 +- .../BatchSpanProcessorCpuBenchmark.java | 9 +- ...tchSpanProcessorDroppedSpansBenchmark.java | 9 +- ...atchSpanProcessorMultiThreadBenchmark.java | 9 +- .../sdk/trace/export/BatchSpanProcessor.java | 32 +- 170 files changed, 3066 insertions(+), 5789 deletions(-) delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/AsynchronousInstrument.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/AsynchronousInstrumentBuilder.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/BatchRecorder.java create mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundDoubleHistogram.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundDoubleValueRecorder.java create mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundLongHistogram.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundLongValueRecorder.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundSynchronousInstrument.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/DefaultMeter.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/DefaultMeterBuilder.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/DefaultMeterProvider.java create mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleGaugeBuilder.java create mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleHistogram.java create mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleHistogramBuilder.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleSumObserver.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleSumObserverBuilder.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleUpDownSumObserver.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleUpDownSumObserverBuilder.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleValueObserver.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleValueObserverBuilder.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleValueRecorder.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleValueRecorderBuilder.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/Instrument.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/InstrumentBuilder.java create mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/LongGaugeBuilder.java create mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/LongHistogram.java create mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/LongHistogramBuilder.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/LongSumObserver.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/LongSumObserverBuilder.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/LongUpDownSumObserver.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/LongUpDownSumObserverBuilder.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/LongValueObserver.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/LongValueObserverBuilder.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/LongValueRecorder.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/LongValueRecorderBuilder.java create mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/ObservableDoubleMeasurement.java create mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/ObservableLongMeasurement.java create mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/ObservableMeasurement.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/SynchronousInstrument.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/SynchronousInstrumentBuilder.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/common/ArrayBackedLabels.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/common/ArrayBackedLabelsBuilder.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/common/Labels.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/common/LabelsBuilder.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/internal/MetricsStringUtils.java create mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/internal/NoopMeter.java create mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/internal/NoopMeterProvider.java delete mode 100644 api/metrics/src/main/java/io/opentelemetry/api/metrics/internal/package-info.java delete mode 100644 api/metrics/src/test/java/io/opentelemetry/api/metrics/BatchRecorderTest.java delete mode 100644 api/metrics/src/test/java/io/opentelemetry/api/metrics/DefaultMeterTest.java delete mode 100644 api/metrics/src/test/java/io/opentelemetry/api/metrics/DoubleCounterTest.java delete mode 100644 api/metrics/src/test/java/io/opentelemetry/api/metrics/DoubleSumObserverTest.java delete mode 100644 api/metrics/src/test/java/io/opentelemetry/api/metrics/DoubleUpDownCounterTest.java delete mode 100644 api/metrics/src/test/java/io/opentelemetry/api/metrics/DoubleUpDownSumObserverTest.java delete mode 100644 api/metrics/src/test/java/io/opentelemetry/api/metrics/DoubleValueObserverTest.java delete mode 100644 api/metrics/src/test/java/io/opentelemetry/api/metrics/DoubleValueRecorderTest.java delete mode 100644 api/metrics/src/test/java/io/opentelemetry/api/metrics/LongCounterTest.java delete mode 100644 api/metrics/src/test/java/io/opentelemetry/api/metrics/LongSumObserverTest.java delete mode 100644 api/metrics/src/test/java/io/opentelemetry/api/metrics/LongUpDownCounterTest.java delete mode 100644 api/metrics/src/test/java/io/opentelemetry/api/metrics/LongUpDownSumObserverTest.java delete mode 100644 api/metrics/src/test/java/io/opentelemetry/api/metrics/LongValueObserverTest.java delete mode 100644 api/metrics/src/test/java/io/opentelemetry/api/metrics/LongValueRecorderTest.java delete mode 100644 api/metrics/src/test/java/io/opentelemetry/api/metrics/common/LabelsTest.java delete mode 100644 api/metrics/src/test/java/io/opentelemetry/api/metrics/internal/MetricsStringUtilsTest.java create mode 100644 api/metrics/src/test/java/io/opentelemetry/api/metrics/internal/NoopMeterProviderTest.java create mode 100644 api/metrics/src/test/java/io/opentelemetry/api/metrics/internal/NoopMeterTest.java create mode 100644 sdk/metrics-testing/src/main/java/io/opentelemetry/sdk/testing/assertj/metrics/DoubleSummaryDataAssert.java create mode 100644 sdk/metrics-testing/src/main/java/io/opentelemetry/sdk/testing/assertj/metrics/DoubleSummaryPointDataAssert.java create mode 100644 sdk/metrics/README.md delete mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractDoubleAsynchronousInstrumentBuilder.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractInstrumentBuilder.java delete mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractLongAsynchronousInstrumentBuilder.java delete mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractSynchronousInstrumentBuilder.java delete mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/BatchRecorderSdk.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/Instrument.java delete mode 100644 sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AbstractInstrumentBuilderTest.java delete mode 100644 sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/BatchRecorderSdkTest.java diff --git a/api/metrics/README.md b/api/metrics/README.md index 9452f1b19c..bc5c618277 100644 --- a/api/metrics/README.md +++ b/api/metrics/README.md @@ -2,8 +2,11 @@ [![Javadocs][javadoc-image]][javadoc-url] +* The code in this module is the implementation of the [experimental OpenTelemetry metrics signal][metrics-spec]. +* The default implementation of the interfaces in this module is in the OpenTelemetry metrics SDK module. * The interfaces in this directory can be implemented to create alternative implementations of the OpenTelemetry library. [javadoc-image]: https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-metrics.svg -[javadoc-url]: https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-metrics \ No newline at end of file +[javadoc-url]: https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-metrics +[metrics-spec]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md \ No newline at end of file diff --git a/api/metrics/build.gradle.kts b/api/metrics/build.gradle.kts index 6965cd451a..9acaf0dfec 100644 --- a/api/metrics/build.gradle.kts +++ b/api/metrics/build.gradle.kts @@ -11,6 +11,7 @@ otelJava.moduleName.set("io.opentelemetry.api.metrics") dependencies { api(project(":api:all")) + api(project(":context")) annotationProcessor("com.google.auto.value:auto-value") diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/AsynchronousInstrument.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/AsynchronousInstrument.java deleted file mode 100644 index 4d68b81b68..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/AsynchronousInstrument.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import io.opentelemetry.api.metrics.common.Labels; -import javax.annotation.concurrent.ThreadSafe; - -/** - * {@code AsynchronousInstrument} is an interface that defines a type of instruments that are used - * to report measurements asynchronously. - * - *

They are reported by a callback, once per collection interval, and lack Context. They are - * permitted to report only one value per distinct label set per period. If the application observes - * multiple values for the same label set, in a single callback, the last value is the only value - * kept. - */ -@ThreadSafe -public interface AsynchronousInstrument extends Instrument { - - /** The result pass to the updater. */ - interface LongResult { - void observe(long value, Labels labels); - } - - /** The result pass to the updater. */ - interface DoubleResult { - void observe(double value, Labels labels); - } -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/AsynchronousInstrumentBuilder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/AsynchronousInstrumentBuilder.java deleted file mode 100644 index 046f87ed59..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/AsynchronousInstrumentBuilder.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import java.util.function.Consumer; - -/** Builder class for {@link AsynchronousInstrument}. */ -public interface AsynchronousInstrumentBuilder extends InstrumentBuilder { - /** - * Sets a consumer that gets executed every collection interval. - * - *

Evaluation is deferred until needed, if this {@code AsynchronousInstrument} metric is not - * exported then it will never be called. - * - * @param updater the consumer to be executed before export. - */ - AsynchronousInstrumentBuilder setUpdater(Consumer updater); - - @Override - AsynchronousInstrument build(); -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/BatchRecorder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/BatchRecorder.java deleted file mode 100644 index f7075839c6..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/BatchRecorder.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import javax.annotation.concurrent.ThreadSafe; - -/** - * Util class that can be use to atomically record measurements associated with a set of Metrics. - * - *

This class is equivalent with individually calling record on every Measure, but has the - * advantage that all these operations are recorded atomically and it is more efficient. - */ -@ThreadSafe -public interface BatchRecorder { - /** - * Associates the {@link LongValueRecorder} with the given value. Subsequent updates to the same - * {@link LongValueRecorder} will overwrite the previous value. - * - * @param valueRecorder the {@link LongValueRecorder}. - * @param value the value to be associated with {@code valueRecorder}. - * @return this. - */ - BatchRecorder put(LongValueRecorder valueRecorder, long value); - - /** - * Associates the {@link DoubleValueRecorder} with the given value. Subsequent updates to the same - * {@link DoubleValueRecorder} will overwrite the previous value. - * - * @param valueRecorder the {@link DoubleValueRecorder}. - * @param value the value to be associated with {@code valueRecorder}. - * @return this. - */ - BatchRecorder put(DoubleValueRecorder valueRecorder, double value); - - /** - * Associates the {@link LongCounter} with the given value. Subsequent updates to the same {@link - * LongCounter} will overwrite the previous value. - * - * @param counter the {@link LongCounter}. - * @param value the value to be associated with {@code counter}. - * @return this. - */ - BatchRecorder put(LongCounter counter, long value); - - /** - * Associates the {@link DoubleCounter} with the given value. Subsequent updates to the same - * {@link DoubleCounter} will overwrite the previous value. - * - * @param counter the {@link DoubleCounter}. - * @param value the value to be associated with {@code counter}. - * @return this. - */ - BatchRecorder put(DoubleCounter counter, double value); - - /** - * Associates the {@link LongUpDownCounter} with the given value. Subsequent updates to the same - * {@link LongCounter} will overwrite the previous value. - * - * @param upDownCounter the {@link LongCounter}. - * @param value the value to be associated with {@code counter}. - * @return this. - */ - BatchRecorder put(LongUpDownCounter upDownCounter, long value); - - /** - * Associates the {@link DoubleUpDownCounter} with the given value. Subsequent updates to the same - * {@link DoubleCounter} will overwrite the previous value. - * - * @param upDownCounter the {@link DoubleCounter}. - * @param value the value to be associated with {@code counter}. - * @return this. - */ - BatchRecorder put(DoubleUpDownCounter upDownCounter, double value); - - /** - * Records all of measurements at the same time. - * - *

This method records all measurements every time it is called, so make sure it is not called - * twice if not needed. - */ - void record(); -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundDoubleCounter.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundDoubleCounter.java index 6a3c450c81..d6233d317d 100644 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundDoubleCounter.java +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundDoubleCounter.java @@ -5,20 +5,35 @@ package io.opentelemetry.api.metrics; +import io.opentelemetry.context.Context; import javax.annotation.concurrent.ThreadSafe; -/** A {@code Bound Instrument} for a {@link DoubleCounter}. */ +/** A counter instrument that records {@code double} values with pre-associated attributes. */ @ThreadSafe -public interface BoundDoubleCounter extends BoundSynchronousInstrument { +public interface BoundDoubleCounter { /** - * Adds the given {@code increment} to the current value. The values cannot be negative. + * Records a value with pre-bound attributes. * - *

The value added is associated with the current {@code Context}. + *

Note: This may use {@code Context.current()} to pull the context associated with this + * measurement. * - * @param increment the value to add. + * @param value The increment amount. MUST be non-negative. */ - void add(double increment); + void add(double value); - @Override + /** + * Records a value with pre-bound attributes. + * + * @param value The increment amount. MUST be non-negative. + * @param context The explicit context to associate with this measurement. + */ + void add(double value, Context context); + + /** + * Unbinds the current bound instance from the {@link DoubleCounter}. + * + *

After this method returns the current instance is considered invalid (not being managed by + * the instrument). + */ void unbind(); } diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundDoubleHistogram.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundDoubleHistogram.java new file mode 100644 index 0000000000..45e2527e46 --- /dev/null +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundDoubleHistogram.java @@ -0,0 +1,39 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.metrics; + +import io.opentelemetry.context.Context; +import javax.annotation.concurrent.ThreadSafe; + +/** A histogram instrument that records {@code long} values with pre-associated attributes. */ +@ThreadSafe +public interface BoundDoubleHistogram { + /** + * Records a value with a pre-bound set of attributes. + * + *

Note: This may use {@code Context.current()} to pull the context associated with this + * measurement. + * + * @param value The amount of the measurement. + */ + void record(double value); + + /** + * Records a value with a pre-bound set of attributes. + * + * @param value The amount of the measurement. + * @param context The explicit context to associate with this measurement. + */ + void record(double value, Context context); + + /** + * Unbinds the current bound instance from the {@link DoubleHistogram}. + * + *

After this method returns the current instance is considered invalid (not being managed by + * the instrument). + */ + void unbind(); +} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundDoubleUpDownCounter.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundDoubleUpDownCounter.java index 24223cb177..6393b9a018 100644 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundDoubleUpDownCounter.java +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundDoubleUpDownCounter.java @@ -5,20 +5,35 @@ package io.opentelemetry.api.metrics; +import io.opentelemetry.context.Context; import javax.annotation.concurrent.ThreadSafe; -/** A {@code Bound Instrument} for a {@link DoubleUpDownCounter}. */ +/** An up-down-counter instrument with pre-bound attributes. */ @ThreadSafe -public interface BoundDoubleUpDownCounter extends BoundSynchronousInstrument { +public interface BoundDoubleUpDownCounter { /** - * Adds the given {@code increment} to the current value. + * Records a value with pre-bound attributes. * - *

The value added is associated with the current {@code Context}. + *

Note: This may use {@code Context.current()} to pull the context associated with this + * measurement. * - * @param increment the value to add. + * @param value The increment amount. May be positive, negative or zero. */ - void add(double increment); + void add(double value); - @Override + /** + * Records a value with a pre-bound attributes. + * + * @param value The increment amount. May be positive, negative or zero. + * @param context The explicit context to associate with this measurement. + */ + void add(double value, Context context); + + /** + * Unbinds the current bound instance from the {@link DoubleUpDownCounter}. + * + *

After this method returns the current instance is considered invalid (not being managed by + * the instrument). + */ void unbind(); } diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundDoubleValueRecorder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundDoubleValueRecorder.java deleted file mode 100644 index 6fc3866d14..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundDoubleValueRecorder.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import javax.annotation.concurrent.ThreadSafe; - -/** A {@code Bound Instrument} for a {@link DoubleValueRecorder}. */ -@ThreadSafe -public interface BoundDoubleValueRecorder extends BoundSynchronousInstrument { - /** - * Records the given measurement, associated with the current {@code Context}. - * - * @param value the measurement to record. - * @throws IllegalArgumentException if value is negative. - */ - void record(double value); - - @Override - void unbind(); -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundLongCounter.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundLongCounter.java index c7fa15e053..81fb520af1 100644 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundLongCounter.java +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundLongCounter.java @@ -5,21 +5,35 @@ package io.opentelemetry.api.metrics; +import io.opentelemetry.context.Context; import javax.annotation.concurrent.ThreadSafe; -/** A {@code Bound Instrument} for a {@link LongCounter}. */ +/** A counter instrument that records {@code long} values with pre-associated attributes. */ @ThreadSafe -public interface BoundLongCounter extends BoundSynchronousInstrument { +public interface BoundLongCounter { + /** + * Records a value with pre-bound attributes. + * + *

Note: This may use {@code Context.current()} to pull the context associated with this + * measurement. + * + * @param value The increment amount. MUST be non-negative. + */ + void add(long value); /** - * Adds the given {@code increment} to the current value. The values cannot be negative. + * Records a value with pre-bound attributes. * - *

The value added is associated with the current {@code Context}. - * - * @param increment the value to add. + * @param value The increment amount. MUST be non-negative. + * @param context The explicit context to associate with this measurement. */ - void add(long increment); + void add(long value, Context context); - @Override + /** + * Unbinds the current bound instance from the {@link LongCounter}. + * + *

After this method returns the current instance is considered invalid (not being managed by + * the instrument). + */ void unbind(); } diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundLongHistogram.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundLongHistogram.java new file mode 100644 index 0000000000..24997f6e04 --- /dev/null +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundLongHistogram.java @@ -0,0 +1,39 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.metrics; + +import io.opentelemetry.context.Context; +import javax.annotation.concurrent.ThreadSafe; + +/** A histogram instrument that records {@code long} values with pre-associated attributes. */ +@ThreadSafe +public interface BoundLongHistogram { + /** + * Records a value with a pre-bound set of attributes. + * + *

Note: This may use {@code Context.current()} to pull the context associated with this + * measurement. + * + * @param value The amount of the measurement. + */ + void record(long value); + + /** + * Records a value with a pre-bound set of attributes. + * + * @param value The amount of the measurement. + * @param context The explicit context to associate with this measurement. + */ + void record(long value, Context context); + + /** + * Unbinds the current bound instance from the {@link LongHistogram}. + * + *

After this method returns the current instance is considered invalid (not being managed by + * the instrument). + */ + void unbind(); +} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundLongUpDownCounter.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundLongUpDownCounter.java index b0c253f1ae..7ca78a37b8 100644 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundLongUpDownCounter.java +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundLongUpDownCounter.java @@ -5,21 +5,35 @@ package io.opentelemetry.api.metrics; +import io.opentelemetry.context.Context; import javax.annotation.concurrent.ThreadSafe; -/** A {@code Bound Instrument} for a {@link LongUpDownCounter}. */ +/** An up-down-counter instrument with pre-bound attributes. */ @ThreadSafe -public interface BoundLongUpDownCounter extends BoundSynchronousInstrument { +public interface BoundLongUpDownCounter { + /** + * Records a value with pre-bound attributes. + * + *

Note: This may use {@code Context.current()} to pull the context associated with this + * measurement. + * + * @param value The increment amount. May be positive, negative or zero. + */ + void add(long value); /** - * Adds the given {@code increment} to the current value. + * Records a value with a pre-bound attributes. * - *

The value added is associated with the current {@code Context}. - * - * @param increment the value to add. + * @param value The increment amount. May be positive, negative or zero. + * @param context The explicit context to associate with this measurement. */ - void add(long increment); + void add(long value, Context context); - @Override + /** + * Unbinds the current bound instance from the {@link LongUpDownCounter}. + * + *

After this method returns the current instance is considered invalid (not being managed by + * the instrument). + */ void unbind(); } diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundLongValueRecorder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundLongValueRecorder.java deleted file mode 100644 index f7c716c767..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundLongValueRecorder.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import javax.annotation.concurrent.ThreadSafe; - -/** A {@code Bound Instrument} for a {@link LongValueRecorder}. */ -@ThreadSafe -public interface BoundLongValueRecorder extends BoundSynchronousInstrument { - /** - * Records the given measurement, associated with the current {@code Context}. - * - * @param value the measurement to record. - * @throws IllegalArgumentException if value is negative. - */ - void record(long value); - - @Override - void unbind(); -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundSynchronousInstrument.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundSynchronousInstrument.java deleted file mode 100644 index 17fdc0da48..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/BoundSynchronousInstrument.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -interface BoundSynchronousInstrument { - /** - * Unbinds the current {@code Bound} from the Instrument. - * - *

After this method returns the current instance {@code Bound} is considered invalid (not - * being managed by the instrument). - */ - void unbind(); -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DefaultMeter.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/DefaultMeter.java deleted file mode 100644 index 0a61f93374..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DefaultMeter.java +++ /dev/null @@ -1,661 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import io.opentelemetry.api.internal.Utils; -import io.opentelemetry.api.metrics.common.Labels; -import io.opentelemetry.api.metrics.internal.MetricsStringUtils; -import java.util.Objects; -import java.util.function.Consumer; -import javax.annotation.concurrent.Immutable; -import javax.annotation.concurrent.ThreadSafe; - -/** No-op implementations of {@link Meter}. */ -@ThreadSafe -final class DefaultMeter implements Meter { - - private static final DefaultMeter INSTANCE = new DefaultMeter(); - private static final String COUNTERS_CAN_ONLY_INCREASE = "Counters can only increase"; - - /* VisibleForTesting */ static final String ERROR_MESSAGE_INVALID_NAME = - "Name should be a ASCII string with a length no greater than " - + MetricsStringUtils.METRIC_NAME_MAX_LENGTH - + " characters."; - - static Meter getInstance() { - return INSTANCE; - } - - @Override - public DoubleCounterBuilder doubleCounterBuilder(String name) { - Objects.requireNonNull(name, "name"); - Utils.checkArgument(MetricsStringUtils.isValidMetricName(name), ERROR_MESSAGE_INVALID_NAME); - return new NoopDoubleCounter.NoopBuilder(); - } - - @Override - public LongCounterBuilder longCounterBuilder(String name) { - Objects.requireNonNull(name, "name"); - Utils.checkArgument(MetricsStringUtils.isValidMetricName(name), ERROR_MESSAGE_INVALID_NAME); - return new NoopLongCounter.NoopBuilder(); - } - - @Override - public DoubleUpDownCounterBuilder doubleUpDownCounterBuilder(String name) { - Objects.requireNonNull(name, "name"); - Utils.checkArgument(MetricsStringUtils.isValidMetricName(name), ERROR_MESSAGE_INVALID_NAME); - return new NoopDoubleUpDownCounter.NoopBuilder(); - } - - @Override - public LongUpDownCounterBuilder longUpDownCounterBuilder(String name) { - Objects.requireNonNull(name, "name"); - Utils.checkArgument(MetricsStringUtils.isValidMetricName(name), ERROR_MESSAGE_INVALID_NAME); - return new NoopLongUpDownCounter.NoopBuilder(); - } - - @Override - public DoubleValueRecorderBuilder doubleValueRecorderBuilder(String name) { - Objects.requireNonNull(name, "name"); - Utils.checkArgument(MetricsStringUtils.isValidMetricName(name), ERROR_MESSAGE_INVALID_NAME); - return new NoopDoubleValueRecorder.NoopBuilder(); - } - - @Override - public LongValueRecorderBuilder longValueRecorderBuilder(String name) { - Objects.requireNonNull(name, "name"); - Utils.checkArgument(MetricsStringUtils.isValidMetricName(name), ERROR_MESSAGE_INVALID_NAME); - return new NoopLongValueRecorder.NoopBuilder(); - } - - @Override - public DoubleSumObserverBuilder doubleSumObserverBuilder(String name) { - Objects.requireNonNull(name, "name"); - Utils.checkArgument(MetricsStringUtils.isValidMetricName(name), ERROR_MESSAGE_INVALID_NAME); - return new NoopDoubleSumObserver.NoopBuilder(); - } - - @Override - public LongSumObserverBuilder longSumObserverBuilder(String name) { - Objects.requireNonNull(name, "name"); - Utils.checkArgument(MetricsStringUtils.isValidMetricName(name), ERROR_MESSAGE_INVALID_NAME); - return new NoopLongSumObserver.NoopBuilder(); - } - - @Override - public DoubleUpDownSumObserverBuilder doubleUpDownSumObserverBuilder(String name) { - Objects.requireNonNull(name, "name"); - Utils.checkArgument(MetricsStringUtils.isValidMetricName(name), ERROR_MESSAGE_INVALID_NAME); - return new NoopDoubleUpDownSumObserver.NoopBuilder(); - } - - @Override - public LongUpDownSumObserverBuilder longUpDownSumObserverBuilder(String name) { - Objects.requireNonNull(name, "name"); - Utils.checkArgument(MetricsStringUtils.isValidMetricName(name), ERROR_MESSAGE_INVALID_NAME); - return new NoopLongUpDownSumObserver.NoopBuilder(); - } - - @Override - public DoubleValueObserverBuilder doubleValueObserverBuilder(String name) { - Objects.requireNonNull(name, "name"); - Utils.checkArgument(MetricsStringUtils.isValidMetricName(name), ERROR_MESSAGE_INVALID_NAME); - return new NoopDoubleValueObserver.NoopBuilder(); - } - - @Override - public LongValueObserverBuilder longValueObserverBuilder(String name) { - Objects.requireNonNull(name, "name"); - Utils.checkArgument(MetricsStringUtils.isValidMetricName(name), ERROR_MESSAGE_INVALID_NAME); - return new NoopLongValueObserver.NoopBuilder(); - } - - @Override - public BatchRecorder newBatchRecorder(String... keyValuePairs) { - validateLabelPairs(keyValuePairs); - return NoopBatchRecorder.INSTANCE; - } - - private DefaultMeter() {} - - /** No-op implementation of {@link DoubleCounter} interface. */ - @Immutable - private static final class NoopDoubleCounter implements DoubleCounter { - - private NoopDoubleCounter() {} - - @Override - public void add(double increment, Labels labels) { - Objects.requireNonNull(labels, "labels"); - Utils.checkArgument(increment >= 0.0, COUNTERS_CAN_ONLY_INCREASE); - } - - @Override - public void add(double increment) { - add(increment, Labels.empty()); - } - - @Override - public NoopBoundDoubleCounter bind(Labels labels) { - Objects.requireNonNull(labels, "labels"); - return NoopBoundDoubleCounter.INSTANCE; - } - - @Immutable - private enum NoopBoundDoubleCounter implements BoundDoubleCounter { - INSTANCE; - - @Override - public void add(double increment) { - Utils.checkArgument(increment >= 0.0, COUNTERS_CAN_ONLY_INCREASE); - } - - @Override - public void unbind() {} - } - - private static final class NoopBuilder extends NoopAbstractInstrumentBuilder - implements DoubleCounterBuilder { - - @Override - protected NoopBuilder getThis() { - return this; - } - - @Override - public DoubleCounter build() { - return new NoopDoubleCounter(); - } - } - } - - /** No-op implementation of {@link LongCounter} interface. */ - @Immutable - private static final class NoopLongCounter implements LongCounter { - - private NoopLongCounter() {} - - @Override - public void add(long increment, Labels labels) { - Objects.requireNonNull(labels, "labels"); - Utils.checkArgument(increment >= 0, COUNTERS_CAN_ONLY_INCREASE); - } - - @Override - public void add(long increment) { - add(increment, Labels.empty()); - } - - @Override - public NoopBoundLongCounter bind(Labels labels) { - Objects.requireNonNull(labels, "labels"); - return NoopBoundLongCounter.INSTANCE; - } - - @Immutable - private enum NoopBoundLongCounter implements BoundLongCounter { - INSTANCE; - - @Override - public void add(long increment) { - Utils.checkArgument(increment >= 0, COUNTERS_CAN_ONLY_INCREASE); - } - - @Override - public void unbind() {} - } - - private static final class NoopBuilder extends NoopAbstractInstrumentBuilder - implements LongCounterBuilder { - - @Override - protected NoopBuilder getThis() { - return this; - } - - @Override - public LongCounter build() { - return new NoopLongCounter(); - } - } - } - - /** No-op implementation of {@link DoubleUpDownCounter} interface. */ - @Immutable - private static final class NoopDoubleUpDownCounter implements DoubleUpDownCounter { - - private NoopDoubleUpDownCounter() {} - - @Override - public void add(double increment, Labels labels) { - Objects.requireNonNull(labels, "labels"); - } - - @Override - public void add(double increment) { - add(increment, Labels.empty()); - } - - @Override - public NoopBoundDoubleUpDownCounter bind(Labels labels) { - Objects.requireNonNull(labels, "labels"); - return NoopBoundDoubleUpDownCounter.INSTANCE; - } - - @Immutable - private enum NoopBoundDoubleUpDownCounter implements BoundDoubleUpDownCounter { - INSTANCE; - - @Override - public void add(double increment) {} - - @Override - public void unbind() {} - } - - private static final class NoopBuilder extends NoopAbstractInstrumentBuilder - implements DoubleUpDownCounterBuilder { - - @Override - protected NoopBuilder getThis() { - return this; - } - - @Override - public DoubleUpDownCounter build() { - return new NoopDoubleUpDownCounter(); - } - } - } - - /** No-op implementation of {@link LongUpDownCounter} interface. */ - @Immutable - private static final class NoopLongUpDownCounter implements LongUpDownCounter { - - private NoopLongUpDownCounter() {} - - @Override - public void add(long increment, Labels labels) { - Objects.requireNonNull(labels, "labels"); - } - - @Override - public void add(long increment) { - add(increment, Labels.empty()); - } - - @Override - public NoopBoundLongUpDownCounter bind(Labels labels) { - Objects.requireNonNull(labels, "labels"); - return NoopBoundLongUpDownCounter.INSTANCE; - } - - @Immutable - private enum NoopBoundLongUpDownCounter implements BoundLongUpDownCounter { - INSTANCE; - - @Override - public void add(long increment) {} - - @Override - public void unbind() {} - } - - private static final class NoopBuilder extends NoopAbstractInstrumentBuilder - implements LongUpDownCounterBuilder { - - @Override - protected NoopBuilder getThis() { - return this; - } - - @Override - public LongUpDownCounter build() { - return new NoopLongUpDownCounter(); - } - } - } - - /** No-op implementation of {@link DoubleValueRecorder} interface. */ - @Immutable - private static final class NoopDoubleValueRecorder implements DoubleValueRecorder { - - private NoopDoubleValueRecorder() {} - - @Override - public void record(double value, Labels labels) { - Objects.requireNonNull(labels, "labels"); - } - - @Override - public void record(double value) { - record(value, Labels.empty()); - } - - @Override - public NoopBoundDoubleValueRecorder bind(Labels labels) { - Objects.requireNonNull(labels, "labels"); - return NoopBoundDoubleValueRecorder.INSTANCE; - } - - @Immutable - private enum NoopBoundDoubleValueRecorder implements BoundDoubleValueRecorder { - INSTANCE; - - @Override - public void record(double value) {} - - @Override - public void unbind() {} - } - - private static final class NoopBuilder extends NoopAbstractInstrumentBuilder - implements DoubleValueRecorderBuilder { - - @Override - protected NoopBuilder getThis() { - return this; - } - - @Override - public DoubleValueRecorder build() { - return new NoopDoubleValueRecorder(); - } - } - } - - /** No-op implementation of {@link LongValueRecorder} interface. */ - @Immutable - private static final class NoopLongValueRecorder implements LongValueRecorder { - - private NoopLongValueRecorder() {} - - @Override - public void record(long value, Labels labels) { - Objects.requireNonNull(labels, "labels"); - } - - @Override - public void record(long value) { - record(value, Labels.empty()); - } - - @Override - public NoopBoundLongValueRecorder bind(Labels labels) { - Objects.requireNonNull(labels, "labels"); - return NoopBoundLongValueRecorder.INSTANCE; - } - - @Immutable - private enum NoopBoundLongValueRecorder implements BoundLongValueRecorder { - INSTANCE; - - @Override - public void record(long value) {} - - @Override - public void unbind() {} - } - - private static final class NoopBuilder extends NoopAbstractInstrumentBuilder - implements LongValueRecorderBuilder { - - @Override - protected NoopBuilder getThis() { - return this; - } - - @Override - public LongValueRecorder build() { - return new NoopLongValueRecorder(); - } - } - } - - /** No-op implementation of {@link DoubleSumObserver} interface. */ - @Immutable - private static final class NoopDoubleSumObserver implements DoubleSumObserver { - - private NoopDoubleSumObserver() {} - - private static final class NoopBuilder extends NoopAbstractInstrumentBuilder - implements DoubleSumObserverBuilder { - - @Override - protected NoopBuilder getThis() { - return this; - } - - @Override - public DoubleSumObserverBuilder setUpdater(Consumer updater) { - Objects.requireNonNull(updater, "callback"); - return this; - } - - @Override - public DoubleSumObserver build() { - return new NoopDoubleSumObserver(); - } - } - } - - /** No-op implementation of {@link LongSumObserver} interface. */ - @Immutable - private static final class NoopLongSumObserver implements LongSumObserver { - - private NoopLongSumObserver() {} - - private static final class NoopBuilder extends NoopAbstractInstrumentBuilder - implements LongSumObserverBuilder { - - @Override - protected NoopBuilder getThis() { - return this; - } - - @Override - public NoopBuilder setUpdater(Consumer updater) { - Objects.requireNonNull(updater, "callback"); - return this; - } - - @Override - public LongSumObserver build() { - return new NoopLongSumObserver(); - } - } - } - - /** No-op implementation of {@link DoubleUpDownSumObserver} interface. */ - @Immutable - private static final class NoopDoubleUpDownSumObserver implements DoubleUpDownSumObserver { - - private NoopDoubleUpDownSumObserver() {} - - private static final class NoopBuilder extends NoopAbstractInstrumentBuilder - implements DoubleUpDownSumObserverBuilder { - - @Override - protected NoopBuilder getThis() { - return this; - } - - @Override - public DoubleUpDownSumObserverBuilder setUpdater(Consumer updater) { - Objects.requireNonNull(updater, "callback"); - return this; - } - - @Override - public DoubleUpDownSumObserver build() { - return new NoopDoubleUpDownSumObserver(); - } - } - } - - /** No-op implementation of {@link LongUpDownSumObserver} interface. */ - @Immutable - private static final class NoopLongUpDownSumObserver implements LongUpDownSumObserver { - - private NoopLongUpDownSumObserver() {} - - private static final class NoopBuilder extends NoopAbstractInstrumentBuilder - implements LongUpDownSumObserverBuilder { - - @Override - protected NoopBuilder getThis() { - return this; - } - - @Override - public LongUpDownSumObserverBuilder setUpdater(Consumer updater) { - Objects.requireNonNull(updater, "callback"); - return this; - } - - @Override - public LongUpDownSumObserver build() { - return new NoopLongUpDownSumObserver(); - } - } - } - - /** No-op implementation of {@link DoubleValueObserver} interface. */ - @Immutable - private static final class NoopDoubleValueObserver implements DoubleValueObserver { - - private NoopDoubleValueObserver() {} - - private static final class NoopBuilder extends NoopAbstractInstrumentBuilder - implements DoubleValueObserverBuilder { - - @Override - protected NoopBuilder getThis() { - return this; - } - - @Override - public DoubleValueObserverBuilder setUpdater(Consumer updater) { - Objects.requireNonNull(updater, "callback"); - return this; - } - - @Override - public DoubleValueObserver build() { - return new NoopDoubleValueObserver(); - } - } - } - - /** No-op implementation of {@link LongValueObserver} interface. */ - @Immutable - private static final class NoopLongValueObserver implements LongValueObserver { - - private NoopLongValueObserver() {} - - private static final class NoopBuilder extends NoopAbstractInstrumentBuilder - implements LongValueObserverBuilder { - - @Override - protected NoopBuilder getThis() { - return this; - } - - @Override - public LongValueObserverBuilder setUpdater(Consumer updater) { - Objects.requireNonNull(updater, "callback"); - return this; - } - - @Override - public LongValueObserver build() { - return new NoopLongValueObserver(); - } - } - } - - /** No-op implementation of {@link BatchRecorder} interface. */ - private enum NoopBatchRecorder implements BatchRecorder { - INSTANCE; - - @Override - public BatchRecorder put(LongValueRecorder valueRecorder, long value) { - Objects.requireNonNull(valueRecorder, "valueRecorder"); - return this; - } - - @Override - public BatchRecorder put(DoubleValueRecorder valueRecorder, double value) { - Objects.requireNonNull(valueRecorder, "valueRecorder"); - return this; - } - - @Override - public BatchRecorder put(LongCounter counter, long value) { - Objects.requireNonNull(counter, "counter"); - Utils.checkArgument(value >= 0, COUNTERS_CAN_ONLY_INCREASE); - return this; - } - - @Override - public BatchRecorder put(DoubleCounter counter, double value) { - Objects.requireNonNull(counter, "counter"); - Utils.checkArgument(value >= 0.0, COUNTERS_CAN_ONLY_INCREASE); - return this; - } - - @Override - public BatchRecorder put(LongUpDownCounter upDownCounter, long value) { - Objects.requireNonNull(upDownCounter, "upDownCounter"); - return this; - } - - @Override - public BatchRecorder put(DoubleUpDownCounter upDownCounter, double value) { - Objects.requireNonNull(upDownCounter, "upDownCounter"); - return this; - } - - @Override - public void record() {} - } - - private abstract static class NoopAbstractInstrumentBuilder< - B extends NoopAbstractInstrumentBuilder> - implements InstrumentBuilder { - - @Override - public B setDescription(String description) { - Objects.requireNonNull(description, "description"); - return getThis(); - } - - @Override - public B setUnit(String unit) { - Objects.requireNonNull(unit, "unit"); - return getThis(); - } - - protected abstract B getThis(); - } - - /** - * Validates that the array of Strings is 1) even in length, and 2) they can be formed into valid - * pairs where the first item in the pair is not null. - * - * @param keyValuePairs The String[] to validate for correctness. - * @throws IllegalArgumentException if any of the preconditions are violated. - */ - private static void validateLabelPairs(String[] keyValuePairs) { - Utils.checkArgument( - keyValuePairs.length % 2 == 0, - "You must provide an even number of key/value pair arguments."); - for (int i = 0; i < keyValuePairs.length; i += 2) { - String key = keyValuePairs[i]; - Objects.requireNonNull(key, "You cannot provide null keys for label creation."); - } - } -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DefaultMeterBuilder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/DefaultMeterBuilder.java deleted file mode 100644 index 5ea9decafa..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DefaultMeterBuilder.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -class DefaultMeterBuilder implements MeterBuilder { - private static final MeterBuilder INSTANCE = new DefaultMeterBuilder(); - - static MeterBuilder getInstance() { - return INSTANCE; - } - - @Override - public MeterBuilder setSchemaUrl(String schemaUrl) { - return this; - } - - @Override - public MeterBuilder setInstrumentationVersion(String instrumentationVersion) { - return this; - } - - @Override - public Meter build() { - return DefaultMeter.getInstance(); - } -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DefaultMeterProvider.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/DefaultMeterProvider.java deleted file mode 100644 index 91db009775..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DefaultMeterProvider.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import javax.annotation.concurrent.ThreadSafe; - -@ThreadSafe -final class DefaultMeterProvider implements MeterProvider { - - private static final MeterProvider INSTANCE = new DefaultMeterProvider(); - - static MeterProvider getInstance() { - return INSTANCE; - } - - @Override - public Meter get(String instrumentationName) { - return get(instrumentationName, null); - } - - @Override - public Meter get(String instrumentationName, String instrumentationVersion) { - return DefaultMeter.getInstance(); - } - - private DefaultMeterProvider() {} -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleCounter.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleCounter.java index 48134d0077..33d11e25ca 100644 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleCounter.java +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleCounter.java @@ -5,59 +5,46 @@ package io.opentelemetry.api.metrics; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.context.Context; import javax.annotation.concurrent.ThreadSafe; -/** - * Counter is the most common synchronous instrument. This instrument supports an {@link - * #add(double, Labels)}` function for reporting an increment, and is restricted to non-negative - * increments. The default aggregation is `Sum`. - * - *

Example: - * - *

{@code
- * class YourClass {
- *   private static final Meter meter = OpenTelemetry.getMeterProvider().get("my_library_name");
- *   private static final DoubleCounter counter =
- *       meter.
- *           .doubleCounterBuilder("allocated_resources")
- *           .setDescription("Total allocated resources")
- *           .setUnit("1")
- *           .build();
- *
- *   // It is recommended that the API user keep references to a Bound Counters.
- *   private static final BoundDoubleCounter someWorkBound =
- *       counter.bind("work_name", "some_work");
- *
- *   void doSomeWork() {
- *      someWorkBound.add(10.2);  // Resources needed for this task.
- *      // Your code here.
- *   }
- * }
- * }
- */ +/** A counter instrument that records {@code double} values. */ @ThreadSafe -public interface DoubleCounter extends SynchronousInstrument { +public interface DoubleCounter { + /** + * Records a value. + * + *

Note: This may use {@code Context.current()} to pull the context associated with this + * measurement. + * + * @param value The increment amount. MUST be non-negative. + */ + void add(double value); /** - * Adds the given {@code increment} to the current value. The values cannot be negative. + * Records a value with a set of attributes. * - *

The value added is associated with the current {@code Context} and provided set of labels. + *

Note: This may use {@code Context.current()} to pull the context associated with this + * measurement. * - * @param increment the value to add. - * @param labels the labels to be associated to this recording. + * @param value The increment amount. MUST be non-negative. + * @param attributes A set of attributes to associate with the count. */ - void add(double increment, Labels labels); + void add(double value, Attributes attributes); /** - * Adds the given {@code increment} to the current value. The values cannot be negative. + * Records a value with a set of attributes. * - *

The value added is associated with the current {@code Context} and with empty labels. - * - * @param increment the value to add. + * @param value The increment amount. MUST be non-negative. + * @param attributes A set of attributes to associate with the count. + * @param context The explicit context to associate with this measurement. */ - void add(double increment); + void add(double value, Attributes attributes, Context context); - @Override - BoundDoubleCounter bind(Labels labels); + /** + * Constructs a bound version of this instrument where all recorded values use the given + * attributes. + */ + BoundDoubleCounter bind(Attributes attributes); } diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleCounterBuilder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleCounterBuilder.java index d7bf2dd367..bcbb2387ff 100644 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleCounterBuilder.java +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleCounterBuilder.java @@ -5,14 +5,42 @@ package io.opentelemetry.api.metrics; +import java.util.function.Consumer; + /** Builder class for {@link DoubleCounter}. */ -public interface DoubleCounterBuilder extends SynchronousInstrumentBuilder { - @Override +public interface DoubleCounterBuilder { + /** + * Sets the description for this instrument. + * + *

Description stirngs should follw the instrument description rules: + * https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-description + */ DoubleCounterBuilder setDescription(String description); - @Override + /** + * Sets the unit of measure for this instrument. + * + *

Unit strings should follow the instrument unit rules: + * https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-unit + */ DoubleCounterBuilder setUnit(String unit); - @Override + /** Sets the counter for recording {@code long} values. */ + LongCounterBuilder ofLongs(); + + /** + * Builds and returns a {@code DoubleCounter} with the desired options. + * + * @return a {@code DoubleCounter} with the desired options. + */ DoubleCounter build(); + + /** + * Builds this asynchronous insturment with the given callback. + * + *

The callback will only be called when the {@link Meter} is being observed. + * + * @param callback A state-capturing callback used to observe values on-demand. + */ + void buildWithCallback(Consumer callback); } diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleGaugeBuilder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleGaugeBuilder.java new file mode 100644 index 0000000000..a1a5d4c7ef --- /dev/null +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleGaugeBuilder.java @@ -0,0 +1,39 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.metrics; + +import java.util.function.Consumer; + +/** A builder for Gauge metric types. These can only be asynchronously collected. */ +public interface DoubleGaugeBuilder { + /** + * Sets the description for this instrument. + * + *

Description strings should follow the instrument description rules: + * https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-description + */ + DoubleGaugeBuilder setDescription(String description); + + /** + * Sets the unit of measure for this instrument. + * + *

Unit strings should follow the instrument unit rules: + * https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-unit + */ + DoubleGaugeBuilder setUnit(String unit); + + /** Sets the gauge for recording {@code long} values. */ + LongGaugeBuilder ofLongs(); + + /** + * Builds this asynchronous instrument with the given callback. + * + *

The callback will only be called when the {@link Meter} is being observed. + * + * @param callback A state-capturing callback used to observe values on-demand. + */ + void buildWithCallback(Consumer callback); +} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleHistogram.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleHistogram.java new file mode 100644 index 0000000000..1205acf9aa --- /dev/null +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleHistogram.java @@ -0,0 +1,51 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.metrics; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.context.Context; +import javax.annotation.concurrent.ThreadSafe; + +/** A histogram instrument that records {@code long} values. */ +@ThreadSafe +public interface DoubleHistogram { + + /** + * Records a value. + * + *

Note: This may use {@code Context.current()} to pull the context associated with this + * measurement. + * + * @param value The amount of the measurement. + */ + void record(double value); + + /** + * Records a value with a set of attributes. + * + *

Note: This may use {@code Context.current()} to pull the context associated with this + * measurement. + * + * @param value The amount of the measurement. + * @param attributes A set of attributes to associate with the count. + */ + void record(double value, Attributes attributes); + + /** + * Records a value with a set of attributes. + * + * @param value The amount of the measurement. + * @param attributes A set of attributes to associate with the count. + * @param context The explicit context to associate with this measurement. + */ + void record(double value, Attributes attributes, Context context); + + /** + * Constructs a bound version of this instrument where all recorded values use the given + * attributes. + */ + BoundDoubleHistogram bind(Attributes attributes); +} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleHistogramBuilder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleHistogramBuilder.java new file mode 100644 index 0000000000..f31b7cbaa5 --- /dev/null +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleHistogramBuilder.java @@ -0,0 +1,36 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.metrics; + +/** Builder class for {@link DoubleHistogram}. */ +public interface DoubleHistogramBuilder { + + /** + * Sets the description for this instrument. + * + *

Description strings should follow the instrument description rules: + * https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-description + */ + DoubleHistogramBuilder setDescription(String description); + + /** + * Sets the unit of measure for this instrument. + * + *

Unit strings should follow the instrument unit rules: + * https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-unit + */ + DoubleHistogramBuilder setUnit(String unit); + + /** Sets the counter for recording {@code long} values. */ + LongHistogramBuilder ofLongs(); + + /** + * Builds and returns a {@code DoubleHistogram} with the desired options. + * + * @return a {@code DoubleHistogram} with the desired options. + */ + DoubleHistogram build(); +} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleSumObserver.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleSumObserver.java deleted file mode 100644 index 2b2dd27d52..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleSumObserver.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import javax.annotation.concurrent.ThreadSafe; - -/** - * {@code SumObserver} is the asynchronous instrument corresponding to Counter, used to capture a - * monotonic sum with Observe(sum). - * - *

"Sum" appears in the name to remind that it is used to capture sums directly. Use a - * SumObserver to capture any value that starts at zero and rises throughout the process lifetime - * and never falls. - * - *

A {@code SumObserver} is a good choice in situations where a measurement is expensive to - * compute, such that it would be wasteful to compute on every request. - * - *

Example: - * - *

{@code
- * // class YourClass {
- * //
- * //   private static final Meter meter = OpenTelemetry.getMeterProvider().get("my_library_name");
- * //   private static final DoubleSumObserver cpuObserver =
- * //       meter.
- * //           .doubleSumObserverBuilder("cpu_time")
- * //           .setDescription("System CPU usage")
- * //           .setUnit("ms")
- * //           .build();
- * //
- * //   void init() {
- * //     cpuObserver.setUpdater(
- * //         new DoubleSumObserver.Callback() {
- * //          @Override
- * //           public void update(DoubleResult result) {
- * //             // Get system cpu usage
- * //             result.observe(cpuIdle, "state", "idle");
- * //             result.observe(cpuUser, "state", "user");
- * //           }
- * //         });
- * //   }
- * // }
- * }
- */ -@ThreadSafe -public interface DoubleSumObserver extends AsynchronousInstrument {} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleSumObserverBuilder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleSumObserverBuilder.java deleted file mode 100644 index c0e2054177..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleSumObserverBuilder.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import java.util.function.Consumer; - -/** Builder class for {@link DoubleSumObserver}. */ -public interface DoubleSumObserverBuilder - extends AsynchronousInstrumentBuilder { - @Override - DoubleSumObserverBuilder setDescription(String description); - - @Override - DoubleSumObserverBuilder setUnit(String unit); - - @Override - DoubleSumObserverBuilder setUpdater(Consumer updater); - - @Override - DoubleSumObserver build(); -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleUpDownCounter.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleUpDownCounter.java index cc521224d4..d8af95372e 100644 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleUpDownCounter.java +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleUpDownCounter.java @@ -5,62 +5,46 @@ package io.opentelemetry.api.metrics; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.context.Context; import javax.annotation.concurrent.ThreadSafe; -/** - * UpDownCounter is a synchronous instrument and very similar to Counter except that Add(increment) - * supports negative increments. This makes UpDownCounter not useful for computing a rate - * aggregation. The default aggregation is `Sum`, only the sum is non-monotonic. It is generally - * useful for capturing changes in an amount of resources used, or any quantity that rises and falls - * during a request. - * - *

Example: - * - *

{@code
- * class YourClass {
- *   private static final Meter meter = OpenTelemetry.getMeterProvider().get("my_library_name");
- *   private static final DoubleUpDownCounter upDownCounter =
- *       meter.
- *           .doubleUpDownCounterBuilder("resource_usage")
- *           .setDescription("Current resource usage")
- *           .setUnit("1")
- *           .build();
- *
- *   // It is recommended that the API user keep references to a Bound Counters.
- *   private static final BoundDoubleUpDownCounter someWorkBound =
- *       upDownCounter.bind("work_name", "some_work");
- *
- *   void doSomeWork() {
- *      someWorkBound.add(10.2);  // Resources needed for this task.
- *      // Your code here.
- *      someWorkBound.add(-10.0);
- *   }
- * }
- * }
- */ +/** An up-down-counter instrument that records {@code double} values. */ @ThreadSafe -public interface DoubleUpDownCounter extends SynchronousInstrument { +public interface DoubleUpDownCounter { + /** + * Records a value. + * + *

Note: This may use {@code Context.current()} to pull the context associated with this + * measurement. + * + * @param value The increment amount. May be positive, negative or zero. + */ + void add(double value); /** - * Adds the given {@code increment} to the current value. + * Records a value with a set of attributes. * - *

The value added is associated with the current {@code Context} and provided set of labels. + *

Note: This may use {@code Context.current()} to pull the context associated with this + * measurement. * - * @param increment the value to add. - * @param labels the labels to be associated to this recording. + * @param value The increment amount. May be positive, negative or zero. + * @param attributes A set of attributes to associate with the count. */ - void add(double increment, Labels labels); + void add(double value, Attributes attributes); /** - * Adds the given {@code increment} to the current value. + * Records a value with a set of attributes. * - *

The value added is associated with the current {@code Context} and empty labels. - * - * @param increment the value to add. + * @param value The increment amount. May be positive, negative or zero. + * @param attributes A set of attributes to associate with the count. + * @param context The explicit context to associate with this measurement. */ - void add(double increment); + void add(double value, Attributes attributes, Context context); - @Override - BoundDoubleUpDownCounter bind(Labels labels); + /** + * Constructs a bound version of this instrument where all recorded values use the given + * attributes. + */ + BoundDoubleUpDownCounter bind(Attributes attributes); } diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleUpDownCounterBuilder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleUpDownCounterBuilder.java index 953da7a86f..1600648fe8 100644 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleUpDownCounterBuilder.java +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleUpDownCounterBuilder.java @@ -5,14 +5,42 @@ package io.opentelemetry.api.metrics; +import java.util.function.Consumer; + /** Builder class for {@link DoubleUpDownCounter}. */ -public interface DoubleUpDownCounterBuilder extends SynchronousInstrumentBuilder { - @Override +public interface DoubleUpDownCounterBuilder { + /** + * Sets the description for this instrument. + * + *

Description strings should follow the instrument description rules: + * https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-description + */ DoubleUpDownCounterBuilder setDescription(String description); - @Override + /** + * Sets the unit of measure for this instrument. + * + *

Unit strings should follow the instrument unit rules: + * https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-unit + */ DoubleUpDownCounterBuilder setUnit(String unit); - @Override + /** Sets the counter for recording {@code long} values. */ + LongUpDownCounterBuilder ofLongs(); + + /** + * Builds and returns a {@code DoubleUpDownCounter} with the desired options. + * + * @return a {@code DoubleUpDownCounter} with the desired options. + */ DoubleUpDownCounter build(); + + /** + * Builds this asynchronous instrument with the given callback. + * + *

The callback will only be called when the {@link Meter} is being observed. + * + * @param callback A state-capturing callback used to observe values on-demand. + */ + void buildWithCallback(Consumer callback); } diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleUpDownSumObserver.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleUpDownSumObserver.java deleted file mode 100644 index 05f1157567..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleUpDownSumObserver.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import javax.annotation.concurrent.ThreadSafe; - -/** - * UpDownSumObserver is the asynchronous instrument corresponding to UpDownCounter, used to capture - * a non-monotonic count with Observe(sum). - * - *

"Sum" appears in the name to remind that it is used to capture sums directly. Use a - * UpDownSumObserver to capture any value that starts at zero and rises or falls throughout the - * process lifetime. - * - *

A {@code UpDownSumObserver} is a good choice in situations where a measurement is expensive to - * compute, such that it would be wasteful to compute on every request. - * - *

Example: - * - *

{@code
- * // class YourClass {
- * //
- * //   private static final Meter meter = OpenTelemetry.getMeterProvider().get("my_library_name");
- * //   private static final DoubleUpDownSumObserver memoryObserver =
- * //       meter.
- * //           .doubleUpDownSumObserverBuilder("memory_usage")
- * //           .setDescription("System memory usage")
- * //           .setUnit("by")
- * //           .build();
- * //
- * //   void init() {
- * //     memoryObserver.setUpdater(
- * //         new DoubleUpDownSumObserver.Callback() {
- * //          @Override
- * //           public void update(DoubleResult result) {
- * //             // Get system memory usage
- * //             result.observe(memoryUsed, "state", "used");
- * //             result.observe(memoryFree, "state", "free");
- * //           }
- * //         });
- * //   }
- * // }
- * }
- */ -@ThreadSafe -public interface DoubleUpDownSumObserver extends AsynchronousInstrument {} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleUpDownSumObserverBuilder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleUpDownSumObserverBuilder.java deleted file mode 100644 index e824091e1f..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleUpDownSumObserverBuilder.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import java.util.function.Consumer; - -/** Builder class for {@link DoubleUpDownSumObserver}. */ -public interface DoubleUpDownSumObserverBuilder - extends AsynchronousInstrumentBuilder { - @Override - DoubleUpDownSumObserverBuilder setDescription(String description); - - @Override - DoubleUpDownSumObserverBuilder setUnit(String unit); - - @Override - DoubleUpDownSumObserverBuilder setUpdater(Consumer updater); - - @Override - DoubleUpDownSumObserver build(); -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleValueObserver.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleValueObserver.java deleted file mode 100644 index 018806beaa..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleValueObserver.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import javax.annotation.concurrent.ThreadSafe; - -/** - * {@code ValueObserver} is the asynchronous instrument corresponding to ValueRecorder, used to - * capture values that are treated as individual observations, recorded with the observe(value) - * method. - * - *

A {@code ValueObserver} is a good choice in situations where a measurement is expensive to - * compute, such that it would be wasteful to compute on every request. - * - *

Example: - * - *

{@code
- * // class YourClass {
- * //
- * //   private static final Meter meter = OpenTelemetry.getMeterProvider().get("my_library_name");
- * //   private static final DoubleValueObserver cpuObserver =
- * //       meter.
- * //           .doubleValueObserverBuilder("cpu_temperature")
- * //           .setDescription("System CPU temperature")
- * //           .setUnit("ms")
- * //           .build();
- * //
- * //   void init() {
- * //     cpuObserver.setUpdater(
- * //         new DoubleValueObserver.Callback() {
- * //          @Override
- * //           public void update(DoubleResult result) {
- * //             // Get system cpu temperature
- * //             result.observe(cpuTemperature);
- * //           }
- * //         });
- * //   }
- * // }
- * }
- */ -@ThreadSafe -public interface DoubleValueObserver extends AsynchronousInstrument {} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleValueObserverBuilder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleValueObserverBuilder.java deleted file mode 100644 index eafa8f0dcd..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleValueObserverBuilder.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import java.util.function.Consumer; - -/** Builder class for {@link DoubleValueObserver}. */ -public interface DoubleValueObserverBuilder - extends AsynchronousInstrumentBuilder { - @Override - DoubleValueObserverBuilder setDescription(String description); - - @Override - DoubleValueObserverBuilder setUnit(String unit); - - @Override - DoubleValueObserverBuilder setUpdater(Consumer updater); - - @Override - DoubleValueObserver build(); -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleValueRecorder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleValueRecorder.java deleted file mode 100644 index 80abefe089..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleValueRecorder.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import io.opentelemetry.api.metrics.common.Labels; -import javax.annotation.concurrent.ThreadSafe; - -/** - * ValueRecorder is a synchronous instrument useful for recording any number, positive or negative. - * Values captured by a Record(value) are treated as individual events belonging to a distribution - * that is being summarized. - * - *

ValueRecorder should be chosen either when capturing measurements that do not contribute - * meaningfully to a sum, or when capturing numbers that are additive in nature, but where the - * distribution of individual increments is considered interesting. - * - *

One of the most common uses for ValueRecorder is to capture latency measurements. Latency - * measurements are not additive in the sense that there is little need to know the latency-sum of - * all processed requests. We use a ValueRecorder instrument to capture latency measurements - * typically because we are interested in knowing mean, median, and other summary statistics about - * individual events. - * - *

Example: - * - *

{@code
- * class YourClass {
- *
- *   private static final Meter meter = OpenTelemetry.getMeterProvider().get("my_library_name");
- *   private static final DoubleValueRecorder valueRecorder =
- *       meter.
- *           .doubleValueRecorderBuilder("doWork_latency")
- *           .setDescription("gRPC Latency")
- *           .setUnit("ms")
- *           .build();
- *
- *   // It is recommended that the API user keep references to a Bound Counters.
- *   private static final BoundDoubleValueRecorder someWorkBound =
- *       valueRecorder.bind("work_name", "some_work");
- *
- *   void doWork() {
- *      long startTime = System.nanoTime();
- *      // Your code here.
- *      someWorkBound.record((System.nanoTime() - startTime) / 1e6);
- *   }
- * }
- * }
- */ -@ThreadSafe -public interface DoubleValueRecorder extends SynchronousInstrument { - - /** - * Records the given measurement, associated with the current {@code Context} and provided set of - * labels. - * - * @param value the measurement to record. - * @param labels the set of labels to be associated to this recording - * @throws IllegalArgumentException if value is negative. - */ - void record(double value, Labels labels); - - /** - * Records the given measurement, associated with the current {@code Context} and empty labels. - * - * @param value the measurement to record. - * @throws IllegalArgumentException if value is negative. - */ - void record(double value); - - @Override - BoundDoubleValueRecorder bind(Labels labels); -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleValueRecorderBuilder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleValueRecorderBuilder.java deleted file mode 100644 index 17b787ea79..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/DoubleValueRecorderBuilder.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -/** Builder class for {@link DoubleValueRecorder}. */ -public interface DoubleValueRecorderBuilder extends SynchronousInstrumentBuilder { - @Override - DoubleValueRecorderBuilder setDescription(String description); - - @Override - DoubleValueRecorderBuilder setUnit(String unit); - - @Override - DoubleValueRecorder build(); -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/GlobalMeterProvider.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/GlobalMeterProvider.java index 9d1b0c9715..833ddc561b 100644 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/GlobalMeterProvider.java +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/GlobalMeterProvider.java @@ -5,29 +5,17 @@ package io.opentelemetry.api.metrics; -import java.util.concurrent.atomic.AtomicReference; +import io.opentelemetry.api.metrics.internal.NoopMeterProvider; -/** - * IMPORTANT: This is a temporary class, and solution for the metrics package until it will be - * marked as stable. - */ -public final class GlobalMeterProvider { - private static final Object mutex = new Object(); - private static final AtomicReference globalMeterProvider = new AtomicReference<>(); +/** This class is a temporary solution until metrics SDK is marked stable. */ +public class GlobalMeterProvider { + private static volatile MeterProvider globalMeterProvider = NoopMeterProvider.getInstance(); private GlobalMeterProvider() {} /** Returns the globally registered {@link MeterProvider}. */ public static MeterProvider get() { - MeterProvider meterProvider = globalMeterProvider.get(); - if (meterProvider == null) { - synchronized (mutex) { - if (globalMeterProvider.get() == null) { - return MeterProvider.noop(); - } - } - } - return meterProvider; + return globalMeterProvider; } /** @@ -36,50 +24,7 @@ public final class GlobalMeterProvider { * early as possible in your application initialization logic, often in a {@code static} block in * your main class. */ - public static void set(MeterProvider meterProvider) { - globalMeterProvider.set(meterProvider); - } - - /** - * Gets or creates a named meter instance from the globally registered {@link MeterProvider}. - * - *

This is a shortcut method for {@code getGlobalMeterProvider().get(instrumentationName)} - * - * @param instrumentationName The name of the instrumentation library, not the name of the - * instrument*ed* library. - * @return a tracer instance. - */ - public static Meter getMeter(String instrumentationName) { - return get().get(instrumentationName); - } - - /** - * Gets or creates a named and versioned meter instance from the globally registered {@link - * MeterProvider}. - * - *

This is a shortcut method for {@code getGlobalMeterProvider().get(instrumentationName, - * instrumentationVersion)} - * - * @param instrumentationName The name of the instrumentation library, not the name of the - * instrument*ed* library. - * @param instrumentationVersion The version of the instrumentation library. - * @return a tracer instance. - */ - public static Meter getMeter(String instrumentationName, String instrumentationVersion) { - return get().get(instrumentationName, instrumentationVersion); - } - - /** - * Creates a {@link MeterBuilder} for a named meter instance. - * - *

This is a shortcut method for {@code get().meterBuilder(instrumentationName)} - * - * @param instrumentationName The name of the instrumentation library, not the name of the - * instrument*ed* library. - * @return a MeterBuilder instance. - * @since 1.4.0 - */ - public static MeterBuilder meterBuilder(String instrumentationName) { - return get().meterBuilder(instrumentationName); + public static void set(MeterProvider provider) { + globalMeterProvider = (provider == null) ? NoopMeterProvider.getInstance() : provider; } } diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/Instrument.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/Instrument.java deleted file mode 100644 index d9e6228fe8..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/Instrument.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import javax.annotation.concurrent.ThreadSafe; - -/** Base interface for all metrics defined in this package. */ -@ThreadSafe -@SuppressWarnings("InterfaceWithOnlyStatics") -public interface Instrument {} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/InstrumentBuilder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/InstrumentBuilder.java deleted file mode 100644 index ef146ed4df..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/InstrumentBuilder.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -/** The {@code Builder} class for the {@code Instrument}. */ -public interface InstrumentBuilder { - /** - * Sets the description of the {@code Instrument}. - * - *

Default value is {@code ""}. - * - * @param description the description of the Instrument. - * @return this. - */ - InstrumentBuilder setDescription(String description); - - /** - * Sets the unit of the {@code Instrument}. - * - *

Default value is {@code "1"}. - * - * @param unit the unit of the Instrument. - * @return this. - */ - InstrumentBuilder setUnit(String unit); - - /** - * Builds and returns a {@code Instrument} with the desired options. - * - * @return a {@code Instrument} with the desired options. - */ - Instrument build(); -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongCounter.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongCounter.java index 3cf662c387..6fdbd2c479 100644 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongCounter.java +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongCounter.java @@ -5,59 +5,47 @@ package io.opentelemetry.api.metrics; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.context.Context; import javax.annotation.concurrent.ThreadSafe; -/** - * Counter is the most common synchronous instrument. This instrument supports an {@link #add(long, - * Labels)}` function for reporting an increment, and is restricted to non-negative increments. The - * default aggregation is `Sum`. - * - *

Example: - * - *

{@code
- * class YourClass {
- *   private static final Meter meter = OpenTelemetry.getMeterProvider().get("my_library_name");
- *   private static final LongCounter counter =
- *       meter.
- *           .longCounterBuilder("processed_jobs")
- *           .setDescription("Processed jobs")
- *           .setUnit("1")
- *           .build();
- *
- *   // It is recommended that the API user keep a reference to a Bound Counter.
- *   private static final BoundLongCounter someWorkBound =
- *       counter.bind("work_name", "some_work");
- *
- *   void doSomeWork() {
- *      // Your code here.
- *      someWorkBound.add(10);
- *   }
- * }
- * }
- */ +/** A counter instrument that records {@code long} values. */ @ThreadSafe -public interface LongCounter extends SynchronousInstrument { +public interface LongCounter { /** - * Adds the given {@code increment} to the current value. The values cannot be negative. + * Records a value. * - *

The value added is associated with the current {@code Context} and provided set of labels. + *

Note: This may use {@code Context.current()} to pull the context associated with this + * measurement. * - * @param increment the value to add. - * @param labels the set of labels to be associated to this recording. + * @param value The increment amount. MUST be non-negative. */ - void add(long increment, Labels labels); + void add(long value); /** - * Adds the given {@code increment} to the current value. The values cannot be negative. + * Records a value with a set of attributes. * - *

The value added is associated with the current {@code Context} and empty labels. + *

Note: This may use {@code Context.current()} to pull the context associated with this + * measurement. * - * @param increment the value to add. + * @param value The increment amount. MUST be non-negative. + * @param attributes A set of attributes to associate with the count. */ - void add(long increment); + void add(long value, Attributes attributes); - @Override - BoundLongCounter bind(Labels labels); + /** + * Records a value with a set of attributes. + * + * @param value The increment amount. MUST be non-negative. + * @param attributes A set of attributes to associate with the count. + * @param context The explicit context to associate with this measurement. + */ + void add(long value, Attributes attributes, Context context); + + /** + * Constructs a bound version of this instrument where all recorded values use the given + * attributes. + */ + BoundLongCounter bind(Attributes attributes); } diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongCounterBuilder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongCounterBuilder.java index fd0811b43c..0361517dbf 100644 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongCounterBuilder.java +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongCounterBuilder.java @@ -5,14 +5,43 @@ package io.opentelemetry.api.metrics; +import java.util.function.Consumer; + /** Builder class for {@link LongCounter}. */ -public interface LongCounterBuilder extends SynchronousInstrumentBuilder { - @Override +public interface LongCounterBuilder { + + /** + * Sets the description for this instrument. + * + *

Description strings should follow the instrument description rules: + * https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-description + */ LongCounterBuilder setDescription(String description); - @Override + /** + * Sets the unit of measure for this instrument. + * + *

Unit strings should follow the instrument unit rules: + * https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-unit + */ LongCounterBuilder setUnit(String unit); - @Override + /** Sets the counter for recording {@code double} values. */ + DoubleCounterBuilder ofDoubles(); + + /** + * Builds and returns a {@code LongCounter} with the desired options. + * + * @return a {@code LongCounter} with the desired options. + */ LongCounter build(); + + /** + * Builds this asynchronous instrument with the given callback. + * + *

The callback will only be called when the {@link Meter} is being observed. + * + * @param callback A state-capturing callback used to observe values on-demand. + */ + void buildWithCallback(Consumer callback); } diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongGaugeBuilder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongGaugeBuilder.java new file mode 100644 index 0000000000..bbac5c5da3 --- /dev/null +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongGaugeBuilder.java @@ -0,0 +1,39 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.metrics; + +import java.util.function.Consumer; + +/** A builder for Gauge metric types. These can only be asynchronously collected. */ +public interface LongGaugeBuilder { + /** + * Sets the description for this instrument. + * + *

Description strings should follow the instrument description rules: + * https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-description + */ + public LongGaugeBuilder setDescription(String description); + + /** + * Sets the unit of measure for this instrument. + * + *

Unit strings should follow the instrument unit rules: + * https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-unit + */ + LongGaugeBuilder setUnit(String unit); + + /** Sets the gauge for recording {@code double} values. */ + DoubleGaugeBuilder ofDoubles(); + + /** + * Builds this asynchronous insturment with the given callback. + * + *

The callback will only be called when the {@link Meter} is being observed. + * + * @param callback A state-capturing callback used to observe values on-demand. + */ + void buildWithCallback(Consumer callback); +} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongHistogram.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongHistogram.java new file mode 100644 index 0000000000..f074b1bf7b --- /dev/null +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongHistogram.java @@ -0,0 +1,51 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.metrics; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.context.Context; +import javax.annotation.concurrent.ThreadSafe; + +/** A histogram instrument that records {@code long} values. */ +@ThreadSafe +public interface LongHistogram { + + /** + * Records a value. + * + *

Note: This may use {@code Context.current()} to pull the context associated with this + * measurement. + * + * @param value The amount of the measurement. + */ + void record(long value); + + /** + * Records a value with a set of attributes. + * + *

Note: This may use {@code Context.current()} to pull the context associated with this + * measurement. + * + * @param value The amount of the measurement. + * @param attributes A set of attributes to associate with the count. + */ + void record(long value, Attributes attributes); + + /** + * Records a value with a set of attributes. + * + * @param value The amount of the measurement. + * @param attributes A set of attributes to associate with the count. + * @param context The explicit context to associate with this measurement. + */ + void record(long value, Attributes attributes, Context context); + + /** + * Construct a bound version of this instrument where all recorded values use the given + * attributes. + */ + BoundLongHistogram bind(Attributes attributes); +} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongHistogramBuilder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongHistogramBuilder.java new file mode 100644 index 0000000000..669f9a7cf8 --- /dev/null +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongHistogramBuilder.java @@ -0,0 +1,35 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.metrics; + +/** Builder class for {@link LongHistogram}. */ +public interface LongHistogramBuilder { + /** + * Sets the description for this instrument. + * + *

Description strings should follow the instrument description rules: + * https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-description + */ + LongHistogramBuilder setDescription(String description); + + /** + * Sets the unit of measure for this instrument. + * + *

Unit strings should follow the instrument unit rules: + * https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-unit + */ + LongHistogramBuilder setUnit(String unit); + + /** Sets the histogram for recording {@code double} values. */ + DoubleHistogramBuilder ofDoubles(); + + /** + * Builds and returns a {@code LongHistogram} with the desired options. + * + * @return a {@code LongHistogram} with the desired options. + */ + LongHistogram build(); +} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongSumObserver.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongSumObserver.java deleted file mode 100644 index 11af6f5ed2..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongSumObserver.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import javax.annotation.concurrent.ThreadSafe; - -/** - * {@code SumObserver} is the asynchronous instrument corresponding to Counter, used to capture a - * monotonic sum with Observe(sum). - * - *

"Sum" appears in the name to remind that it is used to capture sums directly. Use a - * SumObserver to capture any value that starts at zero and rises throughout the process lifetime - * and never falls. - * - *

A {@code SumObserver} is a good choice in situations where a measurement is expensive to - * compute, such that it would be wasteful to compute on every request. - * - *

Example: - * - *

{@code
- * // class YourClass {
- * //
- * //   private static final Meter meter = OpenTelemetry.getMeterProvider().get("my_library_name");
- * //   private static final LongSumObserver cpuObserver =
- * //       meter.
- * //           .longSumObserverBuilder("cpu_time")
- * //           .setDescription("System CPU usage")
- * //           .setUnit("ms")
- * //           .build();
- * //
- * //   void init() {
- * //     cpuObserver.setUpdater(
- * //         new LongSumObserver.Callback() {
- * //          @Override
- * //           public void update(LongResult result) {
- * //             // Get system cpu usage
- * //             result.observe(cpuIdle, "state", "idle");
- * //             result.observe(cpuUser, "state", "user");
- * //           }
- * //         });
- * //   }
- * // }
- * }
- */ -@ThreadSafe -public interface LongSumObserver extends AsynchronousInstrument {} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongSumObserverBuilder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongSumObserverBuilder.java deleted file mode 100644 index 0d80e50cf6..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongSumObserverBuilder.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import java.util.function.Consumer; - -/** Builder class for {@link LongSumObserver}. */ -public interface LongSumObserverBuilder - extends AsynchronousInstrumentBuilder { - @Override - LongSumObserverBuilder setDescription(String description); - - @Override - LongSumObserverBuilder setUnit(String unit); - - @Override - LongSumObserverBuilder setUpdater(Consumer updater); - - @Override - LongSumObserver build(); -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongUpDownCounter.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongUpDownCounter.java index 2789e26bc9..2867963598 100644 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongUpDownCounter.java +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongUpDownCounter.java @@ -5,62 +5,46 @@ package io.opentelemetry.api.metrics; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.context.Context; import javax.annotation.concurrent.ThreadSafe; -/** - * UpDownCounter is a synchronous instrument and very similar to Counter except that Add(increment) - * supports negative increments. This makes UpDownCounter not useful for computing a rate - * aggregation. The default aggregation is `Sum`, only the sum is non-monotonic. It is generally - * useful for capturing changes in an amount of resources used, or any quantity that rises and falls - * during a request. - * - *

Example: - * - *

{@code
- * class YourClass {
- *   private static final Meter meter = OpenTelemetry.getMeterProvider().get("my_library_name");
- *   private static final LongUpDownCounter upDownCounter =
- *       meter.
- *           .longUpDownCounterBuilder("active_tasks")
- *           .setDescription("Number of active tasks")
- *           .setUnit("1")
- *           .build();
- *
- *   // It is recommended that the API user keep a reference to a Bound Counter.
- *   private static final BoundLongUpDownCounter someWorkBound =
- *       upDownCounter.bind("work_name", "some_work");
- *
- *   void doSomeWork() {
- *      someWorkBound.add(1);
- *      // Your code here.
- *      someWorkBound.add(-1);
- *   }
- * }
- * }
- */ +/** An up-down-counter instrument that records {@code long} values. */ @ThreadSafe -public interface LongUpDownCounter extends SynchronousInstrument { +public interface LongUpDownCounter { + /** + * Records a value. + * + *

Note: This may use {@code Context.current()} to pull the context associated with this + * measurement. + * + * @param value The increment amount. May be positive, negative or zero. + */ + void add(long value); /** - * Adds the given {@code increment} to the current value. + * Record a value with a set of attributes. * - *

The value added is associated with the current {@code Context} and provided set of labels. + *

Note: This may use {@code Context.current()} to pull the context associated with this + * measurement. * - * @param increment the value to add. - * @param labels the set of labels to be associated to this recording. + * @param value The increment amount. May be positive, negative or zero. + * @param attributes A set of attributes to associate with the count. */ - void add(long increment, Labels labels); + void add(long value, Attributes attributes); /** - * Adds the given {@code increment} to the current value. + * Records a value with a set of attributes. * - *

The value added is associated with the current {@code Context} and empty labels. - * - * @param increment the value to add. + * @param value The increment amount. May be positive, negative or zero. + * @param attributes A set of attributes to associate with the count. + * @param context The explicit context to associate with this measurement. */ - void add(long increment); + void add(long value, Attributes attributes, Context context); - @Override - BoundLongUpDownCounter bind(Labels labels); + /** + * Construct a bound version of this instrument where all recorded values use the given + * attributes. + */ + BoundLongUpDownCounter bind(Attributes attributes); } diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongUpDownCounterBuilder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongUpDownCounterBuilder.java index 94c203099a..ba17ea2686 100644 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongUpDownCounterBuilder.java +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongUpDownCounterBuilder.java @@ -5,14 +5,42 @@ package io.opentelemetry.api.metrics; +import java.util.function.Consumer; + /** Builder class for {@link LongUpDownCounter}. */ -public interface LongUpDownCounterBuilder extends SynchronousInstrumentBuilder { - @Override +public interface LongUpDownCounterBuilder { + /** + * Sets the description for this instrument. + * + *

Description strings should follow the instrument description rules: + * https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-description + */ LongUpDownCounterBuilder setDescription(String description); - @Override + /** + * Sets the unit of measure for this instrument. + * + *

Unit strings should follow the instrument unit rules: + * https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-unit + */ LongUpDownCounterBuilder setUnit(String unit); - @Override + /** Sets the counter for recording {@code double} values. */ + DoubleUpDownCounterBuilder ofDoubles(); + + /** + * Builds and returns a {@code LongUpDownCounter} with the desired options. + * + * @return a {@code LongUpDownCounter} with the desired options. + */ LongUpDownCounter build(); + + /** + * Builds this asynchronous instrument with the given callback. + * + *

The callback will only be called when the {@link Meter} is being observed. + * + * @param callback A state-capturing callback used to observe values on-demand. + */ + void buildWithCallback(Consumer callback); } diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongUpDownSumObserver.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongUpDownSumObserver.java deleted file mode 100644 index 57828ce687..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongUpDownSumObserver.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import javax.annotation.concurrent.ThreadSafe; - -/** - * UpDownSumObserver is the asynchronous instrument corresponding to UpDownCounter, used to capture - * a non-monotonic count with Observe(sum). - * - *

"Sum" appears in the name to remind that it is used to capture sums directly. Use a - * UpDownSumObserver to capture any value that starts at zero and rises or falls throughout the - * process lifetime. - * - *

A {@code UpDownSumObserver} is a good choice in situations where a measurement is expensive to - * compute, such that it would be wasteful to compute on every request. - * - *

Example: - * - *

{@code
- * // class YourClass {
- * //
- * //   private static final Meter meter = OpenTelemetry.getMeterProvider().get("my_library_name");
- * //   private static final LongUpDownSumObserver memoryObserver =
- * //       meter.
- * //           .longUpDownSumObserverBuilder("memory_usage")
- * //           .setDescription("System memory usage")
- * //           .setUnit("by")
- * //           .build();
- * //
- * //   void init() {
- * //     memoryObserver.setUpdater(
- * //         new LongUpDownSumObserver.Callback() {
- * //          @Override
- * //           public void update(LongResult result) {
- * //             // Get system memory usage
- * //             result.observe(memoryUsed, "state", "used");
- * //             result.observe(memoryFree, "state", "free");
- * //           }
- * //         });
- * //   }
- * // }
- * }
- */ -@ThreadSafe -public interface LongUpDownSumObserver extends AsynchronousInstrument {} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongUpDownSumObserverBuilder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongUpDownSumObserverBuilder.java deleted file mode 100644 index 547f07e159..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongUpDownSumObserverBuilder.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import java.util.function.Consumer; - -/** Builder class for {@link LongUpDownSumObserver}. */ -public interface LongUpDownSumObserverBuilder - extends AsynchronousInstrumentBuilder { - @Override - LongUpDownSumObserverBuilder setDescription(String description); - - @Override - LongUpDownSumObserverBuilder setUnit(String unit); - - @Override - LongUpDownSumObserverBuilder setUpdater(Consumer updater); - - @Override - LongUpDownSumObserver build(); -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongValueObserver.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongValueObserver.java deleted file mode 100644 index 035dac16db..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongValueObserver.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import javax.annotation.concurrent.ThreadSafe; - -/** - * {@code ValueObserver} is the asynchronous instrument corresponding to ValueRecorder, used to - * capture values that are treated as individual observations, recorded with the observe(value) - * method. - * - *

A {@code ValueObserver} is a good choice in situations where a measurement is expensive to - * compute, such that it would be wasteful to compute on every request. - * - *

Example: - * - *

{@code
- * // class YourClass {
- * //
- * //   private static final Meter meter = OpenTelemetry.getMeterProvider().get("my_library_name");
- * //   private static final LongValueObserver cpuObserver =
- * //       meter.
- * //           .longValueObserverBuilder("cpu_fan_speed")
- * //           .setDescription("System CPU fan speed")
- * //           .setUnit("ms")
- * //           .build();
- * //
- * //   void init() {
- * //     cpuObserver.setUpdater(
- * //         new LongValueObserver.Callback() {
- * //          @Override
- * //           public void update(LongResult result) {
- * //             // Get system cpu fan speed
- * //             result.observe(cpuFanSpeed);
- * //           }
- * //         });
- * //   }
- * // }
- * }
- */ -@ThreadSafe -public interface LongValueObserver extends AsynchronousInstrument {} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongValueObserverBuilder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongValueObserverBuilder.java deleted file mode 100644 index 2757bea6c9..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongValueObserverBuilder.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import java.util.function.Consumer; - -/** Builder class for {@link LongValueObserver}. */ -public interface LongValueObserverBuilder - extends AsynchronousInstrumentBuilder { - @Override - LongValueObserverBuilder setDescription(String description); - - @Override - LongValueObserverBuilder setUnit(String unit); - - @Override - LongValueObserverBuilder setUpdater(Consumer updater); - - @Override - LongValueObserver build(); -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongValueRecorder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongValueRecorder.java deleted file mode 100644 index 9ddf39c300..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongValueRecorder.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import io.opentelemetry.api.metrics.common.Labels; -import javax.annotation.concurrent.ThreadSafe; - -/** - * ValueRecorder is a synchronous instrument useful for recording any number, positive or negative. - * Values captured by a Record(value) are treated as individual events belonging to a distribution - * that is being summarized. - * - *

ValueRecorder should be chosen either when capturing measurements that do not contribute - * meaningfully to a sum, or when capturing numbers that are additive in nature, but where the - * distribution of individual increments is considered interesting. - * - *

One of the most common uses for ValueRecorder is to capture latency measurements. Latency - * measurements are not additive in the sense that there is little need to know the latency-sum of - * all processed requests. We use a ValueRecorder instrument to capture latency measurements - * typically because we are interested in knowing mean, median, and other summary statistics about - * individual events. - * - *

Example: - * - *

{@code
- * class YourClass {
- *
- *   private static final Meter meter = OpenTelemetry.getMeterProvider().get("my_library_name");
- *   private static final LongValueRecorder valueRecorder =
- *       meter.
- *           .longValueRecorderBuilder("doWork_latency")
- *           .setDescription("gRPC Latency")
- *           .setUnit("ns")
- *           .build();
- *
- *   // It is recommended that the API user keep a reference to a Bound Counter.
- *   private static final BoundLongValueRecorder someWorkBound =
- *       valueRecorder.bind("work_name", "some_work");
- *
- *   void doWork() {
- *      long startTime = System.nanoTime();
- *      // Your code here.
- *      someWorkBound.record(System.nanoTime() - startTime);
- *   }
- * }
- * }
- */ -@ThreadSafe -public interface LongValueRecorder extends SynchronousInstrument { - - /** - * Records the given measurement, associated with the current {@code Context} and provided set of - * labels. - * - * @param value the measurement to record. - * @param labels the set of labels to be associated to this recording - * @throws IllegalArgumentException if value is negative. - */ - void record(long value, Labels labels); - - /** - * Records the given measurement, associated with the current {@code Context} and empty labels. - * - * @param value the measurement to record. - * @throws IllegalArgumentException if value is negative. - */ - void record(long value); - - @Override - BoundLongValueRecorder bind(Labels labels); -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongValueRecorderBuilder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongValueRecorderBuilder.java deleted file mode 100644 index 05bbc94af2..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/LongValueRecorderBuilder.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -/** Builder class for {@link LongValueRecorder}. */ -public interface LongValueRecorderBuilder extends SynchronousInstrumentBuilder { - @Override - LongValueRecorderBuilder setDescription(String description); - - @Override - LongValueRecorderBuilder setUnit(String unit); - - @Override - LongValueRecorder build(); -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/Meter.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/Meter.java index 96a81e2e05..681a82ed76 100644 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/Meter.java +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/Meter.java @@ -8,174 +8,53 @@ package io.opentelemetry.api.metrics; import javax.annotation.concurrent.ThreadSafe; /** - * Meter is a simple, interface that allows users to record measurements (metrics). + * Provides instruments used to produce metrics. * - *

There are two ways to record measurements: + *

Instruments are obtained through builders provided by this interface. Each builder has a + * default "type" associated with recordings that may be changed. * - *

    - *
  • Record raw measurements, and defer defining the aggregation and the labels for the exported - * Instrument. This should be used in libraries like gRPC to record measurements like - * "server_latency" or "received_bytes". - *
  • Record pre-defined aggregation data (or already aggregated data). This should be used to - * report cpu/memory usage, or simple metrics like "queue_length". - *
- * - *

TODO: Update comment. + *

A Meter is generally associated with an instrumentation library, e.g. "I monitor apache + * httpclient". */ @ThreadSafe public interface Meter { + /** + * Constructs a counter instrument. + * + *

This is used to build both synchronous (in-context) instruments and asynchronous (callback) + * instruments. + * + * @param name the name used for the counter. + * @return a builder for configuring a new Counter instrument. Defaults to recording long values, + * but may be changed. + */ + LongCounterBuilder counterBuilder(String name); /** - * Returns a builder for a {@link DoubleCounter}. + * Constructs an up-down-counter instrument. * - * @param name the name of the instrument. Should be a ASCII string with a length no greater than - * 255 characters. - * @return a {@code DoubleCounter.Builder}. - * @throws NullPointerException if {@code name} is null. - * @throws IllegalArgumentException if different metric with the same name already registered. - * @throws IllegalArgumentException if the {@code name} does not match the requirements. + *

This is used to build both synchronous (in-context) instruments and asynchronous (callback) + * instruments. + * + * @param name the name used for the counter. + * @return a builder for configuring a new Counter synchronous instrument. Defaults to recording + * long values, but may be changed. */ - DoubleCounterBuilder doubleCounterBuilder(String name); + LongUpDownCounterBuilder upDownCounterBuilder(String name); /** - * Returns a builder for a {@link LongCounter}. + * Constructs a Histogram instrument. * - * @param name the name of the instrument. Should be a ASCII string with a length no greater than - * 255 characters. - * @return a {@code LongCounter.Builder}. - * @throws NullPointerException if {@code name} is null. - * @throws IllegalArgumentException if different metric with the same name already registered. - * @throws IllegalArgumentException if the {@code name} does not match the requirements. + * @param name the name used for the counter. + * @return a builder for configuring a new Histogram synchronous instrument. Defaults to recording + * double values, but may be changed. */ - LongCounterBuilder longCounterBuilder(String name); + DoubleHistogramBuilder histogramBuilder(String name); /** - * Returns a builder for a {@link DoubleUpDownCounter}. + * Constructs an asynchronous gauge. * - * @param name the name of the instrument. Should be a ASCII string with a length no greater than - * 255 characters. - * @return a {@code DoubleCounter.Builder}. - * @throws NullPointerException if {@code name} is null. - * @throws IllegalArgumentException if different metric with the same name already registered. - * @throws IllegalArgumentException if the {@code name} does not match the requirements. + * @return a builder used for configuring how to report gauge measurements on demand. */ - DoubleUpDownCounterBuilder doubleUpDownCounterBuilder(String name); - - /** - * Returns a builder for a {@link LongUpDownCounter}. - * - * @param name the name of the instrument. Should be a ASCII string with a length no greater than - * 255 characters. - * @return a {@code LongCounter.Builder}. - * @throws NullPointerException if {@code name} is null. - * @throws IllegalArgumentException if different metric with the same name already registered. - * @throws IllegalArgumentException if the {@code name} does not match the requirements. - */ - LongUpDownCounterBuilder longUpDownCounterBuilder(String name); - - /** - * Returns a new builder for a {@link DoubleValueRecorder}. - * - * @param name the name of the instrument. Should be a ASCII string with a length no greater than - * 255 characters. - * @return a new builder for a {@code DoubleValueRecorder}. - * @throws NullPointerException if {@code name} is null. - * @throws IllegalArgumentException if different metric with the same name already registered. - * @throws IllegalArgumentException if the {@code name} does not match the requirements. - */ - DoubleValueRecorderBuilder doubleValueRecorderBuilder(String name); - - /** - * Returns a new builder for a {@link LongValueRecorder}. - * - * @param name the name of the instrument. Should be a ASCII string with a length no greater than - * 255 characters. - * @return a new builder for a {@code LongValueRecorder}. - * @throws NullPointerException if {@code name} is null. - * @throws IllegalArgumentException if different metric with the same name already registered. - * @throws IllegalArgumentException if the {@code name} does not match the requirements. - */ - LongValueRecorderBuilder longValueRecorderBuilder(String name); - - /** - * Returns a new builder for a {@link DoubleSumObserver}. - * - * @param name the name of the instrument. Should be a ASCII string with a length no greater than - * 255 characters. - * @return a new builder for a {@code DoubleSumObserver}. - * @throws NullPointerException if {@code name} is null. - * @throws IllegalArgumentException if different metric with the same name already registered. - * @throws IllegalArgumentException if the {@code name} does not match the requirements. - */ - DoubleSumObserverBuilder doubleSumObserverBuilder(String name); - - /** - * Returns a new builder for a {@link LongSumObserver}. - * - * @param name the name of the instrument. Should be a ASCII string with a length no greater than - * 255 characters. - * @return a new builder for a {@code LongSumObserver}. - * @throws NullPointerException if {@code name} is null. - * @throws IllegalArgumentException if different metric with the same name already registered. - * @throws IllegalArgumentException if the {@code name} does not match the requirements. - */ - LongSumObserverBuilder longSumObserverBuilder(String name); - - /** - * Returns a new builder for a {@link DoubleUpDownSumObserver}. - * - * @param name the name of the instrument. Should be a ASCII string with a length no greater than - * 255 characters. - * @return a new builder for a {@code DoubleUpDownObserver}. - * @throws NullPointerException if {@code name} is null. - * @throws IllegalArgumentException if different metric with the same name already registered. - * @throws IllegalArgumentException if the {@code name} does not match the requirements. - */ - DoubleUpDownSumObserverBuilder doubleUpDownSumObserverBuilder(String name); - - /** - * Returns a new builder for a {@link LongUpDownSumObserver}. - * - * @param name the name of the instrument. Should be a ASCII string with a length no greater than - * 255 characters. - * @return a new builder for a {@code LongUpDownSumObserver}. - * @throws NullPointerException if {@code name} is null. - * @throws IllegalArgumentException if different metric with the same name already registered. - * @throws IllegalArgumentException if the {@code name} does not match the requirements. - */ - LongUpDownSumObserverBuilder longUpDownSumObserverBuilder(String name); - - /** - * Returns a new builder for a {@link DoubleValueObserver}. - * - * @param name the name of the instrument. Should be a ASCII string with a length no greater than - * 255 characters. - * @return a new builder for a {@code DoubleValueObserver}. - * @throws NullPointerException if {@code name} is null. - * @throws IllegalArgumentException if different metric with the same name already registered. - * @throws IllegalArgumentException if the {@code name} does not match the requirements. - */ - DoubleValueObserverBuilder doubleValueObserverBuilder(String name); - - /** - * Returns a new builder for a {@link LongValueObserver}. - * - * @param name the name of the instrument. Should be a ASCII string with a length no greater than - * 255 characters. - * @return a new builder for a {@code LongValueObserver}. - * @throws NullPointerException if {@code name} is null. - * @throws IllegalArgumentException if different metric with the same name already registered. - * @throws IllegalArgumentException if the {@code name} does not match the requirements. - */ - LongValueObserverBuilder longValueObserverBuilder(String name); - - /** - * Utility method that allows users to atomically record measurements to a set of Instruments with - * a common set of labels. - * - * @param keyValuePairs The set of labels to associate with this recorder and all it's recordings. - * @return a {@code MeasureBatchRecorder} that can be use to atomically record a set of - * measurements associated with different Measures. - */ - BatchRecorder newBatchRecorder(String... keyValuePairs); + DoubleGaugeBuilder gaugeBuilder(String name); } diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/MeterBuilder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/MeterBuilder.java index c84f36ce9d..680ddf2fc9 100644 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/MeterBuilder.java +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/MeterBuilder.java @@ -13,7 +13,7 @@ package io.opentelemetry.api.metrics; public interface MeterBuilder { /** - * Assign an OpenTelemetry schema URL to the resulting Meter. + * Assigns an OpenTelemetry schema URL to the resulting Meter. * * @param schemaUrl The URL of the OpenTelemetry schema being used by this instrumentation * library. @@ -22,7 +22,7 @@ public interface MeterBuilder { MeterBuilder setSchemaUrl(String schemaUrl); /** - * Assign a version to the instrumentation library that is using the resulting Meter. + * Assigns a version to the instrumentation library that is using the resulting Meter. * * @param instrumentationVersion The version of the instrumentation library. * @return this diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/MeterProvider.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/MeterProvider.java index d57d5a2225..4a708d76c6 100644 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/MeterProvider.java +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/MeterProvider.java @@ -5,33 +5,32 @@ package io.opentelemetry.api.metrics; +import io.opentelemetry.api.metrics.internal.NoopMeterProvider; import javax.annotation.concurrent.ThreadSafe; /** - * A registry for creating named {@link Meter}s. The name Provider is for consistency with - * other languages and it is NOT loaded using reflection. + * A registry for creating named {@link Meter}s. + * + *

A MeterProvider represents a configured (or noop) Metric collection system that can be used to + * instrument code. + * + *

The name Provider is for consistency with other languages and it is NOT loaded + * using reflection. * * @see io.opentelemetry.api.metrics.Meter */ @ThreadSafe public interface MeterProvider { - /** - * Returns a {@link MeterProvider} that only creates no-op {@link Instrument}s that neither record - * nor are emitted. - */ - static MeterProvider noop() { - return DefaultMeterProvider.getInstance(); - } - - /** - * Gets or creates a named meter instance. + * Gets or creates a named and versioned meter instance. * * @param instrumentationName The name of the instrumentation library, not the name of the * instrument*ed* library. - * @return a tracer instance. + * @return a meter instance. */ - Meter get(String instrumentationName); + default Meter get(String instrumentationName) { + return meterBuilder(instrumentationName).build(); + } /** * Gets or creates a named and versioned meter instance. @@ -39,9 +38,15 @@ public interface MeterProvider { * @param instrumentationName The name of the instrumentation library, not the name of the * instrument*ed* library. * @param instrumentationVersion The version of the instrumentation library. - * @return a tracer instance. + * @param schemaUrl Specifies the Schema URL that should be recorded in the emitted metrics. + * @return a meter instance. */ - Meter get(String instrumentationName, String instrumentationVersion); + default Meter get(String instrumentationName, String instrumentationVersion, String schemaUrl) { + return meterBuilder(instrumentationName) + .setInstrumentationVersion(instrumentationVersion) + .setSchemaUrl(schemaUrl) + .build(); + } /** * Creates a MeterBuilder for a named meter instance. @@ -51,7 +56,10 @@ public interface MeterProvider { * @return a MeterBuilder instance. * @since 1.4.0 */ - default MeterBuilder meterBuilder(String instrumentationName) { - return DefaultMeterBuilder.getInstance(); + MeterBuilder meterBuilder(String instrumentationName); + + /** Returns a MeterProvider that does nothing. */ + public static MeterProvider noop() { + return NoopMeterProvider.getInstance(); } } diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/ObservableDoubleMeasurement.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/ObservableDoubleMeasurement.java new file mode 100644 index 0000000000..9b821c0567 --- /dev/null +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/ObservableDoubleMeasurement.java @@ -0,0 +1,26 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.metrics; + +import io.opentelemetry.api.common.Attributes; + +/** An interface for observing measurements with {@code double} values. */ +public interface ObservableDoubleMeasurement extends ObservableMeasurement { + /** + * Records a measurement. + * + * @param value The measurement amount. MUST be non-negative. + */ + void observe(double value); + + /** + * Records a measurement with a set of attributes. + * + * @param value The measurement amount. MUST be non-negative. + * @param attributes A set of attributes to associate with the count. + */ + void observe(double value, Attributes attributes); +} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/ObservableLongMeasurement.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/ObservableLongMeasurement.java new file mode 100644 index 0000000000..87a5a57b9b --- /dev/null +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/ObservableLongMeasurement.java @@ -0,0 +1,26 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.metrics; + +import io.opentelemetry.api.common.Attributes; + +/** An interface for observing measurements with {@code long} values. */ +public interface ObservableLongMeasurement extends ObservableMeasurement { + /** + * Records a measurement. + * + * @param value The measurement amount. MUST be non-negative. + */ + void observe(long value); + + /** + * Records a measurement with a set of attributes. + * + * @param value The measurement amount. MUST be non-negative. + * @param attributes A set of attributes to associate with the count. + */ + void observe(long value, Attributes attributes); +} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/ObservableMeasurement.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/ObservableMeasurement.java new file mode 100644 index 0000000000..1a20132362 --- /dev/null +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/ObservableMeasurement.java @@ -0,0 +1,13 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.metrics; + +/** + * A mechanism for observing measurments. + * + *

see {@link ObservableDoubleMeasurement} or {@link ObservableLongMeasurement}. + */ +public interface ObservableMeasurement {} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/SynchronousInstrument.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/SynchronousInstrument.java deleted file mode 100644 index d68de6785d..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/SynchronousInstrument.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import io.opentelemetry.api.metrics.common.Labels; -import javax.annotation.concurrent.ThreadSafe; - -/** - * SynchronousInstrument is an interface that defines a type of instruments that are used to report - * measurements synchronously. That is, when the user reports individual measurements as they occur. - * - *

Synchronous instrument events additionally have a Context associated with them, describing - * properties of the associated trace and distributed correlation values. - * - * @param the specific type of Bound Instrument this instrument can provide. - */ -@ThreadSafe -public interface SynchronousInstrument extends Instrument { - /** - * Returns a {@code Bound Instrument} associated with the specified labels. Multiples requests - * with the same set of labels may return the same {@code Bound Instrument} instance. - * - *

It is recommended that callers keep a reference to the Bound Instrument instead of always - * calling this method for every operation. - * - * @param labels the set of labels, as key-value pairs. - * @return a {@code Bound Instrument} - * @throws NullPointerException if {@code labelValues} is null. - */ - B bind(Labels labels); -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/SynchronousInstrumentBuilder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/SynchronousInstrumentBuilder.java deleted file mode 100644 index 40961b7a66..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/SynchronousInstrumentBuilder.java +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -/** Builder class for {@link SynchronousInstrument}. */ -public interface SynchronousInstrumentBuilder extends InstrumentBuilder { - @Override - SynchronousInstrument build(); -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/common/ArrayBackedLabels.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/common/ArrayBackedLabels.java deleted file mode 100644 index 99ea6bba24..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/common/ArrayBackedLabels.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics.common; - -import io.opentelemetry.api.internal.ImmutableKeyValuePairs; -import javax.annotation.concurrent.Immutable; - -@Immutable -final class ArrayBackedLabels extends ImmutableKeyValuePairs implements Labels { - private static final Labels EMPTY = Labels.builder().build(); - - static Labels empty() { - return EMPTY; - } - - private ArrayBackedLabels(Object[] data) { - super(data); - } - - static Labels sortAndFilterToLabels(Object... data) { - return new ArrayBackedLabels(data); - } - - @Override - public LabelsBuilder toBuilder() { - return new ArrayBackedLabelsBuilder(data()); - } -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/common/ArrayBackedLabelsBuilder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/common/ArrayBackedLabelsBuilder.java deleted file mode 100644 index 44ca9aaf99..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/common/ArrayBackedLabelsBuilder.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics.common; - -import java.util.ArrayList; -import java.util.List; - -class ArrayBackedLabelsBuilder implements LabelsBuilder { - private final List data; - - ArrayBackedLabelsBuilder() { - data = new ArrayList<>(); - } - - ArrayBackedLabelsBuilder(List data) { - this.data = new ArrayList<>(data); - } - - @Override - public Labels build() { - return ArrayBackedLabels.sortAndFilterToLabels(data.toArray()); - } - - @Override - public LabelsBuilder put(String key, String value) { - data.add(key); - data.add(value); - return this; - } -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/common/Labels.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/common/Labels.java deleted file mode 100644 index 8821618ff2..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/common/Labels.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics.common; - -import static io.opentelemetry.api.metrics.common.ArrayBackedLabels.sortAndFilterToLabels; - -import java.util.Map; -import java.util.function.BiConsumer; -import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; - -/** - * An immutable container for labels, which are key-value pairs of {@link String}s. - * - *

Implementations of this interface *must* be immutable and have well-defined value-based - * equals/hashCode implementations. If an implementation does not strictly conform to these - * requirements, behavior of the OpenTelemetry APIs and default SDK cannot be guaranteed. - * - *

For this reason, it is strongly suggested that you use the implementation that is provided - * here via the factory methods and the {@link ArrayBackedLabelsBuilder}. - */ -@Immutable -public interface Labels { - - /** Returns a {@link Labels} instance with no attributes. */ - static Labels empty() { - return ArrayBackedLabels.empty(); - } - - /** Creates a new {@link LabelsBuilder} instance for creating arbitrary {@link Labels}. */ - static LabelsBuilder builder() { - return new ArrayBackedLabelsBuilder(); - } - - /** Returns a {@link Labels} instance with a single key-value pair. */ - static Labels of(String key, String value) { - return sortAndFilterToLabels(key, value); - } - - /** - * Returns a {@link Labels} instance with two key-value pairs. Order of the keys is not preserved. - * Duplicate keys will be removed. - */ - static Labels of(String key1, String value1, String key2, String value2) { - return sortAndFilterToLabels(key1, value1, key2, value2); - } - - /** - * Returns a {@link Labels} instance with three key-value pairs. Order of the keys is not - * preserved. Duplicate keys will be removed. - */ - static Labels of( - String key1, String value1, String key2, String value2, String key3, String value3) { - return sortAndFilterToLabels(key1, value1, key2, value2, key3, value3); - } - - /** - * Returns a {@link Labels} instance with four key-value pairs. Order of the keys is not - * preserved. Duplicate keys will be removed. - */ - static Labels of( - String key1, - String value1, - String key2, - String value2, - String key3, - String value3, - String key4, - String value4) { - return sortAndFilterToLabels(key1, value1, key2, value2, key3, value3, key4, value4); - } - - /** - * Returns a {@link Labels} instance with five key-value pairs. Order of the keys is not - * preserved. Duplicate keys will be removed. - */ - static Labels of( - String key1, - String value1, - String key2, - String value2, - String key3, - String value3, - String key4, - String value4, - String key5, - String value5) { - return sortAndFilterToLabels( - key1, value1, - key2, value2, - key3, value3, - key4, value4, - key5, value5); - } - - /** Returns a {@link Labels} instance with the provided {@code keyValueLabelPairs}. */ - static Labels of(String... keyValueLabelPairs) { - return sortAndFilterToLabels((Object[]) keyValueLabelPairs); - } - - /** Iterates over all the key-value pairs of labels contained by this instance. */ - void forEach(BiConsumer consumer); - - /** The number of key-value pairs of labels in this instance. */ - int size(); - - /** Returns the value for the given {@code key}, or {@code null} if the key is not present. */ - @Nullable - String get(String key); - - /** Returns whether this instance is empty (contains no labels). */ - boolean isEmpty(); - - /** Returns a read-only view of these {@link Labels} as a {@link Map}. */ - Map asMap(); - - /** Create a {@link LabelsBuilder} pre-populated with the contents of this Labels instance. */ - LabelsBuilder toBuilder(); -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/common/LabelsBuilder.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/common/LabelsBuilder.java deleted file mode 100644 index 99da0e85f0..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/common/LabelsBuilder.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics.common; - -/** A builder of {@link Labels} supporting an arbitrary number of key-value pairs. */ -public interface LabelsBuilder { - /** Create the {@link Labels} from this. */ - Labels build(); - - /** - * Puts a single label into this Builder. - * - * @return this Builder - */ - LabelsBuilder put(String key, String value); -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/internal/MetricsStringUtils.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/internal/MetricsStringUtils.java deleted file mode 100644 index c52c4bfff7..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/internal/MetricsStringUtils.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics.internal; - -import javax.annotation.concurrent.Immutable; - -/** Internal utility methods for working with attribute keys, attribute values, and metric names. */ -@Immutable -public final class MetricsStringUtils { - - public static final int METRIC_NAME_MAX_LENGTH = 255; - - /** - * Determines whether the metric name contains a valid metric name. - * - * @param metricName the metric name to be validated. - * @return whether the metricName contains a valid name. - */ - public static boolean isValidMetricName(String metricName) { - if (metricName.isEmpty() || metricName.length() > METRIC_NAME_MAX_LENGTH) { - return false; - } - String pattern = "[aA-zZ][aA-zZ0-9_\\-.]*"; - return metricName.matches(pattern); - } - - private MetricsStringUtils() {} -} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/internal/NoopMeter.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/internal/NoopMeter.java new file mode 100644 index 0000000000..f4b167d3de --- /dev/null +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/internal/NoopMeter.java @@ -0,0 +1,434 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.metrics.internal; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.BoundDoubleCounter; +import io.opentelemetry.api.metrics.BoundDoubleHistogram; +import io.opentelemetry.api.metrics.BoundDoubleUpDownCounter; +import io.opentelemetry.api.metrics.BoundLongCounter; +import io.opentelemetry.api.metrics.BoundLongHistogram; +import io.opentelemetry.api.metrics.BoundLongUpDownCounter; +import io.opentelemetry.api.metrics.DoubleCounter; +import io.opentelemetry.api.metrics.DoubleCounterBuilder; +import io.opentelemetry.api.metrics.DoubleGaugeBuilder; +import io.opentelemetry.api.metrics.DoubleHistogram; +import io.opentelemetry.api.metrics.DoubleHistogramBuilder; +import io.opentelemetry.api.metrics.DoubleUpDownCounter; +import io.opentelemetry.api.metrics.DoubleUpDownCounterBuilder; +import io.opentelemetry.api.metrics.LongCounter; +import io.opentelemetry.api.metrics.LongCounterBuilder; +import io.opentelemetry.api.metrics.LongGaugeBuilder; +import io.opentelemetry.api.metrics.LongHistogram; +import io.opentelemetry.api.metrics.LongHistogramBuilder; +import io.opentelemetry.api.metrics.LongUpDownCounter; +import io.opentelemetry.api.metrics.LongUpDownCounterBuilder; +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; +import io.opentelemetry.api.metrics.ObservableLongMeasurement; +import io.opentelemetry.context.Context; +import java.util.function.Consumer; +import javax.annotation.concurrent.ThreadSafe; + +/** + * No-op implementations of {@link Meter}. + * + *

This implementation should induce as close to zero overhead as possible. + * + *

A few notes from the specificaiton on allowed behaviors leading to this deasign [Instrument + * Spec]: + * + *

    + *
  • Multiple Insturments with the same name under the same Meter MUST return an error + *
  • Different Meters MUST be treated as separate namespaces + *
  • Implementations MUST NOT require users to repeatedly obtain a Meter again with the same + * name+version+schema_url to pick up configuration changes. This can be achieved either by + * allowing to work with an outdated configuration or by ensuring that new configuration + * applies also to previously returned Meters. + *
  • A MeterProvider could also return a no-op Meter here if application owners configure the + * SDK to suppress telemetry produced by this library + *
  • In case an invalid name (null or empty string) is specified, a working Meter implementation + * MUST be returned as a fallback rather than returning null or throwing an exception, + *
+ */ +@ThreadSafe +public class NoopMeter implements Meter { + + private static final NoopMeter INSTANCE = new NoopMeter(); + + public static Meter getInstance() { + return INSTANCE; + } + + @Override + public LongCounterBuilder counterBuilder(String name) { + return new NoopLongCounterBuilder(); + } + + @Override + public LongUpDownCounterBuilder upDownCounterBuilder(String name) { + return new NoopLongUpDownCounterBuilder(); + } + + @Override + public DoubleHistogramBuilder histogramBuilder(String name) { + return new NoopDoubleHistogramBuilder(); + } + + @Override + public DoubleGaugeBuilder gaugeBuilder(String name) { + return new NoopDoubleObservableInstrumentBuilder(); + } + + private NoopMeter() {} + + private static class NoopLongCounter implements LongCounter { + @Override + public void add(long value, Attributes attributes, Context context) {} + + @Override + public void add(long value, Attributes attributes) {} + + @Override + public void add(long value) {} + + @Override + public BoundLongCounter bind(Attributes attributes) { + return new NoopBoundLongCounter(); + } + } + + private static class NoopBoundLongCounter implements BoundLongCounter { + @Override + public void add(long value) {} + + @Override + public void add(long value, Context context) {} + + @Override + public void unbind() {} + } + + private static class NoopDoubleCounter implements DoubleCounter { + @Override + public void add(double value, Attributes attributes, Context context) {} + + @Override + public void add(double value, Attributes attributes) {} + + @Override + public void add(double value) {} + + @Override + public BoundDoubleCounter bind(Attributes attributes) { + return new NoopBoundDoubleCounter(); + } + } + + private static class NoopBoundDoubleCounter implements BoundDoubleCounter { + @Override + public void add(double value) {} + + @Override + public void add(double value, Context context) {} + + @Override + public void unbind() {} + } + + private static class NoopLongCounterBuilder implements LongCounterBuilder { + @Override + public LongCounterBuilder setDescription(String description) { + return this; + } + + @Override + public LongCounterBuilder setUnit(String unit) { + return this; + } + + @Override + public DoubleCounterBuilder ofDoubles() { + return new NoopDoubleCounterBuilder(); + } + + @Override + public LongCounter build() { + return new NoopLongCounter(); + } + + @Override + public void buildWithCallback(Consumer callback) {} + } + + private static class NoopDoubleCounterBuilder implements DoubleCounterBuilder { + @Override + public DoubleCounterBuilder setDescription(String description) { + return this; + } + + @Override + public DoubleCounterBuilder setUnit(String unit) { + return this; + } + + @Override + public LongCounterBuilder ofLongs() { + return new NoopLongCounterBuilder(); + } + + @Override + public DoubleCounter build() { + return new NoopDoubleCounter(); + } + + @Override + public void buildWithCallback(Consumer callback) {} + } + + private static class NoopLongUpDownCounter implements LongUpDownCounter { + @Override + public void add(long value, Attributes attributes, Context context) {} + + @Override + public void add(long value, Attributes attributes) {} + + @Override + public void add(long value) {} + + @Override + public BoundLongUpDownCounter bind(Attributes attributes) { + return new NoopBoundLongUpDownCounter(); + } + } + + private static class NoopBoundLongUpDownCounter implements BoundLongUpDownCounter { + @Override + public void add(long value, Context context) {} + + @Override + public void add(long value) {} + + @Override + public void unbind() {} + } + + private static class NoopDoubleUpDownCounter implements DoubleUpDownCounter { + @Override + public void add(double value, Attributes attributes, Context context) {} + + @Override + public void add(double value, Attributes attributes) {} + + @Override + public void add(double value) {} + + @Override + public BoundDoubleUpDownCounter bind(Attributes attributes) { + return new NoopBoundDoubleUpDownCounter(); + } + } + + private static class NoopBoundDoubleUpDownCounter implements BoundDoubleUpDownCounter { + @Override + public void add(double value, Context context) {} + + @Override + public void add(double value) {} + + @Override + public void unbind() {} + } + + private static class NoopLongUpDownCounterBuilder implements LongUpDownCounterBuilder { + @Override + public LongUpDownCounterBuilder setDescription(String description) { + return this; + } + + @Override + public LongUpDownCounterBuilder setUnit(String unit) { + return this; + } + + @Override + public DoubleUpDownCounterBuilder ofDoubles() { + return new NoopDoubleUpDownCounterBuilder(); + } + + @Override + public LongUpDownCounter build() { + return new NoopLongUpDownCounter(); + } + + @Override + public void buildWithCallback(Consumer callback) {} + } + + private static class NoopDoubleUpDownCounterBuilder implements DoubleUpDownCounterBuilder { + @Override + public DoubleUpDownCounterBuilder setDescription(String description) { + return this; + } + + @Override + public DoubleUpDownCounterBuilder setUnit(String unit) { + return this; + } + + @Override + public LongUpDownCounterBuilder ofLongs() { + return new NoopLongUpDownCounterBuilder(); + } + + @Override + public DoubleUpDownCounter build() { + return new NoopDoubleUpDownCounter(); + } + + @Override + public void buildWithCallback(Consumer callback) {} + } + + public static class NoopDoubleHistogram implements DoubleHistogram { + @Override + public void record(double value, Attributes attributes, Context context) {} + + @Override + public void record(double value, Attributes attributes) {} + + @Override + public void record(double value) {} + + @Override + public BoundDoubleHistogram bind(Attributes attributes) { + return new NoopBoundDoubleHistogram(); + } + } + + public static class NoopBoundDoubleHistogram implements BoundDoubleHistogram { + @Override + public void record(double value, Context context) {} + + @Override + public void record(double value) {} + + @Override + public void unbind() {} + } + + public static class NoopLongHistogram implements LongHistogram { + @Override + public void record(long value, Attributes attributes, Context context) {} + + @Override + public void record(long value, Attributes attributes) {} + + @Override + public void record(long value) {} + + @Override + public BoundLongHistogram bind(Attributes attributes) { + return new NoopBoundLongHistogram(); + } + } + + public static class NoopBoundLongHistogram implements BoundLongHistogram { + @Override + public void record(long value, Context context) {} + + @Override + public void record(long value) {} + + @Override + public void unbind() {} + } + + public static class NoopDoubleHistogramBuilder implements DoubleHistogramBuilder { + @Override + public DoubleHistogramBuilder setDescription(String description) { + return this; + } + + @Override + public DoubleHistogramBuilder setUnit(String unit) { + return this; + } + + @Override + public LongHistogramBuilder ofLongs() { + return new NoopLongHistogramBuilder(); + } + + @Override + public DoubleHistogram build() { + return new NoopDoubleHistogram(); + } + } + + public static class NoopLongHistogramBuilder implements LongHistogramBuilder { + @Override + public LongHistogramBuilder setDescription(String description) { + return this; + } + + @Override + public LongHistogramBuilder setUnit(String unit) { + return this; + } + + @Override + public DoubleHistogramBuilder ofDoubles() { + return new NoopDoubleHistogramBuilder(); + } + + @Override + public LongHistogram build() { + return new NoopLongHistogram(); + } + } + + public static class NoopDoubleObservableInstrumentBuilder implements DoubleGaugeBuilder { + @Override + public DoubleGaugeBuilder setDescription(String description) { + return this; + } + + @Override + public DoubleGaugeBuilder setUnit(String unit) { + return this; + } + + @Override + public LongGaugeBuilder ofLongs() { + return new NoopLongObservableInstrumentBuilder(); + } + + @Override + public void buildWithCallback(Consumer callback) {} + } + + public static class NoopLongObservableInstrumentBuilder implements LongGaugeBuilder { + @Override + public LongGaugeBuilder setDescription(String description) { + return this; + } + + @Override + public LongGaugeBuilder setUnit(String unit) { + return this; + } + + @Override + public DoubleGaugeBuilder ofDoubles() { + return new NoopDoubleObservableInstrumentBuilder(); + } + + @Override + public void buildWithCallback(Consumer callback) {} + } +} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/internal/NoopMeterProvider.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/internal/NoopMeterProvider.java new file mode 100644 index 0000000000..b28956ba64 --- /dev/null +++ b/api/metrics/src/main/java/io/opentelemetry/api/metrics/internal/NoopMeterProvider.java @@ -0,0 +1,45 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.metrics.internal; + +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.api.metrics.MeterBuilder; +import io.opentelemetry.api.metrics.MeterProvider; + +/** A {@link MeterProvider} that does nothing. */ +public class NoopMeterProvider implements MeterProvider { + @Override + public MeterBuilder meterBuilder(String instrumentationName) { + return BUILDER_INSTANCE; + } + + private static final NoopMeterProvider INSTANCE = new NoopMeterProvider(); + private static final MeterBuilder BUILDER_INSTANCE = new NoopMeterBuilder(); + + public static MeterProvider getInstance() { + return INSTANCE; + } + + private NoopMeterProvider() {} + + private static class NoopMeterBuilder implements MeterBuilder { + + @Override + public MeterBuilder setSchemaUrl(String schemaUrl) { + return this; + } + + @Override + public MeterBuilder setInstrumentationVersion(String instrumentationVersion) { + return this; + } + + @Override + public Meter build() { + return NoopMeter.getInstance(); + } + } +} diff --git a/api/metrics/src/main/java/io/opentelemetry/api/metrics/internal/package-info.java b/api/metrics/src/main/java/io/opentelemetry/api/metrics/internal/package-info.java deleted file mode 100644 index 8108f88863..0000000000 --- a/api/metrics/src/main/java/io/opentelemetry/api/metrics/internal/package-info.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * Interfaces and implementations that are internal to OpenTelemetry. - * - *

All the content under this package and its subpackages are considered not part of the public - * API, and must not be used by users of the OpenTelemetry library. - */ -@ParametersAreNonnullByDefault -package io.opentelemetry.api.metrics.internal; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/api/metrics/src/test/java/io/opentelemetry/api/metrics/BatchRecorderTest.java b/api/metrics/src/test/java/io/opentelemetry/api/metrics/BatchRecorderTest.java deleted file mode 100644 index 1819f8a478..0000000000 --- a/api/metrics/src/test/java/io/opentelemetry/api/metrics/BatchRecorderTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import org.junit.jupiter.api.Test; - -class BatchRecorderTest { - private static final Meter meter = DefaultMeter.getInstance(); - - @Test - void testNewBatchRecorder_WrongNumberOfLabels() { - assertThatThrownBy(() -> meter.newBatchRecorder("key")) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("key/value"); - } - - @Test - void testNewBatchRecorder_NullLabelKey() { - assertThatThrownBy(() -> meter.newBatchRecorder(null, "value")) - .isInstanceOf(NullPointerException.class) - .hasMessageContaining("null keys"); - } - - @Test - void preventNull_MeasureLong() { - assertThatThrownBy(() -> meter.newBatchRecorder().put((LongValueRecorder) null, 5L).record()) - .isInstanceOf(NullPointerException.class) - .hasMessage("valueRecorder"); - } - - @Test - void preventNull_MeasureDouble() { - assertThatThrownBy(() -> meter.newBatchRecorder().put((DoubleValueRecorder) null, 5L).record()) - .isInstanceOf(NullPointerException.class) - .hasMessage("valueRecorder"); - } - - @Test - void preventNull_LongCounter() { - assertThatThrownBy(() -> meter.newBatchRecorder().put((LongCounter) null, 5L).record()) - .isInstanceOf(NullPointerException.class) - .hasMessage("counter"); - } - - @Test - void preventNull_DoubleCounter() { - assertThatThrownBy(() -> meter.newBatchRecorder().put((DoubleCounter) null, 5L).record()) - .isInstanceOf(NullPointerException.class) - .hasMessage("counter"); - } - - @Test - void preventNull_LongUpDownCounter() { - assertThatThrownBy(() -> meter.newBatchRecorder().put((LongUpDownCounter) null, 5L).record()) - .isInstanceOf(NullPointerException.class) - .hasMessage("upDownCounter"); - } - - @Test - void preventNull_DoubleUpDownCounter() { - assertThatThrownBy(() -> meter.newBatchRecorder().put((DoubleUpDownCounter) null, 5L).record()) - .isInstanceOf(NullPointerException.class) - .hasMessage("upDownCounter"); - } - - @Test - void doesNotThrow() { - BatchRecorder batchRecorder = meter.newBatchRecorder(); - batchRecorder.put(meter.longValueRecorderBuilder("longValueRecorder").build(), 44L); - batchRecorder.put(meter.longValueRecorderBuilder("negativeLongValueRecorder").build(), -44L); - batchRecorder.put(meter.doubleValueRecorderBuilder("doubleValueRecorder").build(), 77.556d); - batchRecorder.put( - meter.doubleValueRecorderBuilder("negativeDoubleValueRecorder").build(), -77.556d); - batchRecorder.put(meter.longCounterBuilder("longCounter").build(), 44L); - batchRecorder.put(meter.doubleCounterBuilder("doubleCounter").build(), 77.556d); - batchRecorder.put(meter.longUpDownCounterBuilder("longUpDownCounter").build(), -44L); - batchRecorder.put(meter.doubleUpDownCounterBuilder("doubleUpDownCounter").build(), -77.556d); - batchRecorder.record(); - } - - @Test - void negativeValue_DoubleCounter() { - BatchRecorder batchRecorder = meter.newBatchRecorder(); - assertThatThrownBy( - () -> batchRecorder.put(meter.doubleCounterBuilder("doubleCounter").build(), -77.556d)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Counters can only increase"); - } - - @Test - void negativeValue_LongCounter() { - BatchRecorder batchRecorder = meter.newBatchRecorder(); - assertThatThrownBy( - () -> batchRecorder.put(meter.longCounterBuilder("longCounter").build(), -44L)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Counters can only increase"); - } -} diff --git a/api/metrics/src/test/java/io/opentelemetry/api/metrics/DefaultMeterTest.java b/api/metrics/src/test/java/io/opentelemetry/api/metrics/DefaultMeterTest.java deleted file mode 100644 index 2fb7a8bc4e..0000000000 --- a/api/metrics/src/test/java/io/opentelemetry/api/metrics/DefaultMeterTest.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.jupiter.api.Test; - -class DefaultMeterTest { - @Test - void expectDefaultMeter() { - assertThat(MeterProvider.noop().get("test")).isInstanceOf(DefaultMeter.class); - assertThat(MeterProvider.noop().get("test")).isSameAs(DefaultMeter.getInstance()); - assertThat(MeterProvider.noop().get("test", "0.1.0")).isSameAs(DefaultMeter.getInstance()); - assertThat( - MeterProvider.noop() - .meterBuilder("test") - .setInstrumentationVersion("0.1.0") - .setSchemaUrl("http://url") - .build()) - .isSameAs(DefaultMeter.getInstance()); - } -} diff --git a/api/metrics/src/test/java/io/opentelemetry/api/metrics/DoubleCounterTest.java b/api/metrics/src/test/java/io/opentelemetry/api/metrics/DoubleCounterTest.java deleted file mode 100644 index af197ab881..0000000000 --- a/api/metrics/src/test/java/io/opentelemetry/api/metrics/DoubleCounterTest.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import io.opentelemetry.api.metrics.common.Labels; -import io.opentelemetry.api.metrics.internal.MetricsStringUtils; -import java.util.Arrays; -import org.junit.jupiter.api.Test; - -class DoubleCounterTest { - - private static final String NAME = "name"; - private static final String DESCRIPTION = "description"; - private static final String UNIT = "1"; - private static final Meter meter = DefaultMeter.getInstance(); - - @Test - void preventNull_Name() { - assertThatThrownBy(() -> meter.doubleCounterBuilder(null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("name"); - } - - @Test - void preventEmpty_Name() { - assertThatThrownBy(() -> meter.doubleCounterBuilder("").build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventNonPrintableName() { - assertThatThrownBy(() -> meter.doubleCounterBuilder("\2").build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventTooLongName() { - char[] chars = new char[MetricsStringUtils.METRIC_NAME_MAX_LENGTH + 1]; - Arrays.fill(chars, 'a'); - String longName = String.valueOf(chars); - assertThatThrownBy(() -> meter.doubleCounterBuilder(longName).build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventNull_Description() { - assertThatThrownBy(() -> meter.doubleCounterBuilder("metric").setDescription(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("description"); - } - - @Test - void preventNull_Unit() { - assertThatThrownBy(() -> meter.doubleCounterBuilder("metric").setUnit(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("unit"); - } - - @Test - void add_preventNullLabels() { - assertThatThrownBy(() -> meter.doubleCounterBuilder("metric").build().add(1.0, null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("labels"); - } - - @Test - void add_DoesNotThrow() { - DoubleCounter doubleCounter = - meter.doubleCounterBuilder(NAME).setDescription(DESCRIPTION).setUnit(UNIT).build(); - doubleCounter.add(1.0, Labels.empty()); - doubleCounter.add(1.0); - } - - @Test - void add_PreventNegativeValue() { - DoubleCounter doubleCounter = - meter.doubleCounterBuilder(NAME).setDescription(DESCRIPTION).setUnit(UNIT).build(); - assertThatThrownBy(() -> doubleCounter.add(-1.0, Labels.empty())) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Counters can only increase"); - } - - @Test - void bound_PreventNullLabels() { - assertThatThrownBy(() -> meter.doubleCounterBuilder("metric").build().bind(null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("labels"); - } - - @Test - void bound_DoesNotThrow() { - DoubleCounter doubleCounter = - meter.doubleCounterBuilder(NAME).setDescription(DESCRIPTION).setUnit(UNIT).build(); - BoundDoubleCounter bound = doubleCounter.bind(Labels.empty()); - bound.add(1.0); - bound.unbind(); - } - - @Test - void bound_PreventNegativeValue() { - DoubleCounter doubleCounter = - meter.doubleCounterBuilder(NAME).setDescription(DESCRIPTION).setUnit(UNIT).build(); - BoundDoubleCounter bound = doubleCounter.bind(Labels.empty()); - try { - assertThatThrownBy(() -> bound.add(-1.0)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Counters can only increase"); - } finally { - bound.unbind(); - } - } -} diff --git a/api/metrics/src/test/java/io/opentelemetry/api/metrics/DoubleSumObserverTest.java b/api/metrics/src/test/java/io/opentelemetry/api/metrics/DoubleSumObserverTest.java deleted file mode 100644 index 1063c340e9..0000000000 --- a/api/metrics/src/test/java/io/opentelemetry/api/metrics/DoubleSumObserverTest.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import io.opentelemetry.api.metrics.internal.MetricsStringUtils; -import java.util.Arrays; -import org.junit.jupiter.api.Test; - -class DoubleSumObserverTest { - private static final String NAME = "name"; - private static final String DESCRIPTION = "description"; - private static final String UNIT = "1"; - private static final Meter meter = DefaultMeter.getInstance(); - - @Test - void preventNull_Name() { - assertThatThrownBy(() -> meter.doubleSumObserverBuilder(null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("name"); - } - - @Test - void preventEmpty_Name() { - assertThatThrownBy(() -> meter.doubleSumObserverBuilder("").build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventNonPrintableName() { - assertThatThrownBy(() -> meter.doubleSumObserverBuilder("\2").build()) - .isInstanceOf(IllegalArgumentException.class); - } - - @Test - void preventTooLongName() { - char[] chars = new char[MetricsStringUtils.METRIC_NAME_MAX_LENGTH + 1]; - Arrays.fill(chars, 'a'); - String longName = String.valueOf(chars); - assertThatThrownBy(() -> meter.doubleSumObserverBuilder(longName).build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventNull_Description() { - assertThatThrownBy(() -> meter.doubleSumObserverBuilder("metric").setDescription(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("description"); - } - - @Test - void preventNull_Unit() { - assertThatThrownBy(() -> meter.doubleSumObserverBuilder("metric").setUnit(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("unit"); - } - - @Test - void preventNull_Callback() { - assertThatThrownBy(() -> meter.doubleSumObserverBuilder("metric").setUpdater(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("callback"); - } - - @Test - void doesNotThrow() { - meter - .doubleSumObserverBuilder(NAME) - .setDescription(DESCRIPTION) - .setUnit(UNIT) - .setUpdater(result -> {}) - .build(); - } -} diff --git a/api/metrics/src/test/java/io/opentelemetry/api/metrics/DoubleUpDownCounterTest.java b/api/metrics/src/test/java/io/opentelemetry/api/metrics/DoubleUpDownCounterTest.java deleted file mode 100644 index 00b00ddf01..0000000000 --- a/api/metrics/src/test/java/io/opentelemetry/api/metrics/DoubleUpDownCounterTest.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import io.opentelemetry.api.metrics.common.Labels; -import io.opentelemetry.api.metrics.internal.MetricsStringUtils; -import java.util.Arrays; -import org.junit.jupiter.api.Test; - -class DoubleUpDownCounterTest { - - private static final String NAME = "name"; - private static final String DESCRIPTION = "description"; - private static final String UNIT = "1"; - private static final Meter meter = DefaultMeter.getInstance(); - - @Test - void preventNull_Name() { - assertThatThrownBy(() -> meter.doubleUpDownCounterBuilder(null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("name"); - } - - @Test - void preventEmpty_Name() { - assertThatThrownBy(() -> meter.doubleUpDownCounterBuilder("").build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventNonPrintableName() { - assertThatThrownBy(() -> meter.doubleUpDownCounterBuilder("\2").build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventTooLongName() { - char[] chars = new char[MetricsStringUtils.METRIC_NAME_MAX_LENGTH + 1]; - Arrays.fill(chars, 'a'); - String longName = String.valueOf(chars); - assertThatThrownBy(() -> meter.doubleUpDownCounterBuilder(longName).build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventNull_Description() { - assertThatThrownBy( - () -> meter.doubleUpDownCounterBuilder("metric").setDescription(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("description"); - } - - @Test - void preventNull_Unit() { - assertThatThrownBy(() -> meter.doubleUpDownCounterBuilder("metric").setUnit(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("unit"); - } - - @Test - void add_preventNullLabels() { - assertThatThrownBy(() -> meter.doubleUpDownCounterBuilder("metric").build().bind(null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("labels"); - } - - @Test - void add_DoesNotThrow() { - DoubleUpDownCounter doubleUpDownCounter = - meter.doubleUpDownCounterBuilder(NAME).setDescription(DESCRIPTION).setUnit(UNIT).build(); - doubleUpDownCounter.add(1.0, Labels.empty()); - doubleUpDownCounter.add(-1.0, Labels.empty()); - doubleUpDownCounter.add(1.0); - doubleUpDownCounter.add(-1.0); - } - - @Test - void bound_PreventNullLabels() { - assertThatThrownBy(() -> meter.doubleUpDownCounterBuilder("metric").build().bind(null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("labels"); - } - - @Test - void bound_DoesNotThrow() { - DoubleUpDownCounter doubleUpDownCounter = - meter.doubleUpDownCounterBuilder(NAME).setDescription(DESCRIPTION).setUnit(UNIT).build(); - BoundDoubleUpDownCounter bound = doubleUpDownCounter.bind(Labels.empty()); - bound.add(1.0); - bound.add(-1.0); - bound.unbind(); - } -} diff --git a/api/metrics/src/test/java/io/opentelemetry/api/metrics/DoubleUpDownSumObserverTest.java b/api/metrics/src/test/java/io/opentelemetry/api/metrics/DoubleUpDownSumObserverTest.java deleted file mode 100644 index d2d23a7207..0000000000 --- a/api/metrics/src/test/java/io/opentelemetry/api/metrics/DoubleUpDownSumObserverTest.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import io.opentelemetry.api.metrics.internal.MetricsStringUtils; -import java.util.Arrays; -import org.junit.jupiter.api.Test; - -class DoubleUpDownSumObserverTest { - - private static final String NAME = "name"; - private static final String DESCRIPTION = "description"; - private static final String UNIT = "1"; - private static final Meter meter = DefaultMeter.getInstance(); - - @Test - void preventNull_Name() { - assertThatThrownBy(() -> meter.doubleUpDownSumObserverBuilder(null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("name"); - } - - @Test - void preventEmpty_Name() { - assertThatThrownBy(() -> meter.doubleUpDownSumObserverBuilder("").build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventNonPrintableName() { - assertThatThrownBy(() -> meter.doubleUpDownSumObserverBuilder("\2").build()) - .isInstanceOf(IllegalArgumentException.class); - } - - @Test - void preventTooLongName() { - char[] chars = new char[MetricsStringUtils.METRIC_NAME_MAX_LENGTH + 1]; - Arrays.fill(chars, 'a'); - String longName = String.valueOf(chars); - assertThatThrownBy(() -> meter.doubleUpDownSumObserverBuilder(longName).build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventNull_Description() { - assertThatThrownBy( - () -> meter.doubleUpDownSumObserverBuilder("metric").setDescription(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("description"); - } - - @Test - void preventNull_Unit() { - assertThatThrownBy(() -> meter.doubleUpDownSumObserverBuilder("metric").setUnit(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("unit"); - } - - @Test - void preventNull_Callback() { - assertThatThrownBy( - () -> meter.doubleUpDownSumObserverBuilder("metric").setUpdater(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("callback"); - } - - @Test - void doesNotThrow() { - meter - .doubleUpDownSumObserverBuilder(NAME) - .setDescription(DESCRIPTION) - .setUnit(UNIT) - .setUpdater(result -> {}) - .build(); - } -} diff --git a/api/metrics/src/test/java/io/opentelemetry/api/metrics/DoubleValueObserverTest.java b/api/metrics/src/test/java/io/opentelemetry/api/metrics/DoubleValueObserverTest.java deleted file mode 100644 index c74a5db9d6..0000000000 --- a/api/metrics/src/test/java/io/opentelemetry/api/metrics/DoubleValueObserverTest.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import io.opentelemetry.api.metrics.internal.MetricsStringUtils; -import java.util.Arrays; -import org.junit.jupiter.api.Test; - -class DoubleValueObserverTest { - - private static final String NAME = "name"; - private static final String DESCRIPTION = "description"; - private static final String UNIT = "1"; - private static final Meter meter = DefaultMeter.getInstance(); - - @Test - void preventNull_Name() { - assertThatThrownBy(() -> meter.doubleValueObserverBuilder(null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("name"); - } - - @Test - void preventEmpty_Name() { - assertThatThrownBy(() -> meter.doubleValueObserverBuilder("").build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventNonPrintableName() { - assertThatThrownBy(() -> meter.doubleValueObserverBuilder("\2").build()) - .isInstanceOf(IllegalArgumentException.class); - } - - @Test - void preventTooLongName() { - char[] chars = new char[MetricsStringUtils.METRIC_NAME_MAX_LENGTH + 1]; - Arrays.fill(chars, 'a'); - String longName = String.valueOf(chars); - assertThatThrownBy(() -> meter.doubleValueObserverBuilder(longName).build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventNull_Description() { - assertThatThrownBy( - () -> meter.doubleValueObserverBuilder("metric").setDescription(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("description"); - } - - @Test - void preventNull_Unit() { - assertThatThrownBy(() -> meter.doubleValueObserverBuilder("metric").setUnit(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("unit"); - } - - @Test - void preventNull_Callback() { - assertThatThrownBy(() -> meter.doubleValueObserverBuilder("metric").setUpdater(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("callback"); - } - - @Test - void doesNotThrow() { - meter - .doubleValueObserverBuilder(NAME) - .setDescription(DESCRIPTION) - .setUnit(UNIT) - .setUpdater(result -> {}) - .build(); - } -} diff --git a/api/metrics/src/test/java/io/opentelemetry/api/metrics/DoubleValueRecorderTest.java b/api/metrics/src/test/java/io/opentelemetry/api/metrics/DoubleValueRecorderTest.java deleted file mode 100644 index 90b1aeeb71..0000000000 --- a/api/metrics/src/test/java/io/opentelemetry/api/metrics/DoubleValueRecorderTest.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import io.opentelemetry.api.metrics.common.Labels; -import io.opentelemetry.api.metrics.internal.MetricsStringUtils; -import java.util.Arrays; -import org.junit.jupiter.api.Test; - -class DoubleValueRecorderTest { - - private static final String NAME = "name"; - private static final String DESCRIPTION = "description"; - private static final String UNIT = "1"; - private static final Meter meter = DefaultMeter.getInstance(); - - @Test - void preventNull_Name() { - assertThatThrownBy(() -> meter.doubleValueRecorderBuilder(null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("name"); - } - - @Test - void preventEmpty_Name() { - assertThatThrownBy(() -> meter.doubleValueRecorderBuilder("").build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventNonPrintableName() { - assertThatThrownBy(() -> meter.doubleValueRecorderBuilder("\2").build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventTooLongName() { - char[] chars = new char[MetricsStringUtils.METRIC_NAME_MAX_LENGTH + 1]; - Arrays.fill(chars, 'a'); - String longName = String.valueOf(chars); - assertThatThrownBy(() -> meter.doubleValueRecorderBuilder(longName).build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventNull_Description() { - assertThatThrownBy( - () -> meter.doubleValueRecorderBuilder("metric").setDescription(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("description"); - } - - @Test - void preventNull_Unit() { - assertThatThrownBy(() -> meter.doubleValueRecorderBuilder("metric").setUnit(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("unit"); - } - - @Test - void record_PreventNullLabels() { - assertThatThrownBy(() -> meter.doubleValueRecorderBuilder("metric").build().record(1.0, null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("labels"); - } - - @Test - void record_DoesNotThrow() { - DoubleValueRecorder doubleValueRecorder = - meter.doubleValueRecorderBuilder(NAME).setDescription(DESCRIPTION).setUnit(UNIT).build(); - doubleValueRecorder.record(5.0, Labels.empty()); - doubleValueRecorder.record(-5.0, Labels.empty()); - doubleValueRecorder.record(5.0); - doubleValueRecorder.record(-5.0); - } - - @Test - void bound_PreventNullLabels() { - assertThatThrownBy(() -> meter.doubleValueRecorderBuilder("metric").build().bind(null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("labels"); - } - - @Test - void bound_DoesNotThrow() { - DoubleValueRecorder doubleValueRecorder = - meter.doubleValueRecorderBuilder(NAME).setDescription(DESCRIPTION).setUnit(UNIT).build(); - BoundDoubleValueRecorder bound = doubleValueRecorder.bind(Labels.empty()); - bound.record(5.0); - bound.record(-5.0); - bound.unbind(); - } -} diff --git a/api/metrics/src/test/java/io/opentelemetry/api/metrics/LongCounterTest.java b/api/metrics/src/test/java/io/opentelemetry/api/metrics/LongCounterTest.java deleted file mode 100644 index df151ce20e..0000000000 --- a/api/metrics/src/test/java/io/opentelemetry/api/metrics/LongCounterTest.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import io.opentelemetry.api.metrics.common.Labels; -import io.opentelemetry.api.metrics.internal.MetricsStringUtils; -import java.util.Arrays; -import org.junit.jupiter.api.Test; - -class LongCounterTest { - - private static final String NAME = "name"; - private static final String DESCRIPTION = "description"; - private static final String UNIT = "1"; - private static final Meter meter = DefaultMeter.getInstance(); - - @Test - void preventNull_Name() { - assertThatThrownBy(() -> meter.longCounterBuilder(null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("name"); - } - - @Test - void preventEmpty_Name() { - assertThatThrownBy(() -> meter.longCounterBuilder("").build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventNonPrintableName() { - assertThatThrownBy(() -> meter.longCounterBuilder("\2").build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventTooLongName() { - char[] chars = new char[MetricsStringUtils.METRIC_NAME_MAX_LENGTH + 1]; - Arrays.fill(chars, 'a'); - String longName = String.valueOf(chars); - assertThatThrownBy(() -> meter.longCounterBuilder(longName).build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventNull_Description() { - assertThatThrownBy(() -> meter.longCounterBuilder("metric").setDescription(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("description"); - } - - @Test - void preventNull_Unit() { - assertThatThrownBy(() -> meter.longCounterBuilder("metric").setUnit(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("unit"); - } - - @Test - void add_PreventNullLabels() { - assertThatThrownBy(() -> meter.longCounterBuilder("metric").build().add(1, null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("labels"); - } - - @Test - void add_DoesNotThrow() { - LongCounter longCounter = - meter.longCounterBuilder(NAME).setDescription(DESCRIPTION).setUnit(UNIT).build(); - longCounter.add(1, Labels.empty()); - longCounter.add(1); - } - - @Test - void add_PreventNegativeValue() { - LongCounter longCounter = - meter.longCounterBuilder(NAME).setDescription(DESCRIPTION).setUnit(UNIT).build(); - assertThatThrownBy(() -> longCounter.add(-1, Labels.empty())) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Counters can only increase"); - } - - @Test - void bound_PreventNullLabels() { - assertThatThrownBy(() -> meter.longCounterBuilder("metric").build().bind(null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("labels"); - } - - @Test - void bound_DoesNotThrow() { - LongCounter longCounter = - meter.longCounterBuilder(NAME).setDescription(DESCRIPTION).setUnit(UNIT).build(); - BoundLongCounter bound = longCounter.bind(Labels.empty()); - bound.add(1); - bound.unbind(); - } - - @Test - void bound_PreventNegativeValue() { - LongCounter longCounter = - meter.longCounterBuilder(NAME).setDescription(DESCRIPTION).setUnit(UNIT).build(); - BoundLongCounter bound = longCounter.bind(Labels.empty()); - try { - assertThatThrownBy(() -> bound.add(-1)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Counters can only increase"); - } finally { - bound.unbind(); - } - } -} diff --git a/api/metrics/src/test/java/io/opentelemetry/api/metrics/LongSumObserverTest.java b/api/metrics/src/test/java/io/opentelemetry/api/metrics/LongSumObserverTest.java deleted file mode 100644 index 2f48fcbc6c..0000000000 --- a/api/metrics/src/test/java/io/opentelemetry/api/metrics/LongSumObserverTest.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import io.opentelemetry.api.metrics.internal.MetricsStringUtils; -import java.util.Arrays; -import org.junit.jupiter.api.Test; - -class LongSumObserverTest { - - private static final String NAME = "name"; - private static final String DESCRIPTION = "description"; - private static final String UNIT = "1"; - private static final Meter meter = DefaultMeter.getInstance(); - - @Test - void preventNull_Name() { - assertThatThrownBy(() -> meter.longSumObserverBuilder(null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("name"); - } - - @Test - void preventEmpty_Name() { - assertThatThrownBy(() -> meter.longSumObserverBuilder("").build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventNonPrintableName() { - assertThatThrownBy(() -> meter.longSumObserverBuilder("\2").build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventTooLongName() { - char[] chars = new char[MetricsStringUtils.METRIC_NAME_MAX_LENGTH + 1]; - Arrays.fill(chars, 'a'); - String longName = String.valueOf(chars); - assertThatThrownBy(() -> meter.longSumObserverBuilder(longName).build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventNull_Description() { - assertThatThrownBy(() -> meter.longSumObserverBuilder("metric").setDescription(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("description"); - } - - @Test - void preventNull_Unit() { - assertThatThrownBy(() -> meter.longSumObserverBuilder("metric").setUnit(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("unit"); - } - - @Test - void preventNull_Callback() { - assertThatThrownBy(() -> meter.longSumObserverBuilder("metric").setUpdater(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("callback"); - } - - @Test - void doesNotThrow() { - meter - .longSumObserverBuilder(NAME) - .setDescription(DESCRIPTION) - .setUnit(UNIT) - .setUpdater(result -> {}) - .build(); - } -} diff --git a/api/metrics/src/test/java/io/opentelemetry/api/metrics/LongUpDownCounterTest.java b/api/metrics/src/test/java/io/opentelemetry/api/metrics/LongUpDownCounterTest.java deleted file mode 100644 index 148f4014d1..0000000000 --- a/api/metrics/src/test/java/io/opentelemetry/api/metrics/LongUpDownCounterTest.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import io.opentelemetry.api.metrics.common.Labels; -import io.opentelemetry.api.metrics.internal.MetricsStringUtils; -import java.util.Arrays; -import org.junit.jupiter.api.Test; - -class LongUpDownCounterTest { - - private static final String NAME = "name"; - private static final String DESCRIPTION = "description"; - private static final String UNIT = "1"; - private static final Meter meter = DefaultMeter.getInstance(); - - @Test - void preventNull_Name() { - assertThatThrownBy(() -> meter.longUpDownCounterBuilder(null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("name"); - } - - @Test - void preventEmpty_Name() { - assertThatThrownBy(() -> meter.longUpDownCounterBuilder("").build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventNonPrintableName() { - assertThatThrownBy(() -> meter.longUpDownCounterBuilder("\2").build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventTooLongName() { - char[] chars = new char[MetricsStringUtils.METRIC_NAME_MAX_LENGTH + 1]; - Arrays.fill(chars, 'a'); - String longName = String.valueOf(chars); - assertThatThrownBy(() -> meter.longUpDownCounterBuilder(longName).build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventNull_Description() { - assertThatThrownBy(() -> meter.longUpDownCounterBuilder("metric").setDescription(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("description"); - } - - @Test - void preventNull_Unit() { - assertThatThrownBy(() -> meter.longUpDownCounterBuilder("metric").setUnit(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("unit"); - } - - @Test - void add_PreventNullLabels() { - assertThatThrownBy(() -> meter.longUpDownCounterBuilder("metric").build().add(1, null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("labels"); - } - - @Test - void add_DoesNotThrow() { - LongUpDownCounter longUpDownCounter = - meter.longUpDownCounterBuilder(NAME).setDescription(DESCRIPTION).setUnit(UNIT).build(); - longUpDownCounter.add(1, Labels.empty()); - longUpDownCounter.add(-1, Labels.empty()); - longUpDownCounter.add(1); - longUpDownCounter.add(-1); - } - - @Test - void bound_PreventNullLabels() { - assertThatThrownBy(() -> meter.longUpDownCounterBuilder("metric").build().bind(null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("labels"); - } - - @Test - void bound_DoesNotThrow() { - LongUpDownCounter longUpDownCounter = - meter.longUpDownCounterBuilder(NAME).setDescription(DESCRIPTION).setUnit(UNIT).build(); - BoundLongUpDownCounter bound = longUpDownCounter.bind(Labels.empty()); - bound.add(1); - bound.add(-1); - bound.unbind(); - } -} diff --git a/api/metrics/src/test/java/io/opentelemetry/api/metrics/LongUpDownSumObserverTest.java b/api/metrics/src/test/java/io/opentelemetry/api/metrics/LongUpDownSumObserverTest.java deleted file mode 100644 index 1ecc7a19f5..0000000000 --- a/api/metrics/src/test/java/io/opentelemetry/api/metrics/LongUpDownSumObserverTest.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import io.opentelemetry.api.metrics.internal.MetricsStringUtils; -import java.util.Arrays; -import org.junit.jupiter.api.Test; - -class LongUpDownSumObserverTest { - - private static final String NAME = "name"; - private static final String DESCRIPTION = "description"; - private static final String UNIT = "1"; - private static final Meter meter = DefaultMeter.getInstance(); - - @Test - void preventNull_Name() { - assertThatThrownBy(() -> meter.longUpDownSumObserverBuilder(null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("name"); - } - - @Test - void preventEmpty_Name() { - assertThatThrownBy(() -> meter.longUpDownSumObserverBuilder("").build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventNonPrintableName() { - assertThatThrownBy(() -> meter.longUpDownSumObserverBuilder("\2").build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventTooLongName() { - char[] chars = new char[MetricsStringUtils.METRIC_NAME_MAX_LENGTH + 1]; - Arrays.fill(chars, 'a'); - String longName = String.valueOf(chars); - assertThatThrownBy(() -> meter.longUpDownSumObserverBuilder(longName).build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(DefaultMeter.ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventNull_Description() { - assertThatThrownBy( - () -> meter.longUpDownSumObserverBuilder("metric").setDescription(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("description"); - } - - @Test - void preventNull_Unit() { - assertThatThrownBy(() -> meter.longUpDownSumObserverBuilder("metric").setUnit(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("unit"); - } - - @Test - void preventNull_Callback() { - assertThatThrownBy(() -> meter.longUpDownSumObserverBuilder("metric").setUpdater(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("callback"); - } - - @Test - void doesNotThrow() { - meter - .longUpDownSumObserverBuilder(NAME) - .setDescription(DESCRIPTION) - .setUnit(UNIT) - .setUpdater(result -> {}) - .build(); - } -} diff --git a/api/metrics/src/test/java/io/opentelemetry/api/metrics/LongValueObserverTest.java b/api/metrics/src/test/java/io/opentelemetry/api/metrics/LongValueObserverTest.java deleted file mode 100644 index 0f1f9c09e1..0000000000 --- a/api/metrics/src/test/java/io/opentelemetry/api/metrics/LongValueObserverTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import static io.opentelemetry.api.metrics.DefaultMeter.ERROR_MESSAGE_INVALID_NAME; -import static java.util.Arrays.fill; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import io.opentelemetry.api.metrics.internal.MetricsStringUtils; -import org.junit.jupiter.api.Test; - -/** Unit tests for {@link LongValueObserver}. */ -class LongValueObserverTest { - - private static final String NAME = "name"; - private static final String DESCRIPTION = "description"; - private static final String UNIT = "1"; - private static final Meter meter = DefaultMeter.getInstance(); - - @Test - void preventNull_Name() { - assertThatThrownBy(() -> meter.longValueObserverBuilder(null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("name"); - } - - @Test - void preventEmpty_Name() { - assertThatThrownBy(() -> meter.longValueObserverBuilder("").build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventNonPrintableName() { - assertThatThrownBy(() -> meter.longValueObserverBuilder("\2").build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventTooLongName() { - char[] chars = new char[MetricsStringUtils.METRIC_NAME_MAX_LENGTH + 1]; - fill(chars, 'a'); - String longName = String.valueOf(chars); - assertThatThrownBy(() -> meter.longValueObserverBuilder(longName).build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventNull_Description() { - assertThatThrownBy(() -> meter.longValueObserverBuilder("metric").setDescription(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("description"); - } - - @Test - void preventNull_Unit() { - assertThatThrownBy(() -> meter.longValueObserverBuilder("metric").setUnit(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("unit"); - } - - @Test - void preventNull_Callback() { - assertThatThrownBy(() -> meter.longValueObserverBuilder("metric").setUpdater(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("callback"); - } - - @Test - void doesNotThrow() { - meter - .longValueObserverBuilder(NAME) - .setDescription(DESCRIPTION) - .setUnit(UNIT) - .setUpdater(result -> {}) - .build(); - } -} diff --git a/api/metrics/src/test/java/io/opentelemetry/api/metrics/LongValueRecorderTest.java b/api/metrics/src/test/java/io/opentelemetry/api/metrics/LongValueRecorderTest.java deleted file mode 100644 index 1b2da147a8..0000000000 --- a/api/metrics/src/test/java/io/opentelemetry/api/metrics/LongValueRecorderTest.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import static io.opentelemetry.api.metrics.DefaultMeter.ERROR_MESSAGE_INVALID_NAME; -import static java.util.Arrays.fill; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import io.opentelemetry.api.metrics.common.Labels; -import io.opentelemetry.api.metrics.internal.MetricsStringUtils; -import org.junit.jupiter.api.Test; - -/** Tests for {@link LongValueRecorder}. */ -public final class LongValueRecorderTest { - - private static final String NAME = "name"; - private static final String DESCRIPTION = "description"; - private static final String UNIT = "1"; - private static final Meter meter = DefaultMeter.getInstance(); - - @Test - void preventNull_Name() { - assertThatThrownBy(() -> meter.longValueRecorderBuilder(null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("name"); - } - - @Test - void preventEmpty_Name() { - assertThatThrownBy(() -> meter.longValueRecorderBuilder("").build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventNonPrintableMeasureName() { - assertThatThrownBy(() -> meter.longValueRecorderBuilder("\2").build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventTooLongName() { - char[] chars = new char[MetricsStringUtils.METRIC_NAME_MAX_LENGTH + 1]; - fill(chars, 'a'); - String longName = String.valueOf(chars); - assertThatThrownBy(() -> meter.longValueRecorderBuilder(longName).build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventNull_Description() { - assertThatThrownBy(() -> meter.longValueRecorderBuilder("metric").setDescription(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("description"); - } - - @Test - void preventNull_Unit() { - assertThatThrownBy(() -> meter.longValueRecorderBuilder("metric").setUnit(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("unit"); - } - - @Test - void record_PreventNullLabels() { - assertThatThrownBy(() -> meter.longValueRecorderBuilder("metric").build().record(1, null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("labels"); - } - - @Test - void record_DoesNotThrow() { - LongValueRecorder longValueRecorder = - meter.longValueRecorderBuilder(NAME).setDescription(DESCRIPTION).setUnit(UNIT).build(); - longValueRecorder.record(5, Labels.empty()); - longValueRecorder.record(-5, Labels.empty()); - longValueRecorder.record(5); - longValueRecorder.record(-5); - } - - @Test - void bound_PreventNullLabels() { - assertThatThrownBy(() -> meter.longValueRecorderBuilder("metric").build().bind(null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("labels"); - } - - @Test - void bound_DoesNotThrow() { - LongValueRecorder longValueRecorder = - meter.longValueRecorderBuilder(NAME).setDescription(DESCRIPTION).setUnit(UNIT).build(); - BoundLongValueRecorder bound = longValueRecorder.bind(Labels.empty()); - bound.record(5); - bound.record(-5); - bound.unbind(); - } -} diff --git a/api/metrics/src/test/java/io/opentelemetry/api/metrics/common/LabelsTest.java b/api/metrics/src/test/java/io/opentelemetry/api/metrics/common/LabelsTest.java deleted file mode 100644 index bd3c44003d..0000000000 --- a/api/metrics/src/test/java/io/opentelemetry/api/metrics/common/LabelsTest.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics.common; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.entry; - -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; -import org.junit.jupiter.api.Test; - -class LabelsTest { - - @Test - void forEach() { - final Map entriesSeen = new LinkedHashMap<>(); - - Labels labels = - Labels.of( - "key1", "value1", - "key2", "value2"); - - labels.forEach(entriesSeen::put); - - assertThat(entriesSeen).containsExactly(entry("key1", "value1"), entry("key2", "value2")); - } - - @Test - void asMap() { - Labels labels = - Labels.of( - "key1", "value1", - "key2", "value2"); - - assertThat(labels.asMap()).containsExactly(entry("key1", "value1"), entry("key2", "value2")); - } - - @Test - void forEach_singleAttribute() { - final Map entriesSeen = new HashMap<>(); - - Labels labels = Labels.of("key", "value"); - labels.forEach(entriesSeen::put); - - assertThat(entriesSeen).containsExactly(entry("key", "value")); - } - - @Test - void forEach_empty() { - final AtomicBoolean sawSomething = new AtomicBoolean(false); - Labels emptyLabels = Labels.empty(); - emptyLabels.forEach((key, value) -> sawSomething.set(true)); - assertThat(sawSomething.get()).isFalse(); - } - - @Test - void orderIndependentEquality() { - Labels one = - Labels.of( - "key3", "value3", - "key1", "value1", - "key2", "value2"); - Labels two = - Labels.of( - "key2", "value2", - "key3", "value3", - "key1", "value1"); - - assertThat(one).isEqualTo(two); - } - - @Test - void nullValueEquivalentWithMissing() { - Labels one = - Labels.of( - "key3", "value3", - "key4", null, - "key1", "value1", - "key2", "value2"); - Labels two = - Labels.of( - "key2", "value2", - "key3", "value3", - "key1", "value1"); - - assertThat(one).isEqualTo(two); - } - - @Test - void deduplication() { - Labels one = - Labels.of( - "key1", "valueX", - "key1", "value1"); - Labels two = Labels.of("key1", "value1"); - - assertThat(one).isEqualTo(two); - } - - @Test - void threeLabels() { - Labels one = - Labels.of( - "key1", "value1", - "key3", "value3", - "key2", "value2"); - assertThat(one).isNotNull(); - } - - @Test - void fourLabels() { - Labels one = - Labels.of( - "key1", "value1", - "key2", "value2", - "key3", "value3", - "key4", "value4"); - assertThat(one).isNotNull(); - } - - @Test - void builder() { - Labels labels = - Labels.builder() - .put("key1", "duplicateShouldBeIgnored") - .put("key1", "value1") - .put("key2", "value2") - .build(); - - assertThat(labels) - .isEqualTo( - Labels.of( - "key1", "value1", - "key2", "value2")); - } - - @Test - void toBuilder() { - Labels initial = Labels.of("one", "a"); - Labels second = initial.toBuilder().put("two", "b").build(); - assertThat(initial.size()).isEqualTo(1); - assertThat(second.size()).isEqualTo(2); - assertThat(initial).isEqualTo(Labels.of("one", "a")); - assertThat(second).isEqualTo(Labels.of("one", "a", "two", "b")); - } -} diff --git a/api/metrics/src/test/java/io/opentelemetry/api/metrics/internal/MetricsStringUtilsTest.java b/api/metrics/src/test/java/io/opentelemetry/api/metrics/internal/MetricsStringUtilsTest.java deleted file mode 100644 index 5be4d92524..0000000000 --- a/api/metrics/src/test/java/io/opentelemetry/api/metrics/internal/MetricsStringUtilsTest.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics.internal; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.jupiter.api.Test; - -class MetricsStringUtilsTest { - - @Test - void isValidMetricName() { - assertThat(MetricsStringUtils.isValidMetricName("")).isFalse(); - assertThat( - MetricsStringUtils.isValidMetricName( - String.valueOf(new char[MetricsStringUtils.METRIC_NAME_MAX_LENGTH + 1]))) - .isFalse(); - assertThat(MetricsStringUtils.isValidMetricName("abcd")).isTrue(); - assertThat(MetricsStringUtils.isValidMetricName("ab.cd")).isTrue(); - assertThat(MetricsStringUtils.isValidMetricName("ab12cd")).isTrue(); - assertThat(MetricsStringUtils.isValidMetricName("1abcd")).isFalse(); - assertThat(MetricsStringUtils.isValidMetricName("ab*cd")).isFalse(); - } -} diff --git a/api/metrics/src/test/java/io/opentelemetry/api/metrics/internal/NoopMeterProviderTest.java b/api/metrics/src/test/java/io/opentelemetry/api/metrics/internal/NoopMeterProviderTest.java new file mode 100644 index 0000000000..746d536d99 --- /dev/null +++ b/api/metrics/src/test/java/io/opentelemetry/api/metrics/internal/NoopMeterProviderTest.java @@ -0,0 +1,31 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.metrics.internal; + +import io.opentelemetry.api.metrics.MeterProvider; +import org.junit.jupiter.api.Test; + +public class NoopMeterProviderTest { + @Test + void noopMeterProvider_getDoesNotThrow() { + MeterProvider provider = MeterProvider.noop(); + provider.get("user-instrumentation"); + provider.get("schema-instrumentation", "1.0", "myschema://url"); + } + + @Test + void noopMeterProvider_builderDoesNotThrow() { + MeterProvider provider = MeterProvider.noop(); + provider.meterBuilder("user-instrumentation").build(); + provider.meterBuilder("advanced-instrumetnation").setInstrumentationVersion("1.0").build(); + provider.meterBuilder("schema-instrumentation").setSchemaUrl("myschema://url").build(); + provider + .meterBuilder("schema-instrumentation") + .setInstrumentationVersion("1.0") + .setSchemaUrl("myschema://url") + .build(); + } +} diff --git a/api/metrics/src/test/java/io/opentelemetry/api/metrics/internal/NoopMeterTest.java b/api/metrics/src/test/java/io/opentelemetry/api/metrics/internal/NoopMeterTest.java new file mode 100644 index 0000000000..b4657ab6fb --- /dev/null +++ b/api/metrics/src/test/java/io/opentelemetry/api/metrics/internal/NoopMeterTest.java @@ -0,0 +1,268 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.metrics.internal; + +import static io.opentelemetry.api.common.AttributeKey.stringKey; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.BoundDoubleCounter; +import io.opentelemetry.api.metrics.BoundDoubleHistogram; +import io.opentelemetry.api.metrics.BoundDoubleUpDownCounter; +import io.opentelemetry.api.metrics.BoundLongCounter; +import io.opentelemetry.api.metrics.BoundLongHistogram; +import io.opentelemetry.api.metrics.BoundLongUpDownCounter; +import io.opentelemetry.api.metrics.DoubleCounter; +import io.opentelemetry.api.metrics.DoubleHistogram; +import io.opentelemetry.api.metrics.DoubleUpDownCounter; +import io.opentelemetry.api.metrics.LongCounter; +import io.opentelemetry.api.metrics.LongHistogram; +import io.opentelemetry.api.metrics.LongUpDownCounter; +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.context.Context; +import org.junit.jupiter.api.Test; + +public class NoopMeterTest { + private static final Meter meter = NoopMeter.getInstance(); + + @Test + void noopLongCounter_doesNotThrow() { + LongCounter counter = + meter.counterBuilder("size").setDescription("The size I'm measuring").setUnit("1").build(); + counter.add(1); + counter.add(1, Attributes.of(stringKey("thing"), "car")); + counter.add(1, Attributes.of(stringKey("thing"), "car"), Context.current()); + } + + @Test + void noopBoundLongCounter_doesNotThrow() { + BoundLongCounter counter = + meter + .counterBuilder("size") + .setDescription("The size I'm measuring") + .setUnit("1") + .build() + .bind(Attributes.of(stringKey("thing"), "car")); + counter.add(1); + counter.add(1, Context.current()); + } + + @Test + void noopDoubleCounter_doesNotThrow() { + DoubleCounter counter = + meter + .counterBuilder("size") + .ofDoubles() + .setDescription("The size I'm measuring") + .setUnit("1") + .build(); + counter.add(1.2); + counter.add(2.5, Attributes.of(stringKey("thing"), "car")); + counter.add(2.5, Attributes.of(stringKey("thing"), "car"), Context.current()); + } + + @Test + void noopBoundDoubleCounter_doesNotThrow() { + BoundDoubleCounter counter = + meter + .counterBuilder("size") + .ofDoubles() + .setDescription("The size I'm measuring") + .setUnit("1") + .build() + .bind(Attributes.of(stringKey("thing"), "car")); + counter.add(1.2); + counter.add(2.5, Context.current()); + } + + @Test + void noopLongUpDownCounter_doesNotThrow() { + LongUpDownCounter counter = + meter + .upDownCounterBuilder("size") + .setDescription("The size I'm measuring") + .setUnit("1") + .build(); + counter.add(-1); + counter.add(1, Attributes.of(stringKey("thing"), "car")); + counter.add(1, Attributes.of(stringKey("thing"), "car"), Context.current()); + } + + @Test + void noopBoundLongUpDownCounter_doesNotThrow() { + BoundLongUpDownCounter counter = + meter + .upDownCounterBuilder("size") + .setDescription("The size I'm measuring") + .setUnit("1") + .build() + .bind(Attributes.of(stringKey("thing"), "car")); + counter.add(-1); + counter.add(1, Context.current()); + } + + @Test + void noopDoubleUpDownCounter_doesNotThrow() { + DoubleUpDownCounter counter = + meter + .upDownCounterBuilder("size") + .ofDoubles() + .setDescription("The size I'm measuring") + .setUnit("1") + .build(); + counter.add(-2e4); + counter.add(1.0e-1, Attributes.of(stringKey("thing"), "car")); + counter.add(1.0e-1, Attributes.of(stringKey("thing"), "car"), Context.current()); + } + + @Test + void noopBoundDoubleUpDownCounter_doesNotThrow() { + BoundDoubleUpDownCounter counter = + meter + .upDownCounterBuilder("size") + .ofDoubles() + .setDescription("The size I'm measuring") + .setUnit("1") + .build() + .bind(Attributes.of(stringKey("thing"), "car")); + counter.add(-2e4); + counter.add(1.0e-1, Context.current()); + } + + @Test + void noopLongHistogram_doesNotThrow() { + LongHistogram histogram = + meter + .histogramBuilder("size") + .ofLongs() + .setDescription("The size I'm measuring") + .setUnit("1") + .build(); + histogram.record(-1); + histogram.record(1, Attributes.of(stringKey("thing"), "car")); + histogram.record(1, Attributes.of(stringKey("thing"), "car"), Context.current()); + } + + @Test + void noopBoundLongHistogram_doesNotThrow() { + BoundLongHistogram histogram = + meter + .histogramBuilder("size") + .ofLongs() + .setDescription("The size I'm measuring") + .setUnit("1") + .build() + .bind(Attributes.of(stringKey("thing"), "car")); + histogram.record(-1); + histogram.record(1, Context.current()); + } + + @Test + void noopDoubleHistogram_doesNotThrow() { + DoubleHistogram histogram = + meter + .histogramBuilder("size") + .setDescription("The size I'm measuring") + .setUnit("1") + .build(); + histogram.record(-2e4); + histogram.record(1.0e-1, Attributes.of(stringKey("thing"), "car")); + histogram.record(1.0e-1, Attributes.of(stringKey("thing"), "car"), Context.current()); + } + + @Test + void noopBoundDoubleHistogram_doesNotThrow() { + BoundDoubleHistogram histogram = + meter + .histogramBuilder("size") + .setDescription("The size I'm measuring") + .setUnit("1") + .build() + .bind(Attributes.of(stringKey("thing"), "car")); + histogram.record(-2e4); + histogram.record(1.0e-1, Context.current()); + } + + @Test + void noopObservableLongGauage_doesNotThrow() { + meter + .gaugeBuilder("temperature") + .ofLongs() + .setDescription("The current temperature") + .setUnit("C") + .buildWithCallback( + m -> { + m.observe(1); + m.observe(2, Attributes.of(stringKey("thing"), "engine")); + }); + } + + @Test + void noopObservableDoubleGauage_doesNotThrow() { + meter + .gaugeBuilder("temperature") + .setDescription("The current temperature") + .setUnit("C") + .buildWithCallback( + m -> { + m.observe(1.0e1); + m.observe(-27.4, Attributes.of(stringKey("thing"), "engine")); + }); + } + + @Test + void noopObservableLongCounter_doesNotThrow() { + meter + .counterBuilder("temperature") + .setDescription("The current temperature") + .setUnit("C") + .buildWithCallback( + m -> { + m.observe(1); + m.observe(2, Attributes.of(stringKey("thing"), "engine")); + }); + } + + @Test + void noopObservableDoubleCounter_doesNotThrow() { + meter + .counterBuilder("temperature") + .ofDoubles() + .setDescription("The current temperature") + .setUnit("C") + .buildWithCallback( + m -> { + m.observe(1.0e1); + m.observe(-27.4, Attributes.of(stringKey("thing"), "engine")); + }); + } + + @Test + void noopObservableLongUpDownCounter_doesNotThrow() { + meter + .upDownCounterBuilder("temperature") + .setDescription("The current temperature") + .setUnit("C") + .buildWithCallback( + m -> { + m.observe(1); + m.observe(2, Attributes.of(stringKey("thing"), "engine")); + }); + } + + @Test + void noopObservableDoubleUpDownCounter_doesNotThrow() { + meter + .upDownCounterBuilder("temperature") + .ofDoubles() + .setDescription("The current temperature") + .setUnit("C") + .buildWithCallback( + m -> { + m.observe(1.0e1); + m.observe(-27.4, Attributes.of(stringKey("thing"), "engine")); + }); + } +} diff --git a/exporters/otlp-http/trace/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporter.java b/exporters/otlp-http/trace/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporter.java index b21b183324..f6eaee1323 100644 --- a/exporters/otlp-http/trace/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporter.java +++ b/exporters/otlp-http/trace/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporter.java @@ -7,11 +7,11 @@ package io.opentelemetry.exporter.otlp.http.trace; import com.google.rpc.Code; import com.google.rpc.Status; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.BoundLongCounter; import io.opentelemetry.api.metrics.GlobalMeterProvider; import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.exporter.otlp.internal.SpanAdapter; import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest; import io.opentelemetry.sdk.common.CompletableResultCode; @@ -41,11 +41,12 @@ import okio.Okio; public final class OtlpHttpSpanExporter implements SpanExporter { private static final String EXPORTER_NAME = OtlpHttpSpanExporter.class.getSimpleName(); - private static final Labels EXPORTER_NAME_LABELS = Labels.of("exporter", EXPORTER_NAME); - private static final Labels EXPORT_SUCCESS_LABELS = - Labels.of("exporter", EXPORTER_NAME, "success", "true"); - private static final Labels EXPORT_FAILURE_LABELS = - Labels.of("exporter", EXPORTER_NAME, "success", "false"); + private static final Attributes EXPORTER_NAME_LABELS = + Attributes.builder().put("exporter", EXPORTER_NAME).build(); + private static final Attributes EXPORT_SUCCESS_LABELS = + Attributes.builder().put("exporter", EXPORTER_NAME).put("success", true).build(); + private static final Attributes EXPORT_FAILURE_LABELS = + Attributes.builder().put("exporter", EXPORTER_NAME).put("success", false).build(); private static final MediaType PROTOBUF_MEDIA_TYPE = MediaType.parse("application/x-protobuf"); @@ -63,10 +64,9 @@ public final class OtlpHttpSpanExporter implements SpanExporter { OtlpHttpSpanExporter( OkHttpClient client, String endpoint, Headers headers, boolean isCompressionEnabled) { - Meter meter = GlobalMeterProvider.getMeter("io.opentelemetry.exporters.otlp-http"); - this.spansSeen = - meter.longCounterBuilder("spansSeenByExporter").build().bind(EXPORTER_NAME_LABELS); - LongCounter spansExportedCounter = meter.longCounterBuilder("spansExportedByExporter").build(); + Meter meter = GlobalMeterProvider.get().get("io.opentelemetry.exporters.otlp-http"); + this.spansSeen = meter.counterBuilder("spansSeenByExporter").build().bind(EXPORTER_NAME_LABELS); + LongCounter spansExportedCounter = meter.counterBuilder("spansExportedByExporter").build(); this.spansExportedSuccess = spansExportedCounter.bind(EXPORT_SUCCESS_LABELS); this.spansExportedFailure = spansExportedCounter.bind(EXPORT_FAILURE_LABELS); diff --git a/exporters/otlp/trace/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporter.java b/exporters/otlp/trace/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporter.java index acf664c1c5..72ded9f630 100644 --- a/exporters/otlp/trace/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporter.java +++ b/exporters/otlp/trace/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporter.java @@ -11,11 +11,12 @@ import com.google.common.util.concurrent.MoreExecutors; import io.grpc.ConnectivityState; import io.grpc.ManagedChannel; import io.grpc.Status; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.BoundLongCounter; import io.opentelemetry.api.metrics.GlobalMeterProvider; import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.exporter.otlp.internal.SpanAdapter; import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest; import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceResponse; @@ -35,13 +36,15 @@ import javax.annotation.concurrent.ThreadSafe; /** Exports spans using OTLP via gRPC, using OpenTelemetry's protobuf model. */ @ThreadSafe public final class OtlpGrpcSpanExporter implements SpanExporter { - + private static final AttributeKey EXPORTER_KEY = AttributeKey.stringKey("exporter"); + private static final AttributeKey SUCCESS_KEY = AttributeKey.stringKey("success"); private static final String EXPORTER_NAME = OtlpGrpcSpanExporter.class.getSimpleName(); - private static final Labels EXPORTER_NAME_LABELS = Labels.of("exporter", EXPORTER_NAME); - private static final Labels EXPORT_SUCCESS_LABELS = - Labels.of("exporter", EXPORTER_NAME, "success", "true"); - private static final Labels EXPORT_FAILURE_LABELS = - Labels.of("exporter", EXPORTER_NAME, "success", "false"); + private static final Attributes EXPORTER_NAME_Attributes = + Attributes.of(EXPORTER_KEY, EXPORTER_NAME); + private static final Attributes EXPORT_SUCCESS_ATTRIBUTES = + Attributes.of(EXPORTER_KEY, EXPORTER_NAME, SUCCESS_KEY, "true"); + private static final Attributes EXPORT_FAILURE_ATTRIBUTES = + Attributes.of(EXPORTER_KEY, EXPORTER_NAME, SUCCESS_KEY, "false"); private final ThrottlingLogger logger = new ThrottlingLogger(Logger.getLogger(OtlpGrpcSpanExporter.class.getName())); @@ -62,12 +65,13 @@ public final class OtlpGrpcSpanExporter implements SpanExporter { * 0 or to a negative value, the exporter will wait indefinitely. */ OtlpGrpcSpanExporter(ManagedChannel channel, long timeoutNanos) { - Meter meter = GlobalMeterProvider.getMeter("io.opentelemetry.exporters.otlp"); + // TODO: telemetry schema version. + Meter meter = GlobalMeterProvider.get().meterBuilder("io.opentelemetry.exporters.otlp").build(); this.spansSeen = - meter.longCounterBuilder("spansSeenByExporter").build().bind(EXPORTER_NAME_LABELS); - LongCounter spansExportedCounter = meter.longCounterBuilder("spansExportedByExporter").build(); - this.spansExportedSuccess = spansExportedCounter.bind(EXPORT_SUCCESS_LABELS); - this.spansExportedFailure = spansExportedCounter.bind(EXPORT_FAILURE_LABELS); + meter.counterBuilder("spansSeenByExporter").build().bind(EXPORTER_NAME_Attributes); + LongCounter spansExportedCounter = meter.counterBuilder("spansExportedByExporter").build(); + this.spansExportedSuccess = spansExportedCounter.bind(EXPORT_SUCCESS_ATTRIBUTES); + this.spansExportedFailure = spansExportedCounter.bind(EXPORT_FAILURE_ATTRIBUTES); this.managedChannel = channel; this.timeoutNanos = timeoutNanos; diff --git a/sdk-extensions/autoconfigure/src/testPrometheus/java/io/opentelemetry/sdk/autoconfigure/PrometheusTest.java b/sdk-extensions/autoconfigure/src/testPrometheus/java/io/opentelemetry/sdk/autoconfigure/PrometheusTest.java index 50c018f44d..4457d400df 100644 --- a/sdk-extensions/autoconfigure/src/testPrometheus/java/io/opentelemetry/sdk/autoconfigure/PrometheusTest.java +++ b/sdk-extensions/autoconfigure/src/testPrometheus/java/io/opentelemetry/sdk/autoconfigure/PrometheusTest.java @@ -9,8 +9,8 @@ import static org.assertj.core.api.Assertions.assertThat; import com.linecorp.armeria.client.WebClient; import com.linecorp.armeria.common.AggregatedHttpResponse; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.GlobalMeterProvider; -import io.opentelemetry.api.metrics.common.Labels; import java.io.IOException; import java.net.ServerSocket; import org.junit.jupiter.api.Test; @@ -37,9 +37,9 @@ class PrometheusTest { GlobalMeterProvider.get() .get("test") - .longValueObserverBuilder("test") - .setUpdater(result -> result.observe(2, Labels.empty())) - .build(); + .gaugeBuilder("test") + .ofLongs() + .buildWithCallback(result -> result.observe(2, Attributes.empty())); WebClient client = WebClient.of("http://127.0.0.1:" + port); AggregatedHttpResponse response = client.get("/metrics").aggregate().join(); diff --git a/sdk-extensions/logging/src/main/java/io/opentelemetry/sdk/logging/export/BatchLogProcessor.java b/sdk-extensions/logging/src/main/java/io/opentelemetry/sdk/logging/export/BatchLogProcessor.java index 83047bea5e..028104def3 100644 --- a/sdk-extensions/logging/src/main/java/io/opentelemetry/sdk/logging/export/BatchLogProcessor.java +++ b/sdk-extensions/logging/src/main/java/io/opentelemetry/sdk/logging/export/BatchLogProcessor.java @@ -5,11 +5,12 @@ package io.opentelemetry.sdk.logging.export; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.BoundLongCounter; import io.opentelemetry.api.metrics.GlobalMeterProvider; import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.internal.DaemonThreadFactory; import io.opentelemetry.sdk.logging.LogProcessor; @@ -66,19 +67,23 @@ public final class BatchLogProcessor implements LogProcessor { private static class Worker implements Runnable { static { - Meter meter = GlobalMeterProvider.getMeter("io.opentelemetry.sdk.logging"); + // TODO: As of Specification 1.4, this should have a telemetry schema version. + Meter meter = GlobalMeterProvider.get().meterBuilder("io.opentelemetry.sdk.trace").build(); LongCounter logRecordsProcessed = meter - .longCounterBuilder("logRecordsProcessed") + .counterBuilder("logRecordsProcessed") .setUnit("1") .setDescription("Number of records processed") .build(); - successCounter = logRecordsProcessed.bind(Labels.of("result", "success")); + AttributeKey resultKey = AttributeKey.stringKey("result"); + AttributeKey causeKey = AttributeKey.stringKey("cause"); + successCounter = logRecordsProcessed.bind(Attributes.of(resultKey, "success")); exporterFailureCounter = logRecordsProcessed.bind( - Labels.of("result", "dropped record", "cause", "exporter failure")); + Attributes.of(resultKey, "dropped record", causeKey, "exporter failure")); queueFullRecordCounter = - logRecordsProcessed.bind(Labels.of("result", "dropped record", "cause", "queue full")); + logRecordsProcessed.bind( + Attributes.of(resultKey, "dropped record", causeKey, "queue full")); } private static final BoundLongCounter exporterFailureCounter; diff --git a/sdk-extensions/tracing-incubator/src/jmh/java/io/opentelemetry/sdk/extension/incubator/trace/ExecutorServiceSpanProcessorCpuBenchmark.java b/sdk-extensions/tracing-incubator/src/jmh/java/io/opentelemetry/sdk/extension/incubator/trace/ExecutorServiceSpanProcessorCpuBenchmark.java index dcacf1553e..11170b6250 100644 --- a/sdk-extensions/tracing-incubator/src/jmh/java/io/opentelemetry/sdk/extension/incubator/trace/ExecutorServiceSpanProcessorCpuBenchmark.java +++ b/sdk-extensions/tracing-incubator/src/jmh/java/io/opentelemetry/sdk/extension/incubator/trace/ExecutorServiceSpanProcessorCpuBenchmark.java @@ -7,6 +7,7 @@ package io.opentelemetry.sdk.extension.incubator.trace; import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.metrics.export.MetricProducer; import io.opentelemetry.sdk.trace.ReadableSpan; import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.export.SpanExporter; @@ -37,7 +38,7 @@ public class ExecutorServiceSpanProcessorCpuBenchmark { @State(Scope.Benchmark) public static class BenchmarkState { - private SdkMeterProvider sdkMeterProvider; + private MetricProducer collector; private ExecutorServiceSpanProcessor processor; private Tracer tracer; private int numThreads = 1; @@ -50,7 +51,9 @@ public class ExecutorServiceSpanProcessorCpuBenchmark { @Setup(Level.Iteration) public final void setup() { - sdkMeterProvider = SdkMeterProvider.builder().buildAndRegisterGlobal(); + final SdkMeterProvider sdkMeterProvider = SdkMeterProvider.builder().buildAndRegisterGlobal(); + // Note: these will (likely) no longer be the same in future SDK. + collector = sdkMeterProvider; SpanExporter exporter = new DelayingSpanExporter(delayMs); ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); processor = ExecutorServiceSpanProcessor.builder(exporter, executor, true).build(); @@ -61,7 +64,7 @@ public class ExecutorServiceSpanProcessorCpuBenchmark { @TearDown(Level.Iteration) public final void recordMetrics() { BatchSpanProcessorMetrics metrics = - new BatchSpanProcessorMetrics(sdkMeterProvider.collectAllMetrics(), numThreads); + new BatchSpanProcessorMetrics(collector.collectAllMetrics(), numThreads); exportedSpans = metrics.exportedSpans(); droppedSpans = metrics.droppedSpans(); } diff --git a/sdk-extensions/tracing-incubator/src/jmh/java/io/opentelemetry/sdk/extension/incubator/trace/ExecutorServiceSpanProcessorDroppedSpansBenchmark.java b/sdk-extensions/tracing-incubator/src/jmh/java/io/opentelemetry/sdk/extension/incubator/trace/ExecutorServiceSpanProcessorDroppedSpansBenchmark.java index b80f976951..eb6d760de4 100644 --- a/sdk-extensions/tracing-incubator/src/jmh/java/io/opentelemetry/sdk/extension/incubator/trace/ExecutorServiceSpanProcessorDroppedSpansBenchmark.java +++ b/sdk-extensions/tracing-incubator/src/jmh/java/io/opentelemetry/sdk/extension/incubator/trace/ExecutorServiceSpanProcessorDroppedSpansBenchmark.java @@ -7,6 +7,7 @@ package io.opentelemetry.sdk.extension.incubator.trace; import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.metrics.export.MetricProducer; import io.opentelemetry.sdk.trace.ReadableSpan; import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.export.SpanExporter; @@ -30,7 +31,7 @@ public class ExecutorServiceSpanProcessorDroppedSpansBenchmark { @State(Scope.Benchmark) public static class BenchmarkState { - private SdkMeterProvider sdkMeterProvider; + private MetricProducer collector; private ExecutorServiceSpanProcessor processor; private Tracer tracer; private double dropRatio; @@ -40,7 +41,9 @@ public class ExecutorServiceSpanProcessorDroppedSpansBenchmark { @Setup(Level.Iteration) public final void setup() { - sdkMeterProvider = SdkMeterProvider.builder().buildAndRegisterGlobal(); + final SdkMeterProvider sdkMeterProvider = SdkMeterProvider.builder().buildAndRegisterGlobal(); + // Note: these will (likely) no longer be the same in future SDK. + collector = sdkMeterProvider; SpanExporter exporter = new DelayingSpanExporter(0); ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); processor = ExecutorServiceSpanProcessor.builder(exporter, executor, true).build(); @@ -51,7 +54,7 @@ public class ExecutorServiceSpanProcessorDroppedSpansBenchmark { @TearDown(Level.Iteration) public final void recordMetrics() { BatchSpanProcessorMetrics metrics = - new BatchSpanProcessorMetrics(sdkMeterProvider.collectAllMetrics(), numThreads); + new BatchSpanProcessorMetrics(collector.collectAllMetrics(), numThreads); dropRatio = metrics.dropRatio(); exportedSpans = metrics.exportedSpans(); droppedSpans = metrics.droppedSpans(); diff --git a/sdk-extensions/tracing-incubator/src/jmh/java/io/opentelemetry/sdk/extension/incubator/trace/ExecutorServiceSpanProcessorMultiThreadBenchmark.java b/sdk-extensions/tracing-incubator/src/jmh/java/io/opentelemetry/sdk/extension/incubator/trace/ExecutorServiceSpanProcessorMultiThreadBenchmark.java index e5dfea5e57..9681a47d1f 100644 --- a/sdk-extensions/tracing-incubator/src/jmh/java/io/opentelemetry/sdk/extension/incubator/trace/ExecutorServiceSpanProcessorMultiThreadBenchmark.java +++ b/sdk-extensions/tracing-incubator/src/jmh/java/io/opentelemetry/sdk/extension/incubator/trace/ExecutorServiceSpanProcessorMultiThreadBenchmark.java @@ -7,6 +7,7 @@ package io.opentelemetry.sdk.extension.incubator.trace; import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.metrics.export.MetricProducer; import io.opentelemetry.sdk.trace.ReadableSpan; import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.export.SpanExporter; @@ -34,7 +35,7 @@ public class ExecutorServiceSpanProcessorMultiThreadBenchmark { @State(Scope.Benchmark) public static class BenchmarkState { - private SdkMeterProvider sdkMeterProvider; + private MetricProducer collector; private ExecutorServiceSpanProcessor processor; private Tracer tracer; private int numThreads = 1; @@ -47,7 +48,9 @@ public class ExecutorServiceSpanProcessorMultiThreadBenchmark { @Setup(Level.Iteration) public final void setup() { - sdkMeterProvider = SdkMeterProvider.builder().buildAndRegisterGlobal(); + final SdkMeterProvider sdkMeterProvider = SdkMeterProvider.builder().buildAndRegisterGlobal(); + // Note: these will (likely) no longer be the same in future SDK. + collector = sdkMeterProvider; SpanExporter exporter = new DelayingSpanExporter(delayMs); ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); processor = ExecutorServiceSpanProcessor.builder(exporter, executor, true).build(); @@ -58,7 +61,7 @@ public class ExecutorServiceSpanProcessorMultiThreadBenchmark { @TearDown(Level.Iteration) public final void recordMetrics() { BatchSpanProcessorMetrics metrics = - new BatchSpanProcessorMetrics(sdkMeterProvider.collectAllMetrics(), numThreads); + new BatchSpanProcessorMetrics(collector.collectAllMetrics(), numThreads); exportedSpans = metrics.exportedSpans(); droppedSpans = metrics.droppedSpans(); } diff --git a/sdk-extensions/tracing-incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/trace/ExecutorServiceSpanProcessor.java b/sdk-extensions/tracing-incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/trace/ExecutorServiceSpanProcessor.java index a4dc5c680c..ee54edbea5 100644 --- a/sdk-extensions/tracing-incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/trace/ExecutorServiceSpanProcessor.java +++ b/sdk-extensions/tracing-incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/trace/ExecutorServiceSpanProcessor.java @@ -5,11 +5,12 @@ package io.opentelemetry.sdk.extension.incubator.trace; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.BoundLongCounter; import io.opentelemetry.api.metrics.GlobalMeterProvider; import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.context.Context; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.trace.ReadWriteSpan; @@ -35,15 +36,17 @@ import org.jctools.queues.MpscArrayQueue; @SuppressWarnings("FutureReturnValueIgnored") public final class ExecutorServiceSpanProcessor implements SpanProcessor { - private static final String SPAN_PROCESSOR_TYPE_LABEL = "spanProcessorType"; + private static final AttributeKey SPAN_PROCESSOR_TYPE_KEY = + AttributeKey.stringKey("spanProcessorType"); + private static final AttributeKey DROPPED_KEY = AttributeKey.booleanKey("dropped"); private static final String SPAN_PROCESSOR_TYPE_VALUE = ExecutorServiceSpanProcessor.class.getSimpleName(); - private static final Labels SPAN_PROCESSOR_LABELS = - Labels.of(SPAN_PROCESSOR_TYPE_LABEL, SPAN_PROCESSOR_TYPE_VALUE); - private static final Labels SPAN_PROCESSOR_DROPPED_LABELS = - Labels.of(SPAN_PROCESSOR_TYPE_LABEL, SPAN_PROCESSOR_TYPE_VALUE, "dropped", "true"); - private static final Labels SPAN_PROCESSOR_EXPORTED_LABELS = - Labels.of(SPAN_PROCESSOR_TYPE_LABEL, SPAN_PROCESSOR_TYPE_VALUE, "dropped", "false"); + private static final Attributes SPAN_PROCESSOR_LABELS = + Attributes.of(SPAN_PROCESSOR_TYPE_KEY, SPAN_PROCESSOR_TYPE_VALUE); + private static final Attributes SPAN_PROCESSOR_DROPPED_LABELS = + Attributes.of(SPAN_PROCESSOR_TYPE_KEY, SPAN_PROCESSOR_TYPE_VALUE, DROPPED_KEY, true); + private static final Attributes SPAN_PROCESSOR_EXPORTED_LABELS = + Attributes.of(SPAN_PROCESSOR_TYPE_KEY, SPAN_PROCESSOR_TYPE_VALUE, DROPPED_KEY, false); private final Worker worker; private final AtomicBoolean isShutdown = new AtomicBoolean(false); @@ -163,16 +166,17 @@ public final class ExecutorServiceSpanProcessor implements SpanProcessor { ScheduledExecutorService executorService, AtomicBoolean isShutdown, long workerScheduleIntervalNanos) { - Meter meter = GlobalMeterProvider.getMeter("io.opentelemetry.sdk.trace"); + // TODO: As of Specification 1.4, this should have a telemetry schema version. + Meter meter = GlobalMeterProvider.get().meterBuilder("io.opentelemetry.sdk.trace").build(); meter - .longValueObserverBuilder("queueSize") + .gaugeBuilder("queueSize") + .ofLongs() .setDescription("The number of spans queued") .setUnit("1") - .setUpdater(result -> result.observe(queue.size(), SPAN_PROCESSOR_LABELS)) - .build(); + .buildWithCallback(result -> result.observe(queue.size(), SPAN_PROCESSOR_LABELS)); LongCounter processedSpansCounter = meter - .longCounterBuilder("processedSpans") + .counterBuilder("processedSpans") .setUnit("1") .setDescription( "The number of spans processed by the BatchSpanProcessor. " diff --git a/sdk/metrics-testing/src/main/java/io/opentelemetry/sdk/testing/assertj/metrics/DoubleSummaryDataAssert.java b/sdk/metrics-testing/src/main/java/io/opentelemetry/sdk/testing/assertj/metrics/DoubleSummaryDataAssert.java new file mode 100644 index 0000000000..9f87cc1241 --- /dev/null +++ b/sdk/metrics-testing/src/main/java/io/opentelemetry/sdk/testing/assertj/metrics/DoubleSummaryDataAssert.java @@ -0,0 +1,29 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.testing.assertj.metrics; + +import io.opentelemetry.sdk.metrics.data.DoubleSummaryData; +import io.opentelemetry.sdk.metrics.data.DoubleSummaryPointData; +import org.assertj.core.api.AbstractAssert; +import org.assertj.core.api.AbstractIterableAssert; +import org.assertj.core.api.Assertions; + +/** Assert on a {@link DoubleSummaryData} metric. */ +public class DoubleSummaryDataAssert + extends AbstractAssert { + + protected DoubleSummaryDataAssert(DoubleSummaryData actual) { + super(actual, DoubleSummaryDataAssert.class); + } + + /** Returns convenience API to assert against the {@code points} field. */ + public AbstractIterableAssert< + ?, ? extends Iterable, DoubleSummaryPointData, ?> + points() { + isNotNull(); + return Assertions.assertThat(actual.getPoints()); + } +} diff --git a/sdk/metrics-testing/src/main/java/io/opentelemetry/sdk/testing/assertj/metrics/DoubleSummaryPointDataAssert.java b/sdk/metrics-testing/src/main/java/io/opentelemetry/sdk/testing/assertj/metrics/DoubleSummaryPointDataAssert.java new file mode 100644 index 0000000000..456dbf4538 --- /dev/null +++ b/sdk/metrics-testing/src/main/java/io/opentelemetry/sdk/testing/assertj/metrics/DoubleSummaryPointDataAssert.java @@ -0,0 +1,39 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.testing.assertj.metrics; + +import io.opentelemetry.sdk.metrics.data.DoubleSummaryPointData; +import io.opentelemetry.sdk.metrics.data.ValueAtPercentile; +import org.assertj.core.api.Assertions; + +/** Asserts for (deprecated) Summary points. */ +public class DoubleSummaryPointDataAssert + extends AbstractPointDataAssert { + protected DoubleSummaryPointDataAssert(DoubleSummaryPointData actual) { + super(actual, DoubleSummaryPointDataAssert.class); + } + + /** Ensure the summary has seen the expected count of measurements. */ + public DoubleSummaryPointDataAssert hasCount(long expected) { + isNotNull(); + Assertions.assertThat(actual.getCount()).as("count").isEqualTo(expected); + return this; + } + + /** Ensure the summary has the expected sum across all observed measurements. */ + public DoubleSummaryPointDataAssert hasSum(double expected) { + isNotNull(); + Assertions.assertThat(actual.getSum()).as("sum").isEqualTo(expected); + return this; + } + + /** Ensure the summary has exactly, in any order, the given percentile values. */ + public DoubleSummaryPointDataAssert hasPercentileValues(ValueAtPercentile... percentiles) { + isNotNull(); + Assertions.assertThat(actual.getPercentileValues()).containsExactlyInAnyOrder(percentiles); + return this; + } +} diff --git a/sdk/metrics-testing/src/main/java/io/opentelemetry/sdk/testing/assertj/metrics/MetricAssertions.java b/sdk/metrics-testing/src/main/java/io/opentelemetry/sdk/testing/assertj/metrics/MetricAssertions.java index a3550c83ed..e9230d7753 100644 --- a/sdk/metrics-testing/src/main/java/io/opentelemetry/sdk/testing/assertj/metrics/MetricAssertions.java +++ b/sdk/metrics-testing/src/main/java/io/opentelemetry/sdk/testing/assertj/metrics/MetricAssertions.java @@ -10,6 +10,8 @@ import io.opentelemetry.sdk.metrics.data.DoubleHistogramData; import io.opentelemetry.sdk.metrics.data.DoubleHistogramPointData; import io.opentelemetry.sdk.metrics.data.DoublePointData; import io.opentelemetry.sdk.metrics.data.DoubleSumData; +import io.opentelemetry.sdk.metrics.data.DoubleSummaryData; +import io.opentelemetry.sdk.metrics.data.DoubleSummaryPointData; import io.opentelemetry.sdk.metrics.data.LongGaugeData; import io.opentelemetry.sdk.metrics.data.LongPointData; import io.opentelemetry.sdk.metrics.data.LongSumData; @@ -33,11 +35,21 @@ public final class MetricAssertions extends Assertions { return new DoubleHistogramAssert(metric); } + /** Returns an assertion for {@link DoubleSummaryData}. */ + public static DoubleSummaryDataAssert assertThat(DoubleSummaryData metric) { + return new DoubleSummaryDataAssert(metric); + } + /** Returns an assertion for {@link DoubleHistogramPointData}. */ public static DoubleHistogramPointDataAssert assertThat(DoubleHistogramPointData point) { return new DoubleHistogramPointDataAssert(point); } + /** Returns an assertion for {@link DoubleSummaryPointData}. */ + public static DoubleSummaryPointDataAssert assertThat(DoubleSummaryPointData point) { + return new DoubleSummaryPointDataAssert(point); + } + /** Returns an assertion for {@link DoublePointData}. */ public static DoublePointDataAssert assertThat(DoublePointData point) { return new DoublePointDataAssert(point); diff --git a/sdk/metrics-testing/src/main/java/io/opentelemetry/sdk/testing/assertj/metrics/MetricDataAssert.java b/sdk/metrics-testing/src/main/java/io/opentelemetry/sdk/testing/assertj/metrics/MetricDataAssert.java index 3a852c4b44..b4a32b2fa9 100644 --- a/sdk/metrics-testing/src/main/java/io/opentelemetry/sdk/testing/assertj/metrics/MetricDataAssert.java +++ b/sdk/metrics-testing/src/main/java/io/opentelemetry/sdk/testing/assertj/metrics/MetricDataAssert.java @@ -180,4 +180,22 @@ public class MetricDataAssert extends AbstractAssert but found <%s>", + MetricDataType.SUMMARY, + actual.getType()); + } + return new DoubleSummaryDataAssert(actual.getDoubleSummaryData()); + } } diff --git a/sdk/metrics-testing/src/test/java/io/opentelemetry/sdk/testing/assertj/metrics/MetricAssertionsTest.java b/sdk/metrics-testing/src/test/java/io/opentelemetry/sdk/testing/assertj/metrics/MetricAssertionsTest.java index ddedc588aa..7ceb4a6a51 100644 --- a/sdk/metrics-testing/src/test/java/io/opentelemetry/sdk/testing/assertj/metrics/MetricAssertionsTest.java +++ b/sdk/metrics-testing/src/test/java/io/opentelemetry/sdk/testing/assertj/metrics/MetricAssertionsTest.java @@ -17,11 +17,14 @@ import io.opentelemetry.sdk.metrics.data.DoubleGaugeData; import io.opentelemetry.sdk.metrics.data.DoubleHistogramData; import io.opentelemetry.sdk.metrics.data.DoublePointData; import io.opentelemetry.sdk.metrics.data.DoubleSumData; +import io.opentelemetry.sdk.metrics.data.DoubleSummaryData; +import io.opentelemetry.sdk.metrics.data.DoubleSummaryPointData; import io.opentelemetry.sdk.metrics.data.LongExemplar; import io.opentelemetry.sdk.metrics.data.LongGaugeData; import io.opentelemetry.sdk.metrics.data.LongPointData; import io.opentelemetry.sdk.metrics.data.LongSumData; import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.data.ValueAtPercentile; import io.opentelemetry.sdk.resources.Resource; import java.util.Collections; import org.junit.jupiter.api.Test; @@ -55,6 +58,17 @@ public class MetricAssertionsTest { // Points Collections.emptyList())); + private static final MetricData DOUBLE_SUMMARY_METRIC = + MetricData.createDoubleSummary( + RESOURCE, + INSTRUMENTATION_LIBRARY_INFO, + /* name= */ "summary", + /* description= */ "description", + /* unit= */ "unit", + DoubleSummaryData.create( + // Points + Collections.emptyList())); + private static final MetricData DOUBLE_GAUGE_METRIC = MetricData.createDoubleGauge( RESOURCE, @@ -148,6 +162,12 @@ public class MetricAssertionsTest { private static final LongPointData LONG_POINT_DATA_WITH_EXEMPLAR = LongPointData.create(1, 2, Attributes.empty(), 3, Collections.singletonList(LONG_EXEMPLAR)); + private static final ValueAtPercentile PERCENTILE_VALUE = ValueAtPercentile.create(0, 1); + + private static final DoubleSummaryPointData DOUBLE_SUMMARY_POINT_DATA = + DoubleSummaryPointData.create( + 1, 2, Attributes.empty(), 1, 2, Collections.singletonList(PERCENTILE_VALUE)); + @Test void metric_passing() { assertThat(HISTOGRAM_METRIC) @@ -197,6 +217,17 @@ public class MetricAssertionsTest { .isInstanceOf(AssertionError.class); } + @Test + void summary_passing() { + assertThat(DOUBLE_SUMMARY_METRIC).hasDoubleSummary(); + } + + @Test + void sumamry_failing() { + assertThatThrownBy(() -> assertThat(DOUBLE_GAUGE_METRIC).hasDoubleSummary()) + .isInstanceOf(AssertionError.class); + } + @Test void doubleGauge_passing() { assertThat(DOUBLE_GAUGE_METRIC).hasDoubleGauge(); @@ -335,4 +366,30 @@ public class MetricAssertionsTest { assertThatThrownBy(() -> assertThat(HISTOGRAM_DELTA_METRIC).hasLongGauge()) .isInstanceOf(AssertionError.class); } + + @Test + void doubleSummaryPointData_passing() { + assertThat(DOUBLE_SUMMARY_POINT_DATA) + .hasCount(1) + .hasSum(2) + .hasEpochNanos(2) + .hasStartEpochNanos(1) + .hasAttributes(Attributes.empty()) + .hasPercentileValues(PERCENTILE_VALUE); + } + + @Test + void doubleSummaryPointData_failing() { + assertThatThrownBy(() -> assertThat(DOUBLE_SUMMARY_POINT_DATA).hasCount(2)) + .isInstanceOf(AssertionError.class); + + assertThatThrownBy(() -> assertThat(DOUBLE_SUMMARY_POINT_DATA).hasSum(1)) + .isInstanceOf(AssertionError.class); + + assertThatThrownBy( + () -> + assertThat(DOUBLE_SUMMARY_POINT_DATA) + .hasPercentileValues(ValueAtPercentile.create(1, 1))) + .isInstanceOf(AssertionError.class); + } } diff --git a/sdk/metrics/README.md b/sdk/metrics/README.md new file mode 100644 index 0000000000..2908c401fd --- /dev/null +++ b/sdk/metrics/README.md @@ -0,0 +1,15 @@ +# OpenTelemetry Metrics SDK + +The code in this directory is currently the legacy impelmentation of the previous experimental metrics SDK specification. + + +The following set of known issues will be fixed aas the new SDK specification stabilizes: + +- The names of SDK insturments do not line up with API instruments. +- Baggage / Context are not available to metrics / views. +- The View API still uses the term LabelsProcessor. +- Only one exporter is allowed. +- Histograms are generating summaries. +- Exemplars are not sampled +- The set of Aggregators goes well beyond the expected "stable" list and (likely) will have some moved to extensions. +- There is no exposed `MetricProcessor` interface. \ No newline at end of file diff --git a/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/MetricsBenchmarks.java b/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/MetricsBenchmarks.java index d5c18ac11c..d7da05c419 100644 --- a/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/MetricsBenchmarks.java +++ b/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/MetricsBenchmarks.java @@ -5,8 +5,8 @@ package io.opentelemetry.sdk.metrics; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.api.metrics.common.Labels; import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; @@ -37,14 +37,15 @@ public class MetricsBenchmarks { @Param MetricsTestOperationBuilder opBuilder; MetricsTestOperationBuilder.Operation op; - final Labels sharedLabelSet = Labels.of("KEY", "VALUE"); - Labels threadUniqueLabelSet; + final Attributes sharedLabelSet = Attributes.builder().put("KEY", "VALUE").build(); + Attributes threadUniqueLabelSet; @Setup public void setup(ThreadParams threadParams) { Meter meter = sdk.getMeter(); op = opBuilder.build(meter); - threadUniqueLabelSet = Labels.of("KEY", String.valueOf(threadParams.getThreadIndex())); + threadUniqueLabelSet = + Attributes.builder().put("KEY", String.valueOf(threadParams.getThreadIndex())).build(); } } diff --git a/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/MetricsTestOperationBuilder.java b/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/MetricsTestOperationBuilder.java index e3538350cb..2c471f1cae 100644 --- a/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/MetricsTestOperationBuilder.java +++ b/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/MetricsTestOperationBuilder.java @@ -5,16 +5,16 @@ package io.opentelemetry.sdk.metrics; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.BoundDoubleCounter; -import io.opentelemetry.api.metrics.BoundDoubleValueRecorder; +import io.opentelemetry.api.metrics.BoundDoubleHistogram; import io.opentelemetry.api.metrics.BoundLongCounter; -import io.opentelemetry.api.metrics.BoundLongValueRecorder; +import io.opentelemetry.api.metrics.BoundLongHistogram; import io.opentelemetry.api.metrics.DoubleCounter; -import io.opentelemetry.api.metrics.DoubleValueRecorder; +import io.opentelemetry.api.metrics.DoubleHistogram; import io.opentelemetry.api.metrics.LongCounter; -import io.opentelemetry.api.metrics.LongValueRecorder; +import io.opentelemetry.api.metrics.LongHistogram; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.api.metrics.common.Labels; /** * This enum allows for iteration over all of the operations that we want to benchmark. To ensure @@ -27,15 +27,15 @@ public enum MetricsTestOperationBuilder { LongCounterAdd( meter -> { return new Operation() { - final LongCounter metric = meter.longCounterBuilder("long_counter").build(); + final LongCounter metric = meter.counterBuilder("long_counter").build(); final BoundLongCounter boundMetric = meter - .longCounterBuilder("bound_long_counter") + .counterBuilder("bound_long_counter") .build() - .bind(Labels.of("KEY", "VALUE")); + .bind(Attributes.builder().put("KEY", "VALUE").build()); @Override - public void perform(Labels labels) { + public void perform(Attributes labels) { metric.add(5L, labels); } @@ -48,15 +48,16 @@ public enum MetricsTestOperationBuilder { DoubleCounterAdd( meter -> { return new Operation() { - final DoubleCounter metric = meter.doubleCounterBuilder("double_counter").build(); + final DoubleCounter metric = meter.counterBuilder("double_counter").ofDoubles().build(); final BoundDoubleCounter boundMetric = meter - .doubleCounterBuilder("bound_double_counter") + .counterBuilder("bound_double_counter") + .ofDoubles() .build() - .bind(Labels.of("KEY", "VALUE")); + .bind(Attributes.builder().put("KEY", "VALUE").build()); @Override - public void perform(Labels labels) { + public void perform(Attributes labels) { metric.add(5.0d, labels); } @@ -66,19 +67,19 @@ public enum MetricsTestOperationBuilder { } }; }), - DoubleValueRecorderRecord( + DoubleHistogramRecord( meter -> { return new Operation() { - final DoubleValueRecorder metric = - meter.doubleValueRecorderBuilder("double_value_recorder").build(); - final BoundDoubleValueRecorder boundMetric = + final DoubleHistogram metric = + meter.histogramBuilder("double_histogram_recorder").build(); + final BoundDoubleHistogram boundMetric = meter - .doubleValueRecorderBuilder("bound_double_value_recorder") + .histogramBuilder("bound_double_histogram_recorder") .build() - .bind(Labels.of("KEY", "VALUE")); + .bind(Attributes.builder().put("KEY", "VALUE").build()); @Override - public void perform(Labels labels) { + public void perform(Attributes labels) { metric.record(5.0d, labels); } @@ -88,41 +89,20 @@ public enum MetricsTestOperationBuilder { } }; }), - DoubleHistogramRecorderRecord( + LongHistogramRecord( meter -> { return new Operation() { - final DoubleValueRecorder metric = - meter.doubleValueRecorderBuilder("double_histogram_recorder").build(); - final BoundDoubleValueRecorder boundMetric = + final LongHistogram metric = + meter.histogramBuilder("long_value_recorder").ofLongs().build(); + final BoundLongHistogram boundMetric = meter - .doubleValueRecorderBuilder("bound_double_histogram_recorder") + .histogramBuilder("bound_long_value_recorder") + .ofLongs() .build() - .bind(Labels.of("KEY", "VALUE")); + .bind(Attributes.builder().put("KEY", "VALUE").build()); @Override - public void perform(Labels labels) { - metric.record(5.0d, labels); - } - - @Override - public void performBound() { - boundMetric.record(5.0d); - } - }; - }), - LongValueRecorderRecord( - meter -> { - return new Operation() { - final LongValueRecorder metric = - meter.longValueRecorderBuilder("long_value_recorder").build(); - final BoundLongValueRecorder boundMetric = - meter - .longValueRecorderBuilder("bound_long_value_recorder") - .build() - .bind(Labels.of("KEY", "VALUE")); - - @Override - public void perform(Labels labels) { + public void perform(Attributes labels) { metric.record(5L, labels); } @@ -148,7 +128,7 @@ public enum MetricsTestOperationBuilder { } interface Operation { - void perform(Labels labels); + void perform(Attributes labels); void performBound(); } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractDoubleAsynchronousInstrumentBuilder.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractDoubleAsynchronousInstrumentBuilder.java deleted file mode 100644 index 59526f7618..0000000000 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractDoubleAsynchronousInstrumentBuilder.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.metrics; - -import io.opentelemetry.api.metrics.AsynchronousInstrument; -import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; -import io.opentelemetry.sdk.metrics.common.InstrumentType; -import io.opentelemetry.sdk.metrics.common.InstrumentValueType; -import java.util.function.BiFunction; -import java.util.function.Consumer; -import javax.annotation.Nullable; - -abstract class AbstractDoubleAsynchronousInstrumentBuilder> - extends AbstractInstrument.Builder { - private final MeterProviderSharedState meterProviderSharedState; - private final MeterSharedState meterSharedState; - @Nullable private Consumer updater; - - AbstractDoubleAsynchronousInstrumentBuilder( - String name, - InstrumentType instrumentType, - InstrumentValueType instrumentValueType, - MeterProviderSharedState meterProviderSharedState, - MeterSharedState meterSharedState) { - super(name, instrumentType, instrumentValueType); - this.meterProviderSharedState = meterProviderSharedState; - this.meterSharedState = meterSharedState; - } - - public B setUpdater(Consumer updater) { - this.updater = updater; - return getThis(); - } - - final I buildInstrument( - BiFunction instrumentFactory) { - InstrumentDescriptor descriptor = buildDescriptor(); - return meterSharedState - .getInstrumentRegistry() - .register( - instrumentFactory.apply( - descriptor, - AsynchronousInstrumentAccumulator.doubleAsynchronousAccumulator( - meterProviderSharedState, meterSharedState, descriptor, updater))); - } -} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractInstrument.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractInstrument.java index c8330d1a7b..8e0853afc2 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractInstrument.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractInstrument.java @@ -5,16 +5,9 @@ package io.opentelemetry.sdk.metrics; -import io.opentelemetry.api.internal.Utils; -import io.opentelemetry.api.metrics.Instrument; -import io.opentelemetry.api.metrics.InstrumentBuilder; -import io.opentelemetry.api.metrics.internal.MetricsStringUtils; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; -import io.opentelemetry.sdk.metrics.common.InstrumentType; -import io.opentelemetry.sdk.metrics.common.InstrumentValueType; import io.opentelemetry.sdk.metrics.data.MetricData; import java.util.List; -import java.util.Objects; abstract class AbstractInstrument implements Instrument { @@ -52,45 +45,4 @@ abstract class AbstractInstrument implements Instrument { public int hashCode() { return descriptor.hashCode(); } - - abstract static class Builder> - implements InstrumentBuilder { - /* VisibleForTesting */ static final String ERROR_MESSAGE_INVALID_NAME = - "Name should be a ASCII string with a length no greater than " - + MetricsStringUtils.METRIC_NAME_MAX_LENGTH - + " characters."; - - private final String name; - private final InstrumentType instrumentType; - private final InstrumentValueType instrumentValueType; - private String description = ""; - private String unit = "1"; - - Builder(String name, InstrumentType instrumentType, InstrumentValueType instrumentValueType) { - Objects.requireNonNull(name, "name"); - Utils.checkArgument(MetricsStringUtils.isValidMetricName(name), ERROR_MESSAGE_INVALID_NAME); - this.name = name; - this.instrumentType = instrumentType; - this.instrumentValueType = instrumentValueType; - } - - @Override - public final B setDescription(String description) { - this.description = Objects.requireNonNull(description, "description"); - return getThis(); - } - - @Override - public final B setUnit(String unit) { - this.unit = Objects.requireNonNull(unit, "unit"); - return getThis(); - } - - abstract B getThis(); - - final InstrumentDescriptor buildDescriptor() { - return InstrumentDescriptor.create( - name, description, unit, instrumentType, instrumentValueType); - } - } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractInstrumentBuilder.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractInstrumentBuilder.java new file mode 100644 index 0000000000..d22b8b5022 --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractInstrumentBuilder.java @@ -0,0 +1,109 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics; + +import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; +import io.opentelemetry.api.metrics.ObservableLongMeasurement; +import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; +import io.opentelemetry.sdk.metrics.common.InstrumentType; +import io.opentelemetry.sdk.metrics.common.InstrumentValueType; +import java.util.function.BiFunction; +import java.util.function.Consumer; + +/** Helper to make implementing builders easier. */ +public abstract class AbstractInstrumentBuilder> { + private final MeterProviderSharedState meterProviderSharedState; + private final MeterSharedState meterSharedState; + private final String instrumentName; + private String description; + private String unit; + + AbstractInstrumentBuilder( + MeterProviderSharedState meterProviderSharedState, + MeterSharedState meterSharedState, + String name, + String description, + String unit) { + this.instrumentName = name; + this.description = description; + this.unit = unit; + this.meterProviderSharedState = meterProviderSharedState; + this.meterSharedState = meterSharedState; + } + + protected abstract BuilderT getThis(); + + public BuilderT setUnit(String unit) { + this.unit = unit; + return getThis(); + } + + public BuilderT setDescription(String description) { + this.description = description; + return getThis(); + } + + private InstrumentDescriptor makeDescriptor(InstrumentType type, InstrumentValueType valueType) { + return InstrumentDescriptor.create(instrumentName, description, unit, type, valueType); + } + + protected T swapBuilder(SwapBuilder swapper) { + return swapper.newBuilder( + meterProviderSharedState, meterSharedState, instrumentName, description, unit); + } + + final I buildSynchronousInstrument( + InstrumentType type, + InstrumentValueType valueType, + BiFunction, I> instrumentFactory) { + InstrumentDescriptor descriptor = makeDescriptor(type, valueType); + return meterSharedState + .getInstrumentRegistry() + .register( + instrumentFactory.apply( + descriptor, + SynchronousInstrumentAccumulator.create( + meterProviderSharedState, meterSharedState, descriptor))); + } + + final I buildDoubleAsynchronousInstrument( + InstrumentType type, + Consumer updater, + BiFunction instrumentFactory) { + InstrumentDescriptor descriptor = makeDescriptor(type, InstrumentValueType.DOUBLE); + return meterSharedState + .getInstrumentRegistry() + .register( + instrumentFactory.apply( + descriptor, + AsynchronousInstrumentAccumulator.doubleAsynchronousAccumulator( + meterProviderSharedState, meterSharedState, descriptor, updater))); + } + + final I buildLongAsynchronousInstrument( + InstrumentType type, + Consumer updater, + BiFunction instrumentFactory) { + InstrumentDescriptor descriptor = makeDescriptor(type, InstrumentValueType.LONG); + return meterSharedState + .getInstrumentRegistry() + .register( + instrumentFactory.apply( + descriptor, + AsynchronousInstrumentAccumulator.longAsynchronousAccumulator( + meterProviderSharedState, meterSharedState, descriptor, updater))); + } + + @FunctionalInterface + protected static interface SwapBuilder { + T newBuilder( + MeterProviderSharedState meterProviderSharedState, + MeterSharedState meterSharedState, + String name, + String description, + String unit); + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractLongAsynchronousInstrumentBuilder.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractLongAsynchronousInstrumentBuilder.java deleted file mode 100644 index 4fa0739a75..0000000000 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractLongAsynchronousInstrumentBuilder.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.metrics; - -import io.opentelemetry.api.metrics.AsynchronousInstrument; -import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; -import io.opentelemetry.sdk.metrics.common.InstrumentType; -import io.opentelemetry.sdk.metrics.common.InstrumentValueType; -import java.util.function.BiFunction; -import java.util.function.Consumer; -import javax.annotation.Nullable; - -abstract class AbstractLongAsynchronousInstrumentBuilder> - extends AbstractInstrument.Builder { - private final MeterProviderSharedState meterProviderSharedState; - private final MeterSharedState meterSharedState; - @Nullable private Consumer updater; - - AbstractLongAsynchronousInstrumentBuilder( - String name, - InstrumentType instrumentType, - InstrumentValueType instrumentValueType, - MeterProviderSharedState meterProviderSharedState, - MeterSharedState meterSharedState) { - super(name, instrumentType, instrumentValueType); - this.meterProviderSharedState = meterProviderSharedState; - this.meterSharedState = meterSharedState; - } - - public B setUpdater(Consumer updater) { - this.updater = updater; - return getThis(); - } - - final I buildInstrument( - BiFunction instrumentFactory) { - InstrumentDescriptor descriptor = buildDescriptor(); - return meterSharedState - .getInstrumentRegistry() - .register( - instrumentFactory.apply( - descriptor, - AsynchronousInstrumentAccumulator.longAsynchronousAccumulator( - meterProviderSharedState, meterSharedState, descriptor, updater))); - } -} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractSynchronousInstrument.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractSynchronousInstrument.java index 419659208c..1f4f2afb9c 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractSynchronousInstrument.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractSynchronousInstrument.java @@ -5,7 +5,7 @@ package io.opentelemetry.sdk.metrics; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.metrics.aggregator.AggregatorHandle; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.data.MetricData; @@ -25,7 +25,7 @@ abstract class AbstractSynchronousInstrument extends AbstractInstrument { return accumulator.collectAll(epochNanos); } - AggregatorHandle acquireHandle(Labels labels) { + AggregatorHandle acquireHandle(Attributes labels) { return accumulator.bind(labels); } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractSynchronousInstrumentBuilder.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractSynchronousInstrumentBuilder.java deleted file mode 100644 index 4e5f25e5bb..0000000000 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractSynchronousInstrumentBuilder.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.metrics; - -import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; -import io.opentelemetry.sdk.metrics.common.InstrumentType; -import io.opentelemetry.sdk.metrics.common.InstrumentValueType; -import java.util.function.BiFunction; - -abstract class AbstractSynchronousInstrumentBuilder< - B extends AbstractSynchronousInstrumentBuilder> - extends AbstractInstrument.Builder { - private final MeterProviderSharedState meterProviderSharedState; - private final MeterSharedState meterSharedState; - - AbstractSynchronousInstrumentBuilder( - String name, - InstrumentType instrumentType, - InstrumentValueType instrumentValueType, - MeterProviderSharedState meterProviderSharedState, - MeterSharedState meterSharedState) { - super(name, instrumentType, instrumentValueType); - this.meterProviderSharedState = meterProviderSharedState; - this.meterSharedState = meterSharedState; - } - - final I buildInstrument( - BiFunction, I> instrumentFactory) { - InstrumentDescriptor descriptor = buildDescriptor(); - return meterSharedState - .getInstrumentRegistry() - .register( - instrumentFactory.apply( - descriptor, - SynchronousInstrumentAccumulator.create( - meterProviderSharedState, meterSharedState, descriptor))); - } -} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AsynchronousInstrumentAccumulator.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AsynchronousInstrumentAccumulator.java index 5ccbcd5353..e6fe984831 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AsynchronousInstrumentAccumulator.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AsynchronousInstrumentAccumulator.java @@ -5,7 +5,9 @@ package io.opentelemetry.sdk.metrics; -import io.opentelemetry.api.metrics.AsynchronousInstrument; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; +import io.opentelemetry.api.metrics.ObservableLongMeasurement; import io.opentelemetry.context.Context; import io.opentelemetry.sdk.metrics.aggregator.Aggregator; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; @@ -14,7 +16,6 @@ import io.opentelemetry.sdk.metrics.processor.LabelsProcessor; import java.util.List; import java.util.concurrent.locks.ReentrantLock; import java.util.function.Consumer; -import javax.annotation.Nullable; final class AsynchronousInstrumentAccumulator extends AbstractAccumulator { private final ReentrantLock collectLock = new ReentrantLock(); @@ -25,23 +26,29 @@ final class AsynchronousInstrumentAccumulator extends AbstractAccumulator { MeterProviderSharedState meterProviderSharedState, MeterSharedState meterSharedState, InstrumentDescriptor descriptor, - @Nullable Consumer metricUpdater) { + Consumer metricUpdater) { Aggregator aggregator = getAggregator(meterProviderSharedState, meterSharedState, descriptor); - InstrumentProcessor instrumentProcessor = + final InstrumentProcessor instrumentProcessor = new InstrumentProcessor<>(aggregator, meterProviderSharedState.getStartEpochNanos()); - // TODO: Decide what to do with null updater. - if (metricUpdater == null) { - return new AsynchronousInstrumentAccumulator(instrumentProcessor, () -> {}); - } - LabelsProcessor labelsProcessor = + final LabelsProcessor labelsProcessor = getLabelsProcessor(meterProviderSharedState, meterSharedState, descriptor); - AsynchronousInstrument.DoubleResult result = - (value, labels) -> + + final ObservableDoubleMeasurement result = + new ObservableDoubleMeasurement() { + @Override + public void observe(double value, Attributes attributes) { instrumentProcessor.batch( - labelsProcessor.onLabelsBound(Context.current(), labels), + labelsProcessor.onLabelsBound(Context.current(), attributes), aggregator.accumulateDouble(value)); + } + + @Override + public void observe(double value) { + observe(value, Attributes.empty()); + } + }; return new AsynchronousInstrumentAccumulator( instrumentProcessor, () -> metricUpdater.accept(result)); @@ -51,24 +58,29 @@ final class AsynchronousInstrumentAccumulator extends AbstractAccumulator { MeterProviderSharedState meterProviderSharedState, MeterSharedState meterSharedState, InstrumentDescriptor descriptor, - @Nullable Consumer metricUpdater) { + Consumer metricUpdater) { Aggregator aggregator = getAggregator(meterProviderSharedState, meterSharedState, descriptor); - InstrumentProcessor instrumentProcessor = + final InstrumentProcessor instrumentProcessor = new InstrumentProcessor<>(aggregator, meterProviderSharedState.getStartEpochNanos()); - // TODO: Decide what to do with null updater. - if (metricUpdater == null) { - return new AsynchronousInstrumentAccumulator(instrumentProcessor, () -> {}); - } - LabelsProcessor labelsProcessor = + final LabelsProcessor labelsProcessor = getLabelsProcessor(meterProviderSharedState, meterSharedState, descriptor); - AsynchronousInstrument.LongResult result = - (value, labels) -> - instrumentProcessor.batch( - labelsProcessor.onLabelsBound(Context.current(), labels), - aggregator.accumulateLong(value)); + final ObservableLongMeasurement result = + new ObservableLongMeasurement() { + @Override + public void observe(long value, Attributes attributes) { + instrumentProcessor.batch( + labelsProcessor.onLabelsBound(Context.current(), attributes), + aggregator.accumulateLong(value)); + } + + @Override + public void observe(long value) { + observe(value, Attributes.empty()); + } + }; return new AsynchronousInstrumentAccumulator( instrumentProcessor, () -> metricUpdater.accept(result)); } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/BatchRecorderSdk.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/BatchRecorderSdk.java deleted file mode 100644 index 7dc09bb5fb..0000000000 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/BatchRecorderSdk.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.metrics; - -import io.opentelemetry.api.metrics.BatchRecorder; -import io.opentelemetry.api.metrics.DoubleCounter; -import io.opentelemetry.api.metrics.DoubleUpDownCounter; -import io.opentelemetry.api.metrics.DoubleValueRecorder; -import io.opentelemetry.api.metrics.Instrument; -import io.opentelemetry.api.metrics.LongCounter; -import io.opentelemetry.api.metrics.LongUpDownCounter; -import io.opentelemetry.api.metrics.LongValueRecorder; -import io.opentelemetry.api.metrics.common.Labels; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.LinkedTransferQueue; -import java.util.concurrent.TransferQueue; - -/** - * Minimal implementation of the {@link BatchRecorder} that simply redirects the calls to the - * instruments. - */ -final class BatchRecorderSdk implements BatchRecorder { - private final Labels labelSet; - - // todo: this queue is unbounded; should we make it bounded and drop recordings after it gets - // full? - private final TransferQueue pendingRecordings = new LinkedTransferQueue<>(); - - BatchRecorderSdk(String... keyValuePairs) { - this.labelSet = Labels.of(keyValuePairs); - } - - @Override - public BatchRecorder put(LongValueRecorder valueRecorder, long value) { - pendingRecordings.offer(new LongRecording(valueRecorder, value)); - return this; - } - - @Override - public BatchRecorder put(DoubleValueRecorder valueRecorder, double value) { - pendingRecordings.offer(new DoubleRecording(valueRecorder, value)); - return this; - } - - @Override - public BatchRecorder put(LongCounter counter, long value) { - pendingRecordings.offer(new LongRecording(counter, value)); - return this; - } - - @Override - public BatchRecorder put(DoubleCounter counter, double value) { - pendingRecordings.offer(new DoubleRecording(counter, value)); - return this; - } - - @Override - public BatchRecorder put(LongUpDownCounter upDownCounter, long value) { - pendingRecordings.offer(new LongRecording(upDownCounter, value)); - return this; - } - - @Override - public BatchRecorder put(DoubleUpDownCounter upDownCounter, double value) { - pendingRecordings.offer(new DoubleRecording(upDownCounter, value)); - return this; - } - - @Override - public void record() { - List recordings = new ArrayList<>(); - pendingRecordings.drainTo(recordings); - - recordings.forEach( - (recording) -> { - Instrument instrument = recording.getInstrument(); - if (instrument instanceof DoubleUpDownCounter) { - ((DoubleUpDownCounter) instrument).add(recording.getDoubleValue(), labelSet); - } else if (instrument instanceof DoubleCounter) { - ((DoubleCounter) instrument).add(recording.getDoubleValue(), labelSet); - } else if (instrument instanceof DoubleValueRecorder) { - ((DoubleValueRecorder) instrument).record(recording.getDoubleValue(), labelSet); - } else if (instrument instanceof LongUpDownCounter) { - ((LongUpDownCounter) instrument).add(recording.getLongValue(), labelSet); - } else if (instrument instanceof LongCounter) { - ((LongCounter) instrument).add(recording.getLongValue(), labelSet); - } else if (instrument instanceof LongValueRecorder) { - ((LongValueRecorder) instrument).record(recording.getLongValue(), labelSet); - } - }); - } - - private interface Recording { - Instrument getInstrument(); - - long getLongValue(); - - double getDoubleValue(); - } - - private static class LongRecording implements Recording { - private final Instrument instrument; - private final long value; - - private LongRecording(Instrument instrument, long value) { - this.instrument = instrument; - this.value = value; - } - - @Override - public Instrument getInstrument() { - return instrument; - } - - @Override - public long getLongValue() { - return value; - } - - @Override - public double getDoubleValue() { - throw new UnsupportedOperationException(); - } - } - - private static class DoubleRecording implements Recording { - private final Instrument instrument; - private final double value; - - private DoubleRecording(Instrument instrument, double value) { - this.instrument = instrument; - this.value = value; - } - - @Override - public Instrument getInstrument() { - return instrument; - } - - @Override - public long getLongValue() { - throw new UnsupportedOperationException(); - } - - @Override - public double getDoubleValue() { - return value; - } - } -} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/DoubleCounterSdk.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/DoubleCounterSdk.java index 7c0c8b52ac..28505bdbf8 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/DoubleCounterSdk.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/DoubleCounterSdk.java @@ -5,14 +5,18 @@ package io.opentelemetry.sdk.metrics; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.BoundDoubleCounter; import io.opentelemetry.api.metrics.DoubleCounter; import io.opentelemetry.api.metrics.DoubleCounterBuilder; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.metrics.LongCounterBuilder; +import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; +import io.opentelemetry.context.Context; import io.opentelemetry.sdk.metrics.aggregator.AggregatorHandle; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.common.InstrumentType; import io.opentelemetry.sdk.metrics.common.InstrumentValueType; +import java.util.function.Consumer; final class DoubleCounterSdk extends AbstractSynchronousInstrument implements DoubleCounter { @@ -22,7 +26,7 @@ final class DoubleCounterSdk extends AbstractSynchronousInstrument implements Do } @Override - public void add(double increment, Labels labels) { + public void add(double increment, Attributes labels, Context context) { AggregatorHandle aggregatorHandle = acquireHandle(labels); try { if (increment < 0) { @@ -35,12 +39,17 @@ final class DoubleCounterSdk extends AbstractSynchronousInstrument implements Do } @Override - public void add(double increment) { - add(increment, Labels.empty()); + public void add(double increment, Attributes attributes) { + add(increment, attributes, Context.current()); } @Override - public BoundDoubleCounter bind(Labels labels) { + public void add(double increment) { + add(increment, Attributes.empty()); + } + + @Override + public BoundDoubleCounter bind(Attributes labels) { return new BoundInstrument(acquireHandle(labels)); } @@ -52,42 +61,63 @@ final class DoubleCounterSdk extends AbstractSynchronousInstrument implements Do } @Override - public void add(double increment) { + public void add(double increment, Context context) { if (increment < 0) { throw new IllegalArgumentException("Counters can only increase"); } aggregatorHandle.recordDouble(increment); } + @Override + public void add(double increment) { + add(increment, Context.current()); + } + @Override public void unbind() { aggregatorHandle.release(); } } - static final class Builder extends AbstractSynchronousInstrumentBuilder + static final class Builder extends AbstractInstrumentBuilder implements DoubleCounterBuilder { Builder( - String name, MeterProviderSharedState meterProviderSharedState, - MeterSharedState meterSharedState) { - super( - name, - InstrumentType.COUNTER, - InstrumentValueType.DOUBLE, - meterProviderSharedState, - meterSharedState); + MeterSharedState meterSharedState, + String name) { + this(meterProviderSharedState, meterSharedState, name, "", "1"); + } + + Builder( + MeterProviderSharedState meterProviderSharedState, + MeterSharedState sharedState, + String name, + String description, + String unit) { + super(meterProviderSharedState, sharedState, name, description, unit); } @Override - Builder getThis() { + protected Builder getThis() { return this; } @Override public DoubleCounterSdk build() { - return buildInstrument(DoubleCounterSdk::new); + return buildSynchronousInstrument( + InstrumentType.COUNTER, InstrumentValueType.DOUBLE, DoubleCounterSdk::new); + } + + @Override + public LongCounterBuilder ofLongs() { + return swapBuilder(LongCounterSdk.Builder::new); + } + + @Override + public void buildWithCallback(Consumer callback) { + buildDoubleAsynchronousInstrument( + InstrumentType.SUM_OBSERVER, callback, DoubleSumObserverSdk::new); } } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/DoubleSumObserverSdk.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/DoubleSumObserverSdk.java index 9d87bdbfb5..dac43ce1b9 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/DoubleSumObserverSdk.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/DoubleSumObserverSdk.java @@ -5,44 +5,12 @@ package io.opentelemetry.sdk.metrics; -import io.opentelemetry.api.metrics.DoubleSumObserver; -import io.opentelemetry.api.metrics.DoubleSumObserverBuilder; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; -import io.opentelemetry.sdk.metrics.common.InstrumentType; -import io.opentelemetry.sdk.metrics.common.InstrumentValueType; -final class DoubleSumObserverSdk extends AbstractAsynchronousInstrument - implements DoubleSumObserver { +final class DoubleSumObserverSdk extends AbstractAsynchronousInstrument { DoubleSumObserverSdk( InstrumentDescriptor descriptor, AsynchronousInstrumentAccumulator accumulator) { super(descriptor, accumulator); } - - static final class Builder - extends AbstractDoubleAsynchronousInstrumentBuilder - implements DoubleSumObserverBuilder { - - Builder( - String name, - MeterProviderSharedState meterProviderSharedState, - MeterSharedState meterSharedState) { - super( - name, - InstrumentType.SUM_OBSERVER, - InstrumentValueType.DOUBLE, - meterProviderSharedState, - meterSharedState); - } - - @Override - Builder getThis() { - return this; - } - - @Override - public DoubleSumObserverSdk build() { - return buildInstrument(DoubleSumObserverSdk::new); - } - } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/DoubleUpDownCounterSdk.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/DoubleUpDownCounterSdk.java index 9fdb1624f2..d6fd2bace6 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/DoubleUpDownCounterSdk.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/DoubleUpDownCounterSdk.java @@ -5,14 +5,18 @@ package io.opentelemetry.sdk.metrics; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.BoundDoubleUpDownCounter; import io.opentelemetry.api.metrics.DoubleUpDownCounter; import io.opentelemetry.api.metrics.DoubleUpDownCounterBuilder; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.metrics.LongUpDownCounterBuilder; +import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; +import io.opentelemetry.context.Context; import io.opentelemetry.sdk.metrics.aggregator.AggregatorHandle; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.common.InstrumentType; import io.opentelemetry.sdk.metrics.common.InstrumentValueType; +import java.util.function.Consumer; final class DoubleUpDownCounterSdk extends AbstractSynchronousInstrument implements DoubleUpDownCounter { @@ -23,7 +27,7 @@ final class DoubleUpDownCounterSdk extends AbstractSynchronousInstrument } @Override - public void add(double increment, Labels labels) { + public void add(double increment, Attributes labels, Context context) { AggregatorHandle aggregatorHandle = acquireHandle(labels); try { aggregatorHandle.recordDouble(increment); @@ -33,12 +37,17 @@ final class DoubleUpDownCounterSdk extends AbstractSynchronousInstrument } @Override - public void add(double increment) { - add(increment, Labels.empty()); + public void add(double increment, Attributes attributes) { + add(increment, attributes, Context.current()); } @Override - public BoundDoubleUpDownCounter bind(Labels labels) { + public void add(double increment) { + add(increment, Attributes.empty()); + } + + @Override + public BoundDoubleUpDownCounter bind(Attributes labels) { return new BoundInstrument(acquireHandle(labels)); } @@ -50,40 +59,60 @@ final class DoubleUpDownCounterSdk extends AbstractSynchronousInstrument } @Override - public void add(double increment) { + public void add(double increment, Context context) { aggregatorHandle.recordDouble(increment); } + @Override + public void add(double increment) { + add(increment, Context.current()); + } + @Override public void unbind() { aggregatorHandle.release(); } } - static final class Builder - extends AbstractSynchronousInstrumentBuilder + static final class Builder extends AbstractInstrumentBuilder implements DoubleUpDownCounterBuilder { Builder( - String name, MeterProviderSharedState meterProviderSharedState, - MeterSharedState meterSharedState) { - super( - name, - InstrumentType.UP_DOWN_COUNTER, - InstrumentValueType.DOUBLE, - meterProviderSharedState, - meterSharedState); + MeterSharedState meterSharedState, + String name) { + this(meterProviderSharedState, meterSharedState, name, "", "1"); + } + + Builder( + MeterProviderSharedState meterProviderSharedState, + MeterSharedState sharedState, + String name, + String description, + String unit) { + super(meterProviderSharedState, sharedState, name, description, unit); } @Override - Builder getThis() { + protected Builder getThis() { return this; } @Override - public DoubleUpDownCounterSdk build() { - return buildInstrument(DoubleUpDownCounterSdk::new); + public DoubleUpDownCounter build() { + return buildSynchronousInstrument( + InstrumentType.UP_DOWN_COUNTER, InstrumentValueType.DOUBLE, DoubleUpDownCounterSdk::new); + } + + @Override + public LongUpDownCounterBuilder ofLongs() { + return swapBuilder(LongUpDownCounterSdk.Builder::new); + } + + @Override + public void buildWithCallback(Consumer callback) { + buildDoubleAsynchronousInstrument( + InstrumentType.UP_DOWN_SUM_OBSERVER, callback, DoubleUpDownSumObserverSdk::new); } } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/DoubleUpDownSumObserverSdk.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/DoubleUpDownSumObserverSdk.java index 0ce56434fb..a2188ea03e 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/DoubleUpDownSumObserverSdk.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/DoubleUpDownSumObserverSdk.java @@ -5,44 +5,12 @@ package io.opentelemetry.sdk.metrics; -import io.opentelemetry.api.metrics.DoubleUpDownSumObserver; -import io.opentelemetry.api.metrics.DoubleUpDownSumObserverBuilder; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; -import io.opentelemetry.sdk.metrics.common.InstrumentType; -import io.opentelemetry.sdk.metrics.common.InstrumentValueType; -final class DoubleUpDownSumObserverSdk extends AbstractAsynchronousInstrument - implements DoubleUpDownSumObserver { +final class DoubleUpDownSumObserverSdk extends AbstractAsynchronousInstrument { DoubleUpDownSumObserverSdk( InstrumentDescriptor descriptor, AsynchronousInstrumentAccumulator accumulator) { super(descriptor, accumulator); } - - static final class Builder - extends AbstractDoubleAsynchronousInstrumentBuilder - implements DoubleUpDownSumObserverBuilder { - - Builder( - String name, - MeterProviderSharedState meterProviderSharedState, - MeterSharedState meterSharedState) { - super( - name, - InstrumentType.UP_DOWN_SUM_OBSERVER, - InstrumentValueType.DOUBLE, - meterProviderSharedState, - meterSharedState); - } - - @Override - Builder getThis() { - return this; - } - - @Override - public DoubleUpDownSumObserverSdk build() { - return buildInstrument(DoubleUpDownSumObserverSdk::new); - } - } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/DoubleValueObserverSdk.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/DoubleValueObserverSdk.java index ef5af03037..ca65f48546 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/DoubleValueObserverSdk.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/DoubleValueObserverSdk.java @@ -5,44 +5,53 @@ package io.opentelemetry.sdk.metrics; -import io.opentelemetry.api.metrics.DoubleValueObserver; -import io.opentelemetry.api.metrics.DoubleValueObserverBuilder; +import io.opentelemetry.api.metrics.DoubleGaugeBuilder; +import io.opentelemetry.api.metrics.LongGaugeBuilder; +import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.common.InstrumentType; -import io.opentelemetry.sdk.metrics.common.InstrumentValueType; +import java.util.function.Consumer; -final class DoubleValueObserverSdk extends AbstractAsynchronousInstrument - implements DoubleValueObserver { +final class DoubleValueObserverSdk extends AbstractAsynchronousInstrument { DoubleValueObserverSdk( InstrumentDescriptor descriptor, AsynchronousInstrumentAccumulator accumulator) { super(descriptor, accumulator); } - static final class Builder - extends AbstractDoubleAsynchronousInstrumentBuilder - implements DoubleValueObserverBuilder { + static final class Builder extends AbstractInstrumentBuilder + implements DoubleGaugeBuilder { Builder( - String name, MeterProviderSharedState meterProviderSharedState, - MeterSharedState meterSharedState) { - super( - name, - InstrumentType.VALUE_OBSERVER, - InstrumentValueType.DOUBLE, - meterProviderSharedState, - meterSharedState); + MeterSharedState meterSharedState, + String name) { + this(meterProviderSharedState, meterSharedState, name, "", "1"); + } + + Builder( + MeterProviderSharedState meterProviderSharedState, + MeterSharedState sharedState, + String name, + String description, + String unit) { + super(meterProviderSharedState, sharedState, name, description, unit); } @Override - Builder getThis() { + protected Builder getThis() { return this; } @Override - public DoubleValueObserverSdk build() { - return buildInstrument(DoubleValueObserverSdk::new); + public LongGaugeBuilder ofLongs() { + return swapBuilder(LongValueObserverSdk.Builder::new); + } + + @Override + public void buildWithCallback(Consumer callback) { + buildDoubleAsynchronousInstrument( + InstrumentType.VALUE_OBSERVER, callback, DoubleValueObserverSdk::new); } } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/DoubleValueRecorderSdk.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/DoubleValueRecorderSdk.java index d6f4deab94..d6fb15521b 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/DoubleValueRecorderSdk.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/DoubleValueRecorderSdk.java @@ -5,17 +5,19 @@ package io.opentelemetry.sdk.metrics; -import io.opentelemetry.api.metrics.BoundDoubleValueRecorder; -import io.opentelemetry.api.metrics.DoubleValueRecorder; -import io.opentelemetry.api.metrics.DoubleValueRecorderBuilder; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.BoundDoubleHistogram; +import io.opentelemetry.api.metrics.DoubleHistogram; +import io.opentelemetry.api.metrics.DoubleHistogramBuilder; +import io.opentelemetry.api.metrics.LongHistogramBuilder; +import io.opentelemetry.context.Context; import io.opentelemetry.sdk.metrics.aggregator.AggregatorHandle; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.common.InstrumentType; import io.opentelemetry.sdk.metrics.common.InstrumentValueType; final class DoubleValueRecorderSdk extends AbstractSynchronousInstrument - implements DoubleValueRecorder { + implements DoubleHistogram { private DoubleValueRecorderSdk( InstrumentDescriptor descriptor, SynchronousInstrumentAccumulator accumulator) { @@ -23,7 +25,7 @@ final class DoubleValueRecorderSdk extends AbstractSynchronousInstrument } @Override - public void record(double value, Labels labels) { + public void record(double value, Attributes labels, Context context) { AggregatorHandle aggregatorHandle = acquireHandle(labels); try { aggregatorHandle.recordDouble(value); @@ -33,16 +35,21 @@ final class DoubleValueRecorderSdk extends AbstractSynchronousInstrument } @Override - public void record(double value) { - record(value, Labels.empty()); + public void record(double value, Attributes labels) { + record(value, labels, Context.current()); } @Override - public BoundDoubleValueRecorder bind(Labels labels) { + public void record(double value) { + record(value, Attributes.empty()); + } + + @Override + public BoundDoubleHistogram bind(Attributes labels) { return new BoundInstrument(acquireHandle(labels)); } - static final class BoundInstrument implements BoundDoubleValueRecorder { + static final class BoundInstrument implements BoundDoubleHistogram { private final AggregatorHandle aggregatorHandle; BoundInstrument(AggregatorHandle aggregatorHandle) { @@ -50,40 +57,54 @@ final class DoubleValueRecorderSdk extends AbstractSynchronousInstrument } @Override - public void record(double value) { + public void record(double value, Context context) { aggregatorHandle.recordDouble(value); } + @Override + public void record(double value) { + record(value, Context.current()); + } + @Override public void unbind() { aggregatorHandle.release(); } } - static final class Builder - extends AbstractSynchronousInstrumentBuilder - implements DoubleValueRecorderBuilder { + static final class Builder extends AbstractInstrumentBuilder + implements DoubleHistogramBuilder { Builder( - String name, MeterProviderSharedState meterProviderSharedState, - MeterSharedState meterSharedState) { - super( - name, - InstrumentType.VALUE_RECORDER, - InstrumentValueType.DOUBLE, - meterProviderSharedState, - meterSharedState); + MeterSharedState meterSharedState, + String name) { + this(meterProviderSharedState, meterSharedState, name, "", "1"); + } + + Builder( + MeterProviderSharedState meterProviderSharedState, + MeterSharedState sharedState, + String name, + String description, + String unit) { + super(meterProviderSharedState, sharedState, name, description, unit); } @Override - Builder getThis() { + protected Builder getThis() { return this; } @Override public DoubleValueRecorderSdk build() { - return buildInstrument(DoubleValueRecorderSdk::new); + return buildSynchronousInstrument( + InstrumentType.VALUE_RECORDER, InstrumentValueType.DOUBLE, DoubleValueRecorderSdk::new); + } + + @Override + public LongHistogramBuilder ofLongs() { + return swapBuilder(LongValueRecorderSdk.Builder::new); } } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/Instrument.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/Instrument.java new file mode 100644 index 0000000000..6fc8692a37 --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/Instrument.java @@ -0,0 +1,14 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics; + +/** + * Placeholder to avoid modifying SDK implementation. + * + *

Previously, this was defined in the API. However, the new API for asynchronous instruments + * returns no value to the user, as there's nothing the user can alter (yet). + */ +interface Instrument {} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/InstrumentProcessor.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/InstrumentProcessor.java index 1cd45eeb40..5afd286c80 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/InstrumentProcessor.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/InstrumentProcessor.java @@ -5,7 +5,7 @@ package io.opentelemetry.sdk.metrics; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.metrics.aggregator.Aggregator; import io.opentelemetry.sdk.metrics.data.MetricData; import java.util.Collections; @@ -25,7 +25,7 @@ final class InstrumentProcessor { private final Aggregator aggregator; private final long startEpochNanos; private long lastEpochNanos; - private Map accumulationMap; + private Map accumulationMap; InstrumentProcessor(Aggregator aggregator, long startEpochNanos) { this.aggregator = aggregator; @@ -41,7 +41,7 @@ final class InstrumentProcessor { * @param labelSet the {@link Labels} associated with this {@code Aggregator}. * @param accumulation the accumulation produced by this instrument. */ - void batch(Labels labelSet, T accumulation) { + void batch(Attributes labelSet, T accumulation) { T currentAccumulation = accumulationMap.get(labelSet); if (currentAccumulation == null) { accumulationMap.put(labelSet, accumulation); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/LongCounterSdk.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/LongCounterSdk.java index 79a6662b02..47c74872de 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/LongCounterSdk.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/LongCounterSdk.java @@ -5,14 +5,18 @@ package io.opentelemetry.sdk.metrics; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.BoundLongCounter; +import io.opentelemetry.api.metrics.DoubleCounterBuilder; import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.api.metrics.LongCounterBuilder; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.metrics.ObservableLongMeasurement; +import io.opentelemetry.context.Context; import io.opentelemetry.sdk.metrics.aggregator.AggregatorHandle; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.common.InstrumentType; import io.opentelemetry.sdk.metrics.common.InstrumentValueType; +import java.util.function.Consumer; final class LongCounterSdk extends AbstractSynchronousInstrument implements LongCounter { @@ -22,7 +26,7 @@ final class LongCounterSdk extends AbstractSynchronousInstrument implements Long } @Override - public void add(long increment, Labels labels) { + public void add(long increment, Attributes labels, Context context) { AggregatorHandle aggregatorHandle = acquireHandle(labels); try { if (increment < 0) { @@ -35,12 +39,17 @@ final class LongCounterSdk extends AbstractSynchronousInstrument implements Long } @Override - public void add(long increment) { - add(increment, Labels.empty()); + public void add(long increment, Attributes attributes) { + add(increment, attributes, Context.current()); } @Override - public BoundLongCounter bind(Labels labels) { + public void add(long increment) { + add(increment, Attributes.empty()); + } + + @Override + public BoundLongCounter bind(Attributes labels) { return new BoundInstrument(acquireHandle(labels)); } @@ -52,42 +61,63 @@ final class LongCounterSdk extends AbstractSynchronousInstrument implements Long } @Override - public void add(long increment) { + public void add(long increment, Context context) { if (increment < 0) { throw new IllegalArgumentException("Counters can only increase"); } aggregatorHandle.recordLong(increment); } + @Override + public void add(long increment) { + add(increment, Context.current()); + } + @Override public void unbind() { aggregatorHandle.release(); } } - static final class Builder extends AbstractSynchronousInstrumentBuilder + static final class Builder extends AbstractInstrumentBuilder implements LongCounterBuilder { Builder( - String name, MeterProviderSharedState meterProviderSharedState, - MeterSharedState meterSharedState) { - super( - name, - InstrumentType.COUNTER, - InstrumentValueType.LONG, - meterProviderSharedState, - meterSharedState); + MeterSharedState meterSharedState, + String name) { + this(meterProviderSharedState, meterSharedState, name, "", "1"); + } + + Builder( + MeterProviderSharedState meterProviderSharedState, + MeterSharedState sharedState, + String name, + String description, + String unit) { + super(meterProviderSharedState, sharedState, name, description, unit); } @Override - Builder getThis() { + protected Builder getThis() { return this; } @Override public LongCounterSdk build() { - return buildInstrument(LongCounterSdk::new); + return buildSynchronousInstrument( + InstrumentType.COUNTER, InstrumentValueType.LONG, LongCounterSdk::new); + } + + @Override + public DoubleCounterBuilder ofDoubles() { + return swapBuilder(DoubleCounterSdk.Builder::new); + } + + @Override + public void buildWithCallback(Consumer callback) { + buildLongAsynchronousInstrument( + InstrumentType.SUM_OBSERVER, callback, LongSumObserverSdk::new); } } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/LongSumObserverSdk.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/LongSumObserverSdk.java index 8ed14be050..b33203a478 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/LongSumObserverSdk.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/LongSumObserverSdk.java @@ -5,43 +5,12 @@ package io.opentelemetry.sdk.metrics; -import io.opentelemetry.api.metrics.LongSumObserver; -import io.opentelemetry.api.metrics.LongSumObserverBuilder; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; -import io.opentelemetry.sdk.metrics.common.InstrumentType; -import io.opentelemetry.sdk.metrics.common.InstrumentValueType; -final class LongSumObserverSdk extends AbstractAsynchronousInstrument implements LongSumObserver { +final class LongSumObserverSdk extends AbstractAsynchronousInstrument { LongSumObserverSdk( InstrumentDescriptor descriptor, AsynchronousInstrumentAccumulator accumulator) { super(descriptor, accumulator); } - - static final class Builder - extends AbstractLongAsynchronousInstrumentBuilder - implements LongSumObserverBuilder { - - Builder( - String name, - MeterProviderSharedState meterProviderSharedState, - MeterSharedState meterSharedState) { - super( - name, - InstrumentType.SUM_OBSERVER, - InstrumentValueType.LONG, - meterProviderSharedState, - meterSharedState); - } - - @Override - Builder getThis() { - return this; - } - - @Override - public LongSumObserverSdk build() { - return buildInstrument(LongSumObserverSdk::new); - } - } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/LongUpDownCounterSdk.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/LongUpDownCounterSdk.java index 975fcad08f..0bf43e50ce 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/LongUpDownCounterSdk.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/LongUpDownCounterSdk.java @@ -5,14 +5,18 @@ package io.opentelemetry.sdk.metrics; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.BoundLongUpDownCounter; +import io.opentelemetry.api.metrics.DoubleUpDownCounterBuilder; import io.opentelemetry.api.metrics.LongUpDownCounter; import io.opentelemetry.api.metrics.LongUpDownCounterBuilder; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.metrics.ObservableLongMeasurement; +import io.opentelemetry.context.Context; import io.opentelemetry.sdk.metrics.aggregator.AggregatorHandle; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.common.InstrumentType; import io.opentelemetry.sdk.metrics.common.InstrumentValueType; +import java.util.function.Consumer; final class LongUpDownCounterSdk extends AbstractSynchronousInstrument implements LongUpDownCounter { @@ -23,7 +27,7 @@ final class LongUpDownCounterSdk extends AbstractSynchronousInstrument } @Override - public void add(long increment, Labels labels) { + public void add(long increment, Attributes labels, Context context) { AggregatorHandle aggregatorHandle = acquireHandle(labels); try { aggregatorHandle.recordLong(increment); @@ -33,12 +37,17 @@ final class LongUpDownCounterSdk extends AbstractSynchronousInstrument } @Override - public void add(long increment) { - add(increment, Labels.empty()); + public void add(long increment, Attributes attributes) { + add(increment, attributes, Context.current()); } @Override - public BoundLongUpDownCounter bind(Labels labels) { + public void add(long increment) { + add(increment, Attributes.empty()); + } + + @Override + public BoundLongUpDownCounter bind(Attributes labels) { return new BoundInstrument(acquireHandle(labels)); } @@ -50,40 +59,60 @@ final class LongUpDownCounterSdk extends AbstractSynchronousInstrument } @Override - public void add(long increment) { + public void add(long increment, Context context) { aggregatorHandle.recordLong(increment); } + @Override + public void add(long increment) { + add(increment, Context.current()); + } + @Override public void unbind() { aggregatorHandle.release(); } } - static final class Builder - extends AbstractSynchronousInstrumentBuilder + static final class Builder extends AbstractInstrumentBuilder implements LongUpDownCounterBuilder { Builder( - String name, MeterProviderSharedState meterProviderSharedState, - MeterSharedState meterSharedState) { - super( - name, - InstrumentType.UP_DOWN_COUNTER, - InstrumentValueType.LONG, - meterProviderSharedState, - meterSharedState); + MeterSharedState meterSharedState, + String name) { + this(meterProviderSharedState, meterSharedState, name, "", "1"); + } + + Builder( + MeterProviderSharedState meterProviderSharedState, + MeterSharedState sharedState, + String name, + String description, + String unit) { + super(meterProviderSharedState, sharedState, name, description, unit); } @Override - Builder getThis() { + protected Builder getThis() { return this; } @Override - public LongUpDownCounterSdk build() { - return buildInstrument(LongUpDownCounterSdk::new); + public LongUpDownCounter build() { + return buildSynchronousInstrument( + InstrumentType.UP_DOWN_COUNTER, InstrumentValueType.LONG, LongUpDownCounterSdk::new); + } + + @Override + public DoubleUpDownCounterBuilder ofDoubles() { + return swapBuilder(DoubleUpDownCounterSdk.Builder::new); + } + + @Override + public void buildWithCallback(Consumer callback) { + buildLongAsynchronousInstrument( + InstrumentType.UP_DOWN_SUM_OBSERVER, callback, LongUpDownSumObserverSdk::new); } } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/LongUpDownSumObserverSdk.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/LongUpDownSumObserverSdk.java index cb79e12c0d..6507f1aeb3 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/LongUpDownSumObserverSdk.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/LongUpDownSumObserverSdk.java @@ -5,44 +5,12 @@ package io.opentelemetry.sdk.metrics; -import io.opentelemetry.api.metrics.LongUpDownSumObserver; -import io.opentelemetry.api.metrics.LongUpDownSumObserverBuilder; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; -import io.opentelemetry.sdk.metrics.common.InstrumentType; -import io.opentelemetry.sdk.metrics.common.InstrumentValueType; -final class LongUpDownSumObserverSdk extends AbstractAsynchronousInstrument - implements LongUpDownSumObserver { +final class LongUpDownSumObserverSdk extends AbstractAsynchronousInstrument { LongUpDownSumObserverSdk( InstrumentDescriptor descriptor, AsynchronousInstrumentAccumulator accumulator) { super(descriptor, accumulator); } - - static final class Builder - extends AbstractLongAsynchronousInstrumentBuilder - implements LongUpDownSumObserverBuilder { - - Builder( - String name, - MeterProviderSharedState meterProviderSharedState, - MeterSharedState meterSharedState) { - super( - name, - InstrumentType.UP_DOWN_SUM_OBSERVER, - InstrumentValueType.LONG, - meterProviderSharedState, - meterSharedState); - } - - @Override - Builder getThis() { - return this; - } - - @Override - public LongUpDownSumObserverSdk build() { - return buildInstrument(LongUpDownSumObserverSdk::new); - } - } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/LongValueObserverSdk.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/LongValueObserverSdk.java index 59c44e118f..3b16f352ea 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/LongValueObserverSdk.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/LongValueObserverSdk.java @@ -5,44 +5,53 @@ package io.opentelemetry.sdk.metrics; -import io.opentelemetry.api.metrics.LongValueObserver; -import io.opentelemetry.api.metrics.LongValueObserverBuilder; +import io.opentelemetry.api.metrics.DoubleGaugeBuilder; +import io.opentelemetry.api.metrics.LongGaugeBuilder; +import io.opentelemetry.api.metrics.ObservableLongMeasurement; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.common.InstrumentType; -import io.opentelemetry.sdk.metrics.common.InstrumentValueType; +import java.util.function.Consumer; -final class LongValueObserverSdk extends AbstractAsynchronousInstrument - implements LongValueObserver { +final class LongValueObserverSdk extends AbstractAsynchronousInstrument { LongValueObserverSdk( InstrumentDescriptor descriptor, AsynchronousInstrumentAccumulator accumulator) { super(descriptor, accumulator); } - static final class Builder - extends AbstractLongAsynchronousInstrumentBuilder - implements LongValueObserverBuilder { + static final class Builder extends AbstractInstrumentBuilder + implements LongGaugeBuilder { Builder( - String name, MeterProviderSharedState meterProviderSharedState, - MeterSharedState meterSharedState) { - super( - name, - InstrumentType.VALUE_OBSERVER, - InstrumentValueType.LONG, - meterProviderSharedState, - meterSharedState); + MeterSharedState meterSharedState, + String name) { + this(meterProviderSharedState, meterSharedState, name, "", "1"); + } + + Builder( + MeterProviderSharedState meterProviderSharedState, + MeterSharedState sharedState, + String name, + String description, + String unit) { + super(meterProviderSharedState, sharedState, name, description, unit); } @Override - Builder getThis() { + protected Builder getThis() { return this; } @Override - public LongValueObserverSdk build() { - return buildInstrument(LongValueObserverSdk::new); + public DoubleGaugeBuilder ofDoubles() { + return swapBuilder(DoubleValueObserverSdk.Builder::new); + } + + @Override + public void buildWithCallback(Consumer callback) { + buildLongAsynchronousInstrument( + InstrumentType.VALUE_OBSERVER, callback, LongValueObserverSdk::new); } } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/LongValueRecorderSdk.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/LongValueRecorderSdk.java index e8182cfe5d..809d169f91 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/LongValueRecorderSdk.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/LongValueRecorderSdk.java @@ -5,17 +5,18 @@ package io.opentelemetry.sdk.metrics; -import io.opentelemetry.api.metrics.BoundLongValueRecorder; -import io.opentelemetry.api.metrics.LongValueRecorder; -import io.opentelemetry.api.metrics.LongValueRecorderBuilder; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.BoundLongHistogram; +import io.opentelemetry.api.metrics.DoubleHistogramBuilder; +import io.opentelemetry.api.metrics.LongHistogram; +import io.opentelemetry.api.metrics.LongHistogramBuilder; +import io.opentelemetry.context.Context; import io.opentelemetry.sdk.metrics.aggregator.AggregatorHandle; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.common.InstrumentType; import io.opentelemetry.sdk.metrics.common.InstrumentValueType; -final class LongValueRecorderSdk extends AbstractSynchronousInstrument - implements LongValueRecorder { +final class LongValueRecorderSdk extends AbstractSynchronousInstrument implements LongHistogram { private LongValueRecorderSdk( InstrumentDescriptor descriptor, SynchronousInstrumentAccumulator accumulator) { @@ -23,8 +24,8 @@ final class LongValueRecorderSdk extends AbstractSynchronousInstrument } @Override - public void record(long value, Labels labels) { - AggregatorHandle aggregatorHandle = acquireHandle(labels); + public void record(long value, Attributes attributes, Context context) { + AggregatorHandle aggregatorHandle = acquireHandle(attributes); try { aggregatorHandle.recordLong(value); } finally { @@ -33,16 +34,21 @@ final class LongValueRecorderSdk extends AbstractSynchronousInstrument } @Override - public void record(long value) { - record(value, Labels.empty()); + public void record(long value, Attributes attributes) { + record(value, attributes, Context.current()); } @Override - public BoundLongValueRecorder bind(Labels labels) { - return new BoundInstrument(acquireHandle(labels)); + public void record(long value) { + record(value, Attributes.empty()); } - static final class BoundInstrument implements BoundLongValueRecorder { + @Override + public BoundLongHistogram bind(Attributes attributes) { + return new BoundInstrument(acquireHandle(attributes)); + } + + static final class BoundInstrument implements BoundLongHistogram { private final AggregatorHandle aggregatorHandle; BoundInstrument(AggregatorHandle aggregatorHandle) { @@ -50,40 +56,54 @@ final class LongValueRecorderSdk extends AbstractSynchronousInstrument } @Override - public void record(long value) { + public void record(long value, Context context) { aggregatorHandle.recordLong(value); } + @Override + public void record(long value) { + record(value, Context.current()); + } + @Override public void unbind() { aggregatorHandle.release(); } } - static final class Builder - extends AbstractSynchronousInstrumentBuilder - implements LongValueRecorderBuilder { + static final class Builder extends AbstractInstrumentBuilder + implements LongHistogramBuilder { Builder( - String name, MeterProviderSharedState meterProviderSharedState, - MeterSharedState meterSharedState) { - super( - name, - InstrumentType.VALUE_RECORDER, - InstrumentValueType.LONG, - meterProviderSharedState, - meterSharedState); + MeterSharedState meterSharedState, + String name) { + this(meterProviderSharedState, meterSharedState, name, "", "1"); + } + + Builder( + MeterProviderSharedState meterProviderSharedState, + MeterSharedState sharedState, + String name, + String description, + String unit) { + super(meterProviderSharedState, sharedState, name, description, unit); } @Override - Builder getThis() { + protected Builder getThis() { return this; } @Override public LongValueRecorderSdk build() { - return buildInstrument(LongValueRecorderSdk::new); + return buildSynchronousInstrument( + InstrumentType.VALUE_RECORDER, InstrumentValueType.LONG, LongValueRecorderSdk::new); + } + + @Override + public DoubleHistogramBuilder ofDoubles() { + return swapBuilder(DoubleValueRecorderSdk.Builder::new); } } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeter.java index b4cabce438..e1604131a3 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeter.java @@ -5,6 +5,10 @@ package io.opentelemetry.sdk.metrics; +import io.opentelemetry.api.metrics.DoubleGaugeBuilder; +import io.opentelemetry.api.metrics.DoubleHistogramBuilder; +import io.opentelemetry.api.metrics.LongCounterBuilder; +import io.opentelemetry.api.metrics.LongUpDownCounterBuilder; import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.data.MetricData; @@ -28,71 +32,6 @@ final class SdkMeter implements Meter { return meterSharedState.getInstrumentationLibraryInfo(); } - @Override - public DoubleCounterSdk.Builder doubleCounterBuilder(String name) { - return new DoubleCounterSdk.Builder(name, meterProviderSharedState, meterSharedState); - } - - @Override - public LongCounterSdk.Builder longCounterBuilder(String name) { - return new LongCounterSdk.Builder(name, meterProviderSharedState, meterSharedState); - } - - @Override - public DoubleUpDownCounterSdk.Builder doubleUpDownCounterBuilder(String name) { - return new DoubleUpDownCounterSdk.Builder(name, meterProviderSharedState, meterSharedState); - } - - @Override - public LongUpDownCounterSdk.Builder longUpDownCounterBuilder(String name) { - return new LongUpDownCounterSdk.Builder(name, meterProviderSharedState, meterSharedState); - } - - @Override - public DoubleValueRecorderSdk.Builder doubleValueRecorderBuilder(String name) { - return new DoubleValueRecorderSdk.Builder(name, meterProviderSharedState, meterSharedState); - } - - @Override - public LongValueRecorderSdk.Builder longValueRecorderBuilder(String name) { - return new LongValueRecorderSdk.Builder(name, meterProviderSharedState, meterSharedState); - } - - @Override - public DoubleSumObserverSdk.Builder doubleSumObserverBuilder(String name) { - return new DoubleSumObserverSdk.Builder(name, meterProviderSharedState, meterSharedState); - } - - @Override - public LongSumObserverSdk.Builder longSumObserverBuilder(String name) { - return new LongSumObserverSdk.Builder(name, meterProviderSharedState, meterSharedState); - } - - @Override - public DoubleUpDownSumObserverSdk.Builder doubleUpDownSumObserverBuilder(String name) { - return new DoubleUpDownSumObserverSdk.Builder(name, meterProviderSharedState, meterSharedState); - } - - @Override - public LongUpDownSumObserverSdk.Builder longUpDownSumObserverBuilder(String name) { - return new LongUpDownSumObserverSdk.Builder(name, meterProviderSharedState, meterSharedState); - } - - @Override - public DoubleValueObserverSdk.Builder doubleValueObserverBuilder(String name) { - return new DoubleValueObserverSdk.Builder(name, meterProviderSharedState, meterSharedState); - } - - @Override - public LongValueObserverSdk.Builder longValueObserverBuilder(String name) { - return new LongValueObserverSdk.Builder(name, meterProviderSharedState, meterSharedState); - } - - @Override - public BatchRecorderSdk newBatchRecorder(String... keyValuePairs) { - return new BatchRecorderSdk(keyValuePairs); - } - /** Collects all the metric recordings that changed since the previous call. */ Collection collectAll(long epochNanos) { InstrumentRegistry instrumentRegistry = meterSharedState.getInstrumentRegistry(); @@ -103,4 +42,24 @@ final class SdkMeter implements Meter { } return result; } + + @Override + public LongCounterBuilder counterBuilder(String name) { + return new LongCounterSdk.Builder(meterProviderSharedState, meterSharedState, name); + } + + @Override + public LongUpDownCounterBuilder upDownCounterBuilder(String name) { + return new LongUpDownCounterSdk.Builder(meterProviderSharedState, meterSharedState, name); + } + + @Override + public DoubleHistogramBuilder histogramBuilder(String name) { + return new DoubleValueRecorderSdk.Builder(meterProviderSharedState, meterSharedState, name); + } + + @Override + public DoubleGaugeBuilder gaugeBuilder(String name) { + return new DoubleValueObserverSdk.Builder(meterProviderSharedState, meterSharedState, name); + } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProvider.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProvider.java index 58d376b574..b25f1f4e13 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProvider.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProvider.java @@ -6,7 +6,6 @@ package io.opentelemetry.sdk.metrics; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.api.metrics.MeterBuilder; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.sdk.common.Clock; @@ -46,18 +45,6 @@ public final class SdkMeterProvider implements MeterProvider, MetricProducer { instrumentationLibraryInfo -> new SdkMeter(sharedState, instrumentationLibraryInfo)); } - @Override - public Meter get(String instrumentationName) { - return meterBuilder(instrumentationName).build(); - } - - @Override - public Meter get(String instrumentationName, String instrumentationVersion) { - return meterBuilder(instrumentationName) - .setInstrumentationVersion(instrumentationVersion) - .build(); - } - @Override public MeterBuilder meterBuilder(@Nullable String instrumentationName) { if (instrumentationName == null || instrumentationName.isEmpty()) { diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SynchronousInstrumentAccumulator.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SynchronousInstrumentAccumulator.java index 90b08637bd..b95077418c 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SynchronousInstrumentAccumulator.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SynchronousInstrumentAccumulator.java @@ -5,7 +5,7 @@ package io.opentelemetry.sdk.metrics; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.context.Context; import io.opentelemetry.sdk.metrics.aggregator.Aggregator; import io.opentelemetry.sdk.metrics.aggregator.AggregatorHandle; @@ -19,7 +19,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.ReentrantLock; final class SynchronousInstrumentAccumulator extends AbstractAccumulator { - private final ConcurrentHashMap> aggregatorLabels; + private final ConcurrentHashMap> aggregatorLabels; private final ReentrantLock collectLock; private final Aggregator aggregator; private final InstrumentProcessor instrumentProcessor; @@ -48,7 +48,7 @@ final class SynchronousInstrumentAccumulator extends AbstractAccumulator { this.labelsProcessor = labelsProcessor; } - AggregatorHandle bind(Labels labels) { + AggregatorHandle bind(Attributes labels) { Objects.requireNonNull(labels, "labels"); labels = labelsProcessor.onLabelsBound(Context.current(), labels); AggregatorHandle aggregatorHandle = aggregatorLabels.get(labels); @@ -80,7 +80,7 @@ final class SynchronousInstrumentAccumulator extends AbstractAccumulator { List collectAll(long epochNanos) { collectLock.lock(); try { - for (Map.Entry> entry : aggregatorLabels.entrySet()) { + for (Map.Entry> entry : aggregatorLabels.entrySet()) { boolean unmappedEntry = entry.getValue().tryUnmap(); if (unmappedEntry) { // If able to unmap then remove the record from the current Map. This can race with the diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/AbstractMinMaxSumCountAggregator.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/AbstractMinMaxSumCountAggregator.java index 300e66e91f..1f54fb9006 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/AbstractMinMaxSumCountAggregator.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/AbstractMinMaxSumCountAggregator.java @@ -5,7 +5,7 @@ package io.opentelemetry.sdk.metrics.aggregator; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.data.DoubleSummaryData; @@ -35,7 +35,7 @@ abstract class AbstractMinMaxSumCountAggregator @Override public final MetricData toMetricData( - Map accumulationByLabels, + Map accumulationByLabels, long startEpochNanos, long lastCollectionEpoch, long epochNanos) { diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/Aggregator.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/Aggregator.java index a3e0340c3e..c933d1cd99 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/Aggregator.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/Aggregator.java @@ -5,7 +5,7 @@ package io.opentelemetry.sdk.metrics.aggregator; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.data.MetricDataType; import java.util.Map; @@ -81,7 +81,7 @@ public interface Aggregator { */ @Nullable MetricData toMetricData( - Map accumulationByLabels, + Map accumulationByLabels, long startEpochNanos, long lastCollectionEpoch, long epochNanos); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/CountAggregator.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/CountAggregator.java index 3bb289bdb6..ed00da11aa 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/CountAggregator.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/CountAggregator.java @@ -5,7 +5,7 @@ package io.opentelemetry.sdk.metrics.aggregator; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; @@ -55,7 +55,7 @@ final class CountAggregator extends AbstractAggregator { @Override public MetricData toMetricData( - Map accumulationByLabels, + Map accumulationByLabels, long startEpochNanos, long lastCollectionEpoch, long epochNanos) { diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/DoubleHistogramAggregator.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/DoubleHistogramAggregator.java index f476a2d9b0..be2ee6a109 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/DoubleHistogramAggregator.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/DoubleHistogramAggregator.java @@ -5,8 +5,8 @@ package io.opentelemetry.sdk.metrics.aggregator; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.internal.GuardedBy; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; @@ -63,7 +63,7 @@ final class DoubleHistogramAggregator extends AbstractAggregator accumulationByLabels, + Map accumulationByLabels, long startEpochNanos, long lastCollectionEpoch, long epochNanos) { diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/DoubleLastValueAggregator.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/DoubleLastValueAggregator.java index f4ac43800c..f153acf438 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/DoubleLastValueAggregator.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/DoubleLastValueAggregator.java @@ -5,7 +5,7 @@ package io.opentelemetry.sdk.metrics.aggregator; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.data.DoubleGaugeData; @@ -51,7 +51,7 @@ final class DoubleLastValueAggregator extends AbstractAggregator { @Override public MetricData toMetricData( - Map accumulationByLabels, + Map accumulationByLabels, long startEpochNanos, long lastCollectionEpoch, long epochNanos) { diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/DoubleSumAggregator.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/DoubleSumAggregator.java index 0bd1522064..edaded38d9 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/DoubleSumAggregator.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/DoubleSumAggregator.java @@ -5,7 +5,7 @@ package io.opentelemetry.sdk.metrics.aggregator; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; @@ -46,7 +46,7 @@ final class DoubleSumAggregator extends AbstractSumAggregator { @Override public MetricData toMetricData( - Map accumulationByLabels, + Map accumulationByLabels, long startEpochNanos, long lastCollectionEpoch, long epochNanos) { diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/LongLastValueAggregator.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/LongLastValueAggregator.java index b0bd666bab..b899b1e8e4 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/LongLastValueAggregator.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/LongLastValueAggregator.java @@ -5,7 +5,7 @@ package io.opentelemetry.sdk.metrics.aggregator; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.data.LongGaugeData; @@ -49,7 +49,7 @@ final class LongLastValueAggregator extends AbstractAggregator { @Override public MetricData toMetricData( - Map accumulationByLabels, + Map accumulationByLabels, long startEpochNanos, long lastCollectionEpoch, long epochNanos) { diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/LongSumAggregator.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/LongSumAggregator.java index 52a1667dcf..d177f59b5e 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/LongSumAggregator.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/LongSumAggregator.java @@ -5,7 +5,7 @@ package io.opentelemetry.sdk.metrics.aggregator; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; @@ -47,7 +47,7 @@ final class LongSumAggregator extends AbstractSumAggregator { @Override public MetricData toMetricData( - Map accumulationByLabels, + Map accumulationByLabels, long startEpochNanos, long lastCollectionEpoch, long epochNanos) { diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/MetricDataUtils.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/MetricDataUtils.java index 668045dda1..0e0b34c186 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/MetricDataUtils.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/MetricDataUtils.java @@ -6,8 +6,6 @@ package io.opentelemetry.sdk.metrics.aggregator; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.common.AttributesBuilder; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.sdk.metrics.data.DoubleHistogramPointData; import io.opentelemetry.sdk.metrics.data.DoublePointData; import io.opentelemetry.sdk.metrics.data.DoubleSummaryPointData; @@ -19,37 +17,26 @@ import java.util.Map; final class MetricDataUtils { private MetricDataUtils() {} - // Temporary workaround while new API/SDK is implemented. - static Attributes toAttributes(Labels labels) { - AttributesBuilder result = Attributes.builder(); - labels.forEach(result::put); - return result.build(); - } - static List toLongPointList( - Map accumulationMap, long startEpochNanos, long epochNanos) { + Map accumulationMap, long startEpochNanos, long epochNanos) { List points = new ArrayList<>(accumulationMap.size()); accumulationMap.forEach( (labels, accumulation) -> - points.add( - LongPointData.create( - startEpochNanos, epochNanos, toAttributes(labels), accumulation))); + points.add(LongPointData.create(startEpochNanos, epochNanos, labels, accumulation))); return points; } static List toDoublePointList( - Map accumulationMap, long startEpochNanos, long epochNanos) { + Map accumulationMap, long startEpochNanos, long epochNanos) { List points = new ArrayList<>(accumulationMap.size()); accumulationMap.forEach( (labels, accumulation) -> - points.add( - DoublePointData.create( - startEpochNanos, epochNanos, toAttributes(labels), accumulation))); + points.add(DoublePointData.create(startEpochNanos, epochNanos, labels, accumulation))); return points; } static List toDoubleSummaryPointList( - Map accumulationMap, + Map accumulationMap, long startEpochNanos, long epochNanos) { List points = new ArrayList<>(accumulationMap.size()); @@ -60,7 +47,7 @@ final class MetricDataUtils { } static List toDoubleHistogramPointList( - Map accumulationMap, + Map accumulationMap, long startEpochNanos, long epochNanos, List boundaries) { @@ -73,12 +60,7 @@ final class MetricDataUtils { } points.add( DoubleHistogramPointData.create( - startEpochNanos, - epochNanos, - toAttributes(labels), - aggregator.getSum(), - boundaries, - counts)); + startEpochNanos, epochNanos, labels, aggregator.getSum(), boundaries, counts)); }); return points; } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/MinMaxSumCountAccumulation.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/MinMaxSumCountAccumulation.java index 4488c1d167..b877e3ad55 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/MinMaxSumCountAccumulation.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/aggregator/MinMaxSumCountAccumulation.java @@ -6,7 +6,7 @@ package io.opentelemetry.sdk.metrics.aggregator; import com.google.auto.value.AutoValue; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.metrics.data.DoubleSummaryPointData; import io.opentelemetry.sdk.metrics.data.ValueAtPercentile; import java.util.Arrays; @@ -58,11 +58,11 @@ abstract class MinMaxSumCountAccumulation { */ abstract double getMax(); - final DoubleSummaryPointData toPoint(long startEpochNanos, long epochNanos, Labels labels) { + final DoubleSummaryPointData toPoint(long startEpochNanos, long epochNanos, Attributes labels) { return DoubleSummaryPointData.create( startEpochNanos, epochNanos, - MetricDataUtils.toAttributes(labels), + labels, getCount(), getSum(), Arrays.asList( diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/processor/LabelsProcessor.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/processor/LabelsProcessor.java index 7869c44b55..0c33519617 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/processor/LabelsProcessor.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/processor/LabelsProcessor.java @@ -5,7 +5,7 @@ package io.opentelemetry.sdk.metrics.processor; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.context.Context; /** @@ -30,5 +30,5 @@ public interface LabelsProcessor { * @return labels to be used as an input to the next processor in chain or bind() operation if * this is the last processor */ - Labels onLabelsBound(Context ctx, Labels labels); + Attributes onLabelsBound(Context ctx, Attributes labels); } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/processor/NoopLabelsProcessor.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/processor/NoopLabelsProcessor.java index f2c3bf507b..4464a45869 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/processor/NoopLabelsProcessor.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/processor/NoopLabelsProcessor.java @@ -5,13 +5,13 @@ package io.opentelemetry.sdk.metrics.processor; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.context.Context; public class NoopLabelsProcessor implements LabelsProcessor { @Override - public Labels onLabelsBound(Context c, Labels labels) { + public Attributes onLabelsBound(Context c, Attributes labels) { return labels; } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/view/InstrumentSelector.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/view/InstrumentSelector.java index 9caccdabc1..b5a56aa202 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/view/InstrumentSelector.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/view/InstrumentSelector.java @@ -12,8 +12,8 @@ import java.util.regex.Pattern; import javax.annotation.concurrent.Immutable; /** - * Provides means for selecting one ore more {@link io.opentelemetry.api.metrics.Instrument}s. Used - * for configuring aggregations for the specified instruments. + * Provides means for selecting one or more instruments. Used for configuring aggregations for the + * specified instruments. */ @AutoValue @Immutable diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AbstractInstrumentBuilderTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AbstractInstrumentBuilderTest.java deleted file mode 100644 index 99c1442da2..0000000000 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AbstractInstrumentBuilderTest.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.metrics; - -import static io.opentelemetry.sdk.metrics.AbstractInstrument.Builder.ERROR_MESSAGE_INVALID_NAME; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import io.opentelemetry.api.metrics.internal.MetricsStringUtils; -import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; -import io.opentelemetry.sdk.metrics.common.InstrumentType; -import io.opentelemetry.sdk.metrics.common.InstrumentValueType; -import io.opentelemetry.sdk.metrics.data.MetricData; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import org.junit.jupiter.api.Test; - -/** Unit tests for {@link AbstractInstrument.Builder}. */ -class AbstractInstrumentBuilderTest { - - private static final String NAME = "name"; - private static final String DESCRIPTION = "description"; - private static final String UNIT = "1"; - - @Test - void preventNull_Name() { - assertThatThrownBy(() -> new TestInstrumentBuilder(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("name"); - } - - @Test - void preventEmpty_Name() { - assertThatThrownBy(() -> new TestInstrumentBuilder("")) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("Name"); - } - - @Test - void checkCorrect_Name() { - new TestInstrumentBuilder("a"); - new TestInstrumentBuilder("METRIC_name"); - new TestInstrumentBuilder("metric.name_01"); - new TestInstrumentBuilder("metric_name.01"); - assertThatThrownBy(() -> new TestInstrumentBuilder("01.metric_name_01")) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("Name"); - } - - @Test - void preventNonPrintableName() { - assertThatThrownBy(() -> new TestInstrumentBuilder("\2").build()) - .isInstanceOf(IllegalArgumentException.class); - } - - @Test - void preventTooLongName() { - char[] chars = new char[MetricsStringUtils.METRIC_NAME_MAX_LENGTH + 1]; - Arrays.fill(chars, 'a'); - String longName = String.valueOf(chars); - assertThatThrownBy(() -> new TestInstrumentBuilder(longName).build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(ERROR_MESSAGE_INVALID_NAME); - } - - @Test - void preventNull_Description() { - assertThatThrownBy(() -> new TestInstrumentBuilder(NAME).setDescription(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("description"); - } - - @Test - void preventNull_Unit() { - assertThatThrownBy(() -> new TestInstrumentBuilder(NAME).setUnit(null).build()) - .isInstanceOf(NullPointerException.class) - .hasMessage("unit"); - } - - @Test - void defaultValue() { - TestInstrumentBuilder testInstrumentBuilder = new TestInstrumentBuilder(NAME); - TestInstrument testInstrument = testInstrumentBuilder.build(); - assertThat(testInstrument).isInstanceOf(TestInstrument.class); - assertThat(testInstrument.getDescriptor().getName()).isEqualTo(NAME); - assertThat(testInstrument.getDescriptor().getDescription()).isEmpty(); - assertThat(testInstrument.getDescriptor().getUnit()).isEqualTo("1"); - } - - @Test - void setAndGetValues() { - TestInstrumentBuilder testInstrumentBuilder = - new TestInstrumentBuilder(NAME).setDescription(DESCRIPTION).setUnit(UNIT); - - TestInstrument testInstrument = testInstrumentBuilder.build(); - assertThat(testInstrument).isInstanceOf(TestInstrument.class); - assertThat(testInstrument.getDescriptor().getName()).isEqualTo(NAME); - assertThat(testInstrument.getDescriptor().getDescription()).isEqualTo(DESCRIPTION); - assertThat(testInstrument.getDescriptor().getUnit()).isEqualTo(UNIT); - assertThat(testInstrument.getDescriptor().getType()).isEqualTo(InstrumentType.UP_DOWN_COUNTER); - assertThat(testInstrument.getDescriptor().getValueType()).isEqualTo(InstrumentValueType.LONG); - } - - private static final class TestInstrumentBuilder - extends AbstractInstrument.Builder { - TestInstrumentBuilder(String name) { - super(name, InstrumentType.UP_DOWN_COUNTER, InstrumentValueType.LONG); - } - - @Override - TestInstrumentBuilder getThis() { - return this; - } - - @Override - public TestInstrument build() { - return new TestInstrument(buildDescriptor()); - } - } - - private static final class TestInstrument extends AbstractInstrument { - TestInstrument(InstrumentDescriptor descriptor) { - super(descriptor); - } - - @Override - List collectAll(long epochNanos) { - return Collections.emptyList(); - } - } -} diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AsynchronousInstrumentAccumulatorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AsynchronousInstrumentAccumulatorTest.java index b417189510..349064ab1f 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AsynchronousInstrumentAccumulatorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AsynchronousInstrumentAccumulatorTest.java @@ -5,7 +5,7 @@ package io.opentelemetry.sdk.metrics; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.context.Context; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.aggregator.AggregatorFactory; @@ -35,7 +35,7 @@ public class AsynchronousInstrumentAccumulatorTest { // note: can't convert to a lambda here because Mockito gets grumpy new LabelsProcessor() { @Override - public Labels onLabelsBound(Context ctx, Labels labels) { + public Attributes onLabelsBound(Context ctx, Attributes labels) { return labels.toBuilder().build(); } }); @@ -67,9 +67,9 @@ public class AsynchronousInstrumentAccumulatorTest { "unit", InstrumentType.VALUE_OBSERVER, InstrumentValueType.DOUBLE), - value -> value.observe(1.0, Labels.empty())) + value -> value.observe(1.0, Attributes.empty())) .collectAll(testClock.nanoTime()); - Mockito.verify(spyLabelProcessor).onLabelsBound(Context.current(), Labels.empty()); + Mockito.verify(spyLabelProcessor).onLabelsBound(Context.current(), Attributes.empty()); } @Test @@ -83,8 +83,8 @@ public class AsynchronousInstrumentAccumulatorTest { "unit", InstrumentType.VALUE_OBSERVER, InstrumentValueType.LONG), - value -> value.observe(1, Labels.empty())) + value -> value.observe(1, Attributes.empty())) .collectAll(testClock.nanoTime()); - Mockito.verify(spyLabelProcessor).onLabelsBound(Context.current(), Labels.empty()); + Mockito.verify(spyLabelProcessor).onLabelsBound(Context.current(), Attributes.empty()); } } diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/BatchRecorderSdkTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/BatchRecorderSdkTest.java deleted file mode 100644 index e56c593a1a..0000000000 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/BatchRecorderSdkTest.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.metrics; - -import static io.opentelemetry.api.common.AttributeKey.stringKey; -import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.metrics.BatchRecorder; -import io.opentelemetry.api.metrics.DoubleCounter; -import io.opentelemetry.api.metrics.DoubleUpDownCounter; -import io.opentelemetry.api.metrics.DoubleValueRecorder; -import io.opentelemetry.api.metrics.LongCounter; -import io.opentelemetry.api.metrics.LongUpDownCounter; -import io.opentelemetry.api.metrics.LongValueRecorder; -import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; -import io.opentelemetry.sdk.metrics.data.DoubleSummaryData; -import io.opentelemetry.sdk.metrics.data.DoubleSummaryPointData; -import io.opentelemetry.sdk.metrics.data.MetricData; -import io.opentelemetry.sdk.metrics.data.ValueAtPercentile; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.testing.time.TestClock; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import org.junit.jupiter.api.Test; - -/** Unit tests for {@link BatchRecorderSdk}. */ -class BatchRecorderSdkTest { - private static final Resource RESOURCE = - Resource.create(Attributes.of(stringKey("resource_key"), "resource_value")); - private static final InstrumentationLibraryInfo INSTRUMENTATION_LIBRARY_INFO = - InstrumentationLibraryInfo.create(BatchRecorderSdkTest.class.getName(), null); - private final TestClock testClock = TestClock.create(); - private final SdkMeterProvider sdkMeterProvider = - SdkMeterProvider.builder().setClock(testClock).setResource(RESOURCE).build(); - private final Meter sdkMeter = sdkMeterProvider.get(getClass().getName()); - - private static final Attributes attributeSet = Attributes.builder().put("key", "value").build(); - - @Test - void batchRecorder_badLabelSet() { - assertThatThrownBy(() -> sdkMeter.newBatchRecorder("key").record()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("key/value"); - } - - @Test - void batchRecorder() { - DoubleCounter doubleCounter = sdkMeter.doubleCounterBuilder("testDoubleCounter").build(); - LongCounter longCounter = sdkMeter.longCounterBuilder("testLongCounter").build(); - DoubleUpDownCounter doubleUpDownCounter = - sdkMeter.doubleUpDownCounterBuilder("testDoubleUpDownCounter").build(); - LongUpDownCounter longUpDownCounter = - sdkMeter.longUpDownCounterBuilder("testLongUpDownCounter").build(); - DoubleValueRecorder doubleValueRecorder = - sdkMeter.doubleValueRecorderBuilder("testDoubleValueRecorder").build(); - LongValueRecorder longValueRecorder = - sdkMeter.longValueRecorderBuilder("testLongValueRecorder").build(); - - BatchRecorder batchRecorder = sdkMeter.newBatchRecorder("key", "value"); - - batchRecorder - .put(longCounter, 12) - .put(doubleUpDownCounter, -12.1d) - .put(longUpDownCounter, -12) - .put(doubleCounter, 12.1d) - .put(doubleCounter, 12.1d) - .put(longValueRecorder, 13) - .put(doubleValueRecorder, 13.1d); - - // until record() is called, nothing should be recorded. - Collection preRecord = sdkMeterProvider.collectAllMetrics(); - preRecord.forEach(metricData -> assertThat(metricData.isEmpty()).isTrue()); - - batchRecorder.record(); - - assertBatchRecordings( - doubleCounter, - longCounter, - doubleUpDownCounter, - longUpDownCounter, - doubleValueRecorder, - longValueRecorder, - /* shouldHaveDeltas=*/ true); - - // a second record, with no recordings added should not change any of the values. - batchRecorder.record(); - assertBatchRecordings( - doubleCounter, - longCounter, - doubleUpDownCounter, - longUpDownCounter, - doubleValueRecorder, - longValueRecorder, - /* shouldHaveDeltas=*/ false); - } - - @SuppressWarnings("unchecked") - private void assertBatchRecordings( - DoubleCounter doubleCounter, - LongCounter longCounter, - DoubleUpDownCounter doubleUpDownCounter, - LongUpDownCounter longUpDownCounter, - DoubleValueRecorder doubleValueRecorder, - LongValueRecorder longValueRecorder, - boolean shouldHaveDeltas) { - assertThat(((AbstractInstrument) doubleCounter).collectAll(testClock.now())) - .satisfiesExactly( - metric -> - assertThat(metric) - .hasResource(RESOURCE) - .hasInstrumentationLibrary(INSTRUMENTATION_LIBRARY_INFO) - .hasName("testDoubleCounter") - .hasDoubleSum() - .isMonotonic() - .isCumulative() - .points() - .satisfiesExactlyInAnyOrder( - point -> - assertThat(point) - .hasEpochNanos(testClock.now()) - .hasStartEpochNanos(testClock.now()) - .hasValue(24.2d) - .hasAttributes(attributeSet))); - assertThat(((AbstractInstrument) longCounter).collectAll(testClock.now())) - .satisfiesExactly( - metric -> - assertThat(metric) - .hasResource(RESOURCE) - .hasInstrumentationLibrary(INSTRUMENTATION_LIBRARY_INFO) - .hasName("testLongCounter") - .hasLongSum() - .isMonotonic() - .isCumulative() - .points() - .satisfiesExactlyInAnyOrder( - point -> - assertThat(point) - .hasEpochNanos(testClock.now()) - .hasStartEpochNanos(testClock.now()) - .hasValue(12) - .hasAttributes(attributeSet))); - assertThat(((AbstractInstrument) doubleUpDownCounter).collectAll(testClock.now())) - .satisfiesExactly( - metric -> - assertThat(metric) - .hasResource(RESOURCE) - .hasInstrumentationLibrary(INSTRUMENTATION_LIBRARY_INFO) - .hasName("testDoubleUpDownCounter") - .hasDoubleSum() - .isNotMonotonic() - .isCumulative() - .points() - .satisfiesExactlyInAnyOrder( - point -> - assertThat(point) - .hasEpochNanos(testClock.now()) - .hasStartEpochNanos(testClock.now()) - .hasValue(-12.1) - .hasAttributes(attributeSet))); - assertThat(((AbstractInstrument) longUpDownCounter).collectAll(testClock.now())) - .satisfiesExactly( - metric -> - assertThat(metric) - .hasResource(RESOURCE) - .hasInstrumentationLibrary(INSTRUMENTATION_LIBRARY_INFO) - .hasName("testLongUpDownCounter") - .hasLongSum() - .isNotMonotonic() - .isCumulative() - .points() - .satisfiesExactlyInAnyOrder( - point -> - assertThat(point) - .hasEpochNanos(testClock.now()) - .hasStartEpochNanos(testClock.now()) - .hasValue(-12) - .hasAttributes(attributeSet))); - - if (shouldHaveDeltas) { - assertThat(((AbstractInstrument) doubleValueRecorder).collectAll(testClock.now())) - .containsExactly( - MetricData.createDoubleSummary( - RESOURCE, - INSTRUMENTATION_LIBRARY_INFO, - "testDoubleValueRecorder", - "", - "1", - DoubleSummaryData.create( - Collections.singletonList( - DoubleSummaryPointData.create( - testClock.now(), - testClock.now(), - attributeSet, - 1, - 13.1d, - Arrays.asList( - ValueAtPercentile.create(0.0, 13.1), - ValueAtPercentile.create(100.0, 13.1))))))); - } else { - assertThat(((AbstractInstrument) doubleValueRecorder).collectAll(testClock.now())).isEmpty(); - } - - if (shouldHaveDeltas) { - assertThat(((AbstractInstrument) longValueRecorder).collectAll(testClock.now())) - .containsExactly( - MetricData.createDoubleSummary( - RESOURCE, - INSTRUMENTATION_LIBRARY_INFO, - "testLongValueRecorder", - "", - "1", - DoubleSummaryData.create( - Collections.singletonList( - DoubleSummaryPointData.create( - testClock.now(), - testClock.now(), - attributeSet, - 1, - 13, - Arrays.asList( - ValueAtPercentile.create(0.0, 13), - ValueAtPercentile.create(100.0, 13))))))); - } else { - assertThat(((AbstractInstrument) longValueRecorder).collectAll(testClock.now())).isEmpty(); - } - } -} diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/DoubleCounterSdkTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/DoubleCounterSdkTest.java index 1992f387ff..9a586525f0 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/DoubleCounterSdkTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/DoubleCounterSdkTest.java @@ -13,7 +13,6 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.BoundDoubleCounter; import io.opentelemetry.api.metrics.DoubleCounter; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.StressTestRunner.OperationUpdater; import io.opentelemetry.sdk.resources.Resource; @@ -35,22 +34,23 @@ class DoubleCounterSdkTest { @Test void add_PreventNullLabels() { - assertThatThrownBy(() -> sdkMeter.doubleCounterBuilder("testCounter").build().add(1.0, null)) + assertThatThrownBy( + () -> sdkMeter.counterBuilder("testCounter").ofDoubles().build().add(1.0, null)) .isInstanceOf(NullPointerException.class) .hasMessage("labels"); } @Test void bound_PreventNullLabels() { - assertThatThrownBy(() -> sdkMeter.doubleCounterBuilder("testCounter").build().bind(null)) + assertThatThrownBy(() -> sdkMeter.counterBuilder("testCounter").ofDoubles().build().bind(null)) .isInstanceOf(NullPointerException.class) .hasMessage("labels"); } @Test void collectMetrics_NoRecords() { - DoubleCounter doubleCounter = sdkMeter.doubleCounterBuilder("testCounter").build(); - BoundDoubleCounter bound = doubleCounter.bind(Labels.of("foo", "bar")); + DoubleCounter doubleCounter = sdkMeter.counterBuilder("testCounter").ofDoubles().build(); + BoundDoubleCounter bound = doubleCounter.bind(Attributes.builder().put("foo", "bar").build()); try { assertThat(sdkMeterProvider.collectAllMetrics()).isEmpty(); } finally { @@ -63,12 +63,13 @@ class DoubleCounterSdkTest { void collectMetrics_WithEmptyLabel() { DoubleCounter doubleCounter = sdkMeter - .doubleCounterBuilder("testCounter") + .counterBuilder("testCounter") + .ofDoubles() .setDescription("description") .setUnit("ms") .build(); testClock.advance(Duration.ofNanos(SECOND_NANOS)); - doubleCounter.add(12d, Labels.empty()); + doubleCounter.add(12d, Attributes.empty()); doubleCounter.add(12d); assertThat(sdkMeterProvider.collectAllMetrics()) .satisfiesExactly( @@ -96,17 +97,17 @@ class DoubleCounterSdkTest { @SuppressWarnings("unchecked") void collectMetrics_WithMultipleCollects() { long startTime = testClock.now(); - DoubleCounter doubleCounter = sdkMeter.doubleCounterBuilder("testCounter").build(); - BoundDoubleCounter bound = doubleCounter.bind(Labels.of("K", "V")); + DoubleCounter doubleCounter = sdkMeter.counterBuilder("testCounter").ofDoubles().build(); + BoundDoubleCounter bound = doubleCounter.bind(Attributes.builder().put("K", "V").build()); try { // Do some records using bounds and direct calls and bindings. - doubleCounter.add(12.1d, Labels.empty()); + doubleCounter.add(12.1d, Attributes.empty()); bound.add(123.3d); - doubleCounter.add(21.4d, Labels.empty()); + doubleCounter.add(21.4d, Attributes.empty()); // Advancing time here should not matter. testClock.advance(Duration.ofNanos(SECOND_NANOS)); bound.add(321.5d); - doubleCounter.add(111.1d, Labels.of("K", "V")); + doubleCounter.add(111.1d, Attributes.builder().put("K", "V").build()); assertThat(sdkMeterProvider.collectAllMetrics()) .satisfiesExactly( metric -> @@ -138,7 +139,7 @@ class DoubleCounterSdkTest { // Repeat to prove we keep previous values. testClock.advance(Duration.ofNanos(SECOND_NANOS)); bound.add(222d); - doubleCounter.add(11d, Labels.empty()); + doubleCounter.add(11d, Attributes.empty()); assertThat(sdkMeterProvider.collectAllMetrics()) .satisfiesExactly( metric -> @@ -165,24 +166,24 @@ class DoubleCounterSdkTest { @Test void doubleCounterAdd_Monotonicity() { - DoubleCounter doubleCounter = sdkMeter.doubleCounterBuilder("testCounter").build(); + DoubleCounter doubleCounter = sdkMeter.counterBuilder("testCounter").ofDoubles().build(); - assertThatThrownBy(() -> doubleCounter.add(-45.77d, Labels.empty())) + assertThatThrownBy(() -> doubleCounter.add(-45.77d, Attributes.empty())) .isInstanceOf(IllegalArgumentException.class); } @Test void boundDoubleCounterAdd_Monotonicity() { - DoubleCounter doubleCounter = sdkMeter.doubleCounterBuilder("testCounter").build(); + DoubleCounter doubleCounter = sdkMeter.counterBuilder("testCounter").ofDoubles().build(); - assertThatThrownBy(() -> doubleCounter.bind(Labels.empty()).add(-9.3)) + assertThatThrownBy(() -> doubleCounter.bind(Attributes.empty()).add(-9.3)) .isInstanceOf(IllegalArgumentException.class); } @Test @SuppressWarnings("unchecked") void stressTest() { - final DoubleCounter doubleCounter = sdkMeter.doubleCounterBuilder("testCounter").build(); + final DoubleCounter doubleCounter = sdkMeter.counterBuilder("testCounter").ofDoubles().build(); StressTestRunner.Builder stressTestBuilder = StressTestRunner.builder() @@ -195,7 +196,10 @@ class DoubleCounterSdkTest { 1_000, 2, new OperationUpdaterDirectCall(doubleCounter, "K", "V"))); stressTestBuilder.addOperation( StressTestRunner.Operation.create( - 1_000, 2, new OperationUpdaterWithBinding(doubleCounter.bind(Labels.of("K", "V"))))); + 1_000, + 2, + new OperationUpdaterWithBinding( + doubleCounter.bind(Attributes.builder().put("K", "V").build())))); } stressTestBuilder.build().run(); @@ -225,7 +229,7 @@ class DoubleCounterSdkTest { void stressTest_WithDifferentLabelSet() { final String[] keys = {"Key_1", "Key_2", "Key_3", "Key_4"}; final String[] values = {"Value_1", "Value_2", "Value_3", "Value_4"}; - final DoubleCounter doubleCounter = sdkMeter.doubleCounterBuilder("testCounter").build(); + final DoubleCounter doubleCounter = sdkMeter.counterBuilder("testCounter").ofDoubles().build(); StressTestRunner.Builder stressTestBuilder = StressTestRunner.builder() @@ -241,7 +245,8 @@ class DoubleCounterSdkTest { StressTestRunner.Operation.create( 2_000, 1, - new OperationUpdaterWithBinding(doubleCounter.bind(Labels.of(keys[i], values[i]))))); + new OperationUpdaterWithBinding( + doubleCounter.bind(Attributes.builder().put(keys[i], values[i]).build())))); } stressTestBuilder.build().run(); @@ -301,7 +306,7 @@ class DoubleCounterSdkTest { @Override void update() { - doubleCounter.add(11.0, Labels.of(key, value)); + doubleCounter.add(11.0, Attributes.builder().put(key, value).build()); } @Override diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/DoubleSumObserverSdkTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/DoubleSumObserverSdkTest.java index f60e8fc805..77f92f041d 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/DoubleSumObserverSdkTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/DoubleSumObserverSdkTest.java @@ -9,7 +9,6 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.aggregator.AggregatorFactory; import io.opentelemetry.sdk.metrics.common.InstrumentType; @@ -33,28 +32,16 @@ class DoubleSumObserverSdkTest { private final SdkMeterProviderBuilder sdkMeterProviderBuilder = SdkMeterProvider.builder().setClock(testClock).setResource(RESOURCE); - @Test - void collectMetrics_NoCallback() { - SdkMeterProvider sdkMeterProvider = sdkMeterProviderBuilder.build(); - sdkMeterProvider - .get(getClass().getName()) - .doubleSumObserverBuilder("testObserver") - .setDescription("My own DoubleSumObserver") - .setUnit("ms") - .build(); - assertThat(sdkMeterProvider.collectAllMetrics()).isEmpty(); - } - @Test void collectMetrics_NoRecords() { SdkMeterProvider sdkMeterProvider = sdkMeterProviderBuilder.build(); sdkMeterProvider .get(getClass().getName()) - .doubleSumObserverBuilder("testObserver") + .counterBuilder("testObserver") + .ofDoubles() .setDescription("My own DoubleSumObserver") .setUnit("ms") - .setUpdater(result -> {}) - .build(); + .buildWithCallback(result -> {}); assertThat(sdkMeterProvider.collectAllMetrics()).isEmpty(); } @@ -64,11 +51,12 @@ class DoubleSumObserverSdkTest { SdkMeterProvider sdkMeterProvider = sdkMeterProviderBuilder.build(); sdkMeterProvider .get(getClass().getName()) - .doubleSumObserverBuilder("testObserver") + .counterBuilder("testObserver") + .ofDoubles() .setDescription("My own DoubleSumObserver") .setUnit("ms") - .setUpdater(result -> result.observe(12.1d, Labels.of("k", "v"))) - .build(); + .buildWithCallback( + result -> result.observe(12.1d, Attributes.builder().put("k", "v").build())); testClock.advance(Duration.ofNanos(SECOND_NANOS)); assertThat(sdkMeterProvider.collectAllMetrics()) .satisfiesExactly( @@ -129,11 +117,12 @@ class DoubleSumObserverSdkTest { .build(); sdkMeterProvider .get(getClass().getName()) - .doubleSumObserverBuilder("testObserver") + .counterBuilder("testObserver") + .ofDoubles() .setDescription("My own DoubleSumObserver") .setUnit("ms") - .setUpdater(result -> result.observe(12.1d, Labels.of("k", "v"))) - .build(); + .buildWithCallback( + result -> result.observe(12.1d, Attributes.builder().put("k", "v").build())); testClock.advance(Duration.ofNanos(SECOND_NANOS)); assertThat(sdkMeterProvider.collectAllMetrics()) .satisfiesExactly( diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/DoubleUpDownCounterSdkTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/DoubleUpDownCounterSdkTest.java index f6193aa5a7..962c594abb 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/DoubleUpDownCounterSdkTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/DoubleUpDownCounterSdkTest.java @@ -13,7 +13,6 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.BoundDoubleUpDownCounter; import io.opentelemetry.api.metrics.DoubleUpDownCounter; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.StressTestRunner.OperationUpdater; import io.opentelemetry.sdk.resources.Resource; @@ -36,7 +35,12 @@ class DoubleUpDownCounterSdkTest { @Test void add_PreventNullLabels() { assertThatThrownBy( - () -> sdkMeter.doubleUpDownCounterBuilder("testUpDownCounter").build().add(1.0, null)) + () -> + sdkMeter + .upDownCounterBuilder("testUpDownCounter") + .ofDoubles() + .build() + .add(1.0, null)) .isInstanceOf(NullPointerException.class) .hasMessage("labels"); } @@ -44,7 +48,7 @@ class DoubleUpDownCounterSdkTest { @Test void bound_PreventNullLabels() { assertThatThrownBy( - () -> sdkMeter.doubleUpDownCounterBuilder("testUpDownCounter").build().bind(null)) + () -> sdkMeter.upDownCounterBuilder("testUpDownCounter").ofDoubles().build().bind(null)) .isInstanceOf(NullPointerException.class) .hasMessage("labels"); } @@ -52,8 +56,9 @@ class DoubleUpDownCounterSdkTest { @Test void collectMetrics_NoRecords() { DoubleUpDownCounter doubleUpDownCounter = - sdkMeter.doubleUpDownCounterBuilder("testUpDownCounter").build(); - BoundDoubleUpDownCounter bound = doubleUpDownCounter.bind(Labels.of("foo", "bar")); + sdkMeter.upDownCounterBuilder("testUpDownCounter").ofDoubles().build(); + BoundDoubleUpDownCounter bound = + doubleUpDownCounter.bind(Attributes.builder().put("foo", "bar").build()); try { assertThat(sdkMeterProvider.collectAllMetrics()).isEmpty(); } finally { @@ -66,12 +71,13 @@ class DoubleUpDownCounterSdkTest { void collectMetrics_WithEmptyLabel() { DoubleUpDownCounter doubleUpDownCounter = sdkMeter - .doubleUpDownCounterBuilder("testUpDownCounter") + .upDownCounterBuilder("testUpDownCounter") + .ofDoubles() .setDescription("description") .setUnit("ms") .build(); testClock.advance(Duration.ofNanos(SECOND_NANOS)); - doubleUpDownCounter.add(12d, Labels.empty()); + doubleUpDownCounter.add(12d, Attributes.empty()); doubleUpDownCounter.add(12d); assertThat(sdkMeterProvider.collectAllMetrics()) .satisfiesExactly( @@ -100,17 +106,18 @@ class DoubleUpDownCounterSdkTest { void collectMetrics_WithMultipleCollects() { long startTime = testClock.now(); DoubleUpDownCounter doubleUpDownCounter = - sdkMeter.doubleUpDownCounterBuilder("testUpDownCounter").build(); - BoundDoubleUpDownCounter bound = doubleUpDownCounter.bind(Labels.of("K", "V")); + sdkMeter.upDownCounterBuilder("testUpDownCounter").ofDoubles().build(); + BoundDoubleUpDownCounter bound = + doubleUpDownCounter.bind(Attributes.builder().put("K", "V").build()); try { // Do some records using bounds and direct calls and bindings. - doubleUpDownCounter.add(12.1d, Labels.empty()); + doubleUpDownCounter.add(12.1d, Attributes.empty()); bound.add(123.3d); - doubleUpDownCounter.add(21.4d, Labels.empty()); + doubleUpDownCounter.add(21.4d, Attributes.empty()); // Advancing time here should not matter. testClock.advance(Duration.ofNanos(SECOND_NANOS)); bound.add(321.5d); - doubleUpDownCounter.add(111.1d, Labels.of("K", "V")); + doubleUpDownCounter.add(111.1d, Attributes.builder().put("K", "V").build()); assertThat(sdkMeterProvider.collectAllMetrics()) .satisfiesExactly( metric -> @@ -138,7 +145,7 @@ class DoubleUpDownCounterSdkTest { // Repeat to prove we keep previous values. testClock.advance(Duration.ofNanos(SECOND_NANOS)); bound.add(222d); - doubleUpDownCounter.add(11d, Labels.empty()); + doubleUpDownCounter.add(11d, Attributes.empty()); assertThat(sdkMeterProvider.collectAllMetrics()) .satisfiesExactly( metric -> @@ -171,7 +178,7 @@ class DoubleUpDownCounterSdkTest { @SuppressWarnings("unchecked") void stressTest() { final DoubleUpDownCounter doubleUpDownCounter = - sdkMeter.doubleUpDownCounterBuilder("testUpDownCounter").build(); + sdkMeter.upDownCounterBuilder("testUpDownCounter").ofDoubles().build(); StressTestRunner.Builder stressTestBuilder = StressTestRunner.builder() @@ -186,7 +193,8 @@ class DoubleUpDownCounterSdkTest { StressTestRunner.Operation.create( 1_000, 2, - new OperationUpdaterWithBinding(doubleUpDownCounter.bind(Labels.of("K", "V"))))); + new OperationUpdaterWithBinding( + doubleUpDownCounter.bind(Attributes.builder().put("K", "V").build())))); } stressTestBuilder.build().run(); @@ -218,7 +226,7 @@ class DoubleUpDownCounterSdkTest { final String[] keys = {"Key_1", "Key_2", "Key_3", "Key_4"}; final String[] values = {"Value_1", "Value_2", "Value_3", "Value_4"}; final DoubleUpDownCounter doubleUpDownCounter = - sdkMeter.doubleUpDownCounterBuilder("testUpDownCounter").build(); + sdkMeter.upDownCounterBuilder("testUpDownCounter").ofDoubles().build(); StressTestRunner.Builder stressTestBuilder = StressTestRunner.builder() @@ -235,7 +243,7 @@ class DoubleUpDownCounterSdkTest { 2_000, 1, new OperationUpdaterWithBinding( - doubleUpDownCounter.bind(Labels.of(keys[i], values[i]))))); + doubleUpDownCounter.bind(Attributes.builder().put(keys[i], values[i]).build())))); } stressTestBuilder.build().run(); @@ -297,7 +305,7 @@ class DoubleUpDownCounterSdkTest { @Override void update() { - doubleUpDownCounter.add(11.0, Labels.of(key, value)); + doubleUpDownCounter.add(11.0, Attributes.builder().put(key, value).build()); } @Override diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/DoubleUpDownSumObserverSdkTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/DoubleUpDownSumObserverSdkTest.java index 6e0a8f5575..42a8823565 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/DoubleUpDownSumObserverSdkTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/DoubleUpDownSumObserverSdkTest.java @@ -9,7 +9,6 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.aggregator.AggregatorFactory; import io.opentelemetry.sdk.metrics.common.InstrumentType; @@ -33,28 +32,16 @@ class DoubleUpDownSumObserverSdkTest { private final SdkMeterProviderBuilder sdkMeterProviderBuilder = SdkMeterProvider.builder().setClock(testClock).setResource(RESOURCE); - @Test - void collectMetrics_NoCallback() { - SdkMeterProvider sdkMeterProvider = sdkMeterProviderBuilder.build(); - sdkMeterProvider - .get(getClass().getName()) - .doubleUpDownSumObserverBuilder("testObserver") - .setDescription("My own DoubleUpDownSumObserver") - .setUnit("ms") - .build(); - assertThat(sdkMeterProvider.collectAllMetrics()).isEmpty(); - } - @Test void collectMetrics_NoRecords() { SdkMeterProvider sdkMeterProvider = sdkMeterProviderBuilder.build(); sdkMeterProvider .get(getClass().getName()) - .doubleUpDownSumObserverBuilder("testObserver") + .upDownCounterBuilder("testObserver") + .ofDoubles() .setDescription("My own DoubleUpDownSumObserver") .setUnit("ms") - .setUpdater(result -> {}) - .build(); + .buildWithCallback(result -> {}); assertThat(sdkMeterProvider.collectAllMetrics()).isEmpty(); } @@ -64,9 +51,10 @@ class DoubleUpDownSumObserverSdkTest { SdkMeterProvider sdkMeterProvider = sdkMeterProviderBuilder.build(); sdkMeterProvider .get(getClass().getName()) - .doubleUpDownSumObserverBuilder("testObserver") - .setUpdater(result -> result.observe(12.1d, Labels.of("k", "v"))) - .build(); + .upDownCounterBuilder("testObserver") + .ofDoubles() + .buildWithCallback( + result -> result.observe(12.1d, Attributes.builder().put("k", "v").build())); testClock.advance(Duration.ofNanos(SECOND_NANOS)); assertThat(sdkMeterProvider.collectAllMetrics()) .satisfiesExactly( @@ -127,9 +115,10 @@ class DoubleUpDownSumObserverSdkTest { .build(); sdkMeterProvider .get(getClass().getName()) - .doubleUpDownSumObserverBuilder("testObserver") - .setUpdater(result -> result.observe(12.1d, Labels.of("k", "v"))) - .build(); + .upDownCounterBuilder("testObserver") + .ofDoubles() + .buildWithCallback( + result -> result.observe(12.1d, Attributes.builder().put("k", "v").build())); testClock.advance(Duration.ofNanos(SECOND_NANOS)); assertThat(sdkMeterProvider.collectAllMetrics()) .satisfiesExactly( diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/DoubleValueObserverSdkTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/DoubleValueObserverSdkTest.java index 7517d3a641..407da16498 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/DoubleValueObserverSdkTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/DoubleValueObserverSdkTest.java @@ -10,7 +10,6 @@ import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.asse import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.time.TestClock; @@ -28,24 +27,13 @@ class DoubleValueObserverSdkTest { SdkMeterProvider.builder().setClock(testClock).setResource(RESOURCE).build(); private final Meter sdkMeter = sdkMeterProvider.get(getClass().getName()); - @Test - void collectMetrics_NoCallback() { - sdkMeter - .doubleValueObserverBuilder("testObserver") - .setDescription("My own DoubleValueObserver") - .setUnit("ms") - .build(); - assertThat(sdkMeterProvider.collectAllMetrics()).isEmpty(); - } - @Test void collectMetrics_NoRecords() { sdkMeter - .doubleValueObserverBuilder("testObserver") + .gaugeBuilder("testObserver") .setDescription("My own DoubleValueObserver") .setUnit("ms") - .setUpdater(result -> {}) - .build(); + .buildWithCallback(result -> {}); assertThat(sdkMeterProvider.collectAllMetrics()).isEmpty(); } @@ -53,11 +41,11 @@ class DoubleValueObserverSdkTest { @SuppressWarnings("unchecked") void collectMetrics_WithOneRecord() { sdkMeter - .doubleValueObserverBuilder("testObserver") + .gaugeBuilder("testObserver") .setDescription("My own DoubleValueObserver") .setUnit("ms") - .setUpdater(result -> result.observe(12.1d, Labels.of("k", "v"))) - .build(); + .buildWithCallback( + result -> result.observe(12.1d, Attributes.builder().put("k", "v").build())); testClock.advance(Duration.ofSeconds(1)); assertThat(sdkMeterProvider.collectAllMetrics()) .satisfiesExactly( diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/DoubleValueRecorderSdkTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/DoubleValueRecorderSdkTest.java index 3d373a3f71..34e1d1e126 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/DoubleValueRecorderSdkTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/DoubleValueRecorderSdkTest.java @@ -6,14 +6,14 @@ package io.opentelemetry.sdk.metrics; import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.metrics.BoundDoubleValueRecorder; -import io.opentelemetry.api.metrics.DoubleValueRecorder; +import io.opentelemetry.api.metrics.BoundDoubleHistogram; +import io.opentelemetry.api.metrics.DoubleHistogram; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.StressTestRunner.OperationUpdater; import io.opentelemetry.sdk.metrics.data.DoubleSummaryData; @@ -42,24 +42,23 @@ class DoubleValueRecorderSdkTest { @Test void record_PreventNullLabels() { - assertThatThrownBy( - () -> sdkMeter.doubleValueRecorderBuilder("testRecorder").build().record(1.0, null)) + assertThatThrownBy(() -> sdkMeter.histogramBuilder("testRecorder").build().record(1.0, null)) .isInstanceOf(NullPointerException.class) .hasMessage("labels"); } @Test void bound_PreventNullLabels() { - assertThatThrownBy(() -> sdkMeter.doubleValueRecorderBuilder("testRecorder").build().bind(null)) + assertThatThrownBy(() -> sdkMeter.histogramBuilder("testRecorder").build().bind(null)) .isInstanceOf(NullPointerException.class) .hasMessage("labels"); } @Test void collectMetrics_NoRecords() { - DoubleValueRecorder doubleRecorder = - sdkMeter.doubleValueRecorderBuilder("testRecorder").build(); - BoundDoubleValueRecorder bound = doubleRecorder.bind(Labels.of("key", "value")); + DoubleHistogram doubleRecorder = sdkMeter.histogramBuilder("testRecorder").build(); + BoundDoubleHistogram bound = + doubleRecorder.bind(Attributes.builder().put("key", "value").build()); try { assertThat(sdkMeterProvider.collectAllMetrics()).isEmpty(); } finally { @@ -69,14 +68,14 @@ class DoubleValueRecorderSdkTest { @Test void collectMetrics_WithEmptyLabel() { - DoubleValueRecorder doubleRecorder = + DoubleHistogram doubleRecorder = sdkMeter - .doubleValueRecorderBuilder("testRecorder") + .histogramBuilder("testRecorder") .setDescription("description") .setUnit("ms") .build(); testClock.advance(Duration.ofNanos(SECOND_NANOS)); - doubleRecorder.record(12d, Labels.empty()); + doubleRecorder.record(12d, Attributes.empty()); doubleRecorder.record(12d); assertThat(sdkMeterProvider.collectAllMetrics()) .containsExactly( @@ -98,73 +97,86 @@ class DoubleValueRecorderSdkTest { } @Test + @SuppressWarnings("unchecked") void collectMetrics_WithMultipleCollects() { long startTime = testClock.now(); - DoubleValueRecorder doubleRecorder = - sdkMeter.doubleValueRecorderBuilder("testRecorder").build(); - BoundDoubleValueRecorder bound = doubleRecorder.bind(Labels.of("K", "V")); + DoubleHistogram doubleRecorder = sdkMeter.histogramBuilder("testRecorder").build(); + BoundDoubleHistogram bound = doubleRecorder.bind(Attributes.builder().put("K", "V").build()); try { // Do some records using bounds and direct calls and bindings. - doubleRecorder.record(12.1d, Labels.empty()); + doubleRecorder.record(12.1d, Attributes.empty()); bound.record(123.3d); - doubleRecorder.record(-13.1d, Labels.empty()); + doubleRecorder.record(-13.1d, Attributes.empty()); // Advancing time here should not matter. testClock.advance(Duration.ofNanos(SECOND_NANOS)); bound.record(321.5d); - doubleRecorder.record(-121.5d, Labels.of("K", "V")); + doubleRecorder.record(-121.5d, Attributes.builder().put("K", "V").build()); assertThat(sdkMeterProvider.collectAllMetrics()) - .containsExactly( - MetricData.createDoubleSummary( - RESOURCE, - INSTRUMENTATION_LIBRARY_INFO, - "testRecorder", - "", - "1", - DoubleSummaryData.create( - Arrays.asList( - DoubleSummaryPointData.create( - startTime, - testClock.now(), - Attributes.builder().put("K", "V").build(), - 3, - 323.3d, - valueAtPercentiles(-121.5d, 321.5d)), - DoubleSummaryPointData.create( - startTime, - testClock.now(), - Attributes.empty(), - 2, - -1.0d, - valueAtPercentiles(-13.1d, 12.1d)))))); + .satisfiesExactly( + metric -> + assertThat(metric) + .hasResource(RESOURCE) + .hasInstrumentationLibrary(INSTRUMENTATION_LIBRARY_INFO) + .hasName("testRecorder") + .hasDoubleSummary() + .points() + .allSatisfy( + point -> + assertThat(point) + .hasStartEpochNanos(startTime) + .hasEpochNanos(testClock.now())) + .satisfiesExactlyInAnyOrder( + point -> + assertThat(point) + .hasCount(3) + .hasSum(323.3d) + .hasPercentileValues( + valueAtPercentiles(-121.5d, 321.5d) + .toArray(new ValueAtPercentile[0])) + .hasAttributes(Attributes.builder().put("K", "V").build()), + point -> + assertThat(point) + .hasCount(2) + .hasSum(-1.0d) + .hasPercentileValues( + valueAtPercentiles(-13.1d, 12.1d) + .toArray(new ValueAtPercentile[0])) + .hasAttributes(Attributes.empty()))); // Repeat to prove we don't keep previous values. testClock.advance(Duration.ofNanos(SECOND_NANOS)); bound.record(222d); - doubleRecorder.record(17d, Labels.empty()); + doubleRecorder.record(17d, Attributes.empty()); assertThat(sdkMeterProvider.collectAllMetrics()) - .containsExactly( - MetricData.createDoubleSummary( - RESOURCE, - INSTRUMENTATION_LIBRARY_INFO, - "testRecorder", - "", - "1", - DoubleSummaryData.create( - Arrays.asList( - DoubleSummaryPointData.create( - startTime + SECOND_NANOS, - testClock.now(), - Attributes.builder().put("K", "V").build(), - 1, - 222.0d, - valueAtPercentiles(222.0, 222.0d)), - DoubleSummaryPointData.create( - startTime + SECOND_NANOS, - testClock.now(), - Attributes.empty(), - 1, - 17.0d, - valueAtPercentiles(17d, 17d)))))); + .satisfiesExactly( + metric -> + assertThat(metric) + .hasResource(RESOURCE) + .hasInstrumentationLibrary(INSTRUMENTATION_LIBRARY_INFO) + .hasName("testRecorder") + .hasDoubleSummary() + .points() + .allSatisfy( + point -> + assertThat(point) + .hasStartEpochNanos(startTime + SECOND_NANOS) + .hasEpochNanos(testClock.now())) + .satisfiesExactlyInAnyOrder( + point -> + assertThat(point) + .hasCount(1) + .hasSum(222) + .hasPercentileValues( + valueAtPercentiles(222, 222) + .toArray(new ValueAtPercentile[0])) + .hasAttributes(Attributes.builder().put("K", "V").build()), + point -> + assertThat(point) + .hasCount(1) + .hasSum(17) + .hasPercentileValues( + valueAtPercentiles(17, 17).toArray(new ValueAtPercentile[0])) + .hasAttributes(Attributes.empty()))); } finally { bound.unbind(); } @@ -172,8 +184,7 @@ class DoubleValueRecorderSdkTest { @Test void stressTest() { - final DoubleValueRecorder doubleRecorder = - sdkMeter.doubleValueRecorderBuilder("testRecorder").build(); + final DoubleHistogram doubleRecorder = sdkMeter.histogramBuilder("testRecorder").build(); StressTestRunner.Builder stressTestBuilder = StressTestRunner.builder() @@ -188,7 +199,10 @@ class DoubleValueRecorderSdkTest { new DoubleValueRecorderSdkTest.OperationUpdaterDirectCall(doubleRecorder, "K", "V"))); stressTestBuilder.addOperation( StressTestRunner.Operation.create( - 1_000, 2, new OperationUpdaterWithBinding(doubleRecorder.bind(Labels.of("K", "V"))))); + 1_000, + 2, + new OperationUpdaterWithBinding( + doubleRecorder.bind(Attributes.builder().put("K", "V").build())))); } stressTestBuilder.build().run(); @@ -215,8 +229,7 @@ class DoubleValueRecorderSdkTest { void stressTest_WithDifferentLabelSet() { final String[] keys = {"Key_1", "Key_2", "Key_3", "Key_4"}; final String[] values = {"Value_1", "Value_2", "Value_3", "Value_4"}; - final DoubleValueRecorder doubleRecorder = - sdkMeter.doubleValueRecorderBuilder("testRecorder").build(); + final DoubleHistogram doubleRecorder = sdkMeter.histogramBuilder("testRecorder").build(); StressTestRunner.Builder stressTestBuilder = StressTestRunner.builder() @@ -235,54 +248,42 @@ class DoubleValueRecorderSdkTest { StressTestRunner.Operation.create( 2_000, 1, - new OperationUpdaterWithBinding(doubleRecorder.bind(Labels.of(keys[i], values[i]))))); + new OperationUpdaterWithBinding( + doubleRecorder.bind(Attributes.builder().put(keys[i], values[i]).build())))); } stressTestBuilder.build().run(); assertThat(sdkMeterProvider.collectAllMetrics()) - .containsExactly( - MetricData.createDoubleSummary( - RESOURCE, - INSTRUMENTATION_LIBRARY_INFO, - "testRecorder", - "", - "1", - DoubleSummaryData.create( - Arrays.asList( - DoubleSummaryPointData.create( - testClock.now(), - testClock.now(), - Attributes.of(stringKey(keys[0]), values[0]), - 4_000, - 40_000d, - valueAtPercentiles(9.0, 11.0)), - DoubleSummaryPointData.create( - testClock.now(), - testClock.now(), - Attributes.of(stringKey(keys[1]), values[1]), - 4_000, - 40_000d, - valueAtPercentiles(9.0, 11.0)), - DoubleSummaryPointData.create( - testClock.now(), - testClock.now(), - Attributes.of(stringKey(keys[2]), values[2]), - 4_000, - 40_000d, - valueAtPercentiles(9.0, 11.0)), - DoubleSummaryPointData.create( - testClock.now(), - testClock.now(), - Attributes.of(stringKey(keys[3]), values[3]), - 4_000, - 40_000d, - valueAtPercentiles(9.0, 11.0)))))); + .satisfiesExactly( + metric -> + assertThat(metric) + .hasResource(RESOURCE) + .hasInstrumentationLibrary(INSTRUMENTATION_LIBRARY_INFO) + .hasName("testRecorder") + .hasDoubleSummary() + .points() + .allSatisfy( + point -> + assertThat(point) + .hasStartEpochNanos(testClock.now()) + .hasEpochNanos(testClock.now()) + .hasCount(4_000) + .hasSum(40_000) + .hasPercentileValues( + valueAtPercentiles(9.0, 11.0) + .toArray(new ValueAtPercentile[0]))) + .extracting(point -> point.getAttributes()) + .containsExactlyInAnyOrder( + Attributes.of(stringKey(keys[0]), values[0]), + Attributes.of(stringKey(keys[1]), values[1]), + Attributes.of(stringKey(keys[2]), values[2]), + Attributes.of(stringKey(keys[3]), values[3]))); } private static class OperationUpdaterWithBinding extends OperationUpdater { - private final BoundDoubleValueRecorder boundDoubleValueRecorder; + private final BoundDoubleHistogram boundDoubleValueRecorder; - private OperationUpdaterWithBinding(BoundDoubleValueRecorder boundDoubleValueRecorder) { + private OperationUpdaterWithBinding(BoundDoubleHistogram boundDoubleValueRecorder) { this.boundDoubleValueRecorder = boundDoubleValueRecorder; } @@ -298,12 +299,12 @@ class DoubleValueRecorderSdkTest { } private static class OperationUpdaterDirectCall extends OperationUpdater { - private final DoubleValueRecorder doubleValueRecorder; + private final DoubleHistogram doubleValueRecorder; private final String key; private final String value; private OperationUpdaterDirectCall( - DoubleValueRecorder doubleValueRecorder, String key, String value) { + DoubleHistogram doubleValueRecorder, String key, String value) { this.doubleValueRecorder = doubleValueRecorder; this.key = key; this.value = value; @@ -311,7 +312,7 @@ class DoubleValueRecorderSdkTest { @Override void update() { - doubleValueRecorder.record(9.0, Labels.of(key, value)); + doubleValueRecorder.record(9.0, Attributes.builder().put(key, value).build()); } @Override diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/LongCounterSdkTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/LongCounterSdkTest.java index 5280c60f44..ff655b4277 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/LongCounterSdkTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/LongCounterSdkTest.java @@ -13,7 +13,6 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.BoundLongCounter; import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.StressTestRunner.OperationUpdater; import io.opentelemetry.sdk.resources.Resource; @@ -35,22 +34,22 @@ class LongCounterSdkTest { @Test void add_PreventNullLabels() { - assertThatThrownBy(() -> sdkMeter.longCounterBuilder("testCounter").build().add(1, null)) + assertThatThrownBy(() -> sdkMeter.counterBuilder("testCounter").build().add(1, null)) .isInstanceOf(NullPointerException.class) .hasMessage("labels"); } @Test void bound_PreventNullLabels() { - assertThatThrownBy(() -> sdkMeter.longCounterBuilder("testCounter").build().bind(null)) + assertThatThrownBy(() -> sdkMeter.counterBuilder("testCounter").build().bind(null)) .isInstanceOf(NullPointerException.class) .hasMessage("labels"); } @Test void collectMetrics_NoRecords() { - LongCounter longCounter = sdkMeter.longCounterBuilder("testCounter").build(); - BoundLongCounter bound = longCounter.bind(Labels.of("foo", "bar")); + LongCounter longCounter = sdkMeter.counterBuilder("Counter").build(); + BoundLongCounter bound = longCounter.bind(Attributes.builder().put("foo", "bar").build()); try { assertThat(sdkMeterProvider.collectAllMetrics()).isEmpty(); } finally { @@ -62,13 +61,9 @@ class LongCounterSdkTest { @SuppressWarnings("unchecked") void collectMetrics_WithEmptyLabels() { LongCounter longCounter = - sdkMeter - .longCounterBuilder("testCounter") - .setDescription("description") - .setUnit("By") - .build(); + sdkMeter.counterBuilder("testCounter").setDescription("description").setUnit("By").build(); testClock.advance(Duration.ofNanos(SECOND_NANOS)); - longCounter.add(12, Labels.empty()); + longCounter.add(12, Attributes.empty()); longCounter.add(12); assertThat(sdkMeterProvider.collectAllMetrics()) .satisfiesExactly( @@ -96,17 +91,17 @@ class LongCounterSdkTest { @SuppressWarnings("unchecked") void collectMetrics_WithMultipleCollects() { long startTime = testClock.now(); - LongCounter longCounter = sdkMeter.longCounterBuilder("testCounter").build(); - BoundLongCounter bound = longCounter.bind(Labels.of("K", "V")); + LongCounter longCounter = sdkMeter.counterBuilder("testCounter").build(); + BoundLongCounter bound = longCounter.bind(Attributes.builder().put("K", "V").build()); try { // Do some records using bounds and direct calls and bindings. - longCounter.add(12, Labels.empty()); + longCounter.add(12, Attributes.empty()); bound.add(123); - longCounter.add(21, Labels.empty()); + longCounter.add(21, Attributes.empty()); // Advancing time here should not matter. testClock.advance(Duration.ofNanos(SECOND_NANOS)); bound.add(321); - longCounter.add(111, Labels.of("K", "V")); + longCounter.add(111, Attributes.builder().put("K", "V").build()); assertThat(sdkMeterProvider.collectAllMetrics()) .satisfiesExactly( metric -> @@ -133,7 +128,7 @@ class LongCounterSdkTest { // Repeat to prove we keep previous values. testClock.advance(Duration.ofNanos(SECOND_NANOS)); bound.add(222); - longCounter.add(11, Labels.empty()); + longCounter.add(11, Attributes.empty()); assertThat(sdkMeterProvider.collectAllMetrics()) .satisfiesExactly( metric -> @@ -163,24 +158,24 @@ class LongCounterSdkTest { @Test void longCounterAdd_MonotonicityCheck() { - LongCounter longCounter = sdkMeter.longCounterBuilder("testCounter").build(); + LongCounter longCounter = sdkMeter.counterBuilder("testCounter").build(); - assertThatThrownBy(() -> longCounter.add(-45, Labels.empty())) + assertThatThrownBy(() -> longCounter.add(-45, Attributes.empty())) .isInstanceOf(IllegalArgumentException.class); } @Test void boundLongCounterAdd_MonotonicityCheck() { - LongCounter longCounter = sdkMeter.longCounterBuilder("testCounter").build(); + LongCounter longCounter = sdkMeter.counterBuilder("testCounter").build(); - assertThatThrownBy(() -> longCounter.bind(Labels.empty()).add(-9)) + assertThatThrownBy(() -> longCounter.bind(Attributes.empty()).add(-9)) .isInstanceOf(IllegalArgumentException.class); } @Test @SuppressWarnings("unchecked") void stressTest() { - final LongCounter longCounter = sdkMeter.longCounterBuilder("testCounter").build(); + final LongCounter longCounter = sdkMeter.counterBuilder("testCounter").build(); StressTestRunner.Builder stressTestBuilder = StressTestRunner.builder() @@ -193,7 +188,10 @@ class LongCounterSdkTest { 2_000, 1, new OperationUpdaterDirectCall(longCounter, "K", "V"))); stressTestBuilder.addOperation( StressTestRunner.Operation.create( - 2_000, 1, new OperationUpdaterWithBinding(longCounter.bind(Labels.of("K", "V"))))); + 2_000, + 1, + new OperationUpdaterWithBinding( + longCounter.bind(Attributes.builder().put("K", "V").build())))); } stressTestBuilder.build().run(); @@ -224,7 +222,7 @@ class LongCounterSdkTest { void stressTest_WithDifferentLabelSet() { final String[] keys = {"Key_1", "Key_2", "Key_3", "Key_4"}; final String[] values = {"Value_1", "Value_2", "Value_3", "Value_4"}; - final LongCounter longCounter = sdkMeter.longCounterBuilder("testCounter").build(); + final LongCounter longCounter = sdkMeter.counterBuilder("testCounter").build(); StressTestRunner.Builder stressTestBuilder = StressTestRunner.builder() @@ -240,7 +238,8 @@ class LongCounterSdkTest { StressTestRunner.Operation.create( 1_000, 2, - new OperationUpdaterWithBinding(longCounter.bind(Labels.of(keys[i], values[i]))))); + new OperationUpdaterWithBinding( + longCounter.bind(Attributes.builder().put(keys[i], values[i]).build())))); } stressTestBuilder.build().run(); @@ -301,7 +300,7 @@ class LongCounterSdkTest { @Override void update() { - longCounter.add(11, Labels.of(key, value)); + longCounter.add(11, Attributes.builder().put(key, value).build()); } @Override diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/LongSumObserverSdkTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/LongSumObserverSdkTest.java index 564c3c98d3..1b5b1f7e9d 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/LongSumObserverSdkTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/LongSumObserverSdkTest.java @@ -9,7 +9,6 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.aggregator.AggregatorFactory; import io.opentelemetry.sdk.metrics.common.InstrumentType; @@ -33,28 +32,15 @@ class LongSumObserverSdkTest { private final SdkMeterProviderBuilder sdkMeterProviderBuilder = SdkMeterProvider.builder().setClock(testClock).setResource(RESOURCE); - @Test - void collectMetrics_NoCallback() { - SdkMeterProvider sdkMeterProvider = sdkMeterProviderBuilder.build(); - sdkMeterProvider - .get(getClass().getName()) - .longSumObserverBuilder("testObserver") - .setDescription("My own LongSumObserver") - .setUnit("ms") - .build(); - assertThat(sdkMeterProvider.collectAllMetrics()).isEmpty(); - } - @Test void collectMetrics_NoRecords() { SdkMeterProvider sdkMeterProvider = sdkMeterProviderBuilder.build(); sdkMeterProvider .get(getClass().getName()) - .longSumObserverBuilder("testObserver") + .counterBuilder("testObserver") .setDescription("My own LongSumObserver") .setUnit("ms") - .setUpdater(result -> {}) - .build(); + .buildWithCallback(result -> {}); assertThat(sdkMeterProvider.collectAllMetrics()).isEmpty(); } @@ -64,9 +50,9 @@ class LongSumObserverSdkTest { SdkMeterProvider sdkMeterProvider = sdkMeterProviderBuilder.build(); sdkMeterProvider .get(getClass().getName()) - .longSumObserverBuilder("testObserver") - .setUpdater(result -> result.observe(12, Labels.of("k", "v"))) - .build(); + .counterBuilder("testObserver") + .buildWithCallback( + result -> result.observe(12, Attributes.builder().put("k", "v").build())); testClock.advance(Duration.ofNanos(SECOND_NANOS)); assertThat(sdkMeterProvider.collectAllMetrics()) .satisfiesExactly( @@ -125,9 +111,9 @@ class LongSumObserverSdkTest { .build(); sdkMeterProvider .get(getClass().getName()) - .longSumObserverBuilder("testObserver") - .setUpdater(result -> result.observe(12, Labels.of("k", "v"))) - .build(); + .counterBuilder("testObserver") + .buildWithCallback( + result -> result.observe(12, Attributes.builder().put("k", "v").build())); testClock.advance(Duration.ofNanos(SECOND_NANOS)); assertThat(sdkMeterProvider.collectAllMetrics()) .satisfiesExactly( diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/LongUpDownCounterSdkTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/LongUpDownCounterSdkTest.java index 07a0f35580..f30e93d775 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/LongUpDownCounterSdkTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/LongUpDownCounterSdkTest.java @@ -13,7 +13,6 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.BoundLongUpDownCounter; import io.opentelemetry.api.metrics.LongUpDownCounter; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.StressTestRunner.OperationUpdater; import io.opentelemetry.sdk.resources.Resource; @@ -35,15 +34,14 @@ class LongUpDownCounterSdkTest { @Test void add_PreventNullLabels() { - assertThatThrownBy(() -> sdkMeter.longUpDownCounterBuilder("testCounter").build().add(1, null)) + assertThatThrownBy(() -> sdkMeter.upDownCounterBuilder("testCounter").build().add(1, null)) .isInstanceOf(NullPointerException.class) .hasMessage("labels"); } @Test void bound_PreventNullLabels() { - assertThatThrownBy( - () -> sdkMeter.longUpDownCounterBuilder("testUpDownCounter").build().bind(null)) + assertThatThrownBy(() -> sdkMeter.upDownCounterBuilder("testUpDownCounter").build().bind(null)) .isInstanceOf(NullPointerException.class) .hasMessage("labels"); } @@ -51,8 +49,9 @@ class LongUpDownCounterSdkTest { @Test void collectMetrics_NoRecords() { LongUpDownCounter longUpDownCounter = - sdkMeter.longUpDownCounterBuilder("testUpDownCounter").build(); - BoundLongUpDownCounter bound = longUpDownCounter.bind(Labels.of("foo", "bar")); + sdkMeter.upDownCounterBuilder("testUpDownCounter").build(); + BoundLongUpDownCounter bound = + longUpDownCounter.bind(Attributes.builder().put("foo", "bar").build()); try { assertThat(sdkMeterProvider.collectAllMetrics()).isEmpty(); } finally { @@ -65,12 +64,12 @@ class LongUpDownCounterSdkTest { void collectMetrics_WithEmptyLabel() { LongUpDownCounter longUpDownCounter = sdkMeter - .longUpDownCounterBuilder("testUpDownCounter") + .upDownCounterBuilder("testUpDownCounter") .setDescription("description") .setUnit("By") .build(); testClock.advance(Duration.ofNanos(SECOND_NANOS)); - longUpDownCounter.add(12, Labels.empty()); + longUpDownCounter.add(12, Attributes.empty()); longUpDownCounter.add(12); assertThat(sdkMeterProvider.collectAllMetrics()) .satisfiesExactly( @@ -99,17 +98,18 @@ class LongUpDownCounterSdkTest { void collectMetrics_WithMultipleCollects() { long startTime = testClock.now(); LongUpDownCounter longUpDownCounter = - sdkMeter.longUpDownCounterBuilder("testUpDownCounter").build(); - BoundLongUpDownCounter bound = longUpDownCounter.bind(Labels.of("K", "V")); + sdkMeter.upDownCounterBuilder("testUpDownCounter").build(); + BoundLongUpDownCounter bound = + longUpDownCounter.bind(Attributes.builder().put("K", "V").build()); try { // Do some records using bounds and direct calls and bindings. - longUpDownCounter.add(12, Labels.empty()); + longUpDownCounter.add(12, Attributes.empty()); bound.add(123); - longUpDownCounter.add(21, Labels.empty()); + longUpDownCounter.add(21, Attributes.empty()); // Advancing time here should not matter. testClock.advance(Duration.ofNanos(SECOND_NANOS)); bound.add(321); - longUpDownCounter.add(111, Labels.of("K", "V")); + longUpDownCounter.add(111, Attributes.builder().put("K", "V").build()); assertThat(sdkMeterProvider.collectAllMetrics()) .satisfiesExactly( metric -> @@ -136,7 +136,7 @@ class LongUpDownCounterSdkTest { // Repeat to prove we keep previous values. testClock.advance(Duration.ofNanos(SECOND_NANOS)); bound.add(222); - longUpDownCounter.add(11, Labels.empty()); + longUpDownCounter.add(11, Attributes.empty()); assertThat(sdkMeterProvider.collectAllMetrics()) .satisfiesExactly( metric -> @@ -168,7 +168,7 @@ class LongUpDownCounterSdkTest { @SuppressWarnings("unchecked") void stressTest() { final LongUpDownCounter longUpDownCounter = - sdkMeter.longUpDownCounterBuilder("testUpDownCounter").build(); + sdkMeter.upDownCounterBuilder("testUpDownCounter").build(); StressTestRunner.Builder stressTestBuilder = StressTestRunner.builder() @@ -183,7 +183,8 @@ class LongUpDownCounterSdkTest { StressTestRunner.Operation.create( 2_000, 1, - new OperationUpdaterWithBinding(longUpDownCounter.bind(Labels.of("K", "V"))))); + new OperationUpdaterWithBinding( + longUpDownCounter.bind(Attributes.builder().put("K", "V").build())))); } stressTestBuilder.build().run(); @@ -215,7 +216,7 @@ class LongUpDownCounterSdkTest { final String[] keys = {"Key_1", "Key_2", "Key_3", "Key_4"}; final String[] values = {"Value_1", "Value_2", "Value_3", "Value_4"}; final LongUpDownCounter longUpDownCounter = - sdkMeter.longUpDownCounterBuilder("testUpDownCounter").build(); + sdkMeter.upDownCounterBuilder("testUpDownCounter").build(); StressTestRunner.Builder stressTestBuilder = StressTestRunner.builder() @@ -232,7 +233,7 @@ class LongUpDownCounterSdkTest { 1_000, 2, new OperationUpdaterWithBinding( - longUpDownCounter.bind(Labels.of(keys[i], values[i]))))); + longUpDownCounter.bind(Attributes.builder().put(keys[i], values[i]).build())))); } stressTestBuilder.build().run(); @@ -294,7 +295,7 @@ class LongUpDownCounterSdkTest { @Override void update() { - longUpDownCounter.add(11, Labels.of(key, value)); + longUpDownCounter.add(11, Attributes.builder().put(key, value).build()); } @Override diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/LongUpDownSumObserverSdkTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/LongUpDownSumObserverSdkTest.java index 310e33afc7..03c4b4386a 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/LongUpDownSumObserverSdkTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/LongUpDownSumObserverSdkTest.java @@ -9,7 +9,6 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.aggregator.AggregatorFactory; import io.opentelemetry.sdk.metrics.common.InstrumentType; @@ -33,28 +32,15 @@ class LongUpDownSumObserverSdkTest { private final SdkMeterProviderBuilder sdkMeterProviderBuilder = SdkMeterProvider.builder().setClock(testClock).setResource(RESOURCE); - @Test - void collectMetrics_NoCallback() { - SdkMeterProvider sdkMeterProvider = sdkMeterProviderBuilder.build(); - sdkMeterProvider - .get(getClass().getName()) - .longUpDownSumObserverBuilder("testObserver") - .setDescription("My own LongUpDownSumObserver") - .setUnit("ms") - .build(); - assertThat(sdkMeterProvider.collectAllMetrics()).isEmpty(); - } - @Test void collectMetrics_NoRecords() { SdkMeterProvider sdkMeterProvider = sdkMeterProviderBuilder.build(); sdkMeterProvider .get(getClass().getName()) - .longUpDownSumObserverBuilder("testObserver") + .upDownCounterBuilder("testObserver") .setDescription("My own LongUpDownSumObserver") .setUnit("ms") - .setUpdater(result -> {}) - .build(); + .buildWithCallback(result -> {}); assertThat(sdkMeterProvider.collectAllMetrics()).isEmpty(); } @@ -64,9 +50,9 @@ class LongUpDownSumObserverSdkTest { SdkMeterProvider sdkMeterProvider = sdkMeterProviderBuilder.build(); sdkMeterProvider .get(getClass().getName()) - .longUpDownSumObserverBuilder("testObserver") - .setUpdater(result -> result.observe(12, Labels.of("k", "v"))) - .build(); + .upDownCounterBuilder("testObserver") + .buildWithCallback( + result -> result.observe(12, Attributes.builder().put("k", "v").build())); testClock.advance(Duration.ofNanos(SECOND_NANOS)); assertThat(sdkMeterProvider.collectAllMetrics()) .satisfiesExactly( @@ -127,9 +113,9 @@ class LongUpDownSumObserverSdkTest { .build(); sdkMeterProvider .get(getClass().getName()) - .longUpDownSumObserverBuilder("testObserver") - .setUpdater(result -> result.observe(12, Labels.of("k", "v"))) - .build(); + .upDownCounterBuilder("testObserver") + .buildWithCallback( + result -> result.observe(12, Attributes.builder().put("k", "v").build())); testClock.advance(Duration.ofNanos(SECOND_NANOS)); assertThat(sdkMeterProvider.collectAllMetrics()) .satisfiesExactly( diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/LongValueObserverSdkTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/LongValueObserverSdkTest.java index 56e0b9f818..52242a4528 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/LongValueObserverSdkTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/LongValueObserverSdkTest.java @@ -10,7 +10,6 @@ import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.asse import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.time.TestClock; @@ -28,24 +27,14 @@ class LongValueObserverSdkTest { SdkMeterProvider.builder().setClock(testClock).setResource(RESOURCE).build(); private final Meter sdkMeter = sdkMeterProvider.get(getClass().getName()); - @Test - void collectMetrics_NoCallback() { - sdkMeter - .longValueObserverBuilder("testObserver") - .setDescription("My own LongValueObserver") - .setUnit("ms") - .build(); - assertThat(sdkMeterProvider.collectAllMetrics()).isEmpty(); - } - @Test void collectMetrics_NoRecords() { sdkMeter - .longValueObserverBuilder("testObserver") + .gaugeBuilder("testObserver") + .ofLongs() .setDescription("My own LongValueObserver") .setUnit("ms") - .setUpdater(result -> {}) - .build(); + .buildWithCallback(result -> {}); assertThat(sdkMeterProvider.collectAllMetrics()).isEmpty(); } @@ -53,9 +42,10 @@ class LongValueObserverSdkTest { @SuppressWarnings("unchecked") void collectMetrics_WithOneRecord() { sdkMeter - .longValueObserverBuilder("testObserver") - .setUpdater(result -> result.observe(12, Labels.of("k", "v"))) - .build(); + .gaugeBuilder("testObserver") + .ofLongs() + .buildWithCallback( + result -> result.observe(12, Attributes.builder().put("k", "v").build())); testClock.advance(Duration.ofSeconds(1)); assertThat(sdkMeterProvider.collectAllMetrics()) .satisfiesExactly( diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/LongValueRecorderSdkTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/LongValueRecorderSdkTest.java index 82892a9615..554328cc8c 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/LongValueRecorderSdkTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/LongValueRecorderSdkTest.java @@ -6,14 +6,14 @@ package io.opentelemetry.sdk.metrics; import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.metrics.BoundLongValueRecorder; -import io.opentelemetry.api.metrics.LongValueRecorder; +import io.opentelemetry.api.metrics.BoundLongHistogram; +import io.opentelemetry.api.metrics.LongHistogram; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.StressTestRunner.OperationUpdater; import io.opentelemetry.sdk.metrics.data.DoubleSummaryData; @@ -43,22 +43,22 @@ class LongValueRecorderSdkTest { @Test void record_PreventNullLabels() { assertThatThrownBy( - () -> sdkMeter.longValueRecorderBuilder("testRecorder").build().record(1, null)) + () -> sdkMeter.histogramBuilder("testRecorder").ofLongs().build().record(1, null)) .isInstanceOf(NullPointerException.class) .hasMessage("labels"); } @Test void bound_PreventNullLabels() { - assertThatThrownBy(() -> sdkMeter.longValueRecorderBuilder("testRecorder").build().bind(null)) + assertThatThrownBy(() -> sdkMeter.histogramBuilder("testRecorder").ofLongs().build().bind(null)) .isInstanceOf(NullPointerException.class) .hasMessage("labels"); } @Test void collectMetrics_NoRecords() { - LongValueRecorder longRecorder = sdkMeter.longValueRecorderBuilder("testRecorder").build(); - BoundLongValueRecorder bound = longRecorder.bind(Labels.of("key", "value")); + LongHistogram longRecorder = sdkMeter.histogramBuilder("testRecorder").ofLongs().build(); + BoundLongHistogram bound = longRecorder.bind(Attributes.builder().put("key", "value").build()); try { assertThat(sdkMeterProvider.collectAllMetrics()).isEmpty(); } finally { @@ -68,14 +68,15 @@ class LongValueRecorderSdkTest { @Test void collectMetrics_WithEmptyLabel() { - LongValueRecorder longRecorder = + LongHistogram longRecorder = sdkMeter - .longValueRecorderBuilder("testRecorder") + .histogramBuilder("testRecorder") + .ofLongs() .setDescription("description") .setUnit("By") .build(); testClock.advance(Duration.ofNanos(SECOND_NANOS)); - longRecorder.record(12, Labels.empty()); + longRecorder.record(12, Attributes.empty()); longRecorder.record(12); assertThat(sdkMeterProvider.collectAllMetrics()) .containsExactly( @@ -97,72 +98,85 @@ class LongValueRecorderSdkTest { } @Test + @SuppressWarnings("unchecked") void collectMetrics_WithMultipleCollects() { long startTime = testClock.now(); - LongValueRecorder longRecorder = sdkMeter.longValueRecorderBuilder("testRecorder").build(); - BoundLongValueRecorder bound = longRecorder.bind(Labels.of("K", "V")); + LongHistogram longRecorder = sdkMeter.histogramBuilder("testRecorder").ofLongs().build(); + BoundLongHistogram bound = longRecorder.bind(Attributes.builder().put("K", "V").build()); try { // Do some records using bounds and direct calls and bindings. - longRecorder.record(12, Labels.empty()); + longRecorder.record(12, Attributes.empty()); bound.record(123); - longRecorder.record(-14, Labels.empty()); + longRecorder.record(-14, Attributes.empty()); // Advancing time here should not matter. testClock.advance(Duration.ofNanos(SECOND_NANOS)); bound.record(321); - longRecorder.record(-121, Labels.of("K", "V")); + longRecorder.record(-121, Attributes.builder().put("K", "V").build()); assertThat(sdkMeterProvider.collectAllMetrics()) - .containsExactly( - MetricData.createDoubleSummary( - RESOURCE, - INSTRUMENTATION_LIBRARY_INFO, - "testRecorder", - "", - "1", - DoubleSummaryData.create( - Arrays.asList( - DoubleSummaryPointData.create( - startTime, - testClock.now(), - Attributes.builder().put("K", "V").build(), - 3, - 323, - valueAtPercentiles(-121, 321)), - DoubleSummaryPointData.create( - startTime, - testClock.now(), - Attributes.empty(), - 2, - -2, - valueAtPercentiles(-14, 12)))))); + .satisfiesExactly( + metric -> + assertThat(metric) + .hasResource(RESOURCE) + .hasInstrumentationLibrary(INSTRUMENTATION_LIBRARY_INFO) + .hasName("testRecorder") + .hasDoubleSummary() + .points() + .allSatisfy( + point -> + assertThat(point) + .hasStartEpochNanos(startTime) + .hasEpochNanos(testClock.now())) + .satisfiesExactlyInAnyOrder( + point -> + assertThat(point) + .hasCount(3) + .hasSum(323) + .hasPercentileValues( + valueAtPercentiles(-121, 321) + .toArray(new ValueAtPercentile[0])) + .hasAttributes(Attributes.builder().put("K", "V").build()), + point -> + assertThat(point) + .hasCount(2) + .hasSum(-2) + .hasPercentileValues( + valueAtPercentiles(-14, 12).toArray(new ValueAtPercentile[0])) + .hasAttributes(Attributes.empty()))); // Repeat to prove we don't keep previous values. testClock.advance(Duration.ofNanos(SECOND_NANOS)); bound.record(222); - longRecorder.record(17, Labels.empty()); + longRecorder.record(17, Attributes.empty()); assertThat(sdkMeterProvider.collectAllMetrics()) - .containsExactly( - MetricData.createDoubleSummary( - RESOURCE, - INSTRUMENTATION_LIBRARY_INFO, - "testRecorder", - "", - "1", - DoubleSummaryData.create( - Arrays.asList( - DoubleSummaryPointData.create( - startTime + SECOND_NANOS, - testClock.now(), - Attributes.builder().put("K", "V").build(), - 1, - 222, - valueAtPercentiles(222, 222)), - DoubleSummaryPointData.create( - startTime + SECOND_NANOS, - testClock.now(), - Attributes.empty(), - 1, - 17, - valueAtPercentiles(17, 17)))))); + .satisfiesExactly( + metric -> + assertThat(metric) + .hasResource(RESOURCE) + .hasInstrumentationLibrary(INSTRUMENTATION_LIBRARY_INFO) + .hasName("testRecorder") + .hasDoubleSummary() + .points() + .allSatisfy( + point -> + assertThat(point) + .hasStartEpochNanos(startTime + SECOND_NANOS) + .hasEpochNanos(testClock.now())) + .satisfiesExactlyInAnyOrder( + point -> + assertThat(point) + .hasCount(1) + .hasSum(222) + .hasPercentileValues( + valueAtPercentiles(222, 222) + .toArray(new ValueAtPercentile[0])) + .hasAttributes(Attributes.builder().put("K", "V").build()), + point -> + assertThat(point) + .hasCount(1) + .hasSum(17) + .hasPercentileValues( + valueAtPercentiles(17, 17).toArray(new ValueAtPercentile[0])) + .hasAttributes(Attributes.empty()))); } finally { bound.unbind(); } @@ -170,8 +184,7 @@ class LongValueRecorderSdkTest { @Test void stressTest() { - final LongValueRecorder longRecorder = - sdkMeter.longValueRecorderBuilder("testRecorder").build(); + final LongHistogram longRecorder = sdkMeter.histogramBuilder("testRecorder").ofLongs().build(); StressTestRunner.Builder stressTestBuilder = StressTestRunner.builder() @@ -189,7 +202,7 @@ class LongValueRecorderSdkTest { 2_000, 1, new LongValueRecorderSdkTest.OperationUpdaterWithBinding( - longRecorder.bind(Labels.of("K", "V"))))); + longRecorder.bind(Attributes.builder().put("K", "V").build())))); } stressTestBuilder.build().run(); @@ -216,8 +229,7 @@ class LongValueRecorderSdkTest { void stressTest_WithDifferentLabelSet() { final String[] keys = {"Key_1", "Key_2", "Key_3", "Key_4"}; final String[] values = {"Value_1", "Value_2", "Value_3", "Value_4"}; - final LongValueRecorder longRecorder = - sdkMeter.longValueRecorderBuilder("testRecorder").build(); + final LongHistogram longRecorder = sdkMeter.histogramBuilder("testRecorder").ofLongs().build(); StressTestRunner.Builder stressTestBuilder = StressTestRunner.builder() @@ -237,54 +249,40 @@ class LongValueRecorderSdkTest { 1_000, 2, new LongValueRecorderSdkTest.OperationUpdaterWithBinding( - longRecorder.bind(Labels.of(keys[i], values[i]))))); + longRecorder.bind(Attributes.builder().put(keys[i], values[i]).build())))); } stressTestBuilder.build().run(); assertThat(sdkMeterProvider.collectAllMetrics()) - .containsExactly( - MetricData.createDoubleSummary( - RESOURCE, - INSTRUMENTATION_LIBRARY_INFO, - "testRecorder", - "", - "1", - DoubleSummaryData.create( - Arrays.asList( - DoubleSummaryPointData.create( - testClock.now(), - testClock.now(), - Attributes.builder().put(keys[0], values[0]).build(), - 2_000, - 20_000, - valueAtPercentiles(9, 11)), - DoubleSummaryPointData.create( - testClock.now(), - testClock.now(), - Attributes.builder().put(keys[1], values[1]).build(), - 2_000, - 20_000, - valueAtPercentiles(9, 11)), - DoubleSummaryPointData.create( - testClock.now(), - testClock.now(), - Attributes.builder().put(keys[2], values[2]).build(), - 2_000, - 20_000, - valueAtPercentiles(9, 11)), - DoubleSummaryPointData.create( - testClock.now(), - testClock.now(), - Attributes.builder().put(keys[3], values[3]).build(), - 2_000, - 20_000, - valueAtPercentiles(9, 11)))))); + .satisfiesExactly( + metric -> + assertThat(metric) + .hasResource(RESOURCE) + .hasInstrumentationLibrary(INSTRUMENTATION_LIBRARY_INFO) + .hasName("testRecorder") + .hasDoubleSummary() + .points() + .allSatisfy( + point -> + assertThat(point) + .hasStartEpochNanos(testClock.now()) + .hasEpochNanos(testClock.now()) + .hasCount(2_000) + .hasSum(20_000) + .hasPercentileValues( + valueAtPercentiles(9, 11).toArray(new ValueAtPercentile[0]))) + .extracting(point -> point.getAttributes()) + .containsExactlyInAnyOrder( + Attributes.of(stringKey(keys[0]), values[0]), + Attributes.of(stringKey(keys[1]), values[1]), + Attributes.of(stringKey(keys[2]), values[2]), + Attributes.of(stringKey(keys[3]), values[3]))); } private static class OperationUpdaterWithBinding extends OperationUpdater { - private final BoundLongValueRecorder boundLongValueRecorder; + private final BoundLongHistogram boundLongValueRecorder; - private OperationUpdaterWithBinding(BoundLongValueRecorder boundLongValueRecorder) { + private OperationUpdaterWithBinding(BoundLongHistogram boundLongValueRecorder) { this.boundLongValueRecorder = boundLongValueRecorder; } @@ -301,11 +299,11 @@ class LongValueRecorderSdkTest { private static class OperationUpdaterDirectCall extends OperationUpdater { - private final LongValueRecorder longRecorder; + private final LongHistogram longRecorder; private final String key; private final String value; - private OperationUpdaterDirectCall(LongValueRecorder longRecorder, String key, String value) { + private OperationUpdaterDirectCall(LongHistogram longRecorder, String key, String value) { this.longRecorder = longRecorder; this.key = key; this.value = value; @@ -313,7 +311,7 @@ class LongValueRecorderSdkTest { @Override void update() { - longRecorder.record(11, Labels.of(key, value)); + longRecorder.record(11, Attributes.builder().put(key, value).build()); } @Override diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkMeterProviderTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkMeterProviderTest.java index 4f0fcfdb9e..27251f5ff9 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkMeterProviderTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkMeterProviderTest.java @@ -10,13 +10,12 @@ import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.asse import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.DoubleCounter; +import io.opentelemetry.api.metrics.DoubleHistogram; import io.opentelemetry.api.metrics.DoubleUpDownCounter; -import io.opentelemetry.api.metrics.DoubleValueRecorder; import io.opentelemetry.api.metrics.LongCounter; +import io.opentelemetry.api.metrics.LongHistogram; import io.opentelemetry.api.metrics.LongUpDownCounter; -import io.opentelemetry.api.metrics.LongValueRecorder; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.aggregator.AggregatorFactory; import io.opentelemetry.sdk.metrics.common.InstrumentType; @@ -54,22 +53,22 @@ public class SdkMeterProviderTest { void collectAllSyncInstruments() { SdkMeterProvider sdkMeterProvider = sdkMeterProviderBuilder.build(); Meter sdkMeter = sdkMeterProvider.get(SdkMeterProviderTest.class.getName()); - LongCounter longCounter = sdkMeter.longCounterBuilder("testLongCounter").build(); - longCounter.add(10, Labels.empty()); + LongCounter longCounter = sdkMeter.counterBuilder("testLongCounter").build(); + longCounter.add(10, Attributes.empty()); LongUpDownCounter longUpDownCounter = - sdkMeter.longUpDownCounterBuilder("testLongUpDownCounter").build(); - longUpDownCounter.add(-10, Labels.empty()); - LongValueRecorder longValueRecorder = - sdkMeter.longValueRecorderBuilder("testLongValueRecorder").build(); - longValueRecorder.record(10, Labels.empty()); - DoubleCounter doubleCounter = sdkMeter.doubleCounterBuilder("testDoubleCounter").build(); - doubleCounter.add(10.1, Labels.empty()); + sdkMeter.upDownCounterBuilder("testLongUpDownCounter").build(); + longUpDownCounter.add(-10, Attributes.empty()); + LongHistogram longValueRecorder = + sdkMeter.histogramBuilder("testLongValueRecorder").ofLongs().build(); + longValueRecorder.record(10, Attributes.empty()); + DoubleCounter doubleCounter = sdkMeter.counterBuilder("testDoubleCounter").ofDoubles().build(); + doubleCounter.add(10.1, Attributes.empty()); DoubleUpDownCounter doubleUpDownCounter = - sdkMeter.doubleUpDownCounterBuilder("testDoubleUpDownCounter").build(); - doubleUpDownCounter.add(-10.1, Labels.empty()); - DoubleValueRecorder doubleValueRecorder = - sdkMeter.doubleValueRecorderBuilder("testDoubleValueRecorder").build(); - doubleValueRecorder.record(10.1, Labels.empty()); + sdkMeter.upDownCounterBuilder("testDoubleUpDownCounter").ofDoubles().build(); + doubleUpDownCounter.add(-10.1, Attributes.empty()); + DoubleHistogram doubleValueRecorder = + sdkMeter.histogramBuilder("testDoubleValueRecorder").build(); + doubleValueRecorder.record(10.1, Attributes.empty()); assertThat(sdkMeterProvider.collectAllMetrics()) .allSatisfy( @@ -192,8 +191,8 @@ public class SdkMeterProviderTest { SdkMeterProvider sdkMeterProvider = sdkMeterProviderBuilder.build(); Meter sdkMeter = sdkMeterProvider.get(SdkMeterProviderTest.class.getName()); - LongCounter longCounter = sdkMeter.longCounterBuilder("testLongCounter").build(); - longCounter.add(10, Labels.empty()); + LongCounter longCounter = sdkMeter.counterBuilder("testLongCounter").build(); + longCounter.add(10, Attributes.empty()); testClock.advance(Duration.ofNanos(50)); assertThat(sdkMeterProvider.collectAllMetrics()) @@ -215,7 +214,7 @@ public class SdkMeterProviderTest { .hasAttributes(Attributes.empty()) .hasValue(10))); - longCounter.add(10, Labels.empty()); + longCounter.add(10, Attributes.empty()); testClock.advance(Duration.ofNanos(50)); assertThat(sdkMeterProvider.collectAllMetrics()) @@ -244,22 +243,22 @@ public class SdkMeterProviderTest { sdkMeterProviderBuilder, AggregatorFactory.count(AggregationTemporality.DELTA)); SdkMeterProvider sdkMeterProvider = sdkMeterProviderBuilder.build(); Meter sdkMeter = sdkMeterProvider.get(SdkMeterProviderTest.class.getName()); - LongCounter longCounter = sdkMeter.longCounterBuilder("testLongCounter").build(); - longCounter.add(10, Labels.empty()); + LongCounter longCounter = sdkMeter.counterBuilder("testLongCounter").build(); + longCounter.add(10, Attributes.empty()); LongUpDownCounter longUpDownCounter = - sdkMeter.longUpDownCounterBuilder("testLongUpDownCounter").build(); - longUpDownCounter.add(-10, Labels.empty()); - LongValueRecorder longValueRecorder = - sdkMeter.longValueRecorderBuilder("testLongValueRecorder").build(); - longValueRecorder.record(10, Labels.empty()); - DoubleCounter doubleCounter = sdkMeter.doubleCounterBuilder("testDoubleCounter").build(); - doubleCounter.add(10.1, Labels.empty()); + sdkMeter.upDownCounterBuilder("testLongUpDownCounter").build(); + longUpDownCounter.add(-10, Attributes.empty()); + LongHistogram longValueRecorder = + sdkMeter.histogramBuilder("testLongValueRecorder").ofLongs().build(); + longValueRecorder.record(10, Attributes.empty()); + DoubleCounter doubleCounter = sdkMeter.counterBuilder("testDoubleCounter").ofDoubles().build(); + doubleCounter.add(10.1, Attributes.empty()); DoubleUpDownCounter doubleUpDownCounter = - sdkMeter.doubleUpDownCounterBuilder("testDoubleUpDownCounter").build(); - doubleUpDownCounter.add(-10.1, Labels.empty()); - DoubleValueRecorder doubleValueRecorder = - sdkMeter.doubleValueRecorderBuilder("testDoubleValueRecorder").build(); - doubleValueRecorder.record(10.1, Labels.empty()); + sdkMeter.upDownCounterBuilder("testDoubleUpDownCounter").ofDoubles().build(); + doubleUpDownCounter.add(-10.1, Attributes.empty()); + DoubleHistogram doubleValueRecorder = + sdkMeter.histogramBuilder("testDoubleValueRecorder").build(); + doubleValueRecorder.record(10.1, Attributes.empty()); testClock.advance(Duration.ofNanos(50)); @@ -293,12 +292,12 @@ public class SdkMeterProviderTest { testClock.advance(Duration.ofNanos(50)); - longCounter.add(10, Labels.empty()); - longUpDownCounter.add(-10, Labels.empty()); - longValueRecorder.record(10, Labels.empty()); - doubleCounter.add(10.1, Labels.empty()); - doubleUpDownCounter.add(-10.1, Labels.empty()); - doubleValueRecorder.record(10.1, Labels.empty()); + longCounter.add(10, Attributes.empty()); + longUpDownCounter.add(-10, Attributes.empty()); + longValueRecorder.record(10, Attributes.empty()); + doubleCounter.add(10.1, Attributes.empty()); + doubleUpDownCounter.add(-10.1, Attributes.empty()); + doubleValueRecorder.record(10.1, Attributes.empty()); assertThat(sdkMeterProvider.collectAllMetrics()) .allSatisfy( @@ -335,30 +334,27 @@ public class SdkMeterProviderTest { SdkMeterProvider sdkMeterProvider = sdkMeterProviderBuilder.build(); Meter sdkMeter = sdkMeterProvider.get(SdkMeterProviderTest.class.getName()); sdkMeter - .longSumObserverBuilder("testLongSumObserver") - .setUpdater(longResult -> longResult.observe(10, Labels.empty())) - .build(); + .counterBuilder("testLongSumObserver") + .buildWithCallback(longResult -> longResult.observe(10, Attributes.empty())); sdkMeter - .longUpDownSumObserverBuilder("testLongUpDownSumObserver") - .setUpdater(longResult -> longResult.observe(-10, Labels.empty())) - .build(); + .upDownCounterBuilder("testLongUpDownSumObserver") + .buildWithCallback(longResult -> longResult.observe(-10, Attributes.empty())); sdkMeter - .longValueObserverBuilder("testLongValueObserver") - .setUpdater(longResult -> longResult.observe(10, Labels.empty())) - .build(); + .gaugeBuilder("testLongValueObserver") + .ofLongs() + .buildWithCallback(longResult -> longResult.observe(10, Attributes.empty())); sdkMeter - .doubleSumObserverBuilder("testDoubleSumObserver") - .setUpdater(doubleResult -> doubleResult.observe(10.1, Labels.empty())) - .build(); + .counterBuilder("testDoubleSumObserver") + .ofDoubles() + .buildWithCallback(doubleResult -> doubleResult.observe(10.1, Attributes.empty())); sdkMeter - .doubleUpDownSumObserverBuilder("testDoubleUpDownSumObserver") - .setUpdater(doubleResult -> doubleResult.observe(-10.1, Labels.empty())) - .build(); + .upDownCounterBuilder("testDoubleUpDownSumObserver") + .ofDoubles() + .buildWithCallback(doubleResult -> doubleResult.observe(-10.1, Attributes.empty())); sdkMeter - .doubleValueObserverBuilder("testDoubleValueObserver") - .setUpdater(doubleResult -> doubleResult.observe(10.1, Labels.empty())) - .build(); + .gaugeBuilder("testDoubleValueObserver") + .buildWithCallback(doubleResult -> doubleResult.observe(10.1, Attributes.empty())); assertThat(sdkMeterProvider.collectAllMetrics()) .allSatisfy( @@ -459,30 +455,27 @@ public class SdkMeterProviderTest { SdkMeterProvider sdkMeterProvider = sdkMeterProviderBuilder.build(); Meter sdkMeter = sdkMeterProvider.get(SdkMeterProviderTest.class.getName()); sdkMeter - .longSumObserverBuilder("testLongSumObserver") - .setUpdater(longResult -> longResult.observe(10, Labels.empty())) - .build(); + .counterBuilder("testLongSumObserver") + .buildWithCallback(longResult -> longResult.observe(10, Attributes.empty())); sdkMeter - .longUpDownSumObserverBuilder("testLongUpDownSumObserver") - .setUpdater(longResult -> longResult.observe(-10, Labels.empty())) - .build(); + .upDownCounterBuilder("testLongUpDownSumObserver") + .buildWithCallback(longResult -> longResult.observe(-10, Attributes.empty())); sdkMeter - .longValueObserverBuilder("testLongValueObserver") - .setUpdater(longResult -> longResult.observe(10, Labels.empty())) - .build(); + .gaugeBuilder("testLongValueObserver") + .ofLongs() + .buildWithCallback(longResult -> longResult.observe(10, Attributes.empty())); sdkMeter - .doubleSumObserverBuilder("testDoubleSumObserver") - .setUpdater(doubleResult -> doubleResult.observe(10.1, Labels.empty())) - .build(); + .counterBuilder("testDoubleSumObserver") + .ofDoubles() + .buildWithCallback(doubleResult -> doubleResult.observe(10.1, Attributes.empty())); sdkMeter - .doubleUpDownSumObserverBuilder("testDoubleUpDownSumObserver") - .setUpdater(doubleResult -> doubleResult.observe(-10.1, Labels.empty())) - .build(); + .upDownCounterBuilder("testDoubleUpDownSumObserver") + .ofDoubles() + .buildWithCallback(doubleResult -> doubleResult.observe(-10.1, Attributes.empty())); sdkMeter - .doubleValueObserverBuilder("testDoubleValueObserver") - .setUpdater(doubleResult -> doubleResult.observe(10.1, Labels.empty())) - .build(); + .gaugeBuilder("testDoubleValueObserver") + .buildWithCallback(doubleResult -> doubleResult.observe(10.1, Attributes.empty())); testClock.advance(Duration.ofNanos(50)); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkMeterRegistryTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkMeterRegistryTest.java index 2076e4a248..ce77cea0b2 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkMeterRegistryTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkMeterRegistryTest.java @@ -10,9 +10,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.mock; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.sdk.common.Clock; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.resources.Resource; @@ -57,14 +57,12 @@ class SdkMeterRegistryTest { @Test void getSameInstanceForSameName_WithoutVersion() { assertThat(meterProvider.get("test")).isSameAs(meterProvider.get("test")); - assertThat(meterProvider.get("test")).isSameAs(meterProvider.get("test", null)); assertThat(meterProvider.get("test")).isSameAs(meterProvider.meterBuilder("test").build()); } @Test void getSameInstanceForSameName_WithVersion() { - assertThat(meterProvider.get("test", "version")) - .isSameAs(meterProvider.get("test", "version")) + assertThat(meterProvider.meterBuilder("test").setInstrumentationVersion("version").build()) .isSameAs(meterProvider.meterBuilder("test").setInstrumentationVersion("version").build()); } @@ -102,11 +100,11 @@ class SdkMeterRegistryTest { @SuppressWarnings("unchecked") void metricProducer_GetAllMetrics() { Meter sdkMeter1 = meterProvider.get("io.opentelemetry.sdk.metrics.MeterSdkRegistryTest_1"); - LongCounter longCounter1 = sdkMeter1.longCounterBuilder("testLongCounter").build(); - longCounter1.add(10, Labels.empty()); + LongCounter longCounter1 = sdkMeter1.counterBuilder("testLongCounter").build(); + longCounter1.add(10, Attributes.empty()); Meter sdkMeter2 = meterProvider.get("io.opentelemetry.sdk.metrics.MeterSdkRegistryTest_2"); - LongCounter longCounter2 = sdkMeter2.longCounterBuilder("testLongCounter").build(); - longCounter2.add(10, Labels.empty()); + LongCounter longCounter2 = sdkMeter2.counterBuilder("testLongCounter").build(); + longCounter2.add(10, Attributes.empty()); assertThat(meterProvider.collectAllMetrics()) .allSatisfy( @@ -135,10 +133,6 @@ class SdkMeterRegistryTest { assertThat(meter.getInstrumentationLibraryInfo().getName()) .isEqualTo(SdkMeterProvider.DEFAULT_METER_NAME); - meter = (SdkMeter) meterProvider.get(null, null); - assertThat(meter.getInstrumentationLibraryInfo().getName()) - .isEqualTo(SdkMeterProvider.DEFAULT_METER_NAME); - meter = (SdkMeter) meterProvider.meterBuilder(null).build(); assertThat(meter.getInstrumentationLibraryInfo().getName()) .isEqualTo(SdkMeterProvider.DEFAULT_METER_NAME); @@ -150,10 +144,6 @@ class SdkMeterRegistryTest { assertThat(meter.getInstrumentationLibraryInfo().getName()) .isEqualTo(SdkMeterProvider.DEFAULT_METER_NAME); - meter = (SdkMeter) meterProvider.get("", ""); - assertThat(meter.getInstrumentationLibraryInfo().getName()) - .isEqualTo(SdkMeterProvider.DEFAULT_METER_NAME); - meter = (SdkMeter) meterProvider.meterBuilder("").build(); assertThat(meter.getInstrumentationLibraryInfo().getName()) .isEqualTo(SdkMeterProvider.DEFAULT_METER_NAME); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkMeterTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkMeterTest.java index a589249481..8e94ba6e12 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkMeterTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkMeterTest.java @@ -8,19 +8,12 @@ package io.opentelemetry.sdk.metrics; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import io.opentelemetry.api.metrics.BatchRecorder; import io.opentelemetry.api.metrics.DoubleCounter; -import io.opentelemetry.api.metrics.DoubleSumObserver; +import io.opentelemetry.api.metrics.DoubleHistogram; import io.opentelemetry.api.metrics.DoubleUpDownCounter; -import io.opentelemetry.api.metrics.DoubleUpDownSumObserver; -import io.opentelemetry.api.metrics.DoubleValueObserver; -import io.opentelemetry.api.metrics.DoubleValueRecorder; import io.opentelemetry.api.metrics.LongCounter; -import io.opentelemetry.api.metrics.LongSumObserver; +import io.opentelemetry.api.metrics.LongHistogram; import io.opentelemetry.api.metrics.LongUpDownCounter; -import io.opentelemetry.api.metrics.LongUpDownSumObserver; -import io.opentelemetry.api.metrics.LongValueObserver; -import io.opentelemetry.api.metrics.LongValueRecorder; import io.opentelemetry.api.metrics.Meter; import org.junit.jupiter.api.Test; @@ -32,7 +25,7 @@ class SdkMeterTest { void testLongCounter() { LongCounter longCounter = sdkMeter - .longCounterBuilder("testLongCounter") + .counterBuilder("testLongCounter") .setDescription("My very own counter") .setUnit("metric tonnes") .build(); @@ -40,16 +33,16 @@ class SdkMeterTest { assertThat( sdkMeter - .longCounterBuilder("testLongCounter") + .counterBuilder("testLongCounter") .setDescription("My very own counter") .setUnit("metric tonnes") .build()) .isSameAs(longCounter); - assertThatThrownBy(() -> sdkMeter.longCounterBuilder("testLongCounter").build()) + assertThatThrownBy(() -> sdkMeter.counterBuilder("testLongCounter").build()) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Instrument with same name and different descriptor already created."); - assertThatThrownBy(() -> sdkMeter.longCounterBuilder("testLongCounter".toUpperCase()).build()) + assertThatThrownBy(() -> sdkMeter.counterBuilder("testLongCounter".toUpperCase()).build()) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Instrument with same name and different descriptor already created."); } @@ -58,7 +51,7 @@ class SdkMeterTest { void testLongUpDownCounter() { LongUpDownCounter longUpDownCounter = sdkMeter - .longUpDownCounterBuilder("testLongUpDownCounter") + .upDownCounterBuilder("testLongUpDownCounter") .setDescription("My very own counter") .setUnit("metric tonnes") .build(); @@ -66,26 +59,27 @@ class SdkMeterTest { assertThat( sdkMeter - .longUpDownCounterBuilder("testLongUpDownCounter") + .upDownCounterBuilder("testLongUpDownCounter") .setDescription("My very own counter") .setUnit("metric tonnes") .build()) .isSameAs(longUpDownCounter); - assertThatThrownBy(() -> sdkMeter.longUpDownCounterBuilder("testLongUpDownCounter").build()) + assertThatThrownBy(() -> sdkMeter.upDownCounterBuilder("testLongUpDownCounter").build()) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Instrument with same name and different descriptor already created."); assertThatThrownBy( - () -> sdkMeter.longUpDownCounterBuilder("testLongUpDownCounter".toUpperCase()).build()) + () -> sdkMeter.upDownCounterBuilder("testLongUpDownCounter".toUpperCase()).build()) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Instrument with same name and different descriptor already created."); } @Test void testLongValueRecorder() { - LongValueRecorder longValueRecorder = + LongHistogram longValueRecorder = sdkMeter - .longValueRecorderBuilder("testLongValueRecorder") + .histogramBuilder("testLongValueRecorder") + .ofLongs() .setDescription("My very own counter") .setUnit("metric tonnes") .build(); @@ -93,104 +87,89 @@ class SdkMeterTest { assertThat( sdkMeter - .longValueRecorderBuilder("testLongValueRecorder") + .histogramBuilder("testLongValueRecorder") + .ofLongs() .setDescription("My very own counter") .setUnit("metric tonnes") .build()) .isSameAs(longValueRecorder); - assertThatThrownBy(() -> sdkMeter.longValueRecorderBuilder("testLongValueRecorder").build()) + assertThatThrownBy(() -> sdkMeter.histogramBuilder("testLongValueRecorder").ofLongs().build()) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Instrument with same name and different descriptor already created."); assertThatThrownBy( - () -> sdkMeter.longValueRecorderBuilder("testLongValueRecorder".toUpperCase()).build()) + () -> + sdkMeter.histogramBuilder("testLongValueRecorder".toUpperCase()).ofLongs().build()) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Instrument with same name and different descriptor already created."); } @Test void testLongValueObserver() { - LongValueObserver longValueObserver = - sdkMeter - .longValueObserverBuilder("longValueObserver") - .setDescription("My very own counter") - .setUnit("metric tonnes") - .build(); - assertThat(longValueObserver).isNotNull(); + sdkMeter + .gaugeBuilder("longValueObserver") + .ofLongs() + .setDescription("My very own counter") + .setUnit("metric tonnes") + .buildWithCallback(obs -> {}); - assertThat( - sdkMeter - .longValueObserverBuilder("longValueObserver") - .setDescription("My very own counter") - .setUnit("metric tonnes") - .build()) - .isSameAs(longValueObserver); - - assertThatThrownBy(() -> sdkMeter.longValueObserverBuilder("longValueObserver").build()) + assertThatThrownBy( + () -> sdkMeter.gaugeBuilder("longValueObserver").ofLongs().buildWithCallback(x -> {})) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Instrument with same name and different descriptor already created."); assertThatThrownBy( - () -> sdkMeter.longValueObserverBuilder("longValueObserver".toUpperCase()).build()) + () -> + sdkMeter + .gaugeBuilder("longValueObserver".toUpperCase()) + .ofLongs() + .buildWithCallback(x -> {})) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Instrument with same name and different descriptor already created."); } @Test void testLongSumObserver() { - LongSumObserver longObserver = - sdkMeter - .longSumObserverBuilder("testLongSumObserver") - .setDescription("My very own counter") - .setUnit("metric tonnes") - .build(); - assertThat(longObserver).isNotNull(); - - assertThat( - sdkMeter - .longSumObserverBuilder("testLongSumObserver") - .setDescription("My very own counter") - .setUnit("metric tonnes") - .build()) - .isSameAs(longObserver); - - assertThatThrownBy(() -> sdkMeter.longSumObserverBuilder("testLongSumObserver").build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Instrument with same name and different descriptor already created."); + sdkMeter + .counterBuilder("testLongSumObserver") + .setDescription("My very own counter") + .setUnit("metric tonnes") + .buildWithCallback(x -> {}); assertThatThrownBy( - () -> sdkMeter.longSumObserverBuilder("testLongSumObserver".toUpperCase()).build()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Instrument with same name and different descriptor already created."); - } - - @Test - void testLongUpDownSumObserver() { - LongUpDownSumObserver longObserver = - sdkMeter - .longUpDownSumObserverBuilder("testLongUpDownSumObserver") - .setDescription("My very own counter") - .setUnit("metric tonnes") - .build(); - assertThat(longObserver).isNotNull(); - - assertThat( - sdkMeter - .longUpDownSumObserverBuilder("testLongUpDownSumObserver") - .setDescription("My very own counter") - .setUnit("metric tonnes") - .build()) - .isSameAs(longObserver); - - assertThatThrownBy( - () -> sdkMeter.longUpDownSumObserverBuilder("testLongUpDownSumObserver").build()) + () -> sdkMeter.counterBuilder("testLongSumObserver").buildWithCallback(x -> {})) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Instrument with same name and different descriptor already created."); assertThatThrownBy( () -> sdkMeter - .longUpDownSumObserverBuilder("testLongUpDownSumObserver".toUpperCase()) - .build()) + .counterBuilder("testLongSumObserver".toUpperCase()) + .buildWithCallback(x -> {})) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Instrument with same name and different descriptor already created."); + } + + @Test + void testLongUpDownSumObserver() { + sdkMeter + .upDownCounterBuilder("testLongUpDownSumObserver") + .setDescription("My very own counter") + .setUnit("metric tonnes") + .buildWithCallback(x -> {}); + + assertThatThrownBy( + () -> + sdkMeter + .upDownCounterBuilder("testLongUpDownSumObserver") + .buildWithCallback(x -> {})) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Instrument with same name and different descriptor already created."); + + assertThatThrownBy( + () -> + sdkMeter + .upDownCounterBuilder("testLongUpDownSumObserver".toUpperCase()) + .buildWithCallback(x -> {})) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Instrument with same name and different descriptor already created."); } @@ -199,7 +178,8 @@ class SdkMeterTest { void testDoubleCounter() { DoubleCounter doubleCounter = sdkMeter - .doubleCounterBuilder("testDoubleCounter") + .counterBuilder("testDoubleCounter") + .ofDoubles() .setDescription("My very own counter") .setUnit("metric tonnes") .build(); @@ -207,17 +187,18 @@ class SdkMeterTest { assertThat( sdkMeter - .doubleCounterBuilder("testDoubleCounter") + .counterBuilder("testDoubleCounter") + .ofDoubles() .setDescription("My very own counter") .setUnit("metric tonnes") .build()) .isSameAs(doubleCounter); - assertThatThrownBy(() -> sdkMeter.doubleCounterBuilder("testDoubleCounter").build()) + assertThatThrownBy(() -> sdkMeter.counterBuilder("testDoubleCounter").ofDoubles().build()) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Instrument with same name and different descriptor already created."); assertThatThrownBy( - () -> sdkMeter.doubleCounterBuilder("testDoubleCounter".toUpperCase()).build()) + () -> sdkMeter.counterBuilder("testDoubleCounter".toUpperCase()).ofDoubles().build()) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Instrument with same name and different descriptor already created."); } @@ -226,7 +207,8 @@ class SdkMeterTest { void testDoubleUpDownCounter() { DoubleUpDownCounter doubleUpDownCounter = sdkMeter - .doubleUpDownCounterBuilder("testDoubleUpDownCounter") + .upDownCounterBuilder("testDoubleUpDownCounter") + .ofDoubles() .setDescription("My very own counter") .setUnit("metric tonnes") .build(); @@ -234,19 +216,22 @@ class SdkMeterTest { assertThat( sdkMeter - .doubleUpDownCounterBuilder("testDoubleUpDownCounter") + .upDownCounterBuilder("testDoubleUpDownCounter") + .ofDoubles() .setDescription("My very own counter") .setUnit("metric tonnes") .build()) .isSameAs(doubleUpDownCounter); - assertThatThrownBy(() -> sdkMeter.doubleUpDownCounterBuilder("testDoubleUpDownCounter").build()) + assertThatThrownBy( + () -> sdkMeter.upDownCounterBuilder("testDoubleUpDownCounter").ofDoubles().build()) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Instrument with same name and different descriptor already created."); assertThatThrownBy( () -> sdkMeter - .doubleUpDownCounterBuilder("testDoubleUpDownCounter".toUpperCase()) + .upDownCounterBuilder("testDoubleUpDownCounter".toUpperCase()) + .ofDoubles() .build()) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Instrument with same name and different descriptor already created."); @@ -254,9 +239,9 @@ class SdkMeterTest { @Test void testDoubleValueRecorder() { - DoubleValueRecorder doubleValueRecorder = + DoubleHistogram doubleValueRecorder = sdkMeter - .doubleValueRecorderBuilder("testDoubleValueRecorder") + .histogramBuilder("testDoubleValueRecorder") .setDescription("My very own ValueRecorder") .setUnit("metric tonnes") .build(); @@ -264,113 +249,93 @@ class SdkMeterTest { assertThat( sdkMeter - .doubleValueRecorderBuilder("testDoubleValueRecorder") + .histogramBuilder("testDoubleValueRecorder") .setDescription("My very own ValueRecorder") .setUnit("metric tonnes") .build()) .isSameAs(doubleValueRecorder); - assertThatThrownBy(() -> sdkMeter.doubleValueRecorderBuilder("testDoubleValueRecorder").build()) + assertThatThrownBy(() -> sdkMeter.histogramBuilder("testDoubleValueRecorder").build()) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Instrument with same name and different descriptor already created."); assertThatThrownBy( - () -> - sdkMeter - .doubleValueRecorderBuilder("testDoubleValueRecorder".toUpperCase()) - .build()) + () -> sdkMeter.histogramBuilder("testDoubleValueRecorder".toUpperCase()).build()) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Instrument with same name and different descriptor already created."); } @Test void testDoubleSumObserver() { - DoubleSumObserver doubleObserver = - sdkMeter - .doubleSumObserverBuilder("testDoubleSumObserver") - .setDescription("My very own counter") - .setUnit("metric tonnes") - .build(); - assertThat(doubleObserver).isNotNull(); + sdkMeter + .counterBuilder("testDoubleSumObserver") + .ofDoubles() + .setDescription("My very own counter") + .setUnit("metric tonnes") + .buildWithCallback(x -> {}); - assertThat( - sdkMeter - .doubleSumObserverBuilder("testDoubleSumObserver") - .setDescription("My very own counter") - .setUnit("metric tonnes") - .build()) - .isSameAs(doubleObserver); - - assertThatThrownBy(() -> sdkMeter.doubleSumObserverBuilder("testDoubleSumObserver").build()) + assertThatThrownBy( + () -> + sdkMeter + .counterBuilder("testDoubleSumObserver") + .ofDoubles() + .buildWithCallback(x -> {})) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Instrument with same name and different descriptor already created."); assertThatThrownBy( - () -> sdkMeter.doubleSumObserverBuilder("testDoubleSumObserver".toUpperCase()).build()) + () -> + sdkMeter + .counterBuilder("testDoubleSumObserver".toUpperCase()) + .ofDoubles() + .buildWithCallback(x -> {})) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Instrument with same name and different descriptor already created."); } @Test void testDoubleUpDownSumObserver() { - DoubleUpDownSumObserver doubleObserver = - sdkMeter - .doubleUpDownSumObserverBuilder("testDoubleUpDownSumObserver") - .setDescription("My very own counter") - .setUnit("metric tonnes") - .build(); - assertThat(doubleObserver).isNotNull(); - - assertThat( - sdkMeter - .doubleUpDownSumObserverBuilder("testDoubleUpDownSumObserver") - .setDescription("My very own counter") - .setUnit("metric tonnes") - .build()) - .isSameAs(doubleObserver); + sdkMeter + .upDownCounterBuilder("testDoubleUpDownSumObserver") + .ofDoubles() + .setDescription("My very own counter") + .setUnit("metric tonnes") + .buildWithCallback(x -> {}); assertThatThrownBy( - () -> sdkMeter.doubleUpDownSumObserverBuilder("testDoubleUpDownSumObserver").build()) + () -> + sdkMeter + .upDownCounterBuilder("testDoubleUpDownSumObserver") + .ofDoubles() + .buildWithCallback(x -> {})) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Instrument with same name and different descriptor already created."); assertThatThrownBy( () -> sdkMeter - .doubleUpDownSumObserverBuilder("testDoubleUpDownSumObserver".toUpperCase()) - .build()) + .upDownCounterBuilder("testDoubleUpDownSumObserver".toUpperCase()) + .ofDoubles() + .buildWithCallback(x -> {})) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Instrument with same name and different descriptor already created."); } @Test void testDoubleValueObserver() { - DoubleValueObserver doubleValueObserver = - sdkMeter - .doubleValueObserverBuilder("doubleValueObserver") - .setDescription("My very own counter") - .setUnit("metric tonnes") - .build(); - assertThat(doubleValueObserver).isNotNull(); + sdkMeter + .gaugeBuilder("doubleValueObserver") + .setDescription("My very own counter") + .setUnit("metric tonnes") + .buildWithCallback(x -> {}); - assertThat( - sdkMeter - .doubleValueObserverBuilder("doubleValueObserver") - .setDescription("My very own counter") - .setUnit("metric tonnes") - .build()) - .isSameAs(doubleValueObserver); - - assertThatThrownBy(() -> sdkMeter.doubleValueObserverBuilder("doubleValueObserver").build()) + assertThatThrownBy( + () -> sdkMeter.gaugeBuilder("doubleValueObserver").buildWithCallback(x -> {})) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Instrument with same name and different descriptor already created."); assertThatThrownBy( - () -> sdkMeter.doubleValueObserverBuilder("doubleValueObserver".toUpperCase()).build()) + () -> + sdkMeter + .gaugeBuilder("doubleValueObserver".toUpperCase()) + .buildWithCallback(x -> {})) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Instrument with same name and different descriptor already created."); } - - @Test - void testBatchRecorder() { - BatchRecorder batchRecorder = sdkMeter.newBatchRecorder("key", "value"); - assertThat(batchRecorder).isNotNull(); - assertThat(batchRecorder).isInstanceOf(BatchRecorderSdk.class); - } } diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SynchronousInstrumentAccumulatorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SynchronousInstrumentAccumulatorTest.java index 1b47fcdabe..e296cb4694 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SynchronousInstrumentAccumulatorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SynchronousInstrumentAccumulatorTest.java @@ -8,7 +8,7 @@ package io.opentelemetry.sdk.metrics; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static org.assertj.core.api.Assertions.assertThat; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.context.Context; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.aggregator.Aggregator; @@ -44,17 +44,17 @@ public class SynchronousInstrumentAccumulatorTest { SynchronousInstrumentAccumulator accumulator = new SynchronousInstrumentAccumulator<>( aggregator, new InstrumentProcessor<>(aggregator, testClock.now()), spyLabelsProcessor); - accumulator.bind(Labels.empty()); - Mockito.verify(spyLabelsProcessor).onLabelsBound(Context.current(), Labels.empty()); + accumulator.bind(Attributes.empty()); + Mockito.verify(spyLabelsProcessor).onLabelsBound(Context.current(), Attributes.empty()); } @Test void labelsProcessor_applied() { - final Labels labels = Labels.of("K", "V"); + final Attributes labels = Attributes.builder().put("K", "V").build(); LabelsProcessor labelsProcessor = new LabelsProcessor() { @Override - public Labels onLabelsBound(Context ctx, Labels lbls) { + public Attributes onLabelsBound(Context ctx, Attributes lbls) { return lbls.toBuilder().put("modifiedK", "modifiedV").build(); } }; @@ -76,12 +76,15 @@ public class SynchronousInstrumentAccumulatorTest { SynchronousInstrumentAccumulator accumulator = new SynchronousInstrumentAccumulator<>( aggregator, new InstrumentProcessor<>(aggregator, testClock.now()), labelsProcessor); - AggregatorHandle aggregatorHandle = accumulator.bind(Labels.of("K", "V")); - AggregatorHandle duplicateAggregatorHandle = accumulator.bind(Labels.of("K", "V")); + AggregatorHandle aggregatorHandle = + accumulator.bind(Attributes.builder().put("K", "V").build()); + AggregatorHandle duplicateAggregatorHandle = + accumulator.bind(Attributes.builder().put("K", "V").build()); try { assertThat(duplicateAggregatorHandle).isSameAs(aggregatorHandle); accumulator.collectAll(testClock.now()); - AggregatorHandle anotherDuplicateAggregatorHandle = accumulator.bind(Labels.of("K", "V")); + AggregatorHandle anotherDuplicateAggregatorHandle = + accumulator.bind(Attributes.builder().put("K", "V").build()); try { assertThat(anotherDuplicateAggregatorHandle).isSameAs(aggregatorHandle); } finally { diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/CountAggregatorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/CountAggregatorTest.java index 522879a112..d6c377484c 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/CountAggregatorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/CountAggregatorTest.java @@ -9,7 +9,6 @@ import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.asse import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.common.InstrumentType; @@ -80,7 +79,7 @@ class CountAggregatorTest { MetricData metricData = cumulativeAggregator.toMetricData( - Collections.singletonMap(Labels.empty(), aggregatorHandle.accumulateThenReset()), + Collections.singletonMap(Attributes.empty(), aggregatorHandle.accumulateThenReset()), 0, 10, 100); @@ -111,7 +110,7 @@ class CountAggregatorTest { MetricData metricData = deltaAggregator.toMetricData( - Collections.singletonMap(Labels.empty(), aggregatorHandle.accumulateThenReset()), + Collections.singletonMap(Attributes.empty(), aggregatorHandle.accumulateThenReset()), 0, 10, 100); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/DoubleHistogramAggregatorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/DoubleHistogramAggregatorTest.java index efbc387adf..18a9a4847e 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/DoubleHistogramAggregatorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/DoubleHistogramAggregatorTest.java @@ -8,7 +8,7 @@ package io.opentelemetry.sdk.metrics.aggregator; import static org.assertj.core.api.Assertions.assertThat; import com.google.common.collect.ImmutableList; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.common.InstrumentType; @@ -87,7 +87,7 @@ public class DoubleHistogramAggregatorTest { MetricData metricData = aggregator.toMetricData( - Collections.singletonMap(Labels.empty(), aggregatorHandle.accumulateThenReset()), + Collections.singletonMap(Attributes.empty(), aggregatorHandle.accumulateThenReset()), 0, 10, 100); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/DoubleLastValueAggregatorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/DoubleLastValueAggregatorTest.java index 94a23ddd10..a335db61c2 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/DoubleLastValueAggregatorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/DoubleLastValueAggregatorTest.java @@ -9,7 +9,6 @@ import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.asse import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.common.InstrumentType; @@ -69,7 +68,7 @@ class DoubleLastValueAggregatorTest { MetricData metricData = aggregator.toMetricData( - Collections.singletonMap(Labels.empty(), aggregatorHandle.accumulateThenReset()), + Collections.singletonMap(Attributes.empty(), aggregatorHandle.accumulateThenReset()), 0, 10, 100); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/DoubleMinMaxSumCountAggregatorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/DoubleMinMaxSumCountAggregatorTest.java index 74d29f9788..114bf70253 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/DoubleMinMaxSumCountAggregatorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/DoubleMinMaxSumCountAggregatorTest.java @@ -8,7 +8,7 @@ package io.opentelemetry.sdk.metrics.aggregator; import static org.assertj.core.api.Assertions.assertThat; import com.google.errorprone.annotations.concurrent.GuardedBy; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.common.InstrumentType; @@ -82,7 +82,7 @@ class DoubleMinMaxSumCountAggregatorTest { MetricData metricData = aggregator.toMetricData( - Collections.singletonMap(Labels.empty(), aggregatorHandle.accumulateThenReset()), + Collections.singletonMap(Attributes.empty(), aggregatorHandle.accumulateThenReset()), 0, 10, 100); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/DoubleSumAggregatorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/DoubleSumAggregatorTest.java index 3a5cf4dc64..8b8dc6c3cd 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/DoubleSumAggregatorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/DoubleSumAggregatorTest.java @@ -9,7 +9,6 @@ import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.asse import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.aggregator.AbstractSumAggregator.MergeStrategy; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; @@ -106,7 +105,7 @@ class DoubleSumAggregatorTest { MetricData metricData = aggregator.toMetricData( - Collections.singletonMap(Labels.empty(), aggregatorHandle.accumulateThenReset()), + Collections.singletonMap(Attributes.empty(), aggregatorHandle.accumulateThenReset()), 0, 10, 100); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/LongLastValueAggregatorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/LongLastValueAggregatorTest.java index 3aa313cf87..5eb7b3775e 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/LongLastValueAggregatorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/LongLastValueAggregatorTest.java @@ -8,7 +8,6 @@ package io.opentelemetry.sdk.metrics.aggregator; import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.common.InstrumentType; @@ -69,7 +68,7 @@ class LongLastValueAggregatorTest { MetricData metricData = aggregator.toMetricData( - Collections.singletonMap(Labels.empty(), aggregatorHandle.accumulateThenReset()), + Collections.singletonMap(Attributes.empty(), aggregatorHandle.accumulateThenReset()), 0, 10, 100); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/LongMinMaxSumCountAggregatorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/LongMinMaxSumCountAggregatorTest.java index 81a76999e6..3b49ffe8b4 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/LongMinMaxSumCountAggregatorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/LongMinMaxSumCountAggregatorTest.java @@ -8,7 +8,7 @@ package io.opentelemetry.sdk.metrics.aggregator; import static org.assertj.core.api.Assertions.assertThat; import com.google.errorprone.annotations.concurrent.GuardedBy; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.common.InstrumentType; @@ -79,7 +79,7 @@ class LongMinMaxSumCountAggregatorTest { MetricData metricData = aggregator.toMetricData( - Collections.singletonMap(Labels.empty(), aggregatorHandle.accumulateThenReset()), + Collections.singletonMap(Attributes.empty(), aggregatorHandle.accumulateThenReset()), 0, 10, 100); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/LongSumAggregatorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/LongSumAggregatorTest.java index a9c958c48c..d333ed1d0e 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/LongSumAggregatorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/LongSumAggregatorTest.java @@ -9,7 +9,6 @@ import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.asse import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; import io.opentelemetry.sdk.metrics.aggregator.AbstractSumAggregator.MergeStrategy; import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor; @@ -108,7 +107,7 @@ class LongSumAggregatorTest { MetricData metricData = aggregator.toMetricData( - Collections.singletonMap(Labels.empty(), aggregatorHandle.accumulateThenReset()), + Collections.singletonMap(Attributes.empty(), aggregatorHandle.accumulateThenReset()), 0, 10, 100); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/MinMaxSumCountAccumulationTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/MinMaxSumCountAccumulationTest.java index dce726dcba..2f31881834 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/MinMaxSumCountAccumulationTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/aggregator/MinMaxSumCountAccumulationTest.java @@ -8,7 +8,7 @@ package io.opentelemetry.sdk.metrics.aggregator; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static org.assertj.core.api.Assertions.assertThat; -import io.opentelemetry.api.metrics.common.Labels; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.metrics.data.DoubleSummaryPointData; import io.opentelemetry.sdk.metrics.data.ValueAtPercentile; import org.junit.jupiter.api.Test; @@ -26,7 +26,8 @@ class MinMaxSumCountAccumulationTest { } private static DoubleSummaryPointData getPoint(MinMaxSumCountAccumulation accumulation) { - DoubleSummaryPointData point = accumulation.toPoint(12345, 12358, Labels.of("key", "value")); + DoubleSummaryPointData point = + accumulation.toPoint(12345, 12358, Attributes.builder().put("key", "value").build()); assertThat(point).isNotNull(); assertThat(point.getStartEpochNanos()).isEqualTo(12345); assertThat(point.getEpochNanos()).isEqualTo(12358); diff --git a/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorCpuBenchmark.java b/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorCpuBenchmark.java index 918ef2fad1..bc4cb6e827 100644 --- a/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorCpuBenchmark.java +++ b/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorCpuBenchmark.java @@ -7,6 +7,7 @@ package io.opentelemetry.sdk.trace.export; import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.metrics.export.MetricProducer; import io.opentelemetry.sdk.trace.ReadableSpan; import io.opentelemetry.sdk.trace.SdkTracerProvider; import java.util.concurrent.TimeUnit; @@ -33,7 +34,7 @@ import org.openjdk.jmh.annotations.Warmup; public class BatchSpanProcessorCpuBenchmark { @State(Scope.Benchmark) public static class BenchmarkState { - private SdkMeterProvider sdkMeterProvider; + private MetricProducer collector; private BatchSpanProcessor processor; private Tracer tracer; private int numThreads = 1; @@ -46,7 +47,9 @@ public class BatchSpanProcessorCpuBenchmark { @Setup(Level.Iteration) public final void setup() { - sdkMeterProvider = SdkMeterProvider.builder().buildAndRegisterGlobal(); + final SdkMeterProvider sdkMeterProvider = SdkMeterProvider.builder().buildAndRegisterGlobal(); + // Note: these will (likely) no longer be the same in future SDK. + collector = sdkMeterProvider; SpanExporter exporter = new DelayingSpanExporter(delayMs); processor = BatchSpanProcessor.builder(exporter).build(); tracer = @@ -56,7 +59,7 @@ public class BatchSpanProcessorCpuBenchmark { @TearDown(Level.Iteration) public final void recordMetrics() { BatchSpanProcessorMetrics metrics = - new BatchSpanProcessorMetrics(sdkMeterProvider.collectAllMetrics(), numThreads); + new BatchSpanProcessorMetrics(collector.collectAllMetrics(), numThreads); exportedSpans = metrics.exportedSpans(); droppedSpans = metrics.droppedSpans(); } diff --git a/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorDroppedSpansBenchmark.java b/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorDroppedSpansBenchmark.java index ef0775dd1f..b3ae91ab47 100644 --- a/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorDroppedSpansBenchmark.java +++ b/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorDroppedSpansBenchmark.java @@ -7,6 +7,7 @@ package io.opentelemetry.sdk.trace.export; import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.metrics.export.MetricProducer; import io.opentelemetry.sdk.trace.ReadableSpan; import io.opentelemetry.sdk.trace.SdkTracerProvider; import org.openjdk.jmh.annotations.AuxCounters; @@ -27,7 +28,7 @@ public class BatchSpanProcessorDroppedSpansBenchmark { @State(Scope.Benchmark) public static class BenchmarkState { - private SdkMeterProvider sdkMeterProvider; + private MetricProducer collector; private BatchSpanProcessor processor; private Tracer tracer; private double dropRatio; @@ -37,7 +38,9 @@ public class BatchSpanProcessorDroppedSpansBenchmark { @Setup(Level.Iteration) public final void setup() { - sdkMeterProvider = SdkMeterProvider.builder().buildAndRegisterGlobal(); + final SdkMeterProvider sdkMeterProvider = SdkMeterProvider.builder().buildAndRegisterGlobal(); + // Note: these will (likely) no longer be the same in future SDK. + collector = sdkMeterProvider; SpanExporter exporter = new DelayingSpanExporter(0); processor = BatchSpanProcessor.builder(exporter).build(); @@ -47,7 +50,7 @@ public class BatchSpanProcessorDroppedSpansBenchmark { @TearDown(Level.Iteration) public final void recordMetrics() { BatchSpanProcessorMetrics metrics = - new BatchSpanProcessorMetrics(sdkMeterProvider.collectAllMetrics(), numThreads); + new BatchSpanProcessorMetrics(collector.collectAllMetrics(), numThreads); dropRatio = metrics.dropRatio(); exportedSpans = metrics.exportedSpans(); droppedSpans = metrics.droppedSpans(); diff --git a/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorMultiThreadBenchmark.java b/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorMultiThreadBenchmark.java index ba6a05b209..b489bf4feb 100644 --- a/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorMultiThreadBenchmark.java +++ b/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorMultiThreadBenchmark.java @@ -7,6 +7,7 @@ package io.opentelemetry.sdk.trace.export; import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.metrics.export.MetricProducer; import io.opentelemetry.sdk.trace.ReadableSpan; import io.opentelemetry.sdk.trace.SdkTracerProvider; import java.util.concurrent.TimeUnit; @@ -31,7 +32,7 @@ public class BatchSpanProcessorMultiThreadBenchmark { @State(Scope.Benchmark) public static class BenchmarkState { - private SdkMeterProvider sdkMeterProvider; + private MetricProducer collector; private BatchSpanProcessor processor; private Tracer tracer; private int numThreads = 1; @@ -44,7 +45,9 @@ public class BatchSpanProcessorMultiThreadBenchmark { @Setup(Level.Iteration) public final void setup() { - sdkMeterProvider = SdkMeterProvider.builder().buildAndRegisterGlobal(); + final SdkMeterProvider sdkMeterProvider = SdkMeterProvider.builder().buildAndRegisterGlobal(); + // Note: these will (likely) no longer be the same in future SDK. + collector = sdkMeterProvider; SpanExporter exporter = new DelayingSpanExporter(delayMs); processor = BatchSpanProcessor.builder(exporter).build(); tracer = @@ -54,7 +57,7 @@ public class BatchSpanProcessorMultiThreadBenchmark { @TearDown(Level.Iteration) public final void recordMetrics() { BatchSpanProcessorMetrics metrics = - new BatchSpanProcessorMetrics(sdkMeterProvider.collectAllMetrics(), numThreads); + new BatchSpanProcessorMetrics(collector.collectAllMetrics(), numThreads); exportedSpans = metrics.exportedSpans(); droppedSpans = metrics.droppedSpans(); processor.shutdown().join(10, TimeUnit.SECONDS); diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessor.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessor.java index 8922862825..6fe8a57a87 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessor.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessor.java @@ -5,11 +5,12 @@ package io.opentelemetry.sdk.trace.export; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.BoundLongCounter; import io.opentelemetry.api.metrics.GlobalMeterProvider; import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.api.metrics.common.Labels; import io.opentelemetry.context.Context; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.internal.DaemonThreadFactory; @@ -43,7 +44,10 @@ public final class BatchSpanProcessor implements SpanProcessor { private static final String WORKER_THREAD_NAME = BatchSpanProcessor.class.getSimpleName() + "_WorkerThread"; - private static final String SPAN_PROCESSOR_TYPE_LABEL = "spanProcessorType"; + private static final AttributeKey SPAN_PROCESSOR_TYPE_LABEL = + AttributeKey.stringKey("spanProcessorType"); + private static final AttributeKey SPAN_PROCESSOR_DROPPED_LABEL = + AttributeKey.booleanKey("dropped"); private static final String SPAN_PROCESSOR_TYPE_VALUE = BatchSpanProcessor.class.getSimpleName(); private final Worker worker; @@ -156,20 +160,20 @@ public final class BatchSpanProcessor implements SpanProcessor { this.exporterTimeoutNanos = exporterTimeoutNanos; this.queue = queue; this.signal = new ArrayBlockingQueue<>(1); - Meter meter = GlobalMeterProvider.getMeter("io.opentelemetry.sdk.trace"); + Meter meter = GlobalMeterProvider.get().meterBuilder("io.opentelemetry.sdk.trace").build(); meter - .longValueObserverBuilder("queueSize") + .gaugeBuilder("queueSize") + .ofLongs() .setDescription("The number of spans queued") .setUnit("1") - .setUpdater( + .buildWithCallback( result -> result.observe( queue.size(), - Labels.of(SPAN_PROCESSOR_TYPE_LABEL, SPAN_PROCESSOR_TYPE_VALUE))) - .build(); + Attributes.of(SPAN_PROCESSOR_TYPE_LABEL, SPAN_PROCESSOR_TYPE_VALUE))); LongCounter processedSpansCounter = meter - .longCounterBuilder("processedSpans") + .counterBuilder("processedSpans") .setUnit("1") .setDescription( "The number of spans processed by the BatchSpanProcessor. " @@ -177,10 +181,18 @@ public final class BatchSpanProcessor implements SpanProcessor { .build(); droppedSpans = processedSpansCounter.bind( - Labels.of(SPAN_PROCESSOR_TYPE_LABEL, SPAN_PROCESSOR_TYPE_VALUE, "dropped", "true")); + Attributes.of( + SPAN_PROCESSOR_TYPE_LABEL, + SPAN_PROCESSOR_TYPE_VALUE, + SPAN_PROCESSOR_DROPPED_LABEL, + true)); exportedSpans = processedSpansCounter.bind( - Labels.of(SPAN_PROCESSOR_TYPE_LABEL, SPAN_PROCESSOR_TYPE_VALUE, "dropped", "false")); + Attributes.of( + SPAN_PROCESSOR_TYPE_LABEL, + SPAN_PROCESSOR_TYPE_VALUE, + SPAN_PROCESSOR_DROPPED_LABEL, + false)); this.batch = new ArrayList<>(this.maxExportBatchSize); }