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

ru.jts.spring.clickhouse.metrics.ClickHouseMeterRegistry Maven / Gradle / Ivy

/*
 * Copyright 2017 JTS-Team
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package ru.jts.spring.clickhouse.metrics;

import org.springframework.metrics.instrument.*;
import org.springframework.metrics.instrument.Timer;
import org.springframework.metrics.instrument.internal.AbstractMeterRegistry;
import org.springframework.metrics.instrument.internal.MapAccess;
import org.springframework.metrics.instrument.internal.MeterId;
import org.springframework.metrics.instrument.stats.hist.Histogram;
import org.springframework.metrics.instrument.stats.quantile.Quantiles;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.ToDoubleFunction;

import static org.springframework.metrics.instrument.internal.MapAccess.computeIfAbsent;

/**
 * @author Camelion
 * @since 27.06.17
 */
public class ClickHouseMeterRegistry extends AbstractMeterRegistry {
    private ConcurrentMap meterMap = new ConcurrentHashMap<>();

    public ClickHouseMeterRegistry(Clock clock) {
        super(clock);
    }

    @Override
    public Collection getMeters() {
        return meterMap.values();
    }

    @Override
    public  Optional findMeter(Class mClass, String name, Iterable tags) {
        Collection tagsToMatch = new ArrayList<>();
        tags.forEach(tagsToMatch::add);

        return meterMap.keySet().stream()
                .filter(id -> id.getName().equals(name))
                .filter(id -> id.getTags().containsAll(tagsToMatch))
                .findAny()
                .map(meterMap::get)
                .filter(mClass::isInstance)
                .map(mClass::cast);
    }

    @Override
    public Optional findMeter(Meter.Type type, String name, Iterable tags) {
        Collection tagsToMatch = new ArrayList<>();
        tags.forEach(tagsToMatch::add);

        return meterMap.keySet().stream()
                .filter(id -> id.getName().equals(name))
                .filter(id -> id.getTags().containsAll(tagsToMatch))
                .findAny()
                .map(meterMap::get)
                .filter(m -> m.getType().equals(type));
    }

    @Override
    public Counter counter(String name, Iterable tags) {
        MeterId meterId = new MeterId(name, tags);
        return MapAccess.computeIfAbsent(meterMap, meterId, ClickHouseCounter::new);
    }

    @Override
    public LongTaskTimer longTaskTimer(String name, Iterable tags) {
        return computeIfAbsent(meterMap, new MeterId(name, tags), id -> new ClickHouseLongTaskTimer(id, getClock()));
    }

    @Override
    public MeterRegistry register(Meter meter) {
        meterMap.put(new MeterId(meter.getName(), meter.getTags()), meter);
        return this;
    }

    @Override
    public  T gauge(String name, Iterable tags, T obj, ToDoubleFunction f) {
        computeIfAbsent(meterMap, new MeterId(name, tags), id -> new ClickHouseGauge<>(id, obj, f));
        return obj;
    }

    @Override
    protected Timer timer(String name, Iterable tags, Quantiles quantiles, Histogram histogram) {
        registerQuantilesGaugeIfNecessary(name, tags, quantiles);
        registerHistogramCounterIfNecessary(name, tags, histogram);
        return computeIfAbsent(meterMap, new MeterId(name, tags), id -> new ClickHouseTimer(id, getClock()));
    }

    @Override
    protected DistributionSummary distributionSummary(String name, Iterable tags, Quantiles quantiles, Histogram histogram) {
        registerQuantilesGaugeIfNecessary(name, tags, quantiles);
        registerHistogramCounterIfNecessary(name, tags, histogram);
        return computeIfAbsent(meterMap, new MeterId(name, tags), ClickHouseDistributionSummary::new);
    }

    private void registerQuantilesGaugeIfNecessary(String name, Iterable tags, Quantiles quantiles) {
        if (quantiles != null) {
            for (Double q : quantiles.monitored()) {
                List quantileTags = new LinkedList<>();
                tags.forEach(quantileTags::add);

                quantileTags.add(Tag.of("quantile", Double.isNaN(q) ? "NaN" : Double.toString(q)));
                quantileTags.add(Tag.of("statistic", "quantile"));

                computeIfAbsent(meterMap, new MeterId(name + ".quantiles", quantileTags),
                        id -> new ClickHouseGauge<>(id, q, quantiles::get));
            }
        }
    }

    private void registerHistogramCounterIfNecessary(String name, Iterable tags, Histogram histogram) {
        if (histogram != null) {
            computeIfAbsent(meterMap, new MeterId(name + ".histogram", tags),
                    id -> new ClickHouseHistogram(id, histogram));
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy