1 /***
2 * Copyright 2003-2010 Terracotta, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package net.sf.ehcache.hibernate.management.impl;
18
19 import java.util.ArrayList;
20 import java.util.HashMap;
21 import java.util.Map;
22
23 import javax.management.MBeanNotificationInfo;
24 import javax.management.NotCompliantMBeanException;
25 import javax.management.Notification;
26
27 import net.sf.ehcache.Cache;
28 import net.sf.ehcache.CacheManager;
29 import net.sf.ehcache.hibernate.management.api.EhcacheStats;
30 import net.sf.ehcache.management.sampled.SampledCacheManager;
31
32 /***
33 * Implementation of {@link EhcacheStats}
34 *
35 * <p />
36 *
37 * @author <a href="mailto:asanoujam@terracottatech.com">Abhishek Sanoujam</a>
38 *
39 */
40 public class EhcacheStatsImpl extends BaseEmitterBean implements EhcacheStats {
41 private static final long MILLIS_PER_SECOND = 1000;
42 private static final MBeanNotificationInfo NOTIFICATION_INFO;
43
44 private final SampledCacheManager sampledCacheManager;
45 private final CacheManager cacheManager;
46 private long statsSince = System.currentTimeMillis();
47
48 static {
49 final String[] notifTypes = new String[] {CACHE_ENABLED, CACHE_REGION_CHANGED, CACHE_FLUSHED, CACHE_REGION_FLUSHED,
50 CACHE_STATISTICS_ENABLED, CACHE_STATISTICS_RESET, };
51 final String name = Notification.class.getName();
52 final String description = "Ehcache Hibernate Statistics Event";
53 NOTIFICATION_INFO = new MBeanNotificationInfo(notifTypes, name, description);
54 }
55
56 /***
57 * Constructor accepting the backing {@link CacheManager}
58 * @throws NotCompliantMBeanException
59 */
60 public EhcacheStatsImpl(CacheManager manager) throws NotCompliantMBeanException {
61 super(EhcacheStats.class);
62 this.sampledCacheManager = new SampledCacheManager(manager);
63 this.cacheManager = manager;
64 }
65
66 /***
67 * {@inheritDoc}
68 */
69 public boolean isStatisticsEnabled() {
70 return false;
71 }
72
73 /***
74 * {@inheritDoc}
75 */
76 public void clearStats() {
77 sampledCacheManager.clearStatistics();
78 statsSince = System.currentTimeMillis();
79 }
80
81 /***
82 * {@inheritDoc}
83 */
84 public void disableStats() {
85 setStatisticsEnabled(false);
86 }
87
88 /***
89 * {@inheritDoc}
90 */
91 public void enableStats() {
92 setStatisticsEnabled(true);
93 }
94
95 /***
96 * {@inheritDoc}
97 */
98 public void flushRegionCache(String region) {
99 Cache cache = this.cacheManager.getCache(region);
100 if (cache != null) {
101 cache.flush();
102 }
103 }
104
105 /***
106 * {@inheritDoc}
107 */
108 public void flushRegionCaches() {
109 for (String name : cacheManager.getCacheNames()) {
110 Cache cache = this.cacheManager.getCache(name);
111 if (cache != null) {
112 cache.flush();
113 }
114 }
115
116 }
117
118 /***
119 * {@inheritDoc}
120 */
121 public String generateActiveConfigDeclaration() {
122 return this.cacheManager.getActiveConfigurationText();
123 }
124
125 /***
126 * {@inheritDoc}
127 */
128 public String generateActiveConfigDeclaration(String region) {
129 return this.cacheManager.getActiveConfigurationText(region);
130 }
131
132 /***
133 * {@inheritDoc}
134 */
135 public long getCacheHitCount() {
136 long count = 0;
137 for (String name : cacheManager.getCacheNames()) {
138 Cache cache = cacheManager.getCache(name);
139 if (cache != null) {
140 count += cache.getLiveCacheStatistics().getCacheHitCount();
141 }
142 }
143 return count;
144 }
145
146 /***
147 * {@inheritDoc}
148 */
149 public double getCacheHitRate() {
150 long now = System.currentTimeMillis();
151 double deltaSecs = (double) (now - statsSince) / MILLIS_PER_SECOND;
152 return getCacheHitCount() / deltaSecs;
153 }
154
155 /***
156 * {@inheritDoc}
157 */
158 public long getCacheHitSample() {
159 long count = 0;
160 for (String name : cacheManager.getCacheNames()) {
161 Cache cache = cacheManager.getCache(name);
162 if (cache != null) {
163 count += cache.getSampledCacheStatistics().getCacheHitMostRecentSample();
164 }
165 }
166 return count;
167 }
168
169 /***
170 * {@inheritDoc}
171 */
172 public long getCacheMissCount() {
173 long count = 0;
174 for (String name : cacheManager.getCacheNames()) {
175 Cache cache = cacheManager.getCache(name);
176 if (cache != null) {
177 count += cache.getLiveCacheStatistics().getCacheMissCount();
178 }
179 }
180 return count;
181 }
182
183 /***
184 * {@inheritDoc}
185 */
186 public double getCacheMissRate() {
187 long now = System.currentTimeMillis();
188 double deltaSecs = (double) (now - statsSince) / MILLIS_PER_SECOND;
189 return getCacheMissCount() / deltaSecs;
190 }
191
192 /***
193 * {@inheritDoc}
194 */
195 public long getCacheMissSample() {
196 long count = 0;
197 for (String name : cacheManager.getCacheNames()) {
198 Cache cache = cacheManager.getCache(name);
199 if (cache != null) {
200 count += cache.getSampledCacheStatistics().getCacheMissMostRecentSample();
201 }
202 }
203 return count;
204 }
205
206 /***
207 * {@inheritDoc}
208 */
209 public long getCachePutCount() {
210 long count = 0;
211 for (String name : cacheManager.getCacheNames()) {
212 Cache cache = cacheManager.getCache(name);
213 if (cache != null) {
214 count += cache.getLiveCacheStatistics().getPutCount();
215 }
216 }
217 return count;
218 }
219
220 /***
221 * {@inheritDoc}
222 */
223 public double getCachePutRate() {
224 long now = System.currentTimeMillis();
225 double deltaSecs = (double) (now - statsSince) / MILLIS_PER_SECOND;
226 return getCachePutCount() / deltaSecs;
227 }
228
229 /***
230 * {@inheritDoc}
231 */
232 public long getCachePutSample() {
233 long count = 0;
234 for (String name : cacheManager.getCacheNames()) {
235 Cache cache = cacheManager.getCache(name);
236 if (cache != null) {
237 count += cache.getSampledCacheStatistics().getCacheElementPutMostRecentSample();
238 }
239 }
240 return count;
241 }
242
243 /***
244 * {@inheritDoc}
245 */
246 public String getOriginalConfigDeclaration() {
247 return this.cacheManager.getOriginalConfigurationText();
248 }
249
250 /***
251 * {@inheritDoc}
252 */
253 public String getOriginalConfigDeclaration(String region) {
254 return this.cacheManager.getOriginalConfigurationText(region);
255 }
256
257 /***
258 * {@inheritDoc}
259 */
260 public Map<String, Map<String, Object>> getRegionCacheAttributes() {
261 Map<String, Map<String, Object>> result = new HashMap<String, Map<String, Object>>();
262 for (String regionName : this.cacheManager.getCacheNames()) {
263 result.put(regionName, getRegionCacheAttributes(regionName));
264 }
265 return result;
266 }
267
268 /***
269 * {@inheritDoc}
270 */
271 public Map<String, Object> getRegionCacheAttributes(String regionName) {
272 Map<String, Object> result = new HashMap<String, Object>();
273 result.put("Enabled", isRegionCacheEnabled(regionName));
274 result.put("LoggingEnabled", isRegionCacheLoggingEnabled(regionName));
275 result.put("MaxTTISeconds", getRegionCacheMaxTTISeconds(regionName));
276 result.put("MaxTTLSeconds", getRegionCacheMaxTTLSeconds(regionName));
277 result.put("TargetMaxInMemoryCount", getRegionCacheTargetMaxInMemoryCount(regionName));
278 result.put("TargetMaxTotalCount", getRegionCacheTargetMaxTotalCount(regionName));
279 result.put("OrphanEvictionEnabled", isRegionCacheOrphanEvictionEnabled(regionName));
280 result.put("OrphanEvictionPeriod", getRegionCacheOrphanEvictionPeriod(regionName));
281 return result;
282 }
283
284 /***
285 * {@inheritDoc}
286 */
287 public int getRegionCacheMaxTTISeconds(String region) {
288 Cache cache = cacheManager.getCache(region);
289 if (cache != null) {
290 return (int) cache.getCacheConfiguration().getTimeToIdleSeconds();
291 } else {
292 return -1;
293 }
294 }
295
296 /***
297 * {@inheritDoc}
298 */
299 public int getRegionCacheMaxTTLSeconds(String region) {
300 Cache cache = cacheManager.getCache(region);
301 if (cache != null) {
302 return (int) cache.getCacheConfiguration().getTimeToLiveSeconds();
303 } else {
304 return -1;
305 }
306 }
307
308 /***
309 * {@inheritDoc}
310 */
311 public int getRegionCacheOrphanEvictionPeriod(String region) {
312 Cache cache = this.cacheManager.getCache(region);
313 if (cache != null && cache.isTerracottaClustered()) {
314 return cache.getCacheConfiguration().getTerracottaConfiguration().getOrphanEvictionPeriod();
315 } else {
316 return -1;
317 }
318 }
319
320 /***
321 * {@inheritDoc}
322 */
323 public Map<String, int[]> getRegionCacheSamples() {
324 Map<String, int[]> rv = new HashMap<String, int[]>();
325 for (String name : cacheManager.getCacheNames()) {
326 Cache cache = cacheManager.getCache(name);
327 if (cache != null) {
328 rv.put(name, new int[] {(int) cache.getSampledCacheStatistics().getCacheHitMostRecentSample(),
329 (int) (cache.getSampledCacheStatistics().getCacheMissNotFoundMostRecentSample()
330 + cache.getSampledCacheStatistics().getCacheMissExpiredMostRecentSample()),
331 (int) cache.getSampledCacheStatistics().getCacheElementPutMostRecentSample(), });
332 }
333 }
334 return rv;
335 }
336
337 /***
338 * {@inheritDoc}
339 */
340 public int getRegionCacheTargetMaxInMemoryCount(String region) {
341 Cache cache = cacheManager.getCache(region);
342 if (cache != null) {
343 return cache.getCacheConfiguration().getMaxElementsInMemory();
344 } else {
345 return -1;
346 }
347 }
348
349 /***
350 * {@inheritDoc}
351 */
352 public int getRegionCacheTargetMaxTotalCount(String region) {
353 Cache cache = cacheManager.getCache(region);
354 if (cache != null) {
355 return cache.getCacheConfiguration().getMaxElementsOnDisk();
356 } else {
357 return -1;
358 }
359 }
360
361 /***
362 * {@inheritDoc}
363 */
364 public String[] getTerracottaHibernateCacheRegionNames() {
365 ArrayList<String> rv = new ArrayList<String>();
366 for (String name : cacheManager.getCacheNames()) {
367 Cache cache = cacheManager.getCache(name);
368 if (cache != null) {
369 if (cache.getCacheConfiguration().isTerracottaClustered()) {
370 rv.add(name);
371 }
372 }
373 }
374 return rv.toArray(new String[] {});
375 }
376
377 /***
378 * {@inheritDoc}
379 */
380 public boolean isRegionCacheEnabled(String region) {
381 Cache cache = this.cacheManager.getCache(region);
382 if (cache != null) {
383 return !cache.isDisabled();
384 } else {
385 return false;
386 }
387 }
388
389 /***
390 * {@inheritDoc}
391 */
392 public void setRegionCacheEnabled(String region, boolean enabled) {
393 Cache cache = this.cacheManager.getCache(region);
394 if (cache != null) {
395 cache.setDisabled(!enabled);
396 }
397 sendNotification(CACHE_REGION_CHANGED, getRegionCacheAttributes(region), region);
398 }
399
400 /***
401 * {@inheritDoc}
402 */
403 public boolean isRegionCachesEnabled() {
404 for (String name : this.cacheManager.getCacheNames()) {
405 Cache cache = this.cacheManager.getCache(name);
406 if (cache != null) {
407 if (cache.isDisabled()) {
408 return false;
409 }
410 }
411 }
412 return true;
413 }
414
415 /***
416 * @see net.sf.ehcache.hibernate.management.api.EhcacheStats#setRegionCachesEnabled(boolean)
417 */
418 public void setRegionCachesEnabled(final boolean flag) {
419 for (String name : this.cacheManager.getCacheNames()) {
420 Cache cache = this.cacheManager.getCache(name);
421 if (cache != null) {
422 cache.setDisabled(!flag);
423 }
424 }
425 sendNotification(CACHE_ENABLED, flag);
426 }
427
428 /***
429 * {@inheritDoc}
430 */
431 public boolean isRegionCacheLoggingEnabled(String region) {
432 Cache cache = this.cacheManager.getCache(region);
433 if (cache != null) {
434 return cache.getCacheConfiguration().getLogging();
435 } else {
436 return false;
437 }
438 }
439
440 /***
441 * {@inheritDoc}
442 */
443 public boolean isRegionCacheOrphanEvictionEnabled(String region) {
444 Cache cache = this.cacheManager.getCache(region);
445 if (cache != null && cache.isTerracottaClustered()) {
446 return cache.getCacheConfiguration().getTerracottaConfiguration().getOrphanEviction();
447 } else {
448 return false;
449 }
450 }
451
452 /***
453 * {@inheritDoc}
454 */
455 public boolean isTerracottaHibernateCache(String region) {
456 Cache cache = cacheManager.getCache(region);
457 if (cache != null) {
458 return cache.getCacheConfiguration().isTerracottaClustered();
459 } else {
460 return false;
461 }
462 }
463
464 /***
465 * {@inheritDoc}
466 */
467 public void setRegionCacheLoggingEnabled(String region, boolean loggingEnabled) {
468 Cache cache = this.cacheManager.getCache(region);
469 if (cache != null) {
470 cache.getCacheConfiguration().setLogging(loggingEnabled);
471 sendNotification(CACHE_REGION_CHANGED, getRegionCacheAttributes(region), region);
472 }
473 }
474
475 /***
476 * {@inheritDoc}
477 */
478 public void setRegionCacheMaxTTISeconds(String region, int maxTTISeconds) {
479 Cache cache = this.cacheManager.getCache(region);
480 if (cache != null) {
481 cache.getCacheConfiguration().setTimeToIdleSeconds(maxTTISeconds);
482 sendNotification(CACHE_REGION_CHANGED, getRegionCacheAttributes(region), region);
483 }
484 }
485
486 /***
487 * {@inheritDoc}
488 */
489 public void setRegionCacheMaxTTLSeconds(String region, int maxTTLSeconds) {
490 Cache cache = this.cacheManager.getCache(region);
491 if (cache != null) {
492 cache.getCacheConfiguration().setTimeToLiveSeconds(maxTTLSeconds);
493 sendNotification(CACHE_REGION_CHANGED, getRegionCacheAttributes(region), region);
494 }
495 }
496
497 /***
498 * {@inheritDoc}
499 */
500 public void setRegionCacheTargetMaxInMemoryCount(String region, int targetMaxInMemoryCount) {
501 Cache cache = this.cacheManager.getCache(region);
502 if (cache != null) {
503 cache.getCacheConfiguration().setMaxElementsInMemory(targetMaxInMemoryCount);
504 sendNotification(CACHE_REGION_CHANGED, getRegionCacheAttributes(region), region);
505 }
506 }
507
508 /***
509 * {@inheritDoc}
510 */
511 public void setRegionCacheTargetMaxTotalCount(String region, int targetMaxTotalCount) {
512 Cache cache = this.cacheManager.getCache(region);
513 if (cache != null) {
514 cache.getCacheConfiguration().setMaxElementsOnDisk(targetMaxTotalCount);
515 sendNotification(CACHE_REGION_CHANGED, getRegionCacheAttributes(region), region);
516 }
517 }
518
519 /***
520 * {@inheritDoc}
521 *
522 * @see net.sf.ehcache.hibernate.management.api.EhcacheStats#getNumberOfElementsInMemory(java.lang.String)
523 */
524 public int getNumberOfElementsInMemory(String region) {
525 Cache cache = this.cacheManager.getCache(region);
526 if (cache != null) {
527 return (int) cache.getMemoryStoreSize();
528 } else {
529 return -1;
530 }
531 }
532
533 /***
534 * {@inheritDoc}
535 *
536 * @see net.sf.ehcache.hibernate.management.api.EhcacheStats#getNumberOfElementsOffHeap(java.lang.String)
537 */
538 public int getNumberOfElementsOffHeap(String region) {
539 Cache cache = this.cacheManager.getCache(region);
540 if (cache != null) {
541 return (int) cache.getOffHeapStoreSize();
542 } else {
543 return -1;
544 }
545 }
546
547 /***
548 * {@inheritDoc}
549 *
550 * @see net.sf.ehcache.hibernate.management.api.EhcacheStats#getNumberOfElementsOnDisk(java.lang.String)
551 */
552 public int getNumberOfElementsOnDisk(String region) {
553 Cache cache = this.cacheManager.getCache(region);
554 if (cache != null) {
555 return cache.getDiskStoreSize();
556 } else {
557 return -1;
558 }
559 }
560
561 /***
562 * {@inheritDoc}
563 */
564 public void setStatisticsEnabled(boolean flag) {
565 for (String cacheName : cacheManager.getCacheNames()) {
566 Cache cache = cacheManager.getCache(cacheName);
567 if (cache != null) {
568 cache.setStatisticsEnabled(flag);
569 }
570 }
571 if (flag) {
572 clearStats();
573 }
574 sendNotification(CACHE_STATISTICS_ENABLED, flag);
575 }
576
577 /***
578 * {@inheritDoc}
579 */
580 public long getMaxGetTimeMillis() {
581 long rv = 0;
582 for (String cacheName : cacheManager.getCacheNames()) {
583 Cache cache = cacheManager.getCache(cacheName);
584 if (cache != null) {
585 rv = Math.max(rv, cache.getLiveCacheStatistics().getMaxGetTimeMillis());
586 }
587 }
588 return rv;
589 }
590
591 /***
592 * {@inheritDoc}
593 */
594 public long getMinGetTimeMillis() {
595 long rv = 0;
596 for (String cacheName : cacheManager.getCacheNames()) {
597 Cache cache = cacheManager.getCache(cacheName);
598 if (cache != null) {
599 rv = Math.max(rv, cache.getLiveCacheStatistics().getMinGetTimeMillis());
600 }
601 }
602 return rv;
603 }
604
605 /***
606 * {@inheritDoc}
607 *
608 * @see net.sf.ehcache.hibernate.management.api.EhcacheStats#getMaxGetTimeMillis(java.lang.String)
609 */
610 public long getMaxGetTimeMillis(String cacheName) {
611 Cache cache = cacheManager.getCache(cacheName);
612 if (cache != null) {
613 return cache.getLiveCacheStatistics().getMaxGetTimeMillis();
614 } else {
615 return 0;
616 }
617 }
618
619 /***
620 * {@inheritDoc}
621 *
622 * @see net.sf.ehcache.hibernate.management.api.EhcacheStats#getMinGetTimeMillis(java.lang.String)
623 */
624 public long getMinGetTimeMillis(String cacheName) {
625 Cache cache = cacheManager.getCache(cacheName);
626 if (cache != null) {
627 return cache.getLiveCacheStatistics().getMinGetTimeMillis();
628 } else {
629 return 0;
630 }
631 }
632
633 /***
634 * {@inheritDoc}
635 *
636 * @see net.sf.ehcache.hibernate.management.api.EhcacheStats#getAverageGetTimeMillis(java.lang.String)
637 */
638 public float getAverageGetTimeMillis(String region) {
639 Cache cache = this.cacheManager.getCache(region);
640 if (cache != null) {
641 return cache.getLiveCacheStatistics().getAverageGetTimeMillis();
642 } else {
643 return -1f;
644 }
645 }
646
647 /***
648 * {@inheritDoc}
649 */
650 @Override
651 protected void doDispose() {
652
653 }
654
655 /***
656 * @see BaseEmitterBean#getNotificationInfo()
657 */
658 @Override
659 public MBeanNotificationInfo[] getNotificationInfo() {
660 return new MBeanNotificationInfo[]{NOTIFICATION_INFO};
661 }
662 }