DescriptionWith the cache event handlers a listerner can be implemented to provide cache hits and misses information. You can copy and paste the following code to get a statistic of your OSCache integration. Just change the used logger and the sample helps you to improve the cache key creation and to decide which scope to use. Sample CodeStatisticListenerImpl.java /* * Copyright (c) 2002-2005 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.extra; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.opensymphony.oscache.base.Cache; import com.opensymphony.oscache.base.events.*; /** * A simple implementation of a statistic reporter which uses the * CacheMapAccessEventListener, CacheEntryEventListener and ScopeEventListener. * It uses the events to count the cache hit and misses and of course the * flushes. * <p> * We are not using any synchronized so that this does not become a bottleneck. * The consequence is that on retrieving values, the operations that are * currently being done won't be counted. */ public class StatisticListenerImpl implements CacheMapAccessEventListener, CacheEntryEventListener, ScopeEventListener { private static transient final Log log = LogFactory.getLog(StatisticListenerImpl.class); /** * Hit counter */ private int hitCount = 0; /** * Miss counter */ private int missCount = 0; /** * Stale hit counter */ private int staleHitCount = 0; /** * Hit counter sum */ private int hitCountSum = 0; /** * Miss counter sum */ private int missCountSum = 0; /** * Stale hit counter */ private int staleHitCountSum = 0; /** * Flush hit counter */ private int flushCount = 0; /** * Constructor, empty for us */ public StatisticListenerImpl() { log.info("Creation of StatisticListenerImpl"); } /** * This method handles an event each time the cache is accessed * * @param event The event triggered when the cache was accessed * @see com.opensymphony.oscache.base.events.CacheMapAccessEventListener#accessed(CacheMapAccessEvent) */ public void accessed(CacheMapAccessEvent event) { String result = "N/A"; // Retrieve the event type and update the counters CacheMapAccessEventType type = event.getEventType(); // Handles a hit event if (type == CacheMapAccessEventType.HIT) { hitCount++; result = "HIT"; } // Handles a stale hit event else if (type == CacheMapAccessEventType.STALE_HIT) { staleHitCount++; result = "STALE HIT"; } // Handles a miss event else if (type == CacheMapAccessEventType.MISS) { missCount++; result = "MISS"; } if (log.isDebugEnabled()) { log.debug("ACCESS : " + result + ": " + event.getCacheEntryKey()); log.debug("STATISTIC : Hit = " + hitCount + ", stale hit =" + staleHitCount + ", miss = " + missCount); } } /** * Logs the flush of the cache. * * @param info the string to be logged. */ private void flushed(String info) { flushCount++; hitCountSum += hitCount; staleHitCountSum += staleHitCount; missCountSum += missCount; if (log.isInfoEnabled()) { log.info("FLUSH : " + info); log.info("STATISTIC SUM : " + "Hit = " + hitCountSum + ", stale hit = " + staleHitCountSum + ", miss = " + missCountSum + ", flush = " + flushCount); } hitCount = 0; staleHitCount = 0; missCount = 0; } /** * Event fired when a specific or all scopes are flushed. * * @param event ScopeEvent * @see com.opensymphony.oscache.base.events.ScopeEventListener#scopeFlushed(ScopeEvent) */ public void scopeFlushed(ScopeEvent event) { flushed("scope " + ScopeEventListenerImpl.SCOPE_NAMES[event.getScope()]); } /** * Event fired when an entry is added to the cache. * * @param event CacheEntryEvent * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cacheEntryAdded(CacheEntryEvent) */ public void cacheEntryAdded(CacheEntryEvent event) { // do nothing } /** * Event fired when an entry is flushed from the cache. * * @param event CacheEntryEvent * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cacheEntryFlushed(CacheEntryEvent) */ public void cacheEntryFlushed(CacheEntryEvent event) { // do nothing, because a group or other flush is coming if (!Cache.NESTED_EVENT.equals(event.getOrigin())) { flushed("entry " + event.getKey() + " / " + event.getOrigin()); } } /** * Event fired when an entry is removed from the cache. * * @param event CacheEntryEvent * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cacheEntryRemoved(CacheEntryEvent) */ public void cacheEntryRemoved(CacheEntryEvent event) { // do nothing } /** * Event fired when an entry is updated in the cache. * * @param event CacheEntryEvent * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cacheEntryUpdated(CacheEntryEvent) */ public void cacheEntryUpdated(CacheEntryEvent event) { // do nothing } /** * Event fired when a group is flushed from the cache. * * @param event CacheGroupEvent * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cacheGroupFlushed(CacheGroupEvent) */ public void cacheGroupFlushed(CacheGroupEvent event) { flushed("group " + event.getGroup()); } /** * Event fired when a key pattern is flushed from the cache. * * @param event CachePatternEvent * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cachePatternFlushed(CachePatternEvent) */ public void cachePatternFlushed(CachePatternEvent event) { flushed("pattern " + event.getPattern()); } /** * An event that is fired when an entire cache gets flushed. * * @param event CachewideEvent * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cacheFlushed(CachewideEvent) */ public void cacheFlushed(CachewideEvent event) { flushed("wide " + event.getDate()); } /** * Return the counters in a string form * * @return String */ public String toString() { return "StatisticListenerImpl: Hit = " + hitCount + " / " + hitCountSum + + ", stale hit = " + staleHitCount + " / " + staleHitCountSum + ", miss = " + missCount + " / " + missCountSum + ", flush = " + flushCount; } } |