Line data Source code
1 : // Copyright (C) 2015 The Android Open Source Project 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // 7 : // http://www.apache.org/licenses/LICENSE-2.0 8 : // 9 : // Unless required by applicable law or agreed to in writing, software 10 : // distributed under the License is distributed on an "AS IS" BASIS, 11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : // See the License for the specific language governing permissions and 13 : // limitations under the License. 14 : 15 : package com.google.gerrit.server.cache; 16 : 17 : import com.google.common.cache.Cache; 18 : import com.google.common.cache.CacheStats; 19 : import com.google.common.collect.ImmutableSet; 20 : import com.google.gerrit.extensions.registration.DynamicMap; 21 : import com.google.gerrit.extensions.registration.Extension; 22 : import com.google.gerrit.extensions.registration.PluginName; 23 : import com.google.gerrit.metrics.CallbackMetric; 24 : import com.google.gerrit.metrics.CallbackMetric1; 25 : import com.google.gerrit.metrics.Description; 26 : import com.google.gerrit.metrics.Field; 27 : import com.google.gerrit.metrics.MetricMaker; 28 : import com.google.gerrit.server.config.GerritServerConfig; 29 : import com.google.gerrit.server.logging.Metadata; 30 : import com.google.inject.Inject; 31 : import com.google.inject.Singleton; 32 : import java.util.Set; 33 : import org.eclipse.jgit.lib.Config; 34 : 35 : @Singleton 36 : public class CacheMetrics { 37 138 : private static final Field<String> F_NAME = 38 138 : Field.ofString("cache_name", Metadata.Builder::cacheName) 39 138 : .description("The name of the cache.") 40 138 : .build(); 41 : 42 : @Inject 43 : public CacheMetrics( 44 138 : MetricMaker metrics, DynamicMap<Cache<?, ?>> cacheMap, @GerritServerConfig Config config) { 45 138 : CallbackMetric1<String, Long> memEnt = 46 138 : metrics.newCallbackMetric( 47 : "caches/memory_cached", 48 : Long.class, 49 138 : new Description("Memory entries").setGauge().setUnit("entries"), 50 : F_NAME); 51 138 : CallbackMetric1<String, Double> memHit = 52 138 : metrics.newCallbackMetric( 53 : "caches/memory_hit_ratio", 54 : Double.class, 55 138 : new Description("Memory hit ratio").setGauge().setUnit("percent"), 56 : F_NAME); 57 138 : CallbackMetric1<String, Long> memEvict = 58 138 : metrics.newCallbackMetric( 59 : "caches/memory_eviction_count", 60 : Long.class, 61 138 : new Description("Memory eviction count").setGauge().setUnit("evicted entries"), 62 : F_NAME); 63 138 : CallbackMetric1<String, Long> perDiskEnt = 64 138 : metrics.newCallbackMetric( 65 : "caches/disk_cached", 66 : Long.class, 67 138 : new Description("Disk entries used by persistent cache").setGauge().setUnit("entries"), 68 : F_NAME); 69 138 : CallbackMetric1<String, Double> perDiskHit = 70 138 : metrics.newCallbackMetric( 71 : "caches/disk_hit_ratio", 72 : Double.class, 73 138 : new Description("Disk hit ratio for persistent cache").setGauge().setUnit("percent"), 74 : F_NAME); 75 : 76 138 : Set<CallbackMetric<?>> cacheMetrics = 77 138 : ImmutableSet.of(memEnt, memHit, memEvict, perDiskEnt, perDiskHit); 78 : 79 138 : metrics.newTrigger( 80 : cacheMetrics, 81 : () -> { 82 15 : for (Extension<Cache<?, ?>> e : cacheMap) { 83 15 : Cache<?, ?> c = e.getProvider().get(); 84 15 : String name = metricNameOf(e); 85 15 : CacheStats cstats = c.stats(); 86 15 : memEnt.set(name, c.size()); 87 15 : memHit.set(name, cstats.hitRate() * 100); 88 15 : memEvict.set(name, cstats.evictionCount()); 89 15 : if (c instanceof PersistentCache 90 15 : && config.getBoolean("cache", "enableDiskStatMetrics", false)) { 91 0 : PersistentCache.DiskStats d = ((PersistentCache) c).diskStats(); 92 0 : perDiskEnt.set(name, d.size()); 93 0 : perDiskHit.set(name, hitRatio(d)); 94 : } 95 15 : } 96 15 : cacheMetrics.forEach(CallbackMetric::prune); 97 15 : }); 98 138 : } 99 : 100 : private static double hitRatio(PersistentCache.DiskStats d) { 101 0 : if (d.requestCount() <= 0) { 102 0 : return 100; 103 : } 104 0 : return ((double) d.hitCount() / d.requestCount() * 100); 105 : } 106 : 107 : private static String metricNameOf(Extension<Cache<?, ?>> e) { 108 15 : if (PluginName.GERRIT.equals(e.getPluginName())) { 109 15 : return e.getExportName(); 110 : } 111 0 : return String.format("plugin/%s/%s", e.getPluginName(), e.getExportName()); 112 : } 113 : }