001/* 002 * (C) Copyright 2017 Nuxeo (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 */ 017package org.nuxeo.ecm.core.cache; 018 019import java.io.Serializable; 020 021import org.nuxeo.runtime.metrics.MetricsService; 022 023import io.dropwizard.metrics5.Counter; 024import io.dropwizard.metrics5.Gauge; 025import io.dropwizard.metrics5.MetricName; 026import io.dropwizard.metrics5.MetricRegistry; 027import io.dropwizard.metrics5.RatioGauge; 028import io.dropwizard.metrics5.SharedMetricRegistries; 029 030public class CacheMetrics extends CacheWrapper { 031 032 protected MetricRegistry registry; 033 034 protected Counter read; 035 036 protected Counter read_hit; 037 038 protected Counter read_miss; 039 040 protected RatioGauge read_hit_ratio; 041 042 protected Counter write; 043 044 protected Counter invalidation; 045 046 protected Gauge<Long> size; 047 048 protected final MetricName READ_HIT_NAME = nameOf("hit"); 049 050 protected final MetricName READ_HIT_RATIO_NAME = nameOf("hit.ratio"); 051 052 protected final MetricName READ_MISS_NAME = nameOf("miss"); 053 054 protected final MetricName READ_NAME = nameOf("read"); 055 056 protected final MetricName WRITE_NAME = nameOf("write"); 057 058 protected final MetricName INVALIDATE_ALL_NAME = nameOf("invalidation"); 059 060 protected final MetricName SIZE_NAME = nameOf("size"); 061 062 protected MetricName nameOf(String name) { 063 return MetricName.build("nuxeo", "cache", name).tagged("cache", getName()); 064 } 065 066 public CacheMetrics(CacheManagement cache) { 067 super(cache); 068 } 069 070 @Override 071 public void start() { 072 registry = SharedMetricRegistries.getOrCreate(MetricsService.class.getName()); 073 read = registry.counter(READ_NAME); 074 read_hit = registry.counter(READ_HIT_NAME); 075 read_miss = registry.counter(READ_MISS_NAME); 076 registry.register(READ_HIT_RATIO_NAME, read_hit_ratio = new RatioGauge() { 077 078 @Override 079 protected Ratio getRatio() { 080 Ratio ratio = Ratio.of(read_hit.getCount(), read.getCount()); 081 return ratio; 082 } 083 }); 084 write = registry.counter(WRITE_NAME); 085 invalidation = registry.counter(INVALIDATE_ALL_NAME); 086 registry.register(SIZE_NAME, size = new Gauge<Long>() { 087 088 @Override 089 public Long getValue() { 090 return Long.valueOf(getSize()); 091 } 092 }); 093 } 094 095 @Override 096 public void stop() { 097 registry.remove(READ_NAME); 098 registry.remove(READ_HIT_NAME); 099 registry.remove(READ_MISS_NAME); 100 registry.remove(READ_HIT_RATIO_NAME); 101 registry.remove(WRITE_NAME); 102 registry.remove(INVALIDATE_ALL_NAME); 103 registry.remove(SIZE_NAME); 104 } 105 106 @Override 107 public Serializable get(String key) { 108 Serializable value = super.get(key); 109 read.inc(); 110 if (value != null || super.hasEntry(key)) { 111 read_hit.inc(); 112 } else { 113 read_miss.inc(); 114 } 115 return value; 116 } 117 118 @Override 119 public void put(String key, Serializable value) { 120 try { 121 super.put(key, value); 122 } finally { 123 write.inc(); 124 } 125 } 126 127 @Override 128 public void invalidateAll() { 129 try { 130 super.invalidateAll(); 131 } finally { 132 invalidation.inc(); 133 } 134 } 135 136}