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,989
