Merge "Cache in metric registry"

This commit is contained in:
David Pursehouse
2015-11-13 18:50:14 +00:00
committed by Gerrit Code Review
6 changed files with 107 additions and 6 deletions

View File

@@ -24,4 +24,5 @@ import com.google.gerrit.extensions.registration.RegistrationHandle;
* @param <V> type of the metric value, typically Integer or Long.
*/
public interface CallbackMetric<V> extends RegistrationHandle {
public void prune();
}

View File

@@ -37,4 +37,7 @@ public abstract class CallbackMetric0<V> implements CallbackMetric<V> {
* @param value current value.
*/
public abstract void set(V value);
@Override
public void prune() {}
}

View File

@@ -33,6 +33,7 @@ public abstract class CallbackMetric1<F1, V> implements CallbackMetric<V> {
public abstract void forceCreate(F1 field1);
/** Prune any submetrics that were not assigned during this trigger. */
@Override
public void prune() {
}
}

View File

@@ -46,6 +46,7 @@ import com.google.gerrit.metrics.Timer2;
import com.google.gerrit.metrics.Timer3;
import com.google.gerrit.metrics.proc.JGitMetricModule;
import com.google.gerrit.metrics.proc.ProcMetricModule;
import com.google.gerrit.server.cache.CacheMetrics;
import com.google.inject.Inject;
import com.google.inject.Scopes;
import com.google.inject.Singleton;
@@ -75,6 +76,7 @@ public class DropWizardMetricMaker extends MetricMaker {
install(new ProcMetricModule());
install(new JGitMetricModule());
bind(CacheMetrics.class);
}
}

View File

@@ -0,0 +1,90 @@
package com.google.gerrit.server.cache;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheStats;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.metrics.CallbackMetric;
import com.google.gerrit.metrics.CallbackMetric1;
import com.google.gerrit.metrics.Description;
import com.google.gerrit.metrics.Field;
import com.google.gerrit.metrics.MetricMaker;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.util.Set;
@Singleton
public class CacheMetrics {
private static final Field<String> F_NAME = Field.ofString("cache_name");
@Inject
public CacheMetrics(MetricMaker metrics,
final DynamicMap<Cache<?, ?>> cacheMap) {
final CallbackMetric1<String, Long> memEnt =
metrics.newCallbackMetric("caches/memory_cached", Long.class,
new Description("Memory entries").setGauge().setUnit("entries"),
F_NAME);
final CallbackMetric1<String, Double> memHit =
metrics.newCallbackMetric("caches/memory_hit_ratio", Double.class,
new Description("Memory hit ratio").setGauge().setUnit("percent"),
F_NAME);
final CallbackMetric1<String, Long> memEvict =
metrics.newCallbackMetric("caches/memory_eviction_count", Long.class,
new Description("Memory eviction count").setGauge()
.setUnit("evicted entries"),
F_NAME);
final CallbackMetric1<String, Long> perDiskEnt =
metrics.newCallbackMetric("caches/disk_cached", Long.class,
new Description("Disk entries used by persistent cache").setGauge()
.setUnit("entries"),
F_NAME);
final CallbackMetric1<String, Double> perDiskHit =
metrics.newCallbackMetric("caches/disk_hit_ratio", Double.class,
new Description("Disk hit ratio for persistent cache").setGauge()
.setUnit("percent"),
F_NAME);
final Set<CallbackMetric<?>> cacheMetrics =
ImmutableSet.<CallbackMetric<?>> of(memEnt, memHit, memEvict,
perDiskEnt, perDiskHit);
metrics.newTrigger(cacheMetrics, new Runnable() {
@Override
public void run() {
for (DynamicMap.Entry<Cache<?, ?>> e : cacheMap) {
Cache<?, ?> c = e.getProvider().get();
String name = metricNameOf(e);
CacheStats cstats = c.stats();
memEnt.set(name, c.size());
memHit.set(name, cstats.hitRate() * 100);
memEvict.set(name, cstats.evictionCount());
if (c instanceof PersistentCache) {
PersistentCache.DiskStats d = ((PersistentCache) c).diskStats();
perDiskEnt.set(name, d.size());
perDiskHit.set(name, hitRatio(d));
}
}
for (CallbackMetric<?> cbm : cacheMetrics) {
cbm.prune();
}
}
});
}
private static double hitRatio(PersistentCache.DiskStats d) {
if (d.requestCount() <= 0) {
return 100;
}
return ((double) d.hitCount() / d.requestCount() * 100);
}
private static String metricNameOf(DynamicMap.Entry<Cache<?, ?>> e) {
if ("gerrit".equals(e.getPluginName())) {
return e.getExportName();
} else {
return String.format("plugin/%s/%s", e.getPluginName(),
e.getExportName());
}
}
}

View File

@@ -58,15 +58,19 @@ public class ListCaches implements RestReadView<ConfigResource> {
this.cacheMap = cacheMap;
}
public Map<String, CacheInfo> getCacheInfos() {
Map<String, CacheInfo> cacheInfos = new TreeMap<>();
for (DynamicMap.Entry<Cache<?, ?>> e : cacheMap) {
cacheInfos.put(cacheNameOf(e.getPluginName(), e.getExportName()),
new CacheInfo(e.getProvider().get()));
}
return cacheInfos;
}
@Override
public Object apply(ConfigResource rsrc) {
if (format == null) {
Map<String, CacheInfo> cacheInfos = new TreeMap<>();
for (DynamicMap.Entry<Cache<?, ?>> e : cacheMap) {
cacheInfos.put(cacheNameOf(e.getPluginName(), e.getExportName()),
new CacheInfo(e.getProvider().get()));
}
return cacheInfos;
return getCacheInfos();
} else {
List<String> cacheNames = new ArrayList<>();
for (DynamicMap.Entry<Cache<?, ?>> e : cacheMap) {