Implement NamingConvention support in Micrometer bridge (#5328)
* Implement NamingConvention support in Micrometer bridge * default naming convention
This commit is contained in:
parent
2cf853dba3
commit
956b5660de
|
@ -8,6 +8,7 @@ package io.opentelemetry.instrumentation.micrometer.v1_5;
|
|||
import io.micrometer.core.instrument.Meter;
|
||||
import io.micrometer.core.instrument.Statistic;
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
import io.micrometer.core.instrument.config.NamingConvention;
|
||||
import io.opentelemetry.api.common.AttributeKey;
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.api.common.AttributesBuilder;
|
||||
|
@ -17,18 +18,28 @@ final class Bridging {
|
|||
|
||||
private static final Cache<String, AttributeKey<String>> tagsCache = Cache.bounded(1024);
|
||||
|
||||
static Attributes tagsAsAttributes(Meter.Id id) {
|
||||
static Attributes tagsAsAttributes(Meter.Id id, NamingConvention namingConvention) {
|
||||
Iterable<Tag> tags = id.getTagsAsIterable();
|
||||
if (!tags.iterator().hasNext()) {
|
||||
return Attributes.empty();
|
||||
}
|
||||
AttributesBuilder builder = Attributes.builder();
|
||||
for (Tag tag : tags) {
|
||||
builder.put(tagsCache.computeIfAbsent(tag.getKey(), AttributeKey::stringKey), tag.getValue());
|
||||
String tagKey = namingConvention.tagKey(tag.getKey());
|
||||
String tagValue = namingConvention.tagValue(tag.getValue());
|
||||
builder.put(tagsCache.computeIfAbsent(tagKey, AttributeKey::stringKey), tagValue);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
static String name(Meter.Id id, NamingConvention namingConvention) {
|
||||
return name(id.getName(), id, namingConvention);
|
||||
}
|
||||
|
||||
private static String name(String name, Meter.Id id, NamingConvention namingConvention) {
|
||||
return namingConvention.name(name, id.getType(), id.getBaseUnit());
|
||||
}
|
||||
|
||||
static String description(Meter.Id id) {
|
||||
String description = id.getDescription();
|
||||
return description == null ? "" : description;
|
||||
|
@ -39,12 +50,13 @@ final class Bridging {
|
|||
return baseUnit == null ? "1" : baseUnit;
|
||||
}
|
||||
|
||||
static String statisticInstrumentName(Meter.Id id, Statistic statistic) {
|
||||
static String statisticInstrumentName(
|
||||
Meter.Id id, Statistic statistic, NamingConvention namingConvention) {
|
||||
String prefix = id.getName() + ".";
|
||||
// use "total_time" instead of "total" to avoid clashing with Statistic.TOTAL
|
||||
String statisticStr =
|
||||
statistic == Statistic.TOTAL_TIME ? "total_time" : statistic.getTagValueRepresentation();
|
||||
return prefix + statisticStr;
|
||||
return name(prefix + statisticStr, id, namingConvention);
|
||||
}
|
||||
|
||||
private Bridging() {}
|
||||
|
|
|
@ -7,10 +7,12 @@ package io.opentelemetry.instrumentation.micrometer.v1_5;
|
|||
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.baseUnit;
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.description;
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.name;
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.tagsAsAttributes;
|
||||
|
||||
import io.micrometer.core.instrument.Counter;
|
||||
import io.micrometer.core.instrument.Measurement;
|
||||
import io.micrometer.core.instrument.config.NamingConvention;
|
||||
import io.micrometer.core.instrument.util.MeterEquivalence;
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.api.metrics.DoubleCounter;
|
||||
|
@ -28,16 +30,17 @@ final class OpenTelemetryCounter implements Counter, RemovableMeter {
|
|||
|
||||
private volatile boolean removed = false;
|
||||
|
||||
OpenTelemetryCounter(Id id, Meter otelMeter) {
|
||||
OpenTelemetryCounter(Id id, NamingConvention namingConvention, Meter otelMeter) {
|
||||
this.id = id;
|
||||
|
||||
this.attributes = tagsAsAttributes(id, namingConvention);
|
||||
this.otelCounter =
|
||||
otelMeter
|
||||
.counterBuilder(id.getName())
|
||||
.counterBuilder(name(id, namingConvention))
|
||||
.setDescription(description(id))
|
||||
.setUnit(baseUnit(id))
|
||||
.ofDoubles()
|
||||
.build();
|
||||
this.attributes = tagsAsAttributes(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,6 +7,7 @@ package io.opentelemetry.instrumentation.micrometer.v1_5;
|
|||
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.baseUnit;
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.description;
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.name;
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.statisticInstrumentName;
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.tagsAsAttributes;
|
||||
|
||||
|
@ -15,6 +16,7 @@ import io.micrometer.core.instrument.Clock;
|
|||
import io.micrometer.core.instrument.DistributionSummary;
|
||||
import io.micrometer.core.instrument.Measurement;
|
||||
import io.micrometer.core.instrument.Statistic;
|
||||
import io.micrometer.core.instrument.config.NamingConvention;
|
||||
import io.micrometer.core.instrument.distribution.DistributionStatisticConfig;
|
||||
import io.micrometer.core.instrument.distribution.NoopHistogram;
|
||||
import io.micrometer.core.instrument.distribution.TimeWindowMax;
|
||||
|
@ -41,6 +43,7 @@ final class OpenTelemetryDistributionSummary extends AbstractDistributionSummary
|
|||
|
||||
OpenTelemetryDistributionSummary(
|
||||
Id id,
|
||||
NamingConvention namingConvention,
|
||||
Clock clock,
|
||||
DistributionStatisticConfig distributionStatisticConfig,
|
||||
double scale,
|
||||
|
@ -55,16 +58,16 @@ final class OpenTelemetryDistributionSummary extends AbstractDistributionSummary
|
|||
}
|
||||
max = new TimeWindowMax(clock, distributionStatisticConfig);
|
||||
|
||||
this.attributes = tagsAsAttributes(id);
|
||||
this.attributes = tagsAsAttributes(id, namingConvention);
|
||||
this.otelHistogram =
|
||||
otelMeter
|
||||
.histogramBuilder(id.getName())
|
||||
.histogramBuilder(name(id, namingConvention))
|
||||
.setDescription(description(id))
|
||||
.setUnit(baseUnit(id))
|
||||
.build();
|
||||
this.maxHandle =
|
||||
asyncInstrumentRegistry.buildGauge(
|
||||
statisticInstrumentName(id, Statistic.MAX),
|
||||
statisticInstrumentName(id, Statistic.MAX, namingConvention),
|
||||
description(id),
|
||||
baseUnit(id),
|
||||
attributes,
|
||||
|
|
|
@ -7,10 +7,12 @@ package io.opentelemetry.instrumentation.micrometer.v1_5;
|
|||
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.baseUnit;
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.description;
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.name;
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.tagsAsAttributes;
|
||||
|
||||
import io.micrometer.core.instrument.FunctionCounter;
|
||||
import io.micrometer.core.instrument.Measurement;
|
||||
import io.micrometer.core.instrument.config.NamingConvention;
|
||||
import io.micrometer.core.instrument.util.MeterEquivalence;
|
||||
import io.opentelemetry.instrumentation.api.internal.AsyncInstrumentRegistry;
|
||||
import io.opentelemetry.instrumentation.api.internal.AsyncInstrumentRegistry.AsyncMeasurementHandle;
|
||||
|
@ -26,6 +28,7 @@ final class OpenTelemetryFunctionCounter<T> implements FunctionCounter, Removabl
|
|||
|
||||
OpenTelemetryFunctionCounter(
|
||||
Id id,
|
||||
NamingConvention namingConvention,
|
||||
T obj,
|
||||
ToDoubleFunction<T> countFunction,
|
||||
AsyncInstrumentRegistry asyncInstrumentRegistry) {
|
||||
|
@ -33,7 +36,12 @@ final class OpenTelemetryFunctionCounter<T> implements FunctionCounter, Removabl
|
|||
|
||||
countMeasurementHandle =
|
||||
asyncInstrumentRegistry.buildDoubleCounter(
|
||||
id.getName(), description(id), baseUnit(id), tagsAsAttributes(id), obj, countFunction);
|
||||
name(id, namingConvention),
|
||||
description(id),
|
||||
baseUnit(id),
|
||||
tagsAsAttributes(id, namingConvention),
|
||||
obj,
|
||||
countFunction);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -13,6 +13,7 @@ import static io.opentelemetry.instrumentation.micrometer.v1_5.TimeUnitHelper.ge
|
|||
import io.micrometer.core.instrument.FunctionTimer;
|
||||
import io.micrometer.core.instrument.Measurement;
|
||||
import io.micrometer.core.instrument.Statistic;
|
||||
import io.micrometer.core.instrument.config.NamingConvention;
|
||||
import io.micrometer.core.instrument.util.MeterEquivalence;
|
||||
import io.micrometer.core.instrument.util.TimeUtils;
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
|
@ -34,6 +35,7 @@ final class OpenTelemetryFunctionTimer<T> implements FunctionTimer, RemovableMet
|
|||
|
||||
OpenTelemetryFunctionTimer(
|
||||
Id id,
|
||||
NamingConvention namingConvention,
|
||||
T obj,
|
||||
ToLongFunction<T> countFunction,
|
||||
ToDoubleFunction<T> totalTimeFunction,
|
||||
|
@ -44,9 +46,9 @@ final class OpenTelemetryFunctionTimer<T> implements FunctionTimer, RemovableMet
|
|||
this.id = id;
|
||||
this.baseTimeUnit = baseTimeUnit;
|
||||
|
||||
String countMeterName = statisticInstrumentName(id, Statistic.COUNT);
|
||||
String totalTimeMeterName = statisticInstrumentName(id, Statistic.TOTAL_TIME);
|
||||
Attributes attributes = tagsAsAttributes(id);
|
||||
String countMeterName = statisticInstrumentName(id, Statistic.COUNT, namingConvention);
|
||||
String totalTimeMeterName = statisticInstrumentName(id, Statistic.TOTAL_TIME, namingConvention);
|
||||
Attributes attributes = tagsAsAttributes(id, namingConvention);
|
||||
|
||||
countMeasurementHandle =
|
||||
asyncInstrumentRegistry.buildLongCounter(
|
||||
|
|
|
@ -7,10 +7,12 @@ package io.opentelemetry.instrumentation.micrometer.v1_5;
|
|||
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.baseUnit;
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.description;
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.name;
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.tagsAsAttributes;
|
||||
|
||||
import io.micrometer.core.instrument.Gauge;
|
||||
import io.micrometer.core.instrument.Measurement;
|
||||
import io.micrometer.core.instrument.config.NamingConvention;
|
||||
import io.micrometer.core.instrument.util.MeterEquivalence;
|
||||
import io.opentelemetry.instrumentation.api.internal.AsyncInstrumentRegistry;
|
||||
import io.opentelemetry.instrumentation.api.internal.AsyncInstrumentRegistry.AsyncMeasurementHandle;
|
||||
|
@ -26,14 +28,21 @@ final class OpenTelemetryGauge<T> implements Gauge, RemovableMeter {
|
|||
|
||||
OpenTelemetryGauge(
|
||||
Id id,
|
||||
NamingConvention namingConvention,
|
||||
@Nullable T obj,
|
||||
ToDoubleFunction<T> objMetric,
|
||||
AsyncInstrumentRegistry asyncInstrumentRegistry) {
|
||||
|
||||
this.id = id;
|
||||
|
||||
gaugeMeasurementHandle =
|
||||
asyncInstrumentRegistry.buildGauge(
|
||||
id.getName(), description(id), baseUnit(id), tagsAsAttributes(id), obj, objMetric);
|
||||
name(id, namingConvention),
|
||||
description(id),
|
||||
baseUnit(id),
|
||||
tagsAsAttributes(id, namingConvention),
|
||||
obj,
|
||||
objMetric);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
package io.opentelemetry.instrumentation.micrometer.v1_5;
|
||||
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.description;
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.name;
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.statisticInstrumentName;
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.tagsAsAttributes;
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.TimeUnitHelper.getUnitString;
|
||||
|
@ -13,6 +14,7 @@ import static io.opentelemetry.instrumentation.micrometer.v1_5.TimeUnitHelper.ge
|
|||
import io.micrometer.core.instrument.Clock;
|
||||
import io.micrometer.core.instrument.Measurement;
|
||||
import io.micrometer.core.instrument.Statistic;
|
||||
import io.micrometer.core.instrument.config.NamingConvention;
|
||||
import io.micrometer.core.instrument.distribution.DistributionStatisticConfig;
|
||||
import io.micrometer.core.instrument.internal.DefaultLongTaskTimer;
|
||||
import io.micrometer.core.instrument.util.TimeUtils;
|
||||
|
@ -36,6 +38,7 @@ final class OpenTelemetryLongTaskTimer extends DefaultLongTaskTimer implements R
|
|||
|
||||
OpenTelemetryLongTaskTimer(
|
||||
Id id,
|
||||
NamingConvention namingConvention,
|
||||
Clock clock,
|
||||
TimeUnit baseTimeUnit,
|
||||
DistributionStatisticConfig distributionStatisticConfig,
|
||||
|
@ -47,17 +50,18 @@ final class OpenTelemetryLongTaskTimer extends DefaultLongTaskTimer implements R
|
|||
|
||||
this.otelHistogram =
|
||||
otelMeter
|
||||
.histogramBuilder(id.getName())
|
||||
.histogramBuilder(name(id, namingConvention))
|
||||
.setDescription(description(id))
|
||||
.setUnit(getUnitString(baseTimeUnit))
|
||||
.build();
|
||||
this.otelActiveTasksCounter =
|
||||
otelMeter
|
||||
.upDownCounterBuilder(statisticInstrumentName(id, Statistic.ACTIVE_TASKS))
|
||||
.upDownCounterBuilder(
|
||||
statisticInstrumentName(id, Statistic.ACTIVE_TASKS, namingConvention))
|
||||
.setDescription(description(id))
|
||||
.setUnit("tasks")
|
||||
.build();
|
||||
this.attributes = tagsAsAttributes(id);
|
||||
this.attributes = tagsAsAttributes(id, namingConvention);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -12,6 +12,7 @@ import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.tagsAsAt
|
|||
|
||||
import io.micrometer.core.instrument.Measurement;
|
||||
import io.micrometer.core.instrument.Meter;
|
||||
import io.micrometer.core.instrument.config.NamingConvention;
|
||||
import io.micrometer.core.instrument.util.MeterEquivalence;
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.instrumentation.api.internal.AsyncInstrumentRegistry;
|
||||
|
@ -28,13 +29,16 @@ final class OpenTelemetryMeter implements Meter, RemovableMeter {
|
|||
private final List<AsyncMeasurementHandle> measurementHandles;
|
||||
|
||||
OpenTelemetryMeter(
|
||||
Id id, Iterable<Measurement> measurements, AsyncInstrumentRegistry asyncInstrumentRegistry) {
|
||||
Id id,
|
||||
NamingConvention namingConvention,
|
||||
Iterable<Measurement> measurements,
|
||||
AsyncInstrumentRegistry asyncInstrumentRegistry) {
|
||||
this.id = id;
|
||||
Attributes attributes = tagsAsAttributes(id);
|
||||
Attributes attributes = tagsAsAttributes(id, namingConvention);
|
||||
|
||||
List<AsyncMeasurementHandle> measurementHandles = new ArrayList<>();
|
||||
for (Measurement measurement : measurements) {
|
||||
String name = statisticInstrumentName(id, measurement.getStatistic());
|
||||
String name = statisticInstrumentName(id, measurement.getStatistic(), namingConvention);
|
||||
String description = description(id);
|
||||
String baseUnit = baseUnit(id);
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import io.micrometer.core.instrument.Measurement;
|
|||
import io.micrometer.core.instrument.Meter;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.core.instrument.Timer;
|
||||
import io.micrometer.core.instrument.config.NamingConvention;
|
||||
import io.micrometer.core.instrument.distribution.DistributionStatisticConfig;
|
||||
import io.micrometer.core.instrument.distribution.HistogramGauges;
|
||||
import io.micrometer.core.instrument.distribution.pause.PauseDetector;
|
||||
|
@ -59,17 +60,21 @@ public final class OpenTelemetryMeterRegistry extends MeterRegistry {
|
|||
this.baseTimeUnit = baseTimeUnit;
|
||||
this.otelMeter = otelMeter;
|
||||
this.asyncInstrumentRegistry = AsyncInstrumentRegistry.getOrCreate(otelMeter);
|
||||
this.config().onMeterRemoved(OpenTelemetryMeterRegistry::onMeterRemoved);
|
||||
|
||||
this.config()
|
||||
.namingConvention(NamingConvention.identity)
|
||||
.onMeterRemoved(OpenTelemetryMeterRegistry::onMeterRemoved);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T> Gauge newGauge(Meter.Id id, @Nullable T obj, ToDoubleFunction<T> valueFunction) {
|
||||
return new OpenTelemetryGauge<>(id, obj, valueFunction, asyncInstrumentRegistry);
|
||||
return new OpenTelemetryGauge<>(
|
||||
id, config().namingConvention(), obj, valueFunction, asyncInstrumentRegistry);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Counter newCounter(Meter.Id id) {
|
||||
return new OpenTelemetryCounter(id, otelMeter);
|
||||
return new OpenTelemetryCounter(id, config().namingConvention(), otelMeter);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -77,7 +82,12 @@ public final class OpenTelemetryMeterRegistry extends MeterRegistry {
|
|||
Meter.Id id, DistributionStatisticConfig distributionStatisticConfig) {
|
||||
OpenTelemetryLongTaskTimer timer =
|
||||
new OpenTelemetryLongTaskTimer(
|
||||
id, clock, getBaseTimeUnit(), distributionStatisticConfig, otelMeter);
|
||||
id,
|
||||
config().namingConvention(),
|
||||
clock,
|
||||
getBaseTimeUnit(),
|
||||
distributionStatisticConfig,
|
||||
otelMeter);
|
||||
if (timer.isUsingMicrometerHistograms()) {
|
||||
HistogramGauges.registerWithCommonFormat(timer, this);
|
||||
}
|
||||
|
@ -92,6 +102,7 @@ public final class OpenTelemetryMeterRegistry extends MeterRegistry {
|
|||
OpenTelemetryTimer timer =
|
||||
new OpenTelemetryTimer(
|
||||
id,
|
||||
config().namingConvention(),
|
||||
clock,
|
||||
distributionStatisticConfig,
|
||||
pauseDetector,
|
||||
|
@ -109,7 +120,13 @@ public final class OpenTelemetryMeterRegistry extends MeterRegistry {
|
|||
Meter.Id id, DistributionStatisticConfig distributionStatisticConfig, double scale) {
|
||||
OpenTelemetryDistributionSummary distributionSummary =
|
||||
new OpenTelemetryDistributionSummary(
|
||||
id, clock, distributionStatisticConfig, scale, otelMeter, asyncInstrumentRegistry);
|
||||
id,
|
||||
config().namingConvention(),
|
||||
clock,
|
||||
distributionStatisticConfig,
|
||||
scale,
|
||||
otelMeter,
|
||||
asyncInstrumentRegistry);
|
||||
if (distributionSummary.isUsingMicrometerHistograms()) {
|
||||
HistogramGauges.registerWithCommonFormat(distributionSummary, this);
|
||||
}
|
||||
|
@ -118,7 +135,8 @@ public final class OpenTelemetryMeterRegistry extends MeterRegistry {
|
|||
|
||||
@Override
|
||||
protected Meter newMeter(Meter.Id id, Meter.Type type, Iterable<Measurement> measurements) {
|
||||
return new OpenTelemetryMeter(id, measurements, asyncInstrumentRegistry);
|
||||
return new OpenTelemetryMeter(
|
||||
id, config().namingConvention(), measurements, asyncInstrumentRegistry);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -130,6 +148,7 @@ public final class OpenTelemetryMeterRegistry extends MeterRegistry {
|
|||
TimeUnit totalTimeFunctionUnit) {
|
||||
return new OpenTelemetryFunctionTimer<>(
|
||||
id,
|
||||
config().namingConvention(),
|
||||
obj,
|
||||
countFunction,
|
||||
totalTimeFunction,
|
||||
|
@ -141,7 +160,8 @@ public final class OpenTelemetryMeterRegistry extends MeterRegistry {
|
|||
@Override
|
||||
protected <T> FunctionCounter newFunctionCounter(
|
||||
Meter.Id id, T obj, ToDoubleFunction<T> countFunction) {
|
||||
return new OpenTelemetryFunctionCounter<>(id, obj, countFunction, asyncInstrumentRegistry);
|
||||
return new OpenTelemetryFunctionCounter<>(
|
||||
id, config().namingConvention(), obj, countFunction, asyncInstrumentRegistry);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
package io.opentelemetry.instrumentation.micrometer.v1_5;
|
||||
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.description;
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.name;
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.statisticInstrumentName;
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.Bridging.tagsAsAttributes;
|
||||
import static io.opentelemetry.instrumentation.micrometer.v1_5.TimeUnitHelper.getUnitString;
|
||||
|
@ -14,6 +15,7 @@ import io.micrometer.core.instrument.AbstractTimer;
|
|||
import io.micrometer.core.instrument.Clock;
|
||||
import io.micrometer.core.instrument.Measurement;
|
||||
import io.micrometer.core.instrument.Statistic;
|
||||
import io.micrometer.core.instrument.config.NamingConvention;
|
||||
import io.micrometer.core.instrument.distribution.DistributionStatisticConfig;
|
||||
import io.micrometer.core.instrument.distribution.NoopHistogram;
|
||||
import io.micrometer.core.instrument.distribution.TimeWindowMax;
|
||||
|
@ -42,6 +44,7 @@ final class OpenTelemetryTimer extends AbstractTimer implements RemovableMeter {
|
|||
|
||||
OpenTelemetryTimer(
|
||||
Id id,
|
||||
NamingConvention namingConvention,
|
||||
Clock clock,
|
||||
DistributionStatisticConfig distributionStatisticConfig,
|
||||
PauseDetector pauseDetector,
|
||||
|
@ -58,16 +61,16 @@ final class OpenTelemetryTimer extends AbstractTimer implements RemovableMeter {
|
|||
max = new TimeWindowMax(clock, distributionStatisticConfig);
|
||||
|
||||
this.baseTimeUnit = baseTimeUnit;
|
||||
this.attributes = tagsAsAttributes(id);
|
||||
this.attributes = tagsAsAttributes(id, namingConvention);
|
||||
this.otelHistogram =
|
||||
otelMeter
|
||||
.histogramBuilder(id.getName())
|
||||
.histogramBuilder(name(id, namingConvention))
|
||||
.setDescription(description(id))
|
||||
.setUnit(getUnitString(baseTimeUnit))
|
||||
.build();
|
||||
this.maxHandle =
|
||||
asyncInstrumentRegistry.buildGauge(
|
||||
statisticInstrumentName(id, Statistic.MAX),
|
||||
statisticInstrumentName(id, Statistic.MAX, namingConvention),
|
||||
description(id),
|
||||
getUnitString(baseTimeUnit),
|
||||
attributes,
|
||||
|
|
|
@ -0,0 +1,253 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.micrometer.v1_5;
|
||||
|
||||
import static io.opentelemetry.sdk.testing.assertj.MetricAssertions.assertThat;
|
||||
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.attributeEntry;
|
||||
|
||||
import io.micrometer.core.instrument.Counter;
|
||||
import io.micrometer.core.instrument.DistributionSummary;
|
||||
import io.micrometer.core.instrument.Meter;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.core.instrument.Metrics;
|
||||
import io.micrometer.core.instrument.Tags;
|
||||
import io.micrometer.core.instrument.Timer;
|
||||
import io.micrometer.core.instrument.config.NamingConvention;
|
||||
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
|
||||
import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
|
||||
@SuppressWarnings("PreferJavaTimeOverload")
|
||||
class NamingConventionTest {
|
||||
|
||||
static final String INSTRUMENTATION_NAME = "io.opentelemetry.micrometer-1.5";
|
||||
|
||||
@RegisterExtension
|
||||
static final InstrumentationExtension testing = LibraryInstrumentationExtension.create();
|
||||
|
||||
static MeterRegistry otelMeterRegistry;
|
||||
|
||||
@BeforeAll
|
||||
public static void setUpRegistry() {
|
||||
otelMeterRegistry = OpenTelemetryMeterRegistry.create(testing.getOpenTelemetry());
|
||||
otelMeterRegistry
|
||||
.config()
|
||||
.namingConvention(
|
||||
new NamingConvention() {
|
||||
@Override
|
||||
public String name(String name, Meter.Type type, String baseUnit) {
|
||||
return "test." + name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String tagKey(String key) {
|
||||
return "test." + key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String tagValue(String value) {
|
||||
return "test." + value;
|
||||
}
|
||||
});
|
||||
Metrics.addRegistry(otelMeterRegistry);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void tearDownRegistry() {
|
||||
Metrics.removeRegistry(otelMeterRegistry);
|
||||
}
|
||||
|
||||
final AtomicLong num = new AtomicLong(42);
|
||||
|
||||
@Test
|
||||
void renameCounter() {
|
||||
// when
|
||||
Counter counter = Metrics.counter("renamedCounter", "tag", "value");
|
||||
counter.increment();
|
||||
|
||||
// then
|
||||
testing.waitAndAssertMetrics(
|
||||
INSTRUMENTATION_NAME,
|
||||
"test.renamedCounter",
|
||||
metrics ->
|
||||
metrics.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasDoubleSum()
|
||||
.points()
|
||||
.satisfiesExactly(
|
||||
point ->
|
||||
assertThat(point)
|
||||
.attributes()
|
||||
.containsOnly(attributeEntry("test.tag", "test.value")))));
|
||||
}
|
||||
|
||||
@Test
|
||||
void renameDistributionSummary() {
|
||||
// when
|
||||
DistributionSummary summary = Metrics.summary("renamedSummary", "tag", "value");
|
||||
summary.record(42);
|
||||
|
||||
// then
|
||||
testing.waitAndAssertMetrics(
|
||||
INSTRUMENTATION_NAME,
|
||||
"test.renamedSummary",
|
||||
metrics ->
|
||||
metrics.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasDoubleHistogram()
|
||||
.points()
|
||||
.satisfiesExactly(
|
||||
point ->
|
||||
assertThat(point)
|
||||
.attributes()
|
||||
.containsOnly(attributeEntry("test.tag", "test.value")))));
|
||||
testing.waitAndAssertMetrics(
|
||||
INSTRUMENTATION_NAME,
|
||||
"test.renamedSummary.max",
|
||||
metrics ->
|
||||
metrics.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasDoubleGauge()
|
||||
.points()
|
||||
.satisfiesExactly(
|
||||
point ->
|
||||
assertThat(point)
|
||||
.attributes()
|
||||
.containsOnly(attributeEntry("test.tag", "test.value")))));
|
||||
}
|
||||
|
||||
@Test
|
||||
void renameFunctionCounter() {
|
||||
// when
|
||||
Metrics.more().counter("renamedFunctionCounter", Tags.of("tag", "value"), num);
|
||||
|
||||
// then
|
||||
testing.waitAndAssertMetrics(
|
||||
INSTRUMENTATION_NAME,
|
||||
"test.renamedFunctionCounter",
|
||||
metrics ->
|
||||
metrics.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasDoubleSum()
|
||||
.points()
|
||||
.satisfiesExactly(
|
||||
point ->
|
||||
assertThat(point)
|
||||
.attributes()
|
||||
.containsOnly(attributeEntry("test.tag", "test.value")))));
|
||||
}
|
||||
|
||||
@Test
|
||||
void renameFunctionTimer() {
|
||||
// when
|
||||
Metrics.more()
|
||||
.timer(
|
||||
"renamedFunctionTimer",
|
||||
Tags.of("tag", "value"),
|
||||
num,
|
||||
AtomicLong::longValue,
|
||||
AtomicLong::doubleValue,
|
||||
TimeUnit.SECONDS);
|
||||
|
||||
// then
|
||||
testing.waitAndAssertMetrics(
|
||||
INSTRUMENTATION_NAME,
|
||||
"test.renamedFunctionTimer.count",
|
||||
metrics ->
|
||||
metrics.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasLongSum()
|
||||
.points()
|
||||
.satisfiesExactly(
|
||||
point ->
|
||||
assertThat(point)
|
||||
.attributes()
|
||||
.containsOnly(attributeEntry("test.tag", "test.value")))));
|
||||
testing.waitAndAssertMetrics(
|
||||
INSTRUMENTATION_NAME,
|
||||
"test.renamedFunctionTimer.total_time",
|
||||
metrics ->
|
||||
metrics.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasDoubleSum()
|
||||
.points()
|
||||
.satisfiesExactly(
|
||||
point ->
|
||||
assertThat(point)
|
||||
.attributes()
|
||||
.containsOnly(attributeEntry("test.tag", "test.value")))));
|
||||
}
|
||||
|
||||
@Test
|
||||
void renameGauge() {
|
||||
// when
|
||||
Metrics.gauge("renamedGauge", Tags.of("tag", "value"), num);
|
||||
|
||||
// then
|
||||
testing.waitAndAssertMetrics(
|
||||
INSTRUMENTATION_NAME,
|
||||
"test.renamedGauge",
|
||||
metrics ->
|
||||
metrics.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasDoubleGauge()
|
||||
.points()
|
||||
.satisfiesExactly(
|
||||
point ->
|
||||
assertThat(point)
|
||||
.attributes()
|
||||
.containsOnly(attributeEntry("test.tag", "test.value")))));
|
||||
}
|
||||
|
||||
@Test
|
||||
void renameTimer() {
|
||||
// when
|
||||
Timer timer = Metrics.timer("renamedTimer", "tag", "value");
|
||||
timer.record(10, TimeUnit.SECONDS);
|
||||
|
||||
// then
|
||||
testing.waitAndAssertMetrics(
|
||||
INSTRUMENTATION_NAME,
|
||||
"test.renamedTimer",
|
||||
metrics ->
|
||||
metrics.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasDoubleHistogram()
|
||||
.points()
|
||||
.satisfiesExactly(
|
||||
point ->
|
||||
assertThat(point)
|
||||
.attributes()
|
||||
.containsOnly(attributeEntry("test.tag", "test.value")))));
|
||||
testing.waitAndAssertMetrics(
|
||||
INSTRUMENTATION_NAME,
|
||||
"test.renamedTimer.max",
|
||||
metrics ->
|
||||
metrics.anySatisfy(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasDoubleGauge()
|
||||
.points()
|
||||
.satisfiesExactly(
|
||||
point ->
|
||||
assertThat(point)
|
||||
.attributes()
|
||||
.containsOnly(attributeEntry("test.tag", "test.value")))));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue