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

org.zodiac.monitor.metrics.micrometer.MeterFacade Maven / Gradle / Ivy

package org.zodiac.monitor.metrics.micrometer;

import java.lang.reflect.Constructor;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Supplier;

import org.zodiac.sdk.toolkit.util.AssertUtil;
import org.zodiac.sdk.toolkit.util.NetworkUtil;
import org.zodiac.sdk.toolkit.util.collection.CollUtil;

import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.DistributionSummary;
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.ImmutableTag;
import io.micrometer.core.instrument.Meter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.Tags;
import io.micrometer.core.instrument.Timer;
import io.micrometer.core.instrument.distribution.DistributionStatisticConfig;

/**
 * {@link MeterFacade}.
 * 
 * Counter, Timer, Gauge, DistributionSummary, etc.
 * {@link MeterRegistry}
 * 
 */
public abstract class MeterFacade {

    static final Map, Constructor> CONSTRUCTOR_MAP = CollUtil.concurrentMap(8);

    public static final String TAG_SELF_ID = "self";

    private final String serviceId;
    private final boolean secure;
    private final int port;
    private final MeterRegistry meterRegistry;
    private final LocalInstanceSpec localSpec;

    protected MeterFacade(MeterRegistry meterRegistry, String serviceId, boolean secure, int port) {
        this.meterRegistry = AssertUtil.notNullOf(meterRegistry, "meterRegistry");
        /*Replaced on 2024-02-16. START.*/
        //this.serviceId = AssertUtil.hasText(serviceId, "serviceId");
        this.serviceId = AssertUtil.notBlankOf(serviceId, "serviceId");
        /*Replaced on 2024-02-16. END.*/
        this.secure = secure;
        this.port = port;
        this.localSpec = createLocalInstanceSpec();
    }

    public String getServiceId() {
        return serviceId;
    }

    public boolean isSecure() {
        return secure;
    }

    public int getPort() {
        return port;
    }

    public MeterRegistry getMeterRegistry() {
        return meterRegistry;
    }

    public LocalInstanceSpec getLocalSpec() {
        return localSpec;
    }

    protected LocalInstanceSpec createLocalInstanceSpec() {
        String host = NetworkUtil.LOCAL_HOSTNAME;
        String instanceId = host.concat(":").concat(String.valueOf(port));
        return new LocalInstanceSpec(instanceId, serviceId, host, port, secure);
    }

    protected String[] applyDefaultTags(String... tags) {
        List _tags = CollUtil.list(tags);
        _tags.add(TAG_SELF_ID);
        _tags.add(localSpec.getInstanceId());
        return _tags.toArray(new String[0]);
    }

    //
    // --- The Meter Metrics Active Recorder. ---
    //

    // --- Counter. ---

    public Counter counter(String name, String help, String... tags) {
        return Counter.builder(name).description(help).tags(applyDefaultTags(tags)).register(meterRegistry);
    }

    // --- Gauge. ---

    public Gauge gauge(String name, String help, double number, String... tags) {
        return gauge(name, help, () -> number, tags);
    }

    public Gauge gauge(String name, String help, Supplier supplier, String... tags) {
        return Gauge.builder(name, supplier).description(help).tags(applyDefaultTags(tags)).register(meterRegistry);
    }

    // --- Timer. ---

    public Timer timer(String name, String help, double[] percentiles, String... tags) {
        return Timer.builder(name)
                .description(help)
                .tags(applyDefaultTags(tags))
                .publishPercentiles(percentiles)
                .publishPercentileHistogram()
                .register(meterRegistry);
    }

    // --- Summary. ---

    /**
     * Used default configuration refer to: {@link DistributionStatisticConfig#DEFAULT} .
     * 
     * @param name name
     * @param help help
     * @param scale scale
     * @param percentiles percentile list
     * @param tags tag list
     * @return {@link DistributionSummary}
     */
    public DistributionSummary summary(String name, String help, double scale, double[] percentiles, String... tags) {
        return DistributionSummary.builder(name)
                .description(help)
                .tags(applyDefaultTags(tags))
                .publishPercentiles(percentiles)
                .publishPercentileHistogram()
                .scale(scale)
                .register(meterRegistry);
    }

    /**
     * Used default configuration refer to: {@link DistributionStatisticConfig#DEFAULT}.
     * 
     * @param name name
     * @param help help
     * @param scale scale
     * @param tags tag list
     * @return {@link DistributionSummary}
     */
    public DistributionSummary summary(String name, String help, double scale, String... tags) {
        return DistributionSummary.builder(name)
                .description(help)
                .tags(applyDefaultTags(tags))
                .scale(scale)
                .register(meterRegistry);
    }

    public DistributionSummary summary(Meter.Id id, DistributionStatisticConfig distributionStatisticConfig, double scale) {
        List tags = CollUtil.list(id.getTags());
        tags.add(new ImmutableTag(TAG_SELF_ID, localSpec.getInstanceId()));
        Meter.Id newId = new Meter.Id(id.getName(), Tags.of(tags), id.getBaseUnit(), id.getDescription(), id.getType());
        return obtainDistributionSummary(newId, distributionStatisticConfig, scale);
    }

//    //
//    // --- The Metrics Passive Collector. ---
//    //
//
//    public GaugeMetricFamily getGauge(String name, String help, String... labelNames) {
//        MetricFamilySamples samples = sampleRegistry.get(name);
//        if (Objects.isNull(samples)) {
//            synchronized (this) {
//                samples = sampleRegistry.get(name);
//                if (Objects.isNull(samples)) {
//                    sampleRegistry.put(name, samples = new GaugeMetricFamily(name, help, Arrays.asList(labelNames)));
//                }
//            }
//        }
//        samples = new GaugeMetricFamily(name, help, Arrays.asList(labelNames));
//        return (GaugeMetricFamily) samples;
//    }
//
//    public CounterMetricFamily getCounter(String name, String help, String... labelNames) {
//        MetricFamilySamples samples = sampleRegistry.get(name);
//        if (Objects.isNull(samples)) {
//            synchronized (this) {
//                samples = sampleRegistry.get(name);
//                if (Objects.isNull(samples)) {
//                    sampleRegistry.put(name, samples = new CounterMetricFamily(name, help, Arrays.asList(labelNames)));
//                }
//            }
//        }
//        return (CounterMetricFamily) samples;
//    }
//
//    public SummaryMetricFamily getSummary(String name, String help, String... labelNames) {
//        MetricFamilySamples samples = sampleRegistry.get(name);
//        if (Objects.isNull(samples)) {
//            synchronized (this) {
//                samples = sampleRegistry.get(name);
//                if (Objects.isNull(samples)) {
//                    sampleRegistry.put(name, samples = new SummaryMetricFamily(name, help, Arrays.asList(labelNames)));
//                }
//            }
//        }
//        return (SummaryMetricFamily) samples;
//    }

    protected abstract DistributionSummary obtainDistributionSummary(Meter.Id id, DistributionStatisticConfig distributionStatisticConfig,
        double scale);

//    //
//    // --- Tools Function. ---
//    //
//
//    public static Counter newPrometheusCounter(Meter.Id id) {
//        return newConstructor(PrometheusCounter.class, new Object[] { id });
//    }
//
//    public static Timer newPrometheusTimer(Meter.Id id) {
//        return newConstructor(PrometheusTimer.class, new Object[] { id });
//    }
//
//    public static DistributionSummary newPrometheusDistributionSummary(Meter.Id id) {
//        return newConstructor(PrometheusDistributionSummary.class, new Object[] { id });
//    }

    @SuppressWarnings("unchecked")
    public static  T newConstructor(Class clazz, Object... args) {
        try {
            Constructor constructor = (Constructor) CONSTRUCTOR_MAP.get(clazz);
            if (Objects.isNull(constructor)) {
                synchronized (MeterFacade.class) {
                    if (Objects.isNull(constructor)) {
                        CONSTRUCTOR_MAP.put(clazz, constructor = getConstructor0(clazz));
                    }
                }
            }
            return (T) constructor.newInstance(args);
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }
    }

    static  Constructor getConstructor0(Class clazz) throws NoSuchMethodException, SecurityException {
        Constructor constructor = clazz.getDeclaredConstructor(Meter.Id.class);
        constructor.setAccessible(true);
        return constructor;
    }

    protected static class LocalInstanceSpec {

        private String instanceId;
        private String serviceId;
        private String host;
        private int port;
        private boolean secure;

        public LocalInstanceSpec(String instanceId, String serviceId, String host, int port, boolean secure) {
            super();
            this.instanceId = instanceId;
            this.serviceId = serviceId;
            this.host = host;
            this.port = port;
            this.secure = secure;
        }

        public String getInstanceId() {
            return instanceId;
        }

        public String getServiceId() {
            return serviceId;
        }

        public String getHost() {
            return host;
        }

        public int getPort() {
            return port;
        }

        public boolean isSecure() {
            return secure;
        }

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy