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

com.wavefront.agent.logsharvesting.EvictingMetricsRegistry Maven / Gradle / Ivy

There is a newer version: 4.36
Show newest version
package com.wavefront.agent.logsharvesting;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.CacheWriter;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.github.benmanes.caffeine.cache.RemovalCause;
import com.github.benmanes.caffeine.cache.Ticker;
import com.google.common.collect.Sets;
import com.wavefront.agent.config.MetricMatcher;
import com.yammer.metrics.core.Counter;
import com.yammer.metrics.core.DeltaCounter;
import com.yammer.metrics.core.Gauge;
import com.yammer.metrics.core.Histogram;
import com.yammer.metrics.core.Metric;
import com.yammer.metrics.core.MetricName;
import com.yammer.metrics.core.MetricsRegistry;
import com.yammer.metrics.core.WavefrontHistogram;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.function.Supplier;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/**
 * Wrapper for a Yammer {@link com.yammer.metrics.core.MetricsRegistry}, but has extra features
 * regarding automatic removal of metrics.
 *
 * 

With the introduction of Delta Counter for Yammer metrics, this class now treats Counters as * Delta Counters. So anybody using this {@link #getCounter(MetricName, MetricMatcher)} method will * get an instance of Delta counter. * * @author Mori Bellamy ([email protected]) */ public class EvictingMetricsRegistry { private final MetricsRegistry metricsRegistry; private final Cache metricCache; private final LoadingCache> metricNamesForMetricMatchers; private final boolean wavefrontHistograms; private final boolean useDeltaCounters; private final Supplier nowMillis; EvictingMetricsRegistry( MetricsRegistry metricRegistry, long expiryMillis, boolean wavefrontHistograms, boolean useDeltaCounters, Supplier nowMillis, Ticker ticker) { this.metricsRegistry = metricRegistry; this.nowMillis = nowMillis; this.wavefrontHistograms = wavefrontHistograms; this.useDeltaCounters = useDeltaCounters; this.metricCache = Caffeine.newBuilder() .expireAfterAccess(expiryMillis, TimeUnit.MILLISECONDS) .ticker(ticker) .writer( new CacheWriter() { @Override public void write(@Nonnull MetricName key, @Nonnull Metric value) {} @Override public void delete( @Nonnull MetricName key, @Nullable Metric value, @Nonnull RemovalCause cause) { if ((cause == RemovalCause.EXPIRED || cause == RemovalCause.EXPLICIT) && metricsRegistry.allMetrics().get(key) == value) { metricsRegistry.removeMetric(key); } } }) .build(); this.metricNamesForMetricMatchers = Caffeine.newBuilder().build((metricMatcher) -> Sets.newHashSet()); } public Counter getCounter(MetricName metricName, MetricMatcher metricMatcher) { if (useDeltaCounters) { // use delta counters instead of regular counters. It helps with load balancers present // in // front of proxy (PUB-125) MetricName newMetricName = DeltaCounter.getDeltaCounterMetricName(metricName); return put( newMetricName, metricMatcher, key -> DeltaCounter.get(metricsRegistry, newMetricName)); } else { return put(metricName, metricMatcher, metricsRegistry::newCounter); } } public Gauge getGauge(MetricName metricName, MetricMatcher metricMatcher) { return put( metricName, metricMatcher, key -> metricsRegistry.newGauge(key, new ChangeableGauge())); } public Histogram getHistogram(MetricName metricName, MetricMatcher metricMatcher) { return put( metricName, metricMatcher, key -> wavefrontHistograms ? WavefrontHistogram.get(metricsRegistry, key, this.nowMillis) : metricsRegistry.newHistogram(metricName, false)); } public synchronized void evict(MetricMatcher evicted) { for (MetricName toRemove : Objects.requireNonNull(metricNamesForMetricMatchers.get(evicted))) { metricCache.invalidate(toRemove); } metricNamesForMetricMatchers.invalidate(evicted); } public void cleanUp() { metricCache.cleanUp(); } @SuppressWarnings("unchecked") private M put( MetricName metricName, MetricMatcher metricMatcher, Function getter) { @Nullable Metric cached = metricCache.getIfPresent(metricName); Objects.requireNonNull(metricNamesForMetricMatchers.get(metricMatcher)).add(metricName); if (cached != null && cached == metricsRegistry.allMetrics().get(metricName)) { return (M) cached; } return (M) metricCache .asMap() .compute( metricName, (name, existing) -> { @Nullable Metric expected = metricsRegistry.allMetrics().get(name); return expected == null ? getter.apply(name) : expected; }); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy