Home » geronimo-2.2-source-release » org.apache.geronimo.monitoring.snapshot » [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.snapshot;
   18   
   19   import java.sql.Connection;
   20   import java.sql.DriverManager;
   21   import java.sql.ResultSet;
   22   import java.sql.Statement;
   23   import java.text.SimpleDateFormat;
   24   import java.util.ArrayList;
   25   import java.util.Calendar;
   26   import java.util.Date;
   27   import java.util.HashMap;
   28   import java.util.Iterator;
   29   import java.util.TreeMap;
   30   
   31   import javax.sql.DataSource;
   32   
   33   import org.slf4j.Logger;
   34   import org.slf4j.LoggerFactory;
   35   import org.apache.geronimo.monitoring.MonitorConstants;
   36   
   37   public class SnapshotDBHelper {
   38       private static final Logger log = LoggerFactory.getLogger(SnapshotDBHelper.class);
   39       // Connection object used for DB interaction
   40       private static Connection conn = null;
   41       // Data Sources
   42       private static DataSource activeDS = null;
   43       private static DataSource archiveDS = null;
   44       
   45       public SnapshotDBHelper() {
   46           
   47       }
   48       
   49       public SnapshotDBHelper(DataSource activeDS, DataSource archiveDS) {
   50           SnapshotDBHelper.activeDS = activeDS;
   51           SnapshotDBHelper.archiveDS = archiveDS;
   52       }
   53       
   54       /**
   55        * @return A map: mbeanName --> ArrayList of statistic attributes for that mbean
   56        */
   57       public HashMap<String, ArrayList<String>> getAllSnapshotStatAttributes() {
   58           openActiveConnection();
   59           HashMap<String, ArrayList<String>> retval = new HashMap<String, ArrayList<String>>();
   60           try {
   61               Statement stmt = conn.createStatement();
   62               String query = "SELECT DISTINCT mbeanName, statsNameList FROM MBeans";
   63               ResultSet rs = stmt.executeQuery(query);
   64               // add each mbean/statsValue combination to retval
   65               while(rs.next()) {
   66                   String mbeanName = rs.getString( MonitorConstants.MBEANNAME );
   67                   String statsNameStr = rs.getString( MonitorConstants.STATSNAMELIST );
   68                   String[] statsNameList = statsNameStr.split(",");
   69                   ArrayList<String> mbeanAttributeList = new ArrayList<String>();
   70                   // copy from String[] to ArrayList<String>
   71                   for(int i = 0; i < statsNameList.length; i++) {
   72                       mbeanAttributeList.add(statsNameList[i]);
   73                   }
   74                   retval.put(mbeanName, mbeanAttributeList);
   75               }
   76           } catch(Exception e) {
   77               log.error(e.getMessage(), e);
   78           } finally {
   79               closeConnection();
   80           }
   81           return retval;
   82       }
   83       
   84       /**
   85        * 
   86        * @return The number of snapshots present in the active database
   87        */
   88       public Long getSnapshotCount() {
   89           long retval = 0;
   90           try {
   91               openActiveConnection();
   92               Statement stmt = conn.createStatement();
   93               String query = "SELECT COUNT(DISTINCT snapshot_time) FROM Statistics";
   94               ResultSet rs = stmt.executeQuery(query);
   95               rs.next();
   96               retval = rs.getLong(1);
   97           } catch(Exception e) {
   98               log.error(e.getMessage(), e);
   99           } finally {
  100               closeConnection();
  101           }
  102           return new Long(retval);
  103       }
  104       
  105       /**
  106        * @param numberOfSnapshots - the number of latest snapshots to look at
  107        * @return A hashmap which maps an mbean --> a hashmap with an attribute name and its value . All values will be the max.
  108        */
  109       public HashMap<String, HashMap<String, Long>> fetchMaxSnapshotData(Integer numberOfSnapshots) {
  110           return fetchMaxOrMinSnapshotData(numberOfSnapshots, true);
  111       }
  112       /**
  113        * @param numberOfSnapshots - the number of latest snapshots to look at
  114        * @return A hashmap which maps an mbean --> a hashmap with an attribute name and its value . All values will be the min.
  115        */    
  116       public HashMap<String, HashMap<String, Long>> fetchMinSnapshotData(Integer numberOfSnapshots) {
  117           return fetchMaxOrMinSnapshotData(numberOfSnapshots, false);
  118       }
  119       
  120       /**
  121        * @param numberOfSnapshots - the number of latest snapshots to look at.
  122        * @param isMax - true if the result should be all maximum values. otherwise, false.
  123        * @return A hashmap which maps an mbean --> a hashmap with an attribute name and its value . All values will be the min
  124        * or max, depending on the isMax parameter.
  125        */
  126       private HashMap<String, HashMap<String, Long>> fetchMaxOrMinSnapshotData(Integer numberOfSnapshots, boolean isMax) {
  127           openActiveConnection();
  128           ResultSet snapshotTimeTable = fetchSnapshotTimesFromDB();
  129           HashMap<String, HashMap<String, Long>> stats = new HashMap<String, HashMap<String, Long>>();
  130           try {
  131               // for each snapshot in the table
  132               while(snapshotTimeTable.next()) {
  133                   Long snapshotTime = snapshotTimeTable.getLong( MonitorConstants.SNAPSHOT_TIME );
  134                   // retrieve the snapshot information by time
  135                   ResultSet snapshotData = fetchSnapshotDataFromDB(snapshotTime);
  136                   // for each statistic, perform a relaxation
  137                   while(snapshotData.next()) {
  138                       String mbean = snapshotData.getString( MonitorConstants.MBEANNAME );
  139                       // get map associated with mbean
  140                       HashMap<String, Long> mbeanMap = stats.get(mbean);
  141                       if(mbeanMap == null) {
  142                           mbeanMap = new HashMap<String, Long>();
  143                       }
  144                       String[] statsNameList = snapshotData.getString( MonitorConstants.STATSNAMELIST ).split(",");
  145                       String[] statsValueList = snapshotData.getString( MonitorConstants.STATSVALUELIST ).split(",");
  146                       assert(statsNameList.length == statsValueList.length);
  147                       // for each statname/statsvalue combo in an mbean
  148                       for(int i = 0 ; i < statsNameList.length; i++) {
  149                           String statsName = statsNameList[i];
  150                           Long maxStatsValue = mbeanMap.get(statsName);
  151                           // give maxStatsValue some value if there isn't one
  152                           if(maxStatsValue == null) {
  153                               if(isMax) {
  154                                   maxStatsValue = new Long(0);
  155                               } else {
  156                                   maxStatsValue = Long.MAX_VALUE;
  157                               }
  158                           }
  159                           // relax
  160                           if(isMax) {
  161                               maxStatsValue = new Long(Math.max(Long.parseLong(statsValueList[i]), maxStatsValue.longValue()));
  162                           } else {
  163                               maxStatsValue = new Long(Math.min(Long.parseLong(statsValueList[i]), maxStatsValue.longValue()));
  164                           }
  165                           // save name/value back into mbeanMap
  166                           mbeanMap.put(statsName, maxStatsValue);
  167                       }
  168                       // save mbeanMap back into stats
  169                       stats.put(mbean, mbeanMap);
  170                   }
  171                   
  172                   // compute the remaining snapshots left to look at
  173                   numberOfSnapshots--;
  174                   // discontinue once we have looked at numberOfSnapshots snapshots
  175                   if(numberOfSnapshots == 0) {
  176                       break;
  177                   }
  178               }
  179           } catch(Exception e) {
  180               log.error(e.getMessage(), e);
  181           } finally {
  182               closeConnection();
  183           }
  184           return stats;
  185       }
  186       
  187       /**
  188        * @param ds
  189        * @param aggregateStats
  190        * @return Returns a boolean if the snapshot statistics were successfully added
  191        * to the DB.
  192        */
  193       public boolean addSnapshotToDB(HashMap<String, HashMap<String, Long>> aggregateStats) {
  194           boolean success = true;
  195           // get the current time from 1970
  196           String currTime = "";
  197           currTime += (new Date()).getTime();
  198           try {
  199               // for each mbean
  200               for(Iterator itt = aggregateStats.keySet().iterator(); itt.hasNext(); ) {
  201                   String mbean = (String)itt.next();
  202                   // prepare the statsNameList and statsValueList beforehand
  203                   String statsNameList = "", statsValueList = "";
  204                   for(Iterator<String> it = aggregateStats.get(mbean).keySet().iterator(); it.hasNext(); ) {
  205                       String statsName = it.next();
  206                       Long statsValue = aggregateStats.get(mbean).get(statsName);
  207                       if(statsNameList.length() == 0 || statsValueList.length() == 0) {
  208                           // do not add a comma because this is the first occurrence
  209                           statsValueList += statsValue.toString();
  210                           statsNameList += statsName;
  211                       } else {
  212                           // add a comma
  213                           statsValueList += "," + statsValue.toString();
  214                           statsNameList += "," + statsName;
  215                       }
  216                   }
  217                   
  218                   // start talking to DB
  219                   openActiveConnection();
  220                   Statement stmt = conn.createStatement();
  221                   HashMap stats = aggregateStats.get(mbean);
  222                   //--------Ensure MBeans are in place
  223                   int mbeanId = getMBeanId(mbean); 
  224                   if(mbeanId != -1) {
  225                       // mbean already exists in the db
  226                   } else {
  227                       // doesn't exist in the db so add it
  228                       // add mbean record to the db
  229                       stmt.executeUpdate("INSERT INTO MBeans (mbeanName, statsNameList) VALUES ("+ surroundWithQuotes(mbean) + "," + surroundWithQuotes(statsNameList) + ")");
  230                       mbeanId = getMBeanId(mbean);
  231                   }
  232                   
  233                   // insert the statistics into Statistics table
  234                   stmt.executeUpdate( prepareInsertSnapshotStatement(currTime, statsValueList, mbeanId) );
  235                   closeConnection();
  236               }
  237           } catch(Exception  e){
  238               log.error(e.getMessage(), e);
  239               success = false;
  240           } finally {
  241               closeConnection();
  242           }
  243           
  244           // go through the archiving process
  245           try {
  246               int retentionDays = Integer.parseInt(SnapshotConfigXMLBuilder.getAttributeValue("retention"));
  247               long retentionMillis = (long)(retentionDays) * 86400000; // convert from days to milliseconds
  248               archiveSnapshots( Long.parseLong(currTime) - retentionMillis );
  249           } catch(Exception e) {
  250               log.warn("Cannot archive snapshots because attribute 'retention' is not present in snapshot-config.xml.");
  251           }
  252           return success;
  253       }
  254       
  255       /**
  256        * Moves records from the ActiveDB to the ArchiveDB. The records that are moved
  257        * are those whose snapshot_times exceed the retention period
  258        * @param cutOffTime - in milliseconds
  259        */
  260       private void archiveSnapshots(long cutOffTime) {
  261           // for each successful update of Snapshots/Statistics table
  262           // increment or decrement these counters to ensure that nothing is being 
  263           // lost in between. If these counters are non-zero, some records have been
  264           // lost.
  265           int snapshotsOver = 0;
  266           int statisticsOver = 0;
  267           try {
  268               openActiveConnection();
  269               ResultSet overDueSnapshotTimes = getOverDueSnapshotTimes(cutOffTime);
  270               ArrayList<Long> overdueTimes = new ArrayList<Long>();
  271               // save overdue times into an array list for later usage
  272               while(overDueSnapshotTimes.next()) {
  273                   overdueTimes.add(overDueSnapshotTimes.getLong( MonitorConstants.SNAPSHOT_TIME ));
  274               }
  275               closeConnection();
  276               // for each overdue snapshot time
  277               // -transfer all records associated with that snaphot_time to ArchiveDB
  278               for(int i = 0; i < overdueTimes.size(); i++) {
  279                   long snapshotTime = overdueTimes.get(i);
  280                   openActiveConnection();
  281                   ResultSet rsSnapshotData = fetchSnapshotDataFromDB(new Long(snapshotTime));
  282                   HashMap<String, HashMap<String, Long>> snapshotData = new HashMap<String,HashMap<String, Long>>();
  283                   while(rsSnapshotData.next()) {
  284                       // extract values from sql table
  285                       String mbeanName = rsSnapshotData.getString( MonitorConstants.MBEANNAME );
  286                       String statsNameList = rsSnapshotData.getString( MonitorConstants.STATSNAMELIST );
  287                       String statsValueList = rsSnapshotData.getString( MonitorConstants.STATSVALUELIST );
  288                       Long snapshot_time = rsSnapshotData.getLong( MonitorConstants.SNAPSHOT_TIME );
  289                       // get a connection to the archive db too
  290                       Connection archiveConn = archiveDS.getConnection();
  291                       Statement archiveStmt = archiveConn.createStatement();
  292                       //--------Ensure MBeans are in place
  293                       int mbeanId = getMBeanIdFromArchive(mbeanName); 
  294                       if(mbeanId != -1) {
  295                           // mbean already exists in the db
  296                       } else {
  297                           // doesn't exist in the db so add it
  298                           // add mbean record to the db
  299                           archiveStmt.executeUpdate("INSERT INTO MBeans (mbeanName, statsNameList) VALUES ("+ surroundWithQuotes(mbeanName) + ", " + surroundWithQuotes(statsNameList) + ")");
  300                           mbeanId = getMBeanIdFromArchive(mbeanName);
  301                       }
  302                       // ensure Statistics table has record of mbeanId, snapshotId, statsValue, statsName
  303                       String updateStr = prepareInsertSnapshotStatement(snapshot_time + "", statsValueList, mbeanId);
  304                       statisticsOver += archiveStmt.executeUpdate( updateStr );
  305                       // close connection to archiveDB
  306                       archiveConn.close();
  307                   }
  308                   closeConnection();
  309               }
  310               // for each snapshot time, remove all instances that is associated with in 
  311               // in the active DB
  312               for(int i = 0; i < overdueTimes.size(); i++) {
  313                   long snapshotTime = overdueTimes.get(i);
  314                   openActiveConnection();
  315                   Statement stmt = conn.createStatement();
  316                   // remove from Statistics table
  317                   String statisticsUpdate = "DELETE FROM Statistics WHERE snapshot_time=" + snapshotTime;
  318                   statisticsOver -= stmt.executeUpdate(statisticsUpdate);
  319                   closeConnection();
  320               }
  321           } catch(Exception e) {
  322               log.error(e.getMessage(), e);
  323           } finally {
  324               closeConnection();
  325           }
  326           
  327           // ensure that the transferring was good
  328           if(snapshotsOver != 0) {
  329               log.warn("Transferred snapshots was completed, but some things were lost.");
  330           }
  331           if(statisticsOver != 0) {
  332               log.warn("Transferred statistics was completed, but some things were lost.");
  333           }
  334       }
  335       
  336       /**
  337        * @param cutOffTime
  338        * @return An SQL table contain a column of all the times that did not make the cutOffTime.
  339        */
  340       private ResultSet getOverDueSnapshotTimes(long cutOffTime) {
  341           try {
  342               Statement stmt = conn.createStatement();
  343               String query = "SELECT DISTINCT snapshot_time FROM Statistics WHERE snapshot_time < " + cutOffTime;
  344               return stmt.executeQuery(query);
  345           } catch(Exception e) {
  346               log.error(e.getMessage(), e);
  347           }
  348           return null;
  349       }
  350       
  351       /**
  352        * @param mbean
  353        * @return The mbean id of the mbean from table ArchiveDB.MBean. Returns -1 if record does not exist.
  354        */
  355       private int getMBeanIdFromArchive(String mbean) throws Exception {
  356           int retval = -1;
  357           Connection archiveConn = archiveDS.getConnection();
  358           Statement stmt = archiveConn.createStatement();
  359           ResultSet rs = stmt.executeQuery("SELECT id FROM MBeans WHERE mbeanName=" + surroundWithQuotes(mbean));
  360           if(rs.next()) {
  361               retval = rs.getInt("id");
  362           }
  363           stmt.close();
  364           archiveConn.close();
  365           return retval;
  366       }
  367       
  368       /**
  369        * @param mbean
  370        * @return The mbean id of the mbean from table ActiveDB.MBean. Returns -1 if record does not exist.
  371        */
  372       private int getMBeanId(String mbean) throws Exception {
  373           int retval = -1;
  374           Connection conn = activeDS.getConnection();
  375           Statement stmt = conn.createStatement();
  376           ResultSet rs = stmt.executeQuery("SELECT id FROM MBeans WHERE mbeanName=" + surroundWithQuotes(mbean));
  377           if(rs.next()) {
  378               retval = rs.getInt("id");
  379           }
  380           stmt.close();
  381           conn.close();
  382           return retval;
  383       }
  384       
  385       /**
  386        * @param snapshot_time
  387        * @param statsValueList
  388        * @param mbeanId
  389        * @return Returns an SQL insert statement for one statistic given the correct information.
  390        */
  391       public String prepareInsertSnapshotStatement(String snapshot_time, String statsValueList, int mbeanId) {
  392           String retval = "INSERT INTO Statistics (snapshot_time, statsValueList, mbeanId) VALUES (";
  393           retval += snapshot_time;
  394           retval += ",";
  395           retval += surroundWithQuotes(statsValueList);
  396           retval += ",";
  397           retval += mbeanId;
  398           retval += ")";
  399           return retval;
  400       }
  401   
  402       /**
  403        * @param s
  404        * @return A String with ' at the beginning and end
  405        */
  406       private String surroundWithQuotes(String s) {
  407           return "'" + s.trim() + "'";
  408       }
  409       
  410       /**
  411        * Fetches the data stored from the snapshot thread and returns
  412        * it in a ArrayList with each element being a HashMap of the attribute
  413        * mapping to the statistic. Grabs 'numberOfSnapshots' snapshots. Grabs 
  414        * one snapshot per 'everyNthsnapshot'
  415        * 
  416        * @param numberOfSnapshot
  417        * @param everyNthSnapshot
  418        * @return ArrayList
  419        */ 
  420       public ArrayList<HashMap<String, HashMap<String, Object>>> fetchData(Integer numberOfSnapshot, 
  421                                                                                   Integer everyNthSnapshot) {
  422           ArrayList<HashMap<String, HashMap<String, Object>>> stats = new ArrayList<HashMap<String, HashMap<String, Object>>>();
  423           openActiveConnection();
  424           // get all records in the database grouped and ordered by time
  425           ResultSet table = fetchSnapshotTimesFromDB();
  426           // iterate through the table and finds the times (which uniquely IDs a snapshot)
  427           // that are wanted and queries the rest of the DB using the time as the condition
  428           // (i.e. the ones that are in the c*n-th snapshot where c <= numberOfSnapshot
  429           // and n == everyNthSnapshot)
  430           int nthSnapshot = 0;
  431           try {
  432               while(table.next()) {
  433                   Long snapshotTime = table.getLong( MonitorConstants.SNAPSHOT_TIME );
  434                   // grab 0*nth, 1*nth, 2*nth snapshot up to min(numberOfSnapshot*everyNthSnapshot, size of the table)
  435                   if(nthSnapshot % everyNthSnapshot == 0) {
  436                       HashMap<String, HashMap<String, Object>> snapshotData = packageSnapshotData(snapshotTime);
  437                       stats.add( 0, snapshotData );
  438                       numberOfSnapshot--;
  439                   }
  440                   nthSnapshot++;
  441                   // no more snapshots needs to be looked at, we have successfully acquired our goal
  442                   if(numberOfSnapshot == 0) {
  443                       break;
  444                   }
  445               }
  446           } catch(Exception e) {
  447               log.error(e.getMessage(), e);
  448           } finally {
  449               closeConnection();
  450           }
  451           return stats;
  452       }
  453       
  454       /**
  455        * @param snapshotTime
  456        * @return A hashmap in the form <String1, HashMap> where String1 is the mbean name
  457        * and HashMap is a map containing a <String2, Object> where String2 is an attribute name
  458        * and Object is the value. Additionally, if String is "times" then it maps to a HashMap
  459        * containing snapshot_time and snapshot_date information.
  460        */
  461       private HashMap<String, HashMap<String, Object>> packageSnapshotData(Long snapshotTime) {
  462           HashMap<String, HashMap<String, Object>> snapshotPkg = new HashMap<String, HashMap<String, Object>>();
  463           openActiveConnection();
  464           ResultSet snapshotData = fetchSnapshotDataFromDB(snapshotTime);
  465           try {
  466               // for each record save it somewhere in the snapshotPkg
  467               while(snapshotData.next()) {
  468                   String currMBean = snapshotData.getString( MonitorConstants.MBEANNAME );
  469                   // get the information for the mbean defined by currMBean
  470                   HashMap<String, Object> mbeanInfo = snapshotPkg.get(currMBean);
  471                   if(mbeanInfo == null) {
  472                       mbeanInfo = new HashMap<String, Object>();
  473                   }
  474                   // get statistics from resultset
  475                   String statsValueStr = snapshotData.getString( MonitorConstants.STATSVALUELIST );
  476                   String statsNameStr = snapshotData.getString( MonitorConstants.STATSNAMELIST );
  477                   String[] statsValueList = statsValueStr.split(",");
  478                   String[] statsNameList = statsNameStr.split(",");
  479                   assert(statsValueList.length == statsNameList.length);
  480                   // for each statsValue/statsName, save it
  481                   for(int i = 0 ; i < statsValueList.length; i++) {
  482                       long statValue = Long.parseLong(statsValueList[i]);
  483                       mbeanInfo.put(statsNameList[i], new Long(statValue));
  484                   }
  485                   // save the hashmap into the snapshotpkg
  486                   snapshotPkg.put(currMBean, mbeanInfo);
  487               }
  488           } catch(Exception e) {
  489               log.error(e.getMessage(), e);
  490           } finally {
  491               closeConnection();
  492           }
  493           // add the time and date
  494           HashMap<String, Object> timeMap = new HashMap<String, Object>();
  495           timeMap.put( MonitorConstants.SNAPSHOT_TIME, snapshotTime);
  496           snapshotPkg.put("times", timeMap);
  497           
  498           return snapshotPkg;
  499       }
  500       
  501       /**
  502        * @param snapshotTime
  503        * @return Returns a ResultSet with all statistic information that matches the snapshot_time.
  504        */
  505       private ResultSet fetchSnapshotDataFromDB(Long snapshotTime) {
  506           String query = "SELECT S.statsValueList AS statsValueList, M.statsNameList AS statsNameList, S.snapshot_time AS snapshot_time, M.mbeanName AS mbeanName FROM Statistics S, MBeans M WHERE S.snapshot_time=" + snapshotTime;
  507           query += " AND S.mbeanId=M.id";
  508           ResultSet retval = null;
  509           try {
  510               if(conn.isClosed()) {
  511                   openActiveConnection();
  512               }
  513               Statement stmt = conn.createStatement();
  514               retval = stmt.executeQuery(query);
  515           } catch(Exception e) {
  516               log.error(e.getMessage(), e);
  517           }
  518           return retval;
  519       }
  520   
  521       /**
  522        * @return Returns a ResultSet with one column (snapshot_time) sorted in descending order
  523        */
  524       private ResultSet fetchSnapshotTimesFromDB() {
  525           String query = "SELECT DISTINCT snapshot_time FROM Statistics ORDER BY snapshot_time DESC";
  526           ResultSet retval = null;
  527           try {
  528               if(conn.isClosed()) {
  529                   openActiveConnection();
  530               }
  531               Statement stmt = conn.createStatement();
  532               retval = stmt.executeQuery(query);
  533           } catch(Exception e) {
  534               log.error(e.getMessage(), e);
  535           }
  536           return retval;
  537       }
  538       
  539       /**
  540        * Opens the global connection to activeDB
  541        */
  542       private void openActiveConnection() {
  543           try {
  544               conn = activeDS.getConnection();
  545           } catch(Exception e) {
  546               log.error(e.getMessage(), e);
  547           }
  548       }
  549       
  550       /**
  551        * Opens the global connection to archiveDB
  552        */
  553       private void openArchiveConnection() {
  554           try {
  555               conn = archiveDS.getConnection();
  556           } catch(Exception e) {
  557               log.error(e.getMessage(), e);
  558           }
  559       }
  560       
  561       /**
  562        * Closes the global connection to a DB
  563        */
  564       private void closeConnection() {
  565           if(conn != null) {
  566               try {
  567                   conn.close();
  568               } catch(Exception e) {
  569                   log.error(e.getMessage(), e);
  570               }
  571           }
  572       }
  573       
  574       /**
  575        * @param mbeanName
  576        * @param statsName
  577        * @param numberOfSnapshots
  578        * @param everyNthSnapshot
  579        * @return HashMap which maps from a snapshot_time --> value of the mbean.statsName at that time
  580        */
  581       public TreeMap<Long, Long> getSpecificStatistics(    String mbeanName, 
  582                                                                   String statsName, 
  583                                                                   int numberOfSnapshots, 
  584                                                                   int everyNthSnapshot, 
  585                                                                   boolean showArchived) {
  586           openActiveConnection();
  587           TreeMap<Long, Long> stats = new TreeMap<Long, Long>();
  588           int nthSnapshot = 0;
  589           // attempt to get as many snapshots from the active db as possible
  590           try {
  591               Statement stmt = conn.createStatement();
  592               int mbeanId = getMBeanId(mbeanName);
  593               if(mbeanId == -1) {
  594                   log.error(mbeanName + " does not exist in the database.");
  595               } else {
  596                   String query = "SELECT DISTINCT snapshot_time, statsValueList, statsNameList FROM Statistics, MBeans M WHERE mbeanId=" + mbeanId + " AND mbeanId=M.id ORDER BY snapshot_time DESC";
  597                   ResultSet rs = stmt.executeQuery(query);
  598                   // iterate through the table paying attention to those at everyNthSnapshot-th position
  599                   while(rs.next()) {
  600                       // every nth snapshot I save the information into my returning hashmap
  601                       if(nthSnapshot % everyNthSnapshot == 0) {
  602                           String[] statsValueList = rs.getString( MonitorConstants.STATSVALUELIST ).split(",");
  603                           String[] statsNameList = rs.getString( MonitorConstants.STATSNAMELIST ).split(",");
  604                           assert(statsValueList.length == statsNameList.length);
  605                           Long statsValue = null;
  606                           for(int i = 0 ; i < statsNameList.length; i++) {
  607                               if(statsNameList[i].equals(statsName)) {
  608                                   long value = Long.parseLong(statsValueList[i]);
  609                                   statsValue = new Long(value);
  610                               }
  611                           }
  612                           // exit function after error
  613                           if(statsValue == null) {
  614                               log.warn("Statistics name '" + statsName + "' does not exist");
  615                               return stats;
  616                           } else {
  617                               stats.put(rs.getLong( MonitorConstants.SNAPSHOT_TIME ), statsValue);
  618                               numberOfSnapshots--;
  619                           }
  620                       }
  621                       // update counter
  622                       nthSnapshot++;
  623                       // enough data, end this thing
  624                       if(numberOfSnapshots == 0) {
  625                           break;
  626                       }
  627                   }
  628               }
  629           } catch(Exception e) {
  630               log.error(e.getMessage(), e);
  631           } finally {
  632               closeConnection();
  633           }
  634   
  635           nthSnapshot = 0;
  636   
  637           // attempt to get the remaining snapshots requested from the archive DB
  638           // iff the showArchive flag is set
  639           if(showArchived && numberOfSnapshots != 0) {
  640               try {
  641                   openArchiveConnection();    // connection to the Archive DB
  642                   Statement stmt = conn.createStatement();
  643                   int mbeanId = getMBeanId(mbeanName);
  644                   if(mbeanId == -1) {
  645                       log.error(mbeanName + " does not exist in the database.");
  646                   } else {
  647                       String query = "SELECT DISTINCT snapshot_time, statsValueList, statsNameList FROM Statistics, MBeans M WHERE mbeanId=" + mbeanId + " AND mbeanId=M.id ORDER BY snapshot_time DESC";
  648                       ResultSet rs = stmt.executeQuery(query);
  649                       // iterate through the table paying attention to those at everyNthSnapshot-th position
  650                       while(rs.next()) {
  651                           // every nth snapshot I save the information into my returning hashmap
  652                           if(nthSnapshot % everyNthSnapshot == 0) {
  653                               String[] statsValueList = rs.getString( MonitorConstants.STATSVALUELIST ).split(",");
  654                               String[] statsNameList = rs.getString( MonitorConstants.STATSNAMELIST ).split(",");
  655                               assert(statsValueList.length == statsNameList.length);
  656                               Long statsValue = null;
  657                               for(int i = 0 ; i < statsNameList.length; i++) {
  658                                   if(statsNameList[i].equals(statsName)) {
  659                                       long value = Long.parseLong(statsValueList[i]);
  660                                       statsValue = new Long(value);
  661                                   }
  662                               }
  663                               // exit function after error
  664                               if(statsValue == null) {
  665                                   log.warn("Statistics name '" + statsName + "' does not exist");
  666                                   return stats;
  667                               } else {
  668                                   stats.put(rs.getLong( MonitorConstants.SNAPSHOT_TIME ), statsValue);
  669                                   numberOfSnapshots--;
  670                               }
  671                           }
  672                           // update counter
  673                           nthSnapshot++;
  674                           // enough data, end this thing
  675                           if(numberOfSnapshots == 0) {
  676                               break;
  677                           }
  678                       }
  679                   }
  680               } catch(Exception e) {
  681                   log.error(e.getMessage(), e);
  682               } finally {
  683                   closeConnection();
  684               }
  685           }
  686           return stats;
  687       }
  688       
  689       /**
  690        * Sets the necessary data sources for this helper to talk to the db
  691        * @param activeDS
  692        * @param archiveDS
  693        */
  694       public void setDataSources(DataSource active, DataSource archive) {
  695           activeDS = active;
  696           archiveDS = archive;
  697       }
  698   }

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