001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.geronimo.monitoring.snapshot; 018 019 import java.io.File; 020 import java.lang.reflect.UndeclaredThrowableException; 021 import java.util.ArrayList; 022 import java.util.HashMap; 023 import java.util.Iterator; 024 import java.util.Properties; 025 import java.util.Set; 026 027 import javax.management.ObjectName; 028 import javax.naming.Context; 029 import javax.naming.InitialContext; 030 031 import org.apache.commons.logging.Log; 032 import org.apache.commons.logging.LogFactory; 033 import org.apache.geronimo.monitoring.MBeanHelper; 034 import org.apache.geronimo.monitoring.MasterRemoteControlLocal; 035 036 /** 037 * Thread that is in charge of executing every x milliseconds. Upon each 038 * iteration, a snapshot of the server's information is recorded. 039 */ 040 public class SnapshotProcessor { 041 042 private static Log log = LogFactory.getLog(SnapshotProcessor.class); 043 044 /** 045 * Collects JSR-77 statistics for all mbeans that have been chosen to 046 * be monitored and stores it in a DB. Will also, archive snapshots 047 * if they have passed their retention period. 048 * @param username 049 * @param password 050 */ 051 public static void takeSnapshot(String username, String password) { 052 // ensure that there is a 'monitoring' directory 053 ensureMonitorDir(); 054 // get any saved mbean names from snapshot-config.xml 055 ArrayList<String> mbeanNames = SnapshotConfigXMLBuilder.getMBeanNames(); 056 // get a handle on the mrc 057 MasterRemoteControlLocal mrc = getMRC(username, password); 058 // in the case where nothing is present, grab a set of default mbeans 059 if(mbeanNames.size() <= 0) { 060 mbeanNames = getDefaultMBeanList(mrc); 061 } 062 // turn on all stats in the list 063 setStatsOn(mbeanNames, mrc); 064 try { 065 // take a snapshot 066 log.info("======SNAPSHOT======"); 067 // instantiate map <mbean name, stats for mbean> 068 HashMap<String, HashMap<String, Long>> aggregateStats = new HashMap<String, HashMap<String, Long>>(); 069 // for each mbean name in the list, get its stats 070 for(int i = 0; i < mbeanNames.size(); i++) { 071 String mbeanName = mbeanNames.get(i); 072 HashMap<String, Long> stats = (HashMap<String, Long>)mrc.getStats(mbeanName); 073 aggregateStats.put(mbeanName, stats); 074 } 075 076 // store the data in a DB 077 (new SnapshotDBHelper()).addSnapshotToDB(aggregateStats); 078 079 for(Iterator itt = aggregateStats.keySet().iterator(); itt.hasNext(); ) { 080 String mbean = (String)itt.next(); 081 HashMap<String, Long> stats = aggregateStats.get(mbean); 082 log.info(mbean); 083 for(Iterator it = stats.keySet().iterator(); it.hasNext(); ) { 084 String key = (String)it.next(); 085 Long value = (Long)stats.get(key); 086 log.info(key + ": " + value); 087 } 088 } 089 } catch(Exception e) { 090 log.error(e.getMessage(), e); 091 } 092 } 093 094 /** 095 * Turns all statistics on for each mbean in the list. 096 * 097 * @param mbeanList 098 */ 099 private static void setStatsOn(ArrayList<String> mbeanList, MasterRemoteControlLocal mrc) { 100 // for each mbean name in the list 101 for(int i = 0; i < mbeanList.size(); i++) { 102 // turn the statistics collection on 103 String methodName = "setStatsOn"; 104 Object[] params = new Object[] { Boolean.TRUE }; 105 String[] signatures = new String[] { "boolean" }; 106 try { 107 ObjectName objName = new ObjectName(mbeanList.get(i)); 108 mrc.invoke(objName, methodName, params, signatures); 109 log.info("Stats for " + mbeanList.get(i) + " was turned on."); 110 }catch (UndeclaredThrowableException e) { 111 // HACK : this will happen for components that always collect statistics 112 // and do not have StatsOn method. 113 } catch(Exception e) { 114 log.error(e.getMessage(), e); 115 } 116 } 117 } 118 119 /** 120 * @return A list of all default mbeans; namely, all connector or container mbean names 121 * Prereq: in order to be a connector or container mbean the name must contain "Connector"/"Container" 122 * and "Tomcat"/"Jetty" or JVM. 123 */ 124 private static ArrayList<String> getDefaultMBeanList(MasterRemoteControlLocal mrc) { 125 Set<String> mbeans = MBeanHelper.getStatsProvidersMBeans( mrc.getAllMBeanNames() ); 126 ArrayList<String> retval = new ArrayList<String>(); 127 for(Iterator it = mbeans.iterator(); it.hasNext(); ) { 128 String name = (String)it.next(); 129 if(((name.contains("Connector") || name.contains("Container")) && (name.contains("Jetty") || name.contains("Tomcat"))) 130 || name.contains("JVM")) { 131 // this is a connector or JVM, so add to the list 132 retval.add(name); 133 // update the snapshot-config.xml to include these 134 SnapshotConfigXMLBuilder.addMBeanName(name); 135 } 136 } 137 return retval; 138 } 139 140 /** 141 * Checks to see if the GERONIMO_HOME/var/monitoring/ directory was made. 142 * If not, the method creates it. 143 */ 144 public static void ensureMonitorDir() { 145 final String pathToDir = 146 System.getProperty("org.apache.geronimo.home.dir") + "/var/monitoring/"; 147 File dir = new File(pathToDir); 148 if(dir.exists() && dir.isDirectory()) { 149 // all good 150 return; 151 } else { 152 // make a directory 153 if(dir.mkdir()) { 154 // directory was successfully created 155 log.info("/var/monitoring directory created."); 156 return; 157 } else { 158 log.error("Could not make the directory " + pathToDir); 159 } 160 } 161 } 162 163 /** 164 * @return An instance of a MRC. 165 */ 166 public static MasterRemoteControlLocal getMRC(String username, String password) { 167 Properties props = new Properties(); 168 props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.LocalInitialContextFactory"); 169 props.setProperty(Context.SECURITY_PRINCIPAL, username); 170 props.setProperty(Context.SECURITY_CREDENTIALS, password); 171 props.setProperty("openejb.authentication.realmName", "geronimo-admin"); 172 try { 173 Context ic = new InitialContext(props); 174 MasterRemoteControlLocal mrc = (MasterRemoteControlLocal)ic.lookup("ejb/mgmt/MRCLocal"); 175 return mrc; 176 } catch(Exception e) { 177 return null; 178 } 179 } 180 }