View Javadoc
1   package com.atlassian.cache.memory.jmx;
2   
3   import com.atlassian.cache.CacheManager;
4   import com.atlassian.cache.ManagedCache;
5   import org.slf4j.Logger;
6   import org.slf4j.LoggerFactory;
7   
8   import javax.annotation.Nonnull;
9   import javax.management.MBeanServer;
10  import javax.management.MalformedObjectNameException;
11  import javax.management.ObjectName;
12  import java.util.Collection;
13  import java.util.HashSet;
14  import java.util.Set;
15  
16  /**
17   * Helper for registering / unregistering JMX MBeans for Guava Cache.
18   * @since v3.1
19   */
20  public class MemoryCacheMXBeanRegistrar
21  {
22      static final String MBEAN_NAME_PATTERN = "com.google.common.cache:type=CacheStatistics,CacheManager=JIRA Cache Manager,name=%s";
23  
24      private final Logger logger = LoggerFactory.getLogger(MemoryCacheMXBeanRegistrar.class);
25  
26      private MBeanServer mbeanServer;
27      private CacheManager cacheManager;
28      private Set<ObjectName> registeredMBeans = new HashSet<>();
29  
30      /**
31       * Enables collecting JMX metrics.
32       * <p>
33       * Note: it must be called to allow the method <code>registerMBean</code> registering MBeans.
34       *</p>
35       *
36       * @param mbeanServer {@link MBeanServer} instance used for registering and unregistering MBeans
37       * @param cacheManager {@link CacheManager} instance used for retrieving caches metrics
38       */
39      public void enableCollectingJMXMetrics(@Nonnull MBeanServer mbeanServer, @Nonnull CacheManager cacheManager)
40      {
41          this.mbeanServer = mbeanServer;
42          this.cacheManager = cacheManager;
43  
44          Collection<ManagedCache> caches = cacheManager.getManagedCaches();
45          for(ManagedCache cache: caches)
46          {
47              registerMBean(cache.getName());
48          }
49      }
50  
51      /**
52       * Registers JMX MBean for the specified cache name.
53       * <p>
54       * Note: it will not register anything if the method <code>enableCollectingJMXMetrics</code> was not called before
55       * or unregisterMBeans was called .
56       * </p>
57       *
58       * @param cacheName the cache name for which MBean should be registered
59       */
60      public void registerMBean(@Nonnull String cacheName)
61      {
62          if(mbeanServer != null)
63          {
64              try
65              {
66                  ObjectName name = buildName(cacheName);
67  
68                  if (registeredMBeans.contains(name))
69                  {
70                      logger.debug("MBean: " + name.getCanonicalName() + " has been registered previously");
71                      return;
72                  }
73  
74                  MemoryCacheMXBean mbean = new MemoryCacheMXBeanImpl(cacheManager, cacheName);
75                  mbeanServer.registerMBean(mbean, name);
76                  registeredMBeans.add(name);
77              }
78              catch (Exception e)
79              {
80                  logger.warn("Could not register JMX MBean for Guava Cache: " + cacheName, e);
81              }
82          }
83      }
84  
85      /**
86       * Unregisters all registered JMX MBeans.
87       * <p>
88       * Note: it will unregister all registered Cache JMX MBeans
89       *</p>
90       */
91      public void unregisterMBeans()
92      {
93          if(mbeanServer != null)
94          {
95              for(ObjectName mbeanName: registeredMBeans)
96              {
97                  try
98                  {
99                      mbeanServer.unregisterMBean(mbeanName);
100                 }
101                 catch (Exception e)
102                 {
103                     logger.warn("Could not unregister JMX MBean: " + mbeanName.getCanonicalName(), e);
104                 }
105             }
106             registeredMBeans.clear();
107             mbeanServer = null;
108         }
109     }
110 
111     private ObjectName buildName(String cacheName) throws MalformedObjectNameException
112     {
113         return new ObjectName(String.format(MBEAN_NAME_PATTERN, cacheName));
114     }
115 }