/* * * Copyright 2017 Oleksandr Goldobin * * 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 io.github.resilience4j.prometheus; import java.util.List; import java.util.function.Supplier; import io.github.resilience4j.ratelimiter.RateLimiter; import io.github.resilience4j.ratelimiter.RateLimiterRegistry; import io.prometheus.client.Collector; import io.prometheus.client.GaugeMetricFamily; import io.vavr.collection.Array; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static java.util.Objects.requireNonNull; /** * An adapter from builtin {@link RateLimiter.Metrics} to prometheus * {@link io.prometheus.client.CollectorRegistry}. */ public class RateLimiterExports extends Collector { private static final String DEFAULT_NAME = "resilience4j_ratelimiter"; private final String name; private final Supplier<Iterable<RateLimiter>> rateLimitersSupplier; /** * Creates a new instance of {@link RateLimiterExports} with specified metrics names prefix and * {@link Supplier} of rate limiters * * @param prefix the prefix of metrics names * @param rateLimitersSupplier the supplier of rate limiters */ public static RateLimiterExports ofSupplier(String prefix, Supplier<Iterable<RateLimiter>> rateLimitersSupplier) { return new RateLimiterExports(prefix, rateLimitersSupplier); } /** * Creates a new instance of {@link RateLimiterExports} with default metrics names prefix and * {@link Supplier} of rate limiters * * @param rateLimitersSupplier the supplier of rate limiters */ public static RateLimiterExports ofSupplier(Supplier<Iterable<RateLimiter>> rateLimitersSupplier) { return new RateLimiterExports(DEFAULT_NAME, rateLimitersSupplier); } /** * Creates a new instance of {@link RateLimiterExports} with default metrics names prefix and * {@link RateLimiterRegistry} as a source of rate limiters. * @param rateLimiterRegistry the registry of rate limiters */ public static RateLimiterExports ofRateLimiterRegistry(RateLimiterRegistry rateLimiterRegistry) { return new RateLimiterExports(rateLimiterRegistry.getAllRateLimiters()); } /** * Creates a new instance of {@link RateLimiterExports} with default metrics names prefix and * a circuit breaker as a source. * * @param RateLimiter the rate limiter */ public static RateLimiterExports ofRateLimiter(RateLimiter RateLimiter) { return new RateLimiterExports(Array.of(RateLimiter)); } /** * Creates a new instance of {@link RateLimiterExports} with default metrics names prefix and * {@link Iterable} of rate limiters. * * @param RateLimiters the rate limiters */ public static RateLimiterExports ofIterable(Iterable<RateLimiter> RateLimiters) { return new RateLimiterExports(RateLimiters); } /** * Creates a new instance of {@link RateLimiterExports} with specified metrics names prefix and * {@link RateLimiterRegistry} as a source of rate limiters. * * @param prefix the prefix of metrics names * @param rateLimitersSupplier the registry of rate limiters */ public static RateLimiterExports ofRateLimiterRegistry(String prefix, RateLimiterRegistry rateLimitersSupplier) { return new RateLimiterExports(prefix, rateLimitersSupplier); } /** * Creates a new instance of {@link RateLimiterExports} with specified metrics names prefix and * {@link Iterable} of rate limiters. * * @param prefix the prefix of metrics names * @param rateLimiter the rate limiters */ public static RateLimiterExports ofIterable(String prefix, Iterable<RateLimiter> rateLimiter) { return new RateLimiterExports(prefix, rateLimiter); } /** * Creates a new instance of {@link RateLimiterExports} with default metrics names prefix and * a circuit breaker as a source. * * @param prefix the prefix of metrics names * @param RateLimiter the circuit breaker */ public static RateLimiterExports ofRateLimiter(String prefix, RateLimiter RateLimiter) { return new RateLimiterExports(prefix, Array.of(RateLimiter)); } /** * Creates a new instance of {@link RateLimiterExports} with default metric name and * {@link RateLimiterRegistry}. * * @param rateLimiterRegistry the rate limiter registry */ private RateLimiterExports(RateLimiterRegistry rateLimiterRegistry) { this(rateLimiterRegistry::getAllRateLimiters); } /** * Creates a new instance of {@link RateLimiterExports} with default metric name and * {@link Iterable} of rate limiters. * * @param rateLimiters the rate limiters */ private RateLimiterExports(Iterable<RateLimiter> rateLimiters) { this(() -> rateLimiters); } /** * Creates a new instance of {@link RateLimiterExports} with default metric name and * {@link Supplier} of rate limiters * * @param rateLimitersSupplier the supplier of rate limiters */ private RateLimiterExports(Supplier<Iterable<RateLimiter>> rateLimitersSupplier) { this(DEFAULT_NAME, rateLimitersSupplier); } /** * Creates a new instance of {@link RateLimiterExports} with specified metric name and * {@link RateLimiterRegistry}. * * @param name the name of metric * @param rateLimiterRegistry the rate limiter registry */ public RateLimiterExports(String name, RateLimiterRegistry rateLimiterRegistry) { this(name, rateLimiterRegistry::getAllRateLimiters); } /** * Creates a new instance of {@link RateLimiterExports} with specified metric name and * {@link Iterable} of rate limiters. * * @param name the name of metric * @param rateLimiters the rate limiters */ private RateLimiterExports(String name, Iterable<RateLimiter> rateLimiters) { this(name, () -> rateLimiters); } /** * Creates a new instance of {@link RateLimiterExports} with specified metric name and * {@link Supplier} of rate limiters * * @param name the name of metric * @param rateLimitersSupplier the supplier of rate limiters */ private RateLimiterExports(String name, Supplier<Iterable<RateLimiter>> rateLimitersSupplier) { requireNonNull(name); requireNonNull(rateLimitersSupplier); this.name = name; this.rateLimitersSupplier = rateLimitersSupplier; } /** * {@inheritDoc} */ @Override public List<MetricFamilySamples> collect() { final GaugeMetricFamily stats = new GaugeMetricFamily( name, "Rate Limiter Stats", asList("name", "param")); for (RateLimiter rateLimiter : rateLimitersSupplier.get()) { final RateLimiter.Metrics metrics = rateLimiter.getMetrics(); stats.addMetric( asList(rateLimiter.getName(), "available_permissions"), metrics.getAvailablePermissions()); stats.addMetric( asList(rateLimiter.getName(), "waiting_threads"), metrics.getNumberOfWaitingThreads()); } return singletonList(stats); } }