Micrometer
compared to
opentelemetry-java
opentelemetry has no dedicated Timer type.
public class MyService {
MeterRegistry registry;
public void call() {
// base units automatically set based on base unit of time of each registry
try (Timer.ResourceSample t = Timer.resource(registry, "calls")
.description("calls to something")
.publishPercentileHistogram()
.publishPercentiles(0.95)
.serviceLevelObjectives(Duration.ofSeconds(1))
.tags("service", "hi")) {
try {
// do something
t.tag("outcome", "success");
} catch (Exception e) {
t.tags("outcome", "error", "exception", e.getClass().getName());
}
}
}
}
public class MyService {
Meter meter = OpenTelemetry.getMeter("registry");
Map<String, AtomicLong> callSum = Map.of(
"success", new AtomicLong(0),
"failure", new AtomicLong(0)
);
public MyService() {
registerCallSum("success");
registerCallSum("failure");
}
private void registerCallSum(String outcome) {
meter.doubleSumObserverBuilder("calls.sum")
.setDescription("calls to something")
.setConstantLabels(Map.of("service", "hi"))
.build()
.setCallback(result -> result.observe(
(double) callSum.get(outcome).get() / 1e9,
"outcome", outcome));
}
public void call() {
DoubleCounter.Builder callCounter = meter
.doubleCounterBuilder("calls.count")
.setDescription("calls to something")
.setConstantLabels(Map.of("service", "hi"))
.setUnit("requests");
long start = System.nanoTime();
try {
// do something
callCounter.build().add(1, "outcome", "success");
callSum.get("success").addAndGet(System.nanoTime() - start);
} catch (Exception e) {
callCounter.build().add(1, "outcome", "failure",
"exception", e.getClass().getName());
callSum.get("failure").addAndGet(System.nanoTime() - start);
}
}
}
Still lacks max, percentiles, SLOs, histograms, etc.
No clock
abstraction
No time
scaling
opentelemetry has no dedicated Timer type.
- No tracking of a decaying maximum individual timing
- No percentile histograms
- No pre-computed percentiles
- No service level objective boundaries
- No base unit of time scaling
- Manual base unit setting
- No AutoCloseable sampling
- No record(..) convenience methods
opentelemetry has no dedicated DistributionSummary type.
- No tracking of a decaying maximum individual timing
- No percentile histograms
- No pre-computed percentiles
- No service level objective boundaries
- No sample scaling
- Manual base unit setting
opentelemetry has no naming convention normalization.
public class NamingConvention {
// automatically converted to camel when the
// registry is configured for that convention
Counter callCounter = Metrics.counter("service.calls",
"service.name", "hi");
public void call() {
callCounter.increment();
}
}
public class NamingConvention {
Meter camelRegistry = OpenTelemetry.getMeter("camel");
Meter dotRegistry = OpenTelemetry.getMeter("dot");
DoubleCounter camelCallCounter = camelRegistry
.doubleCounterBuilder("callsCount")
.setDescription("calls to something")
.setConstantLabels(Map.of("serviceName", "hi"))
.setUnit("requests")
.build();
DoubleCounter dotCallCounter = dotRegistry
.doubleCounterBuilder("calls.count")
.setDescription("calls to something")
.setConstantLabels(Map.of("service.name", "hi"))
.setUnit("requests")
.build();
public void call() {
camelCallCounter.add(1);
dotCallCounter.add(1);
}
}
opentelemetry also has no equivalent for...
- Time gauges
- Function timers
- Long task timers
- Multi-gauges
- Weak reference vs. strong reference gauges
Micrometer compared with OpenTelemetry
By Jon Schneider
Micrometer compared with OpenTelemetry
- 4,444