Skip to content

Commit

Permalink
MeterProvider that delegates to Micrometer MeterRegistry (#328)
Browse files Browse the repository at this point in the history
* Initial commit of OTel MeterProvider that delegates to Micrometer MeterRegistry

* Fix copypasta

* Unit tests

* Integration test, gradle cleanup

* Documentation

* Handle exceptions on observable instrument callbacksr

* Reduce accessibility of instruments and constructors

* Refactor polling behind interface

* Spotless

* Defer use of MeterRegistry (for Spring), create polling meter on demand

* Rename module to micrometer-meter-provider

* Add timer-based CallbackRegistrar for custom polling

* Add more javadocs, update README.md

* Feedback, switch to ScheduledExecutorService for registrar

* Poll instruments using single schedule with ScheduledCallbackRegistrar

* Add instrumentation tags and cache attributes to tags mappings

* Change TestCallbackRegistrar to not directly extend ArrayList

* PR feedback

* Record absolute values in async counters

* Instrumentation scope as Micrometer tags in meter state

* Switch UpDownCounters to Micrometer Gauge, memoize MeterRegistry supplier, randomize measurements during tests
  • Loading branch information
HaloFour authored May 24, 2022
1 parent 972cf46 commit 29f5ce1
Show file tree
Hide file tree
Showing 52 changed files with 4,488 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .github/component_owners.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ components:
maven-extension:
- cyrille-leclerc
- kenfinnigan
micrometer-meter-provider:
- HaloFour
runtime-attach:
- iNikem
- trask
Expand Down
61 changes: 61 additions & 0 deletions micrometer-meter-provider/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Micrometer MeterProvider

This utility provides an implementation of `MeterProvider` which wraps a Micrometer `MeterRegistry`
and delegates the reporting of all metrics through Micrometer. This enables projects which already
rely on Micrometer and cannot currently migrate to OpenTelemetry Metrics to be able to report on
metrics that are reported through the OpenTelemetry Metrics API.

### Usage

Create the `MicrometerMeterProvider` passing an existing instance of `MeterRegistry`. Then you can
use the OpenTelemetry Metrics `MeterProvider` API to create instruments.

```java
MeterRegistry meterRegistry = ...;

// create the meter provider
MeterProvider meterProvider = MicrometerMeterProvider.builder(meterRegistry)
.build();
Meter meter = meterProvider.get("my-app");

// create an instrument
LongCounter counter = meter.counterBuilder("my.counter")
.build();

// record metrics
count.add(1, Attributes.of(AttributeKey.stringKey("key"), "value"));
```

**Note**: Instruments in OpenTelemetry are created without tags, which are reported with each
measurement. But tags are required to create Micrometer metrics. Because of this difference the
adapter must listen for when measurements are being read by the `MeterRegistry` in order to call
callbacks registered for observable metrics in order to create the Micrometer meters on demand.

By default the `MicrometerMeterProvider` will create a dummy `Metric` with the name
"otel-polling-meter" which will be used to poll the asynchronous OpenTelemetry instruments as it
is measured. However, you can also specify an alternative `CallbackRegistrar` strategy.

```java
MeterRegistry meterRegistry = ...;

// create the meter provider
MeterProvider meterProvider = MicrometerMeterProvider.builder(meterRegistry)
.setCallbackRegistrar(ScheduledCallbackRegistrar.builder()
.setPeriod(Duration.ofSeconds(10L))
.build())
.build();
Meter meter = meterProvider.get("my-app");

// create an asynchronous instrument
ObservableDoubleGauge gauge = meter.gaugeBuilder("my.gauge")
.buildWithCallback(measurement -> {
// record metrics
measurement.record(queue.size(), Attributes.of(AttributeKey.stringKey("key"), "value"));
});
```

## Component owners

- [Justin Spindler](https://github.com/HaloFour), Comcast

Learn more about component owners in [component_owners.yml](../.github/component_owners.yml).
32 changes: 32 additions & 0 deletions micrometer-meter-provider/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
plugins {
id("otel.java-conventions")
id("otel.publish-conventions")
}

description = "OpenTelemetry Micrometer MeterProvider"

dependencies {
api("io.opentelemetry:opentelemetry-api")
api("io.opentelemetry:opentelemetry-sdk-metrics")

compileOnly("io.micrometer:micrometer-core:1.1.0")
compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure")

annotationProcessor("com.google.auto.service:auto-service")
compileOnly("com.google.auto.service:auto-service-annotations")

annotationProcessor("com.google.auto.value:auto-value")
compileOnly("com.google.auto.value:auto-value-annotations")

testImplementation("io.micrometer:micrometer-core:1.8.5")
}

testing {
suites {
val integrationTest by registering(JvmTestSuite::class) {
dependencies {
implementation("io.micrometer:micrometer-registry-prometheus:1.8.5")
}
}
}
}
Loading

0 comments on commit 29f5ce1

Please sign in to comment.