Home » geronimo-2.2-source-release » org.apache.geronimo.monitoring.jmx » [javadoc | source]

    1   /**
    2    *  Licensed to the Apache Software Foundation (ASF) under one or more
    3    *  contributor license agreements.  See the NOTICE file distributed with
    4    *  this work for additional information regarding copyright ownership.
    5    *  The ASF licenses this file to You under the Apache License, Version 2.0
    6    *  (the "License"); you may not use this file except in compliance with
    7    *  the License.  You may obtain a copy of the License at
    8    *
    9    *     http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    *  Unless required by applicable law or agreed to in writing, software
   12    *  distributed under the License is distributed on an "AS IS" BASIS,
   13    *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    *  See the License for the specific language governing permissions and
   15    *  limitations under the License.
   16    */
   17   package org.apache.geronimo.monitoring.jmx;
   18   
   19   import java.util.ArrayList;
   20   import java.util.HashMap;
   21   import java.util.HashSet;
   22   import java.util.Iterator;
   23   import java.util.Set;
   24   import java.util.TreeMap;
   25   
   26   import javax.management.Attribute;
   27   import javax.management.MBeanServer;
   28   import javax.management.MBeanServerFactory;
   29   import javax.management.ObjectName;
   30   import javax.management.j2ee.statistics.RangeStatistic;
   31   import javax.management.j2ee.statistics.Stats;
   32   import javax.management.j2ee.statistics.CountStatistic;
   33   import javax.management.j2ee.statistics.Statistic;
   34   import javax.management.j2ee.statistics.TimeStatistic;
   35   import javax.naming.InitialContext;
   36   import javax.sql.DataSource;
   37   
   38   import org.slf4j.Logger;
   39   import org.slf4j.LoggerFactory;
   40   
   41   
   42   import org.apache.geronimo.gbean.GBeanInfo;
   43   import org.apache.geronimo.gbean.GBeanInfoBuilder;
   44   import org.apache.geronimo.gbean.GBeanLifecycle;
   45   
   46   import org.apache.geronimo.monitoring.MBeanHelper;
   47   import org.apache.geronimo.monitoring.MonitorConstants;
   48   
   49   import org.apache.geronimo.monitoring.jmx.snapshot.SnapshotThread;
   50   import org.apache.geronimo.monitoring.snapshot.SnapshotConfigXMLBuilder;
   51   import org.apache.geronimo.monitoring.snapshot.SnapshotDBHelper;
   52   
   53   /**
   54    * This is the GBean that will be the bottleneck for the communication
   55    * between the management node and the data in the server node.
   56    */
   57   public class MasterRemoteControlJMX implements GBeanLifecycle {
   58       private static final Logger log = LoggerFactory.getLogger(MasterRemoteControlJMX.class);
   59   
   60       // mbean server to talk to other components
   61       private static MBeanServer mbServer = null;
   62       
   63       // threads
   64       private static SnapshotThread snapshotThread = null;
   65       
   66       // datasources
   67       private DataSource activeDS;
   68       private DataSource archiveDS;
   69   
   70       private SnapshotDBHelper snapshotDBHelper;
   71   
   72       public MasterRemoteControlJMX() {
   73           // retrieve the mbean server
   74           ArrayList mbServerList = MBeanServerFactory.findMBeanServer(null);
   75           if(mbServerList.size() >= 1) {
   76               mbServer = (MBeanServer) mbServerList.get(0);
   77               for(int i = 0; i < mbServerList.size(); i++) {
   78                   String domain = ((MBeanServer)mbServerList.get(i)).getDefaultDomain();
   79                   if(domain.equals( MonitorConstants.GERONIMO_DEFAULT_DOMAIN )) {
   80                       mbServer = (MBeanServer)mbServerList.get(i);
   81                       break;
   82                   }
   83               }
   84           }
   85           // ensure that the mbServer has something in it
   86           if(mbServer == null) {
   87               mbServer = MBeanServerFactory.createMBeanServer( MonitorConstants.GERONIMO_DEFAULT_DOMAIN );
   88           }
   89          
   90           // set up SnaphotDBHelper with the necessary data sources
   91           // Note: do not put this in the constructor...datasources are not injected by then
   92           try {
   93               InitialContext ic = new InitialContext();
   94               activeDS = (DataSource)ic.lookup("jca:/org.apache.geronimo.plugins.monitoring/agent-ds/JCAManagedConnectionFactory/jdbc/ActiveDS");
   95               archiveDS = (DataSource)ic.lookup("jca:/org.apache.geronimo.plugins.monitoring/agent-ds/JCAManagedConnectionFactory/jdbc/ArchiveDS");
   96           } catch(Exception e) {
   97               log.error(e.getMessage());
   98           }
   99           snapshotDBHelper = new SnapshotDBHelper(activeDS, archiveDS);
  100       }
  101       
  102       /**
  103        * Looks up the JSR-77 statistics associated with this object name.
  104        * 
  105        * @param objectName
  106        * @return HashMap
  107        * @throws Exception
  108        */
  109       public static HashMap getStats(String objectName) throws Exception {
  110           HashMap statsMap = new HashMap();
  111           Stats stats = (Stats)mbServer.getAttribute(new ObjectName(objectName), "stats");
  112           String[] sttsName = stats.getStatisticNames();
  113           Statistic[] stts = stats.getStatistics();
  114           for(int i = 0; i < sttsName.length; i++) {
  115               Statistic aStat = stats.getStatistic(sttsName[i]);
  116               if(aStat instanceof RangeStatistic) {
  117                   Long current = new Long(((RangeStatistic)aStat).getCurrent());
  118                   Long high = new Long(((RangeStatistic)aStat).getHighWaterMark());
  119                   Long low = new Long(((RangeStatistic)aStat).getLowWaterMark());
  120                   statsMap.put(stts[i].getName() + " Current", current);
  121                   statsMap.put(stts[i].getName() + " Max", high);
  122                   statsMap.put(stts[i].getName() + " Min", low);
  123               } else if(aStat instanceof CountStatistic) {
  124                   Long current = new Long(((CountStatistic)aStat).getCount());
  125                   statsMap.put(stts[i].getName(), current);
  126               } else if(aStat instanceof TimeStatistic) {
  127                   Long current = new Long(((TimeStatistic)aStat).getCount());
  128                   Long max = new Long(((TimeStatistic)aStat).getMaxTime());
  129                   Long min = new Long(((TimeStatistic)aStat).getMinTime());
  130                   Long total = new Long(((TimeStatistic)aStat).getTotalTime());
  131                   statsMap.put(stts[i].getName() + " CurrentTime", current);
  132                   statsMap.put(stts[i].getName() + " MaxTime", max);
  133                   statsMap.put(stts[i].getName() + " MinTime", min);
  134                   statsMap.put(stts[i].getName() + " TotalTime", total);
  135               } else {
  136                   // this should never happen
  137                   throw new Exception();
  138               }
  139           }
  140           return statsMap;
  141       }
  142       
  143       /**
  144        * Changes the objectName's attrName's value to attrValue
  145        * 
  146        * @param objectName
  147        * @param attrName
  148        * @param attrValue
  149        * @throws Exception
  150        */
  151       public void setAttribute(String objectName, String attrName, Object attrValue) throws Exception {
  152           Attribute attr = new Attribute(attrName, attrValue);
  153           mbServer.setAttribute(new ObjectName(objectName), attr);
  154       }
  155       
  156       /**
  157        * Stops the snapshot thread
  158        */
  159       public boolean stopSnapshot() {
  160           if(snapshotThread != null) {
  161               if(snapshotThread.getSnapshotDuration() != Long.MAX_VALUE) {
  162                   saveDuration(snapshotThread.getSnapshotDuration());
  163                   snapshotThread.setSnapshotDuration(Long.MAX_VALUE);
  164                   log.info("Snapshot thread stopped.");
  165                   return true;
  166               } else {
  167                   return false;
  168               }
  169           } else {
  170               log.error("There is not a snapshot thread running. Stopping aborted.");
  171               return false;
  172           }
  173       }
  174       
  175       /**
  176        * Fetches the data stored from the snapshot thread and returns
  177        * it in a ArrayList with each element being a HashMap of the attribute
  178        * mapping to the statistic. All stats will be the average of 
  179        *          1 - n, n+1 - 2n, ..., cn+1 - c(n+1)
  180        *
  181        * Grabs 'numberOfSnapshots' snapshots. Grabs one snapshot per
  182        * 'everyNthsnapshot'
  183        * 
  184        * @param numberOfSnapshot
  185        * @param everyNthSnapshot
  186        * @return ArrayList
  187        */ 
  188       public ArrayList<HashMap<String, HashMap<String, Object>>> fetchSnapshotData(Integer numberOfSnapshot, Integer everyNthSnapshot) {
  189           return snapshotDBHelper.fetchData(numberOfSnapshot, everyNthSnapshot);
  190       }
  191       
  192       /**
  193        * Fetches the max amount for each statistic stored from the snapshot thread
  194        * and returns it in a HashMap
  195        * 
  196        * @param numberOfSnapshot
  197        * @return HashMap
  198        */
  199       public HashMap<String, HashMap<String, Long>> fetchMaxSnapshotData(Integer numberOfSnapshot) {
  200           return snapshotDBHelper.fetchMaxSnapshotData(numberOfSnapshot);
  201       }
  202   
  203       /**
  204        * Fetches the min amount for each statistic stored from the snapshot thread
  205        * and returns it in a HashMap
  206        * 
  207        * @param numberOfSnapshot
  208        * @return HashMap
  209        */
  210       public HashMap<String, HashMap<String, Long>> fetchMinSnapshotData(Integer numberOfSnapshot) {
  211           return snapshotDBHelper.fetchMinSnapshotData(numberOfSnapshot);
  212       }
  213       
  214       /**
  215        * Gets the elapsed time in milliseconds between each snapshot.
  216        * 
  217        * @return Long
  218        */
  219       public Long getSnapshotDuration() {
  220           try {
  221               return Long.parseLong(SnapshotConfigXMLBuilder.getAttributeValue( MonitorConstants.DURATION ));
  222           } catch(Exception e) {
  223               return new Long( MonitorConstants.DEFAULT_DURATION );
  224           }
  225       }
  226       
  227       /**
  228        * Sets the elapsed time in milliseconds between each snapshot.
  229        * 
  230        * @param snapshotDuration
  231        */
  232       public void setSnapshotDuration(Long snapshotDuration) {
  233           if(snapshotThread != null) {
  234               snapshotThread.setSnapshotDuration(snapshotDuration.longValue());
  235               saveDuration(snapshotThread.getSnapshotDuration());
  236           } else {
  237               log.warn("There is not a snapshot thread instantiated.");
  238           }
  239       }
  240       
  241       public void setSnapshotRetention(Integer retention) {
  242           saveRetention(retention.intValue());
  243       }
  244       
  245       /**
  246       * Begins the snapshot process given the time interval between snapshots
  247        *
  248        * Precondition:
  249        *          interval is given in milli seconds
  250        * 
  251        * @param interval
  252        */
  253       public boolean startSnapshot(Long interval) {
  254           // get the saved/default retention period
  255           String retentionStr = null;
  256           try {
  257               retentionStr = SnapshotConfigXMLBuilder.getAttributeValue( MonitorConstants.RETENTION );
  258           } catch(Exception e){
  259               // happens when there is not an instance of "retention" in the config
  260               // which is okay.
  261           }
  262           int retention;
  263           if(retentionStr == null) {
  264               retention = MonitorConstants.DEFAULT_RETENTION;
  265           } else {
  266               retention = Integer.parseInt(retentionStr);
  267           }
  268           return startSnapshot(interval, new Integer(retention));
  269       }
  270       
  271       /**
  272        * Begins the snapshot process given the time interval between snapshots
  273        *
  274        * Precondition:
  275        *          interval is given in milli seconds
  276        * 
  277        * @param interval
  278        */
  279       public boolean startSnapshot(Long interval, Integer retention) {
  280           if((snapshotThread == null || (snapshotThread != null && (snapshotThread.SnapshotStatus() == 0))) && interval.longValue() > 0) {
  281               saveDuration(interval.longValue());
  282               saveRetention(retention.intValue());
  283               snapshotThread = new SnapshotThread(interval.longValue(), mbServer);
  284               snapshotThread.start();
  285               log.info("Snapshot thread successfully created.");
  286               return true;
  287           } else {
  288               log.warn("There is already a snapshot thread running.");
  289               return false;
  290           }
  291       }
  292       
  293       public Long getSnapshotCount() {
  294           return snapshotDBHelper.getSnapshotCount();
  295       }
  296       
  297       /**
  298        * Fetches all mbean names that provide JSR-77 statistics
  299        * 
  300        * @return A set containing all mbean names of mbeans that provide
  301        * statistics
  302        */
  303       public Set<String> getStatisticsProviderMBeanNames() {
  304           return (Set<String>)MBeanHelper.getStatsProvidersMBeans( getAllMBeanNames() );
  305       }
  306       
  307       /**
  308        * Fetches all mbean names
  309        * 
  310        * @return A set containing all mbean names
  311        */
  312       public Set<String> getAllMBeanNames() {
  313           try {
  314               Set<ObjectName> names = (Set<ObjectName>)mbServer.queryNames(null, null);
  315               Set<String> strNames = new HashSet<String>();
  316               for(Iterator<ObjectName> it = names.iterator(); it.hasNext(); ) {
  317                   strNames.add(it.next().getCanonicalName());
  318               }
  319               return strNames;
  320          } catch(Exception e) {
  321               log.error(e.getMessage(), e);
  322               return new HashSet<String>();
  323           }
  324       }
  325       
  326       public void doFail() {
  327           doStop();
  328       }
  329   
  330       /**
  331        * Executes when the GBean starts up. Also starts the snapshot thread.
  332        */
  333       public void doStart() {
  334       
  335       }
  336       
  337       /**
  338        * Executes when the GBean stops. Also stops the snapshot thread.
  339        */
  340       public void doStop() {
  341           if(SnapshotStatus() == 1) {
  342               stopSnapshot();
  343           }
  344       }
  345       
  346       private void saveDuration(long duration) {
  347           SnapshotConfigXMLBuilder.saveDuration(duration);
  348       }
  349       
  350       private void saveRetention(int retention) {
  351           SnapshotConfigXMLBuilder.saveRetention(retention);
  352       }
  353       
  354       /**
  355        * Adds a record of the mbean via its name to take snapshots of. As a result
  356        * the mbeanName will be written to snapshot-config.xml
  357        * 
  358        * @param mbeanName
  359        */
  360       public boolean addMBeanForSnapshot(String mbeanName) {
  361           return SnapshotConfigXMLBuilder.addMBeanName(mbeanName);
  362       }
  363   
  364       /**
  365        * Removes a record of the mbean via its name to take snapshots of. As a result
  366        * the mbeanName will be removed from snapshot-config.xml
  367        * 
  368        * @param mbeanName
  369        */
  370       public boolean removeMBeanForSnapshot(String mbeanName) {
  371           return SnapshotConfigXMLBuilder.removeMBeanName(mbeanName);
  372       }
  373       
  374       /**
  375        * @return A map: mbeanName --> ArrayList of statistic attributes for that mbean
  376        */
  377       public HashMap<String, ArrayList<String>> getAllSnapshotStatAttributes() {
  378           HashMap<String, ArrayList<String>> snapshotAttributes = new HashMap<String, ArrayList<String>>();
  379           Set<String> mbeans = getTrackedMBeans();
  380           // for each mbean name
  381           for(Iterator<String> it = mbeans.iterator(); it.hasNext(); ) {
  382               ArrayList<String> mbeanStatsList = new ArrayList<String>();
  383               String mbeanName = it.next();
  384               try {
  385                   Stats stats = (Stats)mbServer.getAttribute(new ObjectName(mbeanName), "stats");
  386                   String[] sttsName = stats.getStatisticNames();
  387                   Statistic[] stts = stats.getStatistics();
  388                   for(int i = 0; i < sttsName.length; i++) {
  389                       Statistic aStat = stats.getStatistic(sttsName[i]);
  390                       if(aStat instanceof RangeStatistic) {
  391                           mbeanStatsList.add(stts[i].getName() + " Current");
  392                           mbeanStatsList.add(stts[i].getName() + " Max");
  393                           mbeanStatsList.add(stts[i].getName() + " Min");
  394                       } else if(aStat instanceof CountStatistic) {
  395                           mbeanStatsList.add(stts[i].getName());
  396                       } else if(aStat instanceof TimeStatistic) {
  397                           mbeanStatsList.add(stts[i].getName() + " CurrentTime");
  398                           mbeanStatsList.add(stts[i].getName() + " MaxTime");
  399                           mbeanStatsList.add(stts[i].getName() + " MinTime");
  400                           mbeanStatsList.add(stts[i].getName() + " TotalTime");
  401                       } else {
  402                           // for the time being, only numbers should be returned
  403                       }
  404                   }
  405               } catch (Exception e) {
  406                   log.error(e.getMessage(), e);
  407               }
  408               // save attributes to the returning list
  409               snapshotAttributes.put(mbeanName, mbeanStatsList);
  410           }
  411           return snapshotAttributes;
  412       }
  413       
  414       public Set<String> getTrackedMBeans() {
  415           ArrayList<String> mbeans = (ArrayList<String>)SnapshotConfigXMLBuilder.getMBeanNames();
  416           Set<String> set = new HashSet<String>();
  417           for(int i = 0; i < mbeans.size(); i++) {
  418               set.add(mbeans.get(i));
  419           }
  420           return set;
  421       }
  422       
  423       public Integer getSnapshotRetention() {
  424           try {
  425               return new Integer(SnapshotConfigXMLBuilder.getAttributeValue( MonitorConstants.RETENTION ));
  426           } catch(Exception e) {
  427               return new Integer(MonitorConstants.DEFAULT_RETENTION); // the default
  428           }
  429       }
  430       
  431       /**
  432        * @param name - object name of the mbean
  433        * @param operationName - method within the class
  434        * @param params - parameters for the method
  435        * @param signature - types for the parameters
  436        * @return Invokes the method of a class defined.
  437        */
  438       public Object invoke(ObjectName name, String operationName, Object[] params, String[] signature) throws Exception {
  439           return mbServer.invoke(name, operationName, params, signature);
  440       }
  441       
  442       /**
  443        * @param mbeanName
  444        * @param statsName
  445        * @param numberOfSnapshots
  446        * @param everyNthSnapshot
  447        * @return HashMap which maps from a snapshot_time --> value of the mbean.statsName at that time
  448        */
  449       public TreeMap<Long, Long> getSpecificStatistics(   String mbeanName,
  450                                                           String statsName, 
  451                                                           Integer numberOfSnapshots, 
  452                                                           Integer everyNthSnapshot,
  453                                                           Boolean showArchived) {
  454           return snapshotDBHelper.getSpecificStatistics(mbeanName, statsName, numberOfSnapshots.intValue(), everyNthSnapshot.intValue(), showArchived);
  455       }
  456       
  457       /**
  458        * @return Returns true if snapshot is running.
  459        */
  460       public Integer SnapshotStatus() {
  461           // TODO: check if the snapshot thread is running 
  462           if(snapshotThread == null) {
  463               return 0;
  464           } else {
  465               return snapshotThread.SnapshotStatus();
  466           }
  467       }
  468   
  469       public static final GBeanInfo GBEAN_INFO;
  470   
  471       static {
  472           GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic("MasterRemoteControlJMX", MasterRemoteControlJMX.class);
  473           infoFactory.addOperation("getStats", new Class[] {String.class}, "HashMap");
  474           infoFactory.addOperation("setAttribute", new Class[] {String.class, String.class, Object.class}, "void");
  475           infoFactory.addOperation("startSnapshot", new Class[] {Long.class}, "Boolean");
  476           infoFactory.addOperation("startSnapshot", new Class[] {Long.class, Integer.class}, "Boolean");
  477           infoFactory.addOperation("stopSnapshot", new Class[] {}, "Boolean");
  478           infoFactory.addOperation("fetchSnapshotData", new Class[] {Integer.class, Integer.class}, "ArrayList");
  479           infoFactory.addOperation("fetchMaxSnapshotData", new Class[] {Integer.class}, "HashMap");
  480           infoFactory.addOperation("fetchMinSnapshotData", new Class[] {Integer.class}, "HashMap");
  481           infoFactory.addOperation("getSnapshotDuration", new Class[] {}, "Long");
  482           infoFactory.addOperation("getSnapshotCount", new Class[] {}, "Long");
  483           infoFactory.addOperation("setSnapshotDuration", new Class[] {Long.class}, "void");
  484           infoFactory.addOperation("getStatisticsProviderMBeanNames", new Class[] {}, "Set");
  485           infoFactory.addOperation("getAllMBeanNames", new Class[] {}, "Set");
  486           infoFactory.addOperation("getAllSnapshotStatAttributes", new Class[] {}, "HashMap");
  487           infoFactory.addOperation("addMBeanForSnapshot", new Class[] {String.class}, "void");
  488           infoFactory.addOperation("removeMBeanForSnapshot", new Class[] {String.class}, "void");
  489           infoFactory.addOperation("getSnapshotRetention", new Class[] {}, "Integer");
  490           infoFactory.addOperation("setSnapshotRetention", new Class[] {Integer.class}, "void");
  491           infoFactory.addOperation("SnapshotStatus", new Class[] {}, "Integer");
  492           infoFactory.addOperation("getSpecificStatistics", new Class[] {String.class, String.class, Integer.class, Integer.class, Boolean.class}, "TreeMap");
  493           infoFactory.addOperation("getTrackedMBeans", new Class[] {}, "Set");
  494           infoFactory.setConstructor(new String[] {});
  495           GBEAN_INFO = infoFactory.getBeanInfo();
  496       }
  497   
  498       public static GBeanInfo getGBeanInfo() {
  499           return GBEAN_INFO;
  500       }
  501   }

Home » geronimo-2.2-source-release » org.apache.geronimo.monitoring.jmx » [javadoc | source]