| // Copyright (C) 2015 The Android Open Source Project | |
| // | |
| // 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 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.extensions.registration.Extension; | |
| import com.google.gerrit.extensions.registration.PluginName; | |
| 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.gerrit.server.config.GerritServerConfig; | |
| import com.google.gerrit.server.logging.Metadata; | |
| import com.google.inject.Inject; | |
| import com.google.inject.Singleton; | |
| import java.util.Set; | |
| import org.eclipse.jgit.lib.Config; | |
| @Singleton | |
| public class CacheMetrics { | |
| private static final Field<String> F_NAME = | |
| Field.ofString("cache_name", Metadata.Builder::cacheName) | |
| .description("The name of the cache.") | |
| .build(); | |
| @Inject | |
| public CacheMetrics( | |
| MetricMaker metrics, DynamicMap<Cache<?, ?>> cacheMap, @GerritServerConfig Config config) { | |
| CallbackMetric1<String, Long> memEnt = | |
| metrics.newCallbackMetric( | |
| "caches/memory_cached", | |
| Long.class, | |
| new Description("Memory entries").setGauge().setUnit("entries"), | |
| F_NAME); | |
| CallbackMetric1<String, Double> memHit = | |
| metrics.newCallbackMetric( | |
| "caches/memory_hit_ratio", | |
| Double.class, | |
| new Description("Memory hit ratio").setGauge().setUnit("percent"), | |
| F_NAME); | |
| CallbackMetric1<String, Long> memEvict = | |
| metrics.newCallbackMetric( | |
| "caches/memory_eviction_count", | |
| Long.class, | |
| new Description("Memory eviction count").setGauge().setUnit("evicted entries"), | |
| F_NAME); | |
| CallbackMetric1<String, Long> perDiskEnt = | |
| metrics.newCallbackMetric( | |
| "caches/disk_cached", | |
| Long.class, | |
| new Description("Disk entries used by persistent cache").setGauge().setUnit("entries"), | |
| F_NAME); | |
| 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); | |
| Set<CallbackMetric<?>> cacheMetrics = | |
| ImmutableSet.of(memEnt, memHit, memEvict, perDiskEnt, perDiskHit); | |
| metrics.newTrigger( | |
| cacheMetrics, | |
| () -> { | |
| for (Extension<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 | |
| && config.getBoolean("cache", "enableDiskStatMetrics", false)) { | |
| PersistentCache.DiskStats d = ((PersistentCache) c).diskStats(); | |
| perDiskEnt.set(name, d.size()); | |
| perDiskHit.set(name, hitRatio(d)); | |
| } | |
| } | |
| cacheMetrics.forEach(CallbackMetric::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(Extension<Cache<?, ?>> e) { | |
| if (PluginName.GERRIT.equals(e.getPluginName())) { | |
| return e.getExportName(); | |
| } | |
| return String.format("plugin/%s/%s", e.getPluginName(), e.getExportName()); | |
| } | |
| } |