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 com.codahale.metrics.Counter; 024import com.codahale.metrics.Gauge; 025import com.codahale.metrics.MetricRegistry; 026import com.codahale.metrics.RatioGauge; 027import com.codahale.metrics.SharedMetricRegistries; 028 029public class CacheMetrics extends CacheWrapper { 030 031 protected final MetricRegistry registry; 032 033 protected final Counter read; 034 035 protected final Counter read_hit; 036 037 protected final Counter read_miss; 038 039 protected final RatioGauge read_hit_ratio; 040 041 protected final Counter write; 042 043 protected final Counter invalidation; 044 045 protected final Gauge<Long> size; 046 047 protected final String READ_HIT_NAME = nameOf("read-hit-counter"); 048 049 protected final String READ_HIT_RATIO_NAME = nameOf("read-hit-ratio"); 050 051 protected final String READ_MISS_NAME = nameOf("read-miss-counter"); 052 053 protected final String READ_NAME = nameOf("read-counter"); 054 055 protected final String WRITE_NAME = nameOf("write-counter"); 056 057 protected final String INVALIDATE_ALL_NAME = nameOf("invalidate-all-counter"); 058 059 protected final String SIZE_NAME = nameOf("size"); 060 061 public CacheMetrics(Cache cache) { 062 super(cache); 063 registry = SharedMetricRegistries.getOrCreate(MetricsService.class.getName()); 064 read = registry.counter(READ_NAME); 065 read_hit = registry.counter(READ_HIT_NAME); 066 read_miss = registry.counter(READ_MISS_NAME); 067 registry.register(READ_HIT_RATIO_NAME, read_hit_ratio = new RatioGauge() { 068 069 @Override 070 protected Ratio getRatio() { 071 Ratio ratio = Ratio.of(read_hit.getCount(), read.getCount()); 072 return ratio; 073 } 074 }); 075 write = registry.counter(WRITE_NAME); 076 invalidation = registry.counter(INVALIDATE_ALL_NAME); 077 registry.register(SIZE_NAME, size = new Gauge<Long>() { 078 079 @Override 080 public Long getValue() { 081 return Long.valueOf(cache.getSize()); 082 } 083 084 }); 085 } 086 087 protected String nameOf(String name) { 088 return MetricRegistry.name("nuxeo", "cache", cache.getName(), name); 089 } 090 091 @Override 092 protected void onStop() { 093 registry.remove(READ_NAME); 094 registry.remove(READ_HIT_NAME); 095 registry.remove(READ_HIT_RATIO_NAME); 096 registry.remove(READ_MISS_NAME); 097 registry.remove(WRITE_NAME); 098 registry.remove(INVALIDATE_ALL_NAME); 099 registry.remove(SIZE_NAME); 100 } 101 102 @Override 103 public Serializable get(String key) { 104 Serializable value = cache.get(key); 105 read.inc(); 106 if (value != null || cache.hasEntry(key)) { 107 read_hit.inc(); 108 } else { 109 read_miss.inc(); 110 } 111 return value; 112 } 113 114 @Override 115 public void put(String key, Serializable value) { 116 try { 117 super.put(key, value); 118 } finally { 119 write.inc(); 120 } 121 } 122 123 @Override 124 public void invalidate(String key) { 125 cache.invalidate(key); 126 } 127 128 @Override 129 public void invalidateAll() { 130 try { 131 cache.invalidateAll(); 132 } finally { 133 invalidation.inc(); 134 } 135 } 136 137 @Override 138 public long getSize() { 139 return cache.getSize(); 140 } 141 142}