All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.opentelemetry.contrib.metrics.micrometer.internal.PollingMeterCallbackRegistrar Maven / Gradle / Ivy

There is a newer version: 1.42.0-alpha
Show newest version
/*
 * Copyright The OpenTelemetry Authors
 * SPDX-License-Identifier: Apache-2.0
 */

package io.opentelemetry.contrib.metrics.micrometer.internal;

import io.micrometer.core.instrument.Meter;
import io.micrometer.core.instrument.MeterRegistry;
import io.opentelemetry.contrib.metrics.micrometer.CallbackRegistrar;
import io.opentelemetry.contrib.metrics.micrometer.CallbackRegistration;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Supplier;
import javax.annotation.Nullable;

/**
 * Implementation of a {@link CallbackRegistrar} that uses a Micrometer {@link Meter} to invoke the
 * callbacks when the meter is measured.
 *
 * 

This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. */ public final class PollingMeterCallbackRegistrar implements CallbackRegistrar { static final String OTEL_POLLING_METER_NAME = "otel_polling_meter"; private final Supplier meterRegistrySupplier; private final List callbacks; @Nullable private volatile Meter pollingMeter; public PollingMeterCallbackRegistrar(Supplier meterRegistrySupplier) { this.meterRegistrySupplier = meterRegistrySupplier; this.callbacks = new CopyOnWriteArrayList<>(); } private void poll() { for (Runnable callback : this.callbacks) { callback.run(); } } @Override public CallbackRegistration registerCallback(Runnable callback) { if (callback != null) { ensurePollingMeterCreated(); callbacks.add(callback); return () -> callbacks.remove(callback); } else { return () -> {}; } } private synchronized void ensurePollingMeterCreated() { if (pollingMeter == null) { pollingMeter = createPollingMeter(meterRegistrySupplier.get()); } } /** * Creates a dummy {@link Meter} which will be used to intercept when measurements are being * enumerated so that observable instruments can be polled to record their metrics. */ private Meter createPollingMeter(MeterRegistry meterRegistry) { return Meter.builder(OTEL_POLLING_METER_NAME, Meter.Type.OTHER, PollingIterable.of(this::poll)) .register(meterRegistry); } @Override public synchronized void close() { if (pollingMeter != null) { meterRegistrySupplier.get().remove(pollingMeter); pollingMeter = null; } } /** * An implementation of an {@link Iterable Iterable} that will invoke a {@link Runnable} when * it is enumerated. */ @SuppressWarnings("IterableAndIterator") private static class PollingIterable implements Iterable, Iterator { static Iterable of(Runnable callback) { return new PollingIterable<>(callback); } private final Runnable callback; public PollingIterable(Runnable callback) { this.callback = callback; } @Override public Iterator iterator() { return this; } @Override public boolean hasNext() { callback.run(); return false; } @Override public T next() { throw new NoSuchElementException(); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy