Plugin aggregator for observer, add tests, fix lock. (#1018)
Signed-off-by: Bogdan Drutu <bogdandrutu@gmail.com>
This commit is contained in:
parent
29297249ab
commit
a8401f933e
|
|
@ -17,7 +17,9 @@
|
|||
package io.opentelemetry.sdk.metrics;
|
||||
|
||||
import io.opentelemetry.metrics.Observer;
|
||||
import io.opentelemetry.sdk.metrics.common.InstrumentType;
|
||||
import io.opentelemetry.sdk.metrics.common.InstrumentValueType;
|
||||
import io.opentelemetry.sdk.metrics.view.Aggregations;
|
||||
|
||||
abstract class AbstractObserver extends AbstractInstrument {
|
||||
private final boolean monotonic;
|
||||
|
|
@ -33,7 +35,15 @@ abstract class AbstractObserver extends AbstractInstrument {
|
|||
descriptor,
|
||||
meterProviderSharedState,
|
||||
meterSharedState,
|
||||
new ActiveBatcher(Batchers.getNoop()));
|
||||
new ActiveBatcher(
|
||||
new ActiveBatcher(
|
||||
getDefaultBatcher(
|
||||
descriptor,
|
||||
getInstrumentType(monotonic),
|
||||
instrumentValueType,
|
||||
meterProviderSharedState,
|
||||
meterSharedState,
|
||||
Aggregations.lastValue()))));
|
||||
this.monotonic = monotonic;
|
||||
this.instrumentValueType = instrumentValueType;
|
||||
}
|
||||
|
|
@ -88,4 +98,8 @@ abstract class AbstractObserver extends AbstractInstrument {
|
|||
return this.monotonic;
|
||||
}
|
||||
}
|
||||
|
||||
private static InstrumentType getInstrumentType(boolean monotonic) {
|
||||
return monotonic ? InstrumentType.OBSERVER_MONOTONIC : InstrumentType.OBSERVER_NON_MONOTONIC;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,10 +23,12 @@ import io.opentelemetry.sdk.metrics.common.InstrumentValueType;
|
|||
import io.opentelemetry.sdk.metrics.data.MetricData;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
final class DoubleObserverSdk extends AbstractObserver implements DoubleObserver {
|
||||
@Nullable private volatile Callback<ResultDoubleObserver> metricUpdater = null;
|
||||
private final ReentrantLock collectLock = new ReentrantLock();
|
||||
|
||||
DoubleObserverSdk(
|
||||
InstrumentDescriptor descriptor,
|
||||
|
|
@ -35,7 +37,7 @@ final class DoubleObserverSdk extends AbstractObserver implements DoubleObserver
|
|||
boolean monotonic) {
|
||||
super(
|
||||
descriptor,
|
||||
InstrumentValueType.LONG,
|
||||
InstrumentValueType.DOUBLE,
|
||||
meterProviderSharedState,
|
||||
meterSharedState,
|
||||
monotonic);
|
||||
|
|
@ -47,9 +49,14 @@ final class DoubleObserverSdk extends AbstractObserver implements DoubleObserver
|
|||
if (currentMetricUpdater == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final ActiveBatcher activeBatcher = getActiveBatcher();
|
||||
currentMetricUpdater.update(new ResultDoubleObserverSdk(activeBatcher, isMonotonic()));
|
||||
return activeBatcher.completeCollectionCycle();
|
||||
collectLock.lock();
|
||||
try {
|
||||
final ActiveBatcher activeBatcher = getActiveBatcher();
|
||||
currentMetricUpdater.update(new ResultDoubleObserverSdk(activeBatcher, isMonotonic()));
|
||||
return activeBatcher.completeCollectionCycle();
|
||||
} finally {
|
||||
collectLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -23,10 +23,12 @@ import io.opentelemetry.sdk.metrics.common.InstrumentValueType;
|
|||
import io.opentelemetry.sdk.metrics.data.MetricData;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
final class LongObserverSdk extends AbstractObserver implements LongObserver {
|
||||
@Nullable private volatile Callback<ResultLongObserver> metricUpdater = null;
|
||||
private final ReentrantLock collectLock = new ReentrantLock();
|
||||
|
||||
LongObserverSdk(
|
||||
InstrumentDescriptor descriptor,
|
||||
|
|
@ -47,9 +49,14 @@ final class LongObserverSdk extends AbstractObserver implements LongObserver {
|
|||
if (currentMetricUpdater == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final ActiveBatcher activeBatcher = getActiveBatcher();
|
||||
currentMetricUpdater.update(new ResultLongObserverSdk(activeBatcher, isMonotonic()));
|
||||
return activeBatcher.completeCollectionCycle();
|
||||
collectLock.lock();
|
||||
try {
|
||||
final ActiveBatcher activeBatcher = getActiveBatcher();
|
||||
currentMetricUpdater.update(new ResultLongObserverSdk(activeBatcher, isMonotonic()));
|
||||
return activeBatcher.completeCollectionCycle();
|
||||
} finally {
|
||||
collectLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -16,11 +16,18 @@
|
|||
|
||||
package io.opentelemetry.sdk.metrics;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import io.opentelemetry.common.AttributeValue;
|
||||
import io.opentelemetry.metrics.DoubleObserver.ResultDoubleObserver;
|
||||
import io.opentelemetry.metrics.Observer.Callback;
|
||||
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
|
||||
import io.opentelemetry.sdk.internal.TestClock;
|
||||
import io.opentelemetry.sdk.metrics.data.MetricData;
|
||||
import io.opentelemetry.sdk.metrics.data.MetricData.Descriptor;
|
||||
import io.opentelemetry.sdk.metrics.data.MetricData.Descriptor.Type;
|
||||
import io.opentelemetry.sdk.metrics.data.MetricData.DoublePoint;
|
||||
import io.opentelemetry.sdk.metrics.data.MetricData.Point;
|
||||
import io.opentelemetry.sdk.resources.Resource;
|
||||
import java.util.Collections;
|
||||
import org.junit.Rule;
|
||||
|
|
@ -34,6 +41,7 @@ import org.junit.runners.JUnit4;
|
|||
public class DoubleObserverSdkTest {
|
||||
|
||||
@Rule public ExpectedException thrown = ExpectedException.none();
|
||||
private static final long SECOND_NANOS = 1_000_000_000;
|
||||
private static final Resource RESOURCE =
|
||||
Resource.create(
|
||||
Collections.singletonMap(
|
||||
|
|
@ -46,6 +54,99 @@ public class DoubleObserverSdkTest {
|
|||
private final MeterSdk testSdk =
|
||||
new MeterSdk(meterProviderSharedState, INSTRUMENTATION_LIBRARY_INFO);
|
||||
|
||||
@Test
|
||||
public void collectMetrics_NoCallback() {
|
||||
DoubleObserverSdk doubleObserver =
|
||||
testSdk
|
||||
.doubleObserverBuilder("testObserver")
|
||||
.setConstantLabels(Collections.singletonMap("sk1", "sv1"))
|
||||
.setLabelKeys(Collections.singletonList("sk1"))
|
||||
.setDescription("My very own measure")
|
||||
.setUnit("ms")
|
||||
.build();
|
||||
assertThat(doubleObserver.collectAll()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void collectMetrics_NoRecords() {
|
||||
DoubleObserverSdk doubleObserver =
|
||||
testSdk
|
||||
.doubleObserverBuilder("testObserver")
|
||||
.setConstantLabels(Collections.singletonMap("sk1", "sv1"))
|
||||
.setLabelKeys(Collections.singletonList("sk1"))
|
||||
.setDescription("My very own measure")
|
||||
.setUnit("ms")
|
||||
.build();
|
||||
doubleObserver.setCallback(
|
||||
new Callback<ResultDoubleObserver>() {
|
||||
@Override
|
||||
public void update(ResultDoubleObserver result) {
|
||||
// Do nothing.
|
||||
}
|
||||
});
|
||||
assertThat(doubleObserver.collectAll())
|
||||
.containsExactly(
|
||||
MetricData.create(
|
||||
Descriptor.create(
|
||||
"testObserver",
|
||||
"My very own measure",
|
||||
"ms",
|
||||
Type.NON_MONOTONIC_DOUBLE,
|
||||
Collections.singletonMap("sk1", "sv1")),
|
||||
RESOURCE,
|
||||
INSTRUMENTATION_LIBRARY_INFO,
|
||||
Collections.<Point>emptyList()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void collectMetrics_WithOneRecord() {
|
||||
DoubleObserverSdk doubleObserver =
|
||||
testSdk.doubleObserverBuilder("testObserver").setMonotonic(true).build();
|
||||
doubleObserver.setCallback(
|
||||
new Callback<ResultDoubleObserver>() {
|
||||
@Override
|
||||
public void update(ResultDoubleObserver result) {
|
||||
result.observe(12.1d, "k", "v");
|
||||
}
|
||||
});
|
||||
testClock.advanceNanos(SECOND_NANOS);
|
||||
assertThat(doubleObserver.collectAll())
|
||||
.containsExactly(
|
||||
MetricData.create(
|
||||
Descriptor.create(
|
||||
"testObserver",
|
||||
"",
|
||||
"1",
|
||||
Type.MONOTONIC_DOUBLE,
|
||||
Collections.<String, String>emptyMap()),
|
||||
RESOURCE,
|
||||
INSTRUMENTATION_LIBRARY_INFO,
|
||||
Collections.<Point>singletonList(
|
||||
DoublePoint.create(
|
||||
testClock.now() - SECOND_NANOS,
|
||||
testClock.now(),
|
||||
Collections.singletonMap("k", "v"),
|
||||
12.1d))));
|
||||
testClock.advanceNanos(SECOND_NANOS);
|
||||
assertThat(doubleObserver.collectAll())
|
||||
.containsExactly(
|
||||
MetricData.create(
|
||||
Descriptor.create(
|
||||
"testObserver",
|
||||
"",
|
||||
"1",
|
||||
Type.MONOTONIC_DOUBLE,
|
||||
Collections.<String, String>emptyMap()),
|
||||
RESOURCE,
|
||||
INSTRUMENTATION_LIBRARY_INFO,
|
||||
Collections.<Point>singletonList(
|
||||
DoublePoint.create(
|
||||
testClock.now() - 2 * SECOND_NANOS,
|
||||
testClock.now(),
|
||||
Collections.singletonMap("k", "v"),
|
||||
12.1d))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void observeMonotonic_NegativeValue() {
|
||||
DoubleObserverSdk doubleObserver =
|
||||
|
|
|
|||
|
|
@ -16,11 +16,18 @@
|
|||
|
||||
package io.opentelemetry.sdk.metrics;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import io.opentelemetry.common.AttributeValue;
|
||||
import io.opentelemetry.metrics.LongObserver.ResultLongObserver;
|
||||
import io.opentelemetry.metrics.Observer.Callback;
|
||||
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
|
||||
import io.opentelemetry.sdk.internal.TestClock;
|
||||
import io.opentelemetry.sdk.metrics.data.MetricData;
|
||||
import io.opentelemetry.sdk.metrics.data.MetricData.Descriptor;
|
||||
import io.opentelemetry.sdk.metrics.data.MetricData.Descriptor.Type;
|
||||
import io.opentelemetry.sdk.metrics.data.MetricData.LongPoint;
|
||||
import io.opentelemetry.sdk.metrics.data.MetricData.Point;
|
||||
import io.opentelemetry.sdk.resources.Resource;
|
||||
import java.util.Collections;
|
||||
import org.junit.Rule;
|
||||
|
|
@ -34,6 +41,7 @@ import org.junit.runners.JUnit4;
|
|||
public class LongObserverSdkTest {
|
||||
|
||||
@Rule public ExpectedException thrown = ExpectedException.none();
|
||||
private static final long SECOND_NANOS = 1_000_000_000;
|
||||
private static final Resource RESOURCE =
|
||||
Resource.create(
|
||||
Collections.singletonMap(
|
||||
|
|
@ -46,6 +54,99 @@ public class LongObserverSdkTest {
|
|||
private final MeterSdk testSdk =
|
||||
new MeterSdk(meterProviderSharedState, INSTRUMENTATION_LIBRARY_INFO);
|
||||
|
||||
@Test
|
||||
public void collectMetrics_NoCallback() {
|
||||
LongObserverSdk longObserver =
|
||||
testSdk
|
||||
.longObserverBuilder("testObserver")
|
||||
.setConstantLabels(Collections.singletonMap("sk1", "sv1"))
|
||||
.setLabelKeys(Collections.singletonList("sk1"))
|
||||
.setDescription("My very own measure")
|
||||
.setUnit("ms")
|
||||
.build();
|
||||
assertThat(longObserver.collectAll()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void collectMetrics_NoRecords() {
|
||||
LongObserverSdk longObserver =
|
||||
testSdk
|
||||
.longObserverBuilder("testObserver")
|
||||
.setConstantLabels(Collections.singletonMap("sk1", "sv1"))
|
||||
.setLabelKeys(Collections.singletonList("sk1"))
|
||||
.setDescription("My very own measure")
|
||||
.setUnit("ms")
|
||||
.build();
|
||||
longObserver.setCallback(
|
||||
new Callback<ResultLongObserver>() {
|
||||
@Override
|
||||
public void update(ResultLongObserver result) {
|
||||
// Do nothing.
|
||||
}
|
||||
});
|
||||
assertThat(longObserver.collectAll())
|
||||
.containsExactly(
|
||||
MetricData.create(
|
||||
Descriptor.create(
|
||||
"testObserver",
|
||||
"My very own measure",
|
||||
"ms",
|
||||
Type.NON_MONOTONIC_LONG,
|
||||
Collections.singletonMap("sk1", "sv1")),
|
||||
RESOURCE,
|
||||
INSTRUMENTATION_LIBRARY_INFO,
|
||||
Collections.<Point>emptyList()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void collectMetrics_WithOneRecord() {
|
||||
LongObserverSdk longObserver =
|
||||
testSdk.longObserverBuilder("testObserver").setMonotonic(true).build();
|
||||
longObserver.setCallback(
|
||||
new Callback<ResultLongObserver>() {
|
||||
@Override
|
||||
public void update(ResultLongObserver result) {
|
||||
result.observe(12, "k", "v");
|
||||
}
|
||||
});
|
||||
testClock.advanceNanos(SECOND_NANOS);
|
||||
assertThat(longObserver.collectAll())
|
||||
.containsExactly(
|
||||
MetricData.create(
|
||||
Descriptor.create(
|
||||
"testObserver",
|
||||
"",
|
||||
"1",
|
||||
Type.MONOTONIC_LONG,
|
||||
Collections.<String, String>emptyMap()),
|
||||
RESOURCE,
|
||||
INSTRUMENTATION_LIBRARY_INFO,
|
||||
Collections.<Point>singletonList(
|
||||
LongPoint.create(
|
||||
testClock.now() - SECOND_NANOS,
|
||||
testClock.now(),
|
||||
Collections.singletonMap("k", "v"),
|
||||
12))));
|
||||
testClock.advanceNanos(SECOND_NANOS);
|
||||
assertThat(longObserver.collectAll())
|
||||
.containsExactly(
|
||||
MetricData.create(
|
||||
Descriptor.create(
|
||||
"testObserver",
|
||||
"",
|
||||
"1",
|
||||
Type.MONOTONIC_LONG,
|
||||
Collections.<String, String>emptyMap()),
|
||||
RESOURCE,
|
||||
INSTRUMENTATION_LIBRARY_INFO,
|
||||
Collections.<Point>singletonList(
|
||||
LongPoint.create(
|
||||
testClock.now() - 2 * SECOND_NANOS,
|
||||
testClock.now(),
|
||||
Collections.singletonMap("k", "v"),
|
||||
12))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void observeMonotonic_NegativeValue() {
|
||||
LongObserverSdk longObserver =
|
||||
|
|
|
|||
Loading…
Reference in New Issue