Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stabilize synchronous gauge #6419

Merged
merged 3 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -320,8 +320,10 @@ public LongHistogram build() {
}

private static class NoopDoubleGaugeBuilder implements DoubleGaugeBuilder {
private static final ObservableDoubleGauge NOOP = new ObservableDoubleGauge() {};
private static final ObservableDoubleGauge NOOP_OBSERVABLE_GAUGE =
new ObservableDoubleGauge() {};
private static final LongGaugeBuilder NOOP_LONG_GAUGE_BUILDER = new NoopLongGaugeBuilder();
private static final NoopDoubleGauge NOOP_GAUGE = new NoopDoubleGauge();

@Override
public DoubleGaugeBuilder setDescription(String description) {
Expand All @@ -340,17 +342,34 @@ public LongGaugeBuilder ofLongs() {

@Override
public ObservableDoubleGauge buildWithCallback(Consumer<ObservableDoubleMeasurement> callback) {
return NOOP;
return NOOP_OBSERVABLE_GAUGE;
}

@Override
public ObservableDoubleMeasurement buildObserver() {
return NOOP_OBSERVABLE_DOUBLE_MEASUREMENT;
}

@Override
public DoubleGauge build() {
return NOOP_GAUGE;
}
}

private static class NoopDoubleGauge implements DoubleGauge {
@Override
public void set(double value) {}

@Override
public void set(double value, Attributes attributes) {}

@Override
public void set(double value, Attributes attributes, Context context) {}
}

private static class NoopLongGaugeBuilder implements LongGaugeBuilder {
private static final ObservableLongGauge NOOP = new ObservableLongGauge() {};
private static final ObservableLongGauge NOOP_OBSERVABLE_GAUGE = new ObservableLongGauge() {};
private static final NoopLongGauge NOOP_GAUGE = new NoopLongGauge();

@Override
public LongGaugeBuilder setDescription(String description) {
Expand All @@ -364,13 +383,29 @@ public LongGaugeBuilder setUnit(String unit) {

@Override
public ObservableLongGauge buildWithCallback(Consumer<ObservableLongMeasurement> callback) {
return NOOP;
return NOOP_OBSERVABLE_GAUGE;
}

@Override
public ObservableLongMeasurement buildObserver() {
return NOOP_OBSERVABLE_LONG_MEASUREMENT;
}

@Override
public LongGauge build() {
return NOOP_GAUGE;
}
}

private static class NoopLongGauge implements LongGauge {
@Override
public void set(long value) {}

@Override
public void set(long value, Attributes attributes) {}

@Override
public void set(long value, Attributes attributes, Context context) {}
}

private static class NoopObservableDoubleMeasurement implements ObservableDoubleMeasurement {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.api.incubator.metrics;
package io.opentelemetry.api.metrics;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.context.Context;
import javax.annotation.concurrent.ThreadSafe;

/** A gauge instrument that synchronously records {@code double} values. */
Expand All @@ -26,5 +27,12 @@ public interface DoubleGauge {
*/
void set(double value, Attributes attributes);

// TODO(jack-berg): should we add overload with Context argument?
/**
* Records a value with a set of attributes.
*
* @param value The current gauge value.
* @param attributes A set of attributes to associate with the value.
* @param context The explicit context to associate with this measurement.
*/
void set(double value, Attributes attributes, Context context);
trask marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,17 @@
default ObservableDoubleMeasurement buildObserver() {
return DefaultMeter.getInstance().gaugeBuilder("noop").buildObserver();
}

/**
* Builds and returns a DoubleGauge instrument with the configuration.
*
* <p>NOTE: This produces a synchronous gauge which records gauge values as they occur. Most users
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe something about how only the most recent one is exported, since I think that part of synchronous gauges is most likely to trip people up?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add a comment to that effect.

* will want to instead register an {@link #buildWithCallback(Consumer)} to asynchronously observe
* the value of the gauge when metrics are collected.
*
* @return The DoubleGauge instrument.
*/
default DoubleGauge build() {
return DefaultMeter.getInstance().gaugeBuilder("noop").build();

Check warning on line 79 in api/all/src/main/java/io/opentelemetry/api/metrics/DoubleGaugeBuilder.java

View check run for this annotation

Codecov / codecov/patch

api/all/src/main/java/io/opentelemetry/api/metrics/DoubleGaugeBuilder.java#L79

Added line #L79 was not covered by tests
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.api.incubator.metrics;
package io.opentelemetry.api.metrics;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.context.Context;
import javax.annotation.concurrent.ThreadSafe;

/** A gauge instrument that synchronously records {@code long} values. */
Expand All @@ -26,5 +27,12 @@ public interface LongGauge {
*/
void set(long value, Attributes attributes);

// TODO(jack-berg): should we add overload with Context argument?
/**
* Records a value with a set of attributes.
*
* @param value The current gauge value.
* @param attributes A set of attributes to associate with the value.
* @param context The explicit context to associate with this measurement.
*/
void set(long value, Attributes attributes, Context context);
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,17 @@
default ObservableLongMeasurement buildObserver() {
return DefaultMeter.getInstance().gaugeBuilder("noop").ofLongs().buildObserver();
}

/**
* Builds and returns a LongGauge instrument with the configuration.
*
* <p>NOTE: This produces a synchronous gauge which records gauge values as they occur. Most users
* will want to instead register an {@link #buildWithCallback(Consumer)} to asynchronously observe
* the value of the gauge when metrics are collected.
*
* @return The LongGauge instrument.
*/
default LongGauge build() {
return DefaultMeter.getInstance().gaugeBuilder("noop").ofLongs().build();

Check warning on line 76 in api/all/src/main/java/io/opentelemetry/api/metrics/LongGaugeBuilder.java

View check run for this annotation

Codecov / codecov/patch

api/all/src/main/java/io/opentelemetry/api/metrics/LongGaugeBuilder.java#L76

Added line #L76 was not covered by tests
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,20 @@ void noopDoubleHistogram_doesNotThrow() {
histogram.record(1.0e-1, Attributes.of(stringKey("thing"), "car"), Context.current());
}

@Test
void noopLongGauage_doesNotThrow() {
LongGauge gauge =
METER
.gaugeBuilder("temperature")
.ofLongs()
.setDescription("The current temperature")
.setUnit("C")
.build();
gauge.set(1);
gauge.set(2, Attributes.of(stringKey("thing"), "engine"));
gauge.set(2, Attributes.of(stringKey("thing"), "engine"), Context.current());
}

@Test
void noopObservableLongGauage_doesNotThrow() {
METER
Expand All @@ -107,6 +121,19 @@ void noopObservableLongGauage_doesNotThrow() {
});
}

@Test
void noopDoubleGauage_doesNotThrow() {
DoubleGauge gauge =
METER
.gaugeBuilder("temperature")
.setDescription("The current temperature")
.setUnit("C")
.build();
gauge.set(1);
gauge.set(2, Attributes.of(stringKey("thing"), "engine"));
gauge.set(2, Attributes.of(stringKey("thing"), "engine"), Context.current());
}

@Test
void noopObservableDoubleGauage_doesNotThrow() {
METER
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,10 @@
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.metrics.DoubleGaugeBuilder;
import java.util.List;
import java.util.function.Consumer;

/** Extended {@link DoubleGaugeBuilder} with experimental APIs. */
public interface ExtendedDoubleGaugeBuilder extends DoubleGaugeBuilder {

/**
* Builds and returns a DoubleGauge instrument with the configuration.
*
* <p>NOTE: This produces a synchronous gauge which records gauge values as they occur. Most users
* will want to instead register an {@link #buildWithCallback(Consumer)} to asynchronously observe
* the value of the gauge when metrics are collected.
*
* @return The DoubleGauge instrument.
*/
DoubleGauge build();

/**
* Specify the attribute advice, which suggests the recommended set of attribute keys to be used
* for this gauge.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,10 @@
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.metrics.LongGaugeBuilder;
import java.util.List;
import java.util.function.Consumer;

/** Extended {@link LongGaugeBuilder} with experimental APIs. */
public interface ExtendedLongGaugeBuilder extends LongGaugeBuilder {

/**
* Builds and returns a LongGauge instrument with the configuration.
*
* <p>NOTE: This produces a synchronous gauge which records gauge values as they occur. Most users
* will want to instead register an {@link #buildWithCallback(Consumer)} to asynchronously observe
* the value of the gauge when metrics are collected.
*
* @return The LongGauge instrument.
*/
LongGauge build();

/**
* Specify the attribute advice, which suggests the recommended set of attribute keys to be used
* for this gauge.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,48 +23,6 @@
/** Demonstrating usage of extended Metrics API. */
class ExtendedMetricsApiUsageTest {

@Test
void synchronousGaugeUsage() {
// Setup SdkMeterProvider
InMemoryMetricReader reader = InMemoryMetricReader.create();
SdkMeterProvider meterProvider =
SdkMeterProvider.builder()
// Default resource used for demonstration purposes
.setResource(Resource.getDefault())
// In-memory reader used for demonstration purposes
.registerMetricReader(reader)
.build();

// Get a Meter for a scope
Meter meter = meterProvider.get("org.foo.my-scope");

// Cast GaugeBuilder to ExtendedDoubleGaugeBuilder
DoubleGauge gauge = ((ExtendedDoubleGaugeBuilder) meter.gaugeBuilder("my-gauge")).build();

// Call set synchronously to set the value
gauge.set(1.0, Attributes.builder().put("key", "value1").build());
gauge.set(2.0, Attributes.builder().put("key", "value2").build());

assertThat(reader.collectAllMetrics())
.satisfiesExactly(
metricData ->
assertThat(metricData)
.hasName("my-gauge")
.hasDoubleGaugeSatisfying(
gaugeAssert ->
gaugeAssert.hasPointsSatisfying(
point ->
point
.hasValue(1.0)
.hasAttributes(
Attributes.builder().put("key", "value1").build()),
point ->
point
.hasValue(2.0)
.hasAttributes(
Attributes.builder().put("key", "value2").build()))));
}

@Test
void attributesAdvice() {
// Setup SdkMeterProvider
Expand Down
19 changes: 18 additions & 1 deletion docs/apidiffs/current_vs_latest/opentelemetry-api.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,19 @@
Comparing source compatibility of against
No changes.
+++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.metrics.DoubleGauge (not serializable)
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
+++ NEW SUPERCLASS: java.lang.Object
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void set(double)
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void set(double, io.opentelemetry.api.common.Attributes)
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void set(double, io.opentelemetry.api.common.Attributes, io.opentelemetry.context.Context)
*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.metrics.DoubleGaugeBuilder (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.metrics.DoubleGauge build()
+++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.metrics.LongGauge (not serializable)
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
+++ NEW SUPERCLASS: java.lang.Object
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void set(long)
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void set(long, io.opentelemetry.api.common.Attributes)
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void set(long, io.opentelemetry.api.common.Attributes, io.opentelemetry.context.Context)
*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.metrics.LongGaugeBuilder (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.metrics.LongGauge build()
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ Comparing source compatibility of against
*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++ NEW METHOD: PUBLIC(+) STATIC(+) java.lang.String asString(io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector)
*** MODIFIED ENUM: PUBLIC FINAL io.opentelemetry.sdk.metrics.InstrumentType (compatible)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.sdk.metrics.InstrumentType GAUGE
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ public enum InstrumentType {
OBSERVABLE_COUNTER,
OBSERVABLE_UP_DOWN_COUNTER,
OBSERVABLE_GAUGE,
GAUGE,
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.incubator.metrics.DoubleGauge;
import io.opentelemetry.api.incubator.metrics.ExtendedDoubleGaugeBuilder;
import io.opentelemetry.api.metrics.DoubleGauge;
import io.opentelemetry.api.metrics.DoubleGaugeBuilder;
import io.opentelemetry.api.metrics.LongGaugeBuilder;
import io.opentelemetry.api.metrics.ObservableDoubleGauge;
Expand All @@ -31,8 +31,13 @@
}

@Override
public void set(double increment, Attributes attributes) {
storage.recordDouble(increment, attributes, Context.root());
public void set(double value, Attributes attributes) {
storage.recordDouble(value, attributes, Context.current());
}

@Override
public void set(double value, Attributes attributes, Context context) {
storage.recordDouble(value, attributes, context);

Check warning on line 40 in sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java

View check run for this annotation

Codecov / codecov/patch

sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java#L40

Added line #L40 was not covered by tests
}

@Override
Expand All @@ -48,11 +53,10 @@
MeterSharedState meterSharedState,
String name) {

// TODO: use InstrumentType.GAUGE when available
builder =
new InstrumentBuilder(
name,
InstrumentType.OBSERVABLE_GAUGE,
InstrumentType.GAUGE,
InstrumentValueType.DOUBLE,
meterProviderSharedState,
meterSharedState);
Expand Down Expand Up @@ -88,13 +92,11 @@

@Override
public ObservableDoubleGauge buildWithCallback(Consumer<ObservableDoubleMeasurement> callback) {
// TODO: use InstrumentType.GAUGE when available
return builder.buildDoubleAsynchronousInstrument(InstrumentType.OBSERVABLE_GAUGE, callback);
}

@Override
public ObservableDoubleMeasurement buildObserver() {
// TODO: use InstrumentType.GAUGE when available
return builder.buildObservableMeasurement(InstrumentType.OBSERVABLE_GAUGE);
}

Expand Down
Loading
Loading