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 <jkwatson@gmail.com> * Fixes from review. * Fixes from review. * Update OTLP HTTP exporter to use new metrics api Co-authored-by: John Watson <jkwatson@gmail.com>
This commit is contained in:
		
							parent
							
								
									20f872d8dc
								
							
						
					
					
						commit
						0ef19291c2
					
				|  | @ -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 | ||||
| [metrics-spec]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md | ||||
|  | @ -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") | ||||
| 
 | ||||
|  |  | |||
|  | @ -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. | ||||
|  * | ||||
|  * <p>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); | ||||
|   } | ||||
| } | ||||
|  | @ -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<R> extends InstrumentBuilder { | ||||
|   /** | ||||
|    * Sets a consumer that gets executed every collection interval. | ||||
|    * | ||||
|    * <p>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<R> setUpdater(Consumer<R> updater); | ||||
| 
 | ||||
|   @Override | ||||
|   AsynchronousInstrument build(); | ||||
| } | ||||
|  | @ -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. | ||||
|  * | ||||
|  * <p>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. | ||||
|    * | ||||
|    * <p>This method records all measurements every time it is called, so make sure it is not called | ||||
|    * twice if not needed. | ||||
|    */ | ||||
|   void record(); | ||||
| } | ||||
|  | @ -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. | ||||
|    * | ||||
|    * <p>The value added is associated with the current {@code Context}. | ||||
|    * <p>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}. | ||||
|    * | ||||
|    * <p>After this method returns the current instance is considered invalid (not being managed by | ||||
|    * the instrument). | ||||
|    */ | ||||
|   void unbind(); | ||||
| } | ||||
|  |  | |||
|  | @ -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. | ||||
|    * | ||||
|    * <p>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}. | ||||
|    * | ||||
|    * <p>After this method returns the current instance is considered invalid (not being managed by | ||||
|    * the instrument). | ||||
|    */ | ||||
|   void unbind(); | ||||
| } | ||||
|  | @ -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. | ||||
|    * | ||||
|    * <p>The value added is associated with the current {@code Context}. | ||||
|    * <p>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}. | ||||
|    * | ||||
|    * <p>After this method returns the current instance is considered invalid (not being managed by | ||||
|    * the instrument). | ||||
|    */ | ||||
|   void unbind(); | ||||
| } | ||||
|  |  | |||
|  | @ -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(); | ||||
| } | ||||
|  | @ -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. | ||||
|    * | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>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}. | ||||
|    * | ||||
|    * <p>After this method returns the current instance is considered invalid (not being managed by | ||||
|    * the instrument). | ||||
|    */ | ||||
|   void unbind(); | ||||
| } | ||||
|  |  | |||
|  | @ -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. | ||||
|    * | ||||
|    * <p>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}. | ||||
|    * | ||||
|    * <p>After this method returns the current instance is considered invalid (not being managed by | ||||
|    * the instrument). | ||||
|    */ | ||||
|   void unbind(); | ||||
| } | ||||
|  | @ -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. | ||||
|    * | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>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}. | ||||
|    * | ||||
|    * <p>After this method returns the current instance is considered invalid (not being managed by | ||||
|    * the instrument). | ||||
|    */ | ||||
|   void unbind(); | ||||
| } | ||||
|  |  | |||
|  | @ -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(); | ||||
| } | ||||
|  | @ -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. | ||||
|    * | ||||
|    * <p>After this method returns the current instance {@code Bound} is considered invalid (not | ||||
|    * being managed by the instrument). | ||||
|    */ | ||||
|   void unbind(); | ||||
| } | ||||
|  | @ -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<NoopBuilder> | ||||
|         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<NoopBuilder> | ||||
|         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<NoopBuilder> | ||||
|         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<NoopBuilder> | ||||
|         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<NoopBuilder> | ||||
|         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<NoopBuilder> | ||||
|         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<NoopBuilder> | ||||
|         implements DoubleSumObserverBuilder { | ||||
| 
 | ||||
|       @Override | ||||
|       protected NoopBuilder getThis() { | ||||
|         return this; | ||||
|       } | ||||
| 
 | ||||
|       @Override | ||||
|       public DoubleSumObserverBuilder setUpdater(Consumer<DoubleResult> 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<NoopBuilder> | ||||
|         implements LongSumObserverBuilder { | ||||
| 
 | ||||
|       @Override | ||||
|       protected NoopBuilder getThis() { | ||||
|         return this; | ||||
|       } | ||||
| 
 | ||||
|       @Override | ||||
|       public NoopBuilder setUpdater(Consumer<LongResult> 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<NoopBuilder> | ||||
|         implements DoubleUpDownSumObserverBuilder { | ||||
| 
 | ||||
|       @Override | ||||
|       protected NoopBuilder getThis() { | ||||
|         return this; | ||||
|       } | ||||
| 
 | ||||
|       @Override | ||||
|       public DoubleUpDownSumObserverBuilder setUpdater(Consumer<DoubleResult> 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<NoopBuilder> | ||||
|         implements LongUpDownSumObserverBuilder { | ||||
| 
 | ||||
|       @Override | ||||
|       protected NoopBuilder getThis() { | ||||
|         return this; | ||||
|       } | ||||
| 
 | ||||
|       @Override | ||||
|       public LongUpDownSumObserverBuilder setUpdater(Consumer<LongResult> 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<NoopBuilder> | ||||
|         implements DoubleValueObserverBuilder { | ||||
| 
 | ||||
|       @Override | ||||
|       protected NoopBuilder getThis() { | ||||
|         return this; | ||||
|       } | ||||
| 
 | ||||
|       @Override | ||||
|       public DoubleValueObserverBuilder setUpdater(Consumer<DoubleResult> 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<NoopBuilder> | ||||
|         implements LongValueObserverBuilder { | ||||
| 
 | ||||
|       @Override | ||||
|       protected NoopBuilder getThis() { | ||||
|         return this; | ||||
|       } | ||||
| 
 | ||||
|       @Override | ||||
|       public LongValueObserverBuilder setUpdater(Consumer<LongResult> 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<B>> | ||||
|       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."); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -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(); | ||||
|   } | ||||
| } | ||||
|  | @ -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() {} | ||||
| } | ||||
|  | @ -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`. | ||||
|  * | ||||
|  * <p>Example: | ||||
|  * | ||||
|  * <pre>{@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. | ||||
|  *   } | ||||
|  * } | ||||
|  * }</pre> | ||||
|  */ | ||||
| /** A counter instrument that records {@code double} values. */ | ||||
| @ThreadSafe | ||||
| public interface DoubleCounter extends SynchronousInstrument<BoundDoubleCounter> { | ||||
| public interface DoubleCounter { | ||||
|   /** | ||||
|    * Records a value. | ||||
|    * | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>The value added is associated with the current {@code Context} and provided set of labels. | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>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); | ||||
| } | ||||
|  |  | |||
|  | @ -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. | ||||
|    * | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>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<ObservableDoubleMeasurement> callback); | ||||
| } | ||||
|  |  | |||
|  | @ -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. | ||||
|    * | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>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<ObservableDoubleMeasurement> callback); | ||||
| } | ||||
|  | @ -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. | ||||
|    * | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>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); | ||||
| } | ||||
|  | @ -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. | ||||
|    * | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>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(); | ||||
| } | ||||
|  | @ -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). | ||||
|  * | ||||
|  * <p>"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. | ||||
|  * | ||||
|  * <p>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. | ||||
|  * | ||||
|  * <p>Example: | ||||
|  * | ||||
|  * <pre>{@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<DoubleResult>() { | ||||
|  * //          @Override | ||||
|  * //           public void update(DoubleResult result) { | ||||
|  * //             // Get system cpu usage | ||||
|  * //             result.observe(cpuIdle, "state", "idle"); | ||||
|  * //             result.observe(cpuUser, "state", "user"); | ||||
|  * //           } | ||||
|  * //         }); | ||||
|  * //   } | ||||
|  * // } | ||||
|  * }</pre> | ||||
|  */ | ||||
| @ThreadSafe | ||||
| public interface DoubleSumObserver extends AsynchronousInstrument {} | ||||
|  | @ -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<AsynchronousInstrument.DoubleResult> { | ||||
|   @Override | ||||
|   DoubleSumObserverBuilder setDescription(String description); | ||||
| 
 | ||||
|   @Override | ||||
|   DoubleSumObserverBuilder setUnit(String unit); | ||||
| 
 | ||||
|   @Override | ||||
|   DoubleSumObserverBuilder setUpdater(Consumer<AsynchronousInstrument.DoubleResult> updater); | ||||
| 
 | ||||
|   @Override | ||||
|   DoubleSumObserver build(); | ||||
| } | ||||
|  | @ -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. | ||||
|  * | ||||
|  * <p>Example: | ||||
|  * | ||||
|  * <pre>{@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); | ||||
|  *   } | ||||
|  * } | ||||
|  * }</pre> | ||||
|  */ | ||||
| /** An up-down-counter instrument that records {@code double} values. */ | ||||
| @ThreadSafe | ||||
| public interface DoubleUpDownCounter extends SynchronousInstrument<BoundDoubleUpDownCounter> { | ||||
| public interface DoubleUpDownCounter { | ||||
|   /** | ||||
|    * Records a value. | ||||
|    * | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>The value added is associated with the current {@code Context} and provided set of labels. | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>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); | ||||
| } | ||||
|  |  | |||
|  | @ -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. | ||||
|    * | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>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<ObservableDoubleMeasurement> callback); | ||||
| } | ||||
|  |  | |||
|  | @ -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). | ||||
|  * | ||||
|  * <p>"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. | ||||
|  * | ||||
|  * <p>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. | ||||
|  * | ||||
|  * <p>Example: | ||||
|  * | ||||
|  * <pre>{@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<DoubleResult>() { | ||||
|  * //          @Override | ||||
|  * //           public void update(DoubleResult result) { | ||||
|  * //             // Get system memory usage | ||||
|  * //             result.observe(memoryUsed, "state", "used"); | ||||
|  * //             result.observe(memoryFree, "state", "free"); | ||||
|  * //           } | ||||
|  * //         }); | ||||
|  * //   } | ||||
|  * // } | ||||
|  * }</pre> | ||||
|  */ | ||||
| @ThreadSafe | ||||
| public interface DoubleUpDownSumObserver extends AsynchronousInstrument {} | ||||
|  | @ -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<AsynchronousInstrument.DoubleResult> { | ||||
|   @Override | ||||
|   DoubleUpDownSumObserverBuilder setDescription(String description); | ||||
| 
 | ||||
|   @Override | ||||
|   DoubleUpDownSumObserverBuilder setUnit(String unit); | ||||
| 
 | ||||
|   @Override | ||||
|   DoubleUpDownSumObserverBuilder setUpdater(Consumer<AsynchronousInstrument.DoubleResult> updater); | ||||
| 
 | ||||
|   @Override | ||||
|   DoubleUpDownSumObserver build(); | ||||
| } | ||||
|  | @ -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. | ||||
|  * | ||||
|  * <p>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. | ||||
|  * | ||||
|  * <p>Example: | ||||
|  * | ||||
|  * <pre>{@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<DoubleResult>() { | ||||
|  * //          @Override | ||||
|  * //           public void update(DoubleResult result) { | ||||
|  * //             // Get system cpu temperature | ||||
|  * //             result.observe(cpuTemperature); | ||||
|  * //           } | ||||
|  * //         }); | ||||
|  * //   } | ||||
|  * // } | ||||
|  * }</pre> | ||||
|  */ | ||||
| @ThreadSafe | ||||
| public interface DoubleValueObserver extends AsynchronousInstrument {} | ||||
|  | @ -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<AsynchronousInstrument.DoubleResult> { | ||||
|   @Override | ||||
|   DoubleValueObserverBuilder setDescription(String description); | ||||
| 
 | ||||
|   @Override | ||||
|   DoubleValueObserverBuilder setUnit(String unit); | ||||
| 
 | ||||
|   @Override | ||||
|   DoubleValueObserverBuilder setUpdater(Consumer<AsynchronousInstrument.DoubleResult> updater); | ||||
| 
 | ||||
|   @Override | ||||
|   DoubleValueObserver build(); | ||||
| } | ||||
|  | @ -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. | ||||
|  * | ||||
|  * <p>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. | ||||
|  * | ||||
|  * <p>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. | ||||
|  * | ||||
|  * <p>Example: | ||||
|  * | ||||
|  * <pre>{@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); | ||||
|  *   } | ||||
|  * } | ||||
|  * }</pre> | ||||
|  */ | ||||
| @ThreadSafe | ||||
| public interface DoubleValueRecorder extends SynchronousInstrument<BoundDoubleValueRecorder> { | ||||
| 
 | ||||
|   /** | ||||
|    * 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); | ||||
| } | ||||
|  | @ -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(); | ||||
| } | ||||
|  | @ -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<MeterProvider> 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}. | ||||
|    * | ||||
|    * <p>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}. | ||||
|    * | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>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; | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -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 {} | ||||
|  | @ -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}. | ||||
|    * | ||||
|    * <p>Default value is {@code ""}. | ||||
|    * | ||||
|    * @param description the description of the Instrument. | ||||
|    * @return this. | ||||
|    */ | ||||
|   InstrumentBuilder setDescription(String description); | ||||
| 
 | ||||
|   /** | ||||
|    * Sets the unit of the {@code Instrument}. | ||||
|    * | ||||
|    * <p>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(); | ||||
| } | ||||
|  | @ -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`. | ||||
|  * | ||||
|  * <p>Example: | ||||
|  * | ||||
|  * <pre>{@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); | ||||
|  *   } | ||||
|  * } | ||||
|  * }</pre> | ||||
|  */ | ||||
| /** A counter instrument that records {@code long} values. */ | ||||
| @ThreadSafe | ||||
| public interface LongCounter extends SynchronousInstrument<BoundLongCounter> { | ||||
| public interface LongCounter { | ||||
| 
 | ||||
|   /** | ||||
|    * Adds the given {@code increment} to the current value. The values cannot be negative. | ||||
|    * Records a value. | ||||
|    * | ||||
|    * <p>The value added is associated with the current {@code Context} and provided set of labels. | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>The value added is associated with the current {@code Context} and empty labels. | ||||
|    * <p>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); | ||||
| } | ||||
|  |  | |||
|  | @ -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. | ||||
|    * | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>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<ObservableLongMeasurement> callback); | ||||
| } | ||||
|  |  | |||
|  | @ -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. | ||||
|    * | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>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<ObservableLongMeasurement> callback); | ||||
| } | ||||
|  | @ -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. | ||||
|    * | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>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); | ||||
| } | ||||
|  | @ -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. | ||||
|    * | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>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(); | ||||
| } | ||||
|  | @ -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). | ||||
|  * | ||||
|  * <p>"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. | ||||
|  * | ||||
|  * <p>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. | ||||
|  * | ||||
|  * <p>Example: | ||||
|  * | ||||
|  * <pre>{@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<LongResult>() { | ||||
|  * //          @Override | ||||
|  * //           public void update(LongResult result) { | ||||
|  * //             // Get system cpu usage | ||||
|  * //             result.observe(cpuIdle, "state", "idle"); | ||||
|  * //             result.observe(cpuUser, "state", "user"); | ||||
|  * //           } | ||||
|  * //         }); | ||||
|  * //   } | ||||
|  * // } | ||||
|  * }</pre> | ||||
|  */ | ||||
| @ThreadSafe | ||||
| public interface LongSumObserver extends AsynchronousInstrument {} | ||||
|  | @ -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<AsynchronousInstrument.LongResult> { | ||||
|   @Override | ||||
|   LongSumObserverBuilder setDescription(String description); | ||||
| 
 | ||||
|   @Override | ||||
|   LongSumObserverBuilder setUnit(String unit); | ||||
| 
 | ||||
|   @Override | ||||
|   LongSumObserverBuilder setUpdater(Consumer<AsynchronousInstrument.LongResult> updater); | ||||
| 
 | ||||
|   @Override | ||||
|   LongSumObserver build(); | ||||
| } | ||||
|  | @ -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. | ||||
|  * | ||||
|  * <p>Example: | ||||
|  * | ||||
|  * <pre>{@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); | ||||
|  *   } | ||||
|  * } | ||||
|  * }</pre> | ||||
|  */ | ||||
| /** An up-down-counter instrument that records {@code long} values. */ | ||||
| @ThreadSafe | ||||
| public interface LongUpDownCounter extends SynchronousInstrument<BoundLongUpDownCounter> { | ||||
| public interface LongUpDownCounter { | ||||
|   /** | ||||
|    * Records a value. | ||||
|    * | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>The value added is associated with the current {@code Context} and provided set of labels. | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>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); | ||||
| } | ||||
|  |  | |||
|  | @ -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. | ||||
|    * | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>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. | ||||
|    * | ||||
|    * <p>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<ObservableLongMeasurement> callback); | ||||
| } | ||||
|  |  | |||
|  | @ -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). | ||||
|  * | ||||
|  * <p>"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. | ||||
|  * | ||||
|  * <p>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. | ||||
|  * | ||||
|  * <p>Example: | ||||
|  * | ||||
|  * <pre>{@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<LongResult>() { | ||||
|  * //          @Override | ||||
|  * //           public void update(LongResult result) { | ||||
|  * //             // Get system memory usage | ||||
|  * //             result.observe(memoryUsed, "state", "used"); | ||||
|  * //             result.observe(memoryFree, "state", "free"); | ||||
|  * //           } | ||||
|  * //         }); | ||||
|  * //   } | ||||
|  * // } | ||||
|  * }</pre> | ||||
|  */ | ||||
| @ThreadSafe | ||||
| public interface LongUpDownSumObserver extends AsynchronousInstrument {} | ||||
|  | @ -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<AsynchronousInstrument.LongResult> { | ||||
|   @Override | ||||
|   LongUpDownSumObserverBuilder setDescription(String description); | ||||
| 
 | ||||
|   @Override | ||||
|   LongUpDownSumObserverBuilder setUnit(String unit); | ||||
| 
 | ||||
|   @Override | ||||
|   LongUpDownSumObserverBuilder setUpdater(Consumer<AsynchronousInstrument.LongResult> updater); | ||||
| 
 | ||||
|   @Override | ||||
|   LongUpDownSumObserver build(); | ||||
| } | ||||
|  | @ -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. | ||||
|  * | ||||
|  * <p>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. | ||||
|  * | ||||
|  * <p>Example: | ||||
|  * | ||||
|  * <pre>{@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<LongResult>() { | ||||
|  * //          @Override | ||||
|  * //           public void update(LongResult result) { | ||||
|  * //             // Get system cpu fan speed | ||||
|  * //             result.observe(cpuFanSpeed); | ||||
|  * //           } | ||||
|  * //         }); | ||||
|  * //   } | ||||
|  * // } | ||||
|  * }</pre> | ||||
|  */ | ||||
| @ThreadSafe | ||||
| public interface LongValueObserver extends AsynchronousInstrument {} | ||||
|  | @ -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<AsynchronousInstrument.LongResult> { | ||||
|   @Override | ||||
|   LongValueObserverBuilder setDescription(String description); | ||||
| 
 | ||||
|   @Override | ||||
|   LongValueObserverBuilder setUnit(String unit); | ||||
| 
 | ||||
|   @Override | ||||
|   LongValueObserverBuilder setUpdater(Consumer<AsynchronousInstrument.LongResult> updater); | ||||
| 
 | ||||
|   @Override | ||||
|   LongValueObserver build(); | ||||
| } | ||||
|  | @ -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. | ||||
|  * | ||||
|  * <p>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. | ||||
|  * | ||||
|  * <p>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. | ||||
|  * | ||||
|  * <p>Example: | ||||
|  * | ||||
|  * <pre>{@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); | ||||
|  *   } | ||||
|  * } | ||||
|  * }</pre> | ||||
|  */ | ||||
| @ThreadSafe | ||||
| public interface LongValueRecorder extends SynchronousInstrument<BoundLongValueRecorder> { | ||||
| 
 | ||||
|   /** | ||||
|    * 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); | ||||
| } | ||||
|  | @ -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(); | ||||
| } | ||||
|  | @ -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. | ||||
|  * | ||||
|  * <p>There are two ways to record measurements: | ||||
|  * <p>Instruments are obtained through builders provided by this interface. Each builder has a | ||||
|  * default "type" associated with recordings that may be changed. | ||||
|  * | ||||
|  * <ul> | ||||
|  *   <li>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". | ||||
|  *   <li>Record pre-defined aggregation data (or already aggregated data). This should be used to | ||||
|  *       report cpu/memory usage, or simple metrics like "queue_length". | ||||
|  * </ul> | ||||
|  * | ||||
|  * <p>TODO: Update comment. | ||||
|  * <p>A Meter is generally associated with an instrumentation library, e.g. "I monitor apache | ||||
|  * httpclient". | ||||
|  */ | ||||
| @ThreadSafe | ||||
| public interface Meter { | ||||
|   /** | ||||
|    * Constructs a counter instrument. | ||||
|    * | ||||
|    * <p>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. | ||||
|    * <p>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); | ||||
| } | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 <i>Provider</i> is for consistency with | ||||
|  * other languages and it is <b>NOT</b> loaded using reflection. | ||||
|  * A registry for creating named {@link Meter}s. | ||||
|  * | ||||
|  * <p>A MeterProvider represents a configured (or noop) Metric collection system that can be used to | ||||
|  * instrument code. | ||||
|  * | ||||
|  * <p>The name <i>Provider</i> is for consistency with other languages and it is <b>NOT</b> 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(); | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -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); | ||||
| } | ||||
|  | @ -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); | ||||
| } | ||||
|  | @ -0,0 +1,13 @@ | |||
| /* | ||||
|  * Copyright The OpenTelemetry Authors | ||||
|  * SPDX-License-Identifier: Apache-2.0 | ||||
|  */ | ||||
| 
 | ||||
| package io.opentelemetry.api.metrics; | ||||
| 
 | ||||
| /** | ||||
|  * A mechanism for observing measurments. | ||||
|  * | ||||
|  * <p>see {@link ObservableDoubleMeasurement} or {@link ObservableLongMeasurement}. | ||||
|  */ | ||||
| public interface ObservableMeasurement {} | ||||
|  | @ -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. | ||||
|  * | ||||
|  * <p>Synchronous instrument events additionally have a Context associated with them, describing | ||||
|  * properties of the associated trace and distributed correlation values. | ||||
|  * | ||||
|  * @param <B> the specific type of Bound Instrument this instrument can provide. | ||||
|  */ | ||||
| @ThreadSafe | ||||
| public interface SynchronousInstrument<B extends BoundSynchronousInstrument> 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. | ||||
|    * | ||||
|    * <p>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); | ||||
| } | ||||
|  | @ -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(); | ||||
| } | ||||
|  | @ -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<String, String> 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()); | ||||
|   } | ||||
| } | ||||
|  | @ -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<Object> data; | ||||
| 
 | ||||
|   ArrayBackedLabelsBuilder() { | ||||
|     data = new ArrayList<>(); | ||||
|   } | ||||
| 
 | ||||
|   ArrayBackedLabelsBuilder(List<Object> 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; | ||||
|   } | ||||
| } | ||||
|  | @ -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. | ||||
|  * | ||||
|  * <p>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. | ||||
|  * | ||||
|  * <p>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<? super String, ? super String> 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<String, String> asMap(); | ||||
| 
 | ||||
|   /** Create a {@link LabelsBuilder} pre-populated with the contents of this Labels instance. */ | ||||
|   LabelsBuilder toBuilder(); | ||||
| } | ||||
|  | @ -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); | ||||
| } | ||||
|  | @ -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() {} | ||||
| } | ||||
|  | @ -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}. | ||||
|  * | ||||
|  * <p>This implementation should induce as close to zero overhead as possible. | ||||
|  * | ||||
|  * <p>A few notes from the specificaiton on allowed behaviors leading to this deasign [<a | ||||
|  * href="https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument">Instrument | ||||
|  * Spec</a>]: | ||||
|  * | ||||
|  * <ul> | ||||
|  *   <li>Multiple Insturments with the same name under the same Meter MUST return an error | ||||
|  *   <li>Different Meters MUST be treated as separate namespaces | ||||
|  *   <li>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. | ||||
|  *   <li>A MeterProvider could also return a no-op Meter here if application owners configure the | ||||
|  *       SDK to suppress telemetry produced by this library | ||||
|  *   <li>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, | ||||
|  * </ul> | ||||
|  */ | ||||
| @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<ObservableLongMeasurement> 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<ObservableDoubleMeasurement> 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<ObservableLongMeasurement> 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<ObservableDoubleMeasurement> 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<ObservableDoubleMeasurement> 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<ObservableLongMeasurement> callback) {} | ||||
|   } | ||||
| } | ||||
|  | @ -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(); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -1,15 +0,0 @@ | |||
| /* | ||||
|  * Copyright The OpenTelemetry Authors | ||||
|  * SPDX-License-Identifier: Apache-2.0 | ||||
|  */ | ||||
| 
 | ||||
| /** | ||||
|  * Interfaces and implementations that are internal to OpenTelemetry. | ||||
|  * | ||||
|  * <p>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; | ||||
|  | @ -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"); | ||||
|   } | ||||
| } | ||||
|  | @ -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()); | ||||
|   } | ||||
| } | ||||
|  | @ -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(); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -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(); | ||||
|   } | ||||
| } | ||||
|  | @ -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(); | ||||
|   } | ||||
| } | ||||
|  | @ -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(); | ||||
|   } | ||||
| } | ||||
|  | @ -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(); | ||||
|   } | ||||
| } | ||||
|  | @ -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(); | ||||
|   } | ||||
| } | ||||
|  | @ -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(); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -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(); | ||||
|   } | ||||
| } | ||||
|  | @ -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(); | ||||
|   } | ||||
| } | ||||
|  | @ -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(); | ||||
|   } | ||||
| } | ||||
|  | @ -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(); | ||||
|   } | ||||
| } | ||||
|  | @ -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(); | ||||
|   } | ||||
| } | ||||
|  | @ -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<String, String> 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<String, String> 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")); | ||||
|   } | ||||
| } | ||||
|  | @ -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(); | ||||
|   } | ||||
| } | ||||
|  | @ -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(); | ||||
|   } | ||||
| } | ||||
|  | @ -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")); | ||||
|             }); | ||||
|   } | ||||
| } | ||||
|  | @ -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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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<String> EXPORTER_KEY = AttributeKey.stringKey("exporter"); | ||||
|   private static final AttributeKey<String> 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; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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(); | ||||
|  |  | |||
|  | @ -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<String> resultKey = AttributeKey.stringKey("result"); | ||||
|       AttributeKey<String> 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; | ||||
|  |  | |||
|  | @ -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(); | ||||
|     } | ||||
|  |  | |||
|  | @ -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(); | ||||
|  |  | |||
|  | @ -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(); | ||||
|     } | ||||
|  |  | |||
|  | @ -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<String> SPAN_PROCESSOR_TYPE_KEY = | ||||
|       AttributeKey.stringKey("spanProcessorType"); | ||||
|   private static final AttributeKey<Boolean> 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. " | ||||
|  |  | |||
|  | @ -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<DoubleSummaryDataAssert, DoubleSummaryData> { | ||||
| 
 | ||||
|   protected DoubleSummaryDataAssert(DoubleSummaryData actual) { | ||||
|     super(actual, DoubleSummaryDataAssert.class); | ||||
|   } | ||||
| 
 | ||||
|   /** Returns convenience API to assert against the {@code points} field. */ | ||||
|   public AbstractIterableAssert< | ||||
|           ?, ? extends Iterable<? extends DoubleSummaryPointData>, DoubleSummaryPointData, ?> | ||||
|       points() { | ||||
|     isNotNull(); | ||||
|     return Assertions.assertThat(actual.getPoints()); | ||||
|   } | ||||
| } | ||||
|  | @ -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<DoubleSummaryPointDataAssert, DoubleSummaryPointData> { | ||||
|   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; | ||||
|   } | ||||
| } | ||||
|  | @ -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); | ||||
|  |  | |||
|  | @ -180,4 +180,22 @@ public class MetricDataAssert extends AbstractAssert<MetricDataAssert, MetricDat | |||
|     } | ||||
|     return new LongSumDataAssert(actual.getLongSumData()); | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Ensures this {@link MetricData} is a {@code DoubleSummaryData}. | ||||
|    * | ||||
|    * @return convenience API to assert against the {@code DoubleSummaryData}. | ||||
|    */ | ||||
|   public DoubleSummaryDataAssert hasDoubleSummary() { | ||||
|     isNotNull(); | ||||
|     if (actual.getType() != MetricDataType.SUMMARY) { | ||||
|       failWithActualExpectedAndMessage( | ||||
|           actual, | ||||
|           "type: SUMMARY", | ||||
|           "Exepcted MetricData to have type <%s> but found <%s>", | ||||
|           MetricDataType.SUMMARY, | ||||
|           actual.getType()); | ||||
|     } | ||||
|     return new DoubleSummaryDataAssert(actual.getDoubleSummaryData()); | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -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); | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -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. | ||||
|  | @ -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(); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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(); | ||||
|   } | ||||
|  |  | |||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue