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.io.File; 20 import java.lang.reflect.UndeclaredThrowableException; 21 import java.util.ArrayList; 22 import java.util.HashMap; 23 import java.util.Set; 24 25 import javax.management.ObjectName; 26 27 import org.apache.geronimo.kernel.NoSuchOperationException; 28 import org.apache.geronimo.monitoring.MBeanHelper; 29 import org.apache.geronimo.monitoring.MasterRemoteControl; 30 import org.slf4j.Logger; 31 import org.slf4j.LoggerFactory; 32 33 /** 34 * Thread that is in charge of executing every x milliseconds. Upon each 35 * iteration, a snapshot of the server's information is recorded. 36 */ 37 public class SnapshotProcessor { 38 39 private static final Logger log = LoggerFactory.getLogger(SnapshotProcessor.class); 40 41 /** 42 * Collects JSR-77 statistics for all mbeans that have been chosen to 43 * be monitored and stores it in a DB. Will also, archive snapshots 44 * if they have passed their retention period. 45 * @param mrc 46 */ 47 public static void takeSnapshot(MasterRemoteControl mrc) { 48 // ensure that there is a 'monitoring' directory 49 ensureMonitorDir(); 50 // get any saved mbean names from snapshot-config.xml 51 ArrayList<String> mbeanNames = SnapshotConfigXMLBuilder.getMBeanNames(); 52 // in the case where nothing is present, grab a set of default mbeans 53 if(mbeanNames.size() <= 0) { 54 mbeanNames = getDefaultMBeanList(mrc); 55 } 56 // turn on all stats in the list 57 setStatsOn(mbeanNames, mrc); 58 try { 59 // take a snapshot 60 log.info("======SNAPSHOT======"); 61 // instantiate map <mbean name, stats for mbean> 62 HashMap<String, HashMap<String, Long>> aggregateStats = new HashMap<String, HashMap<String, Long>>(); 63 // for each mbean name in the list, get its stats 64 for (String mbeanName : mbeanNames) { 65 HashMap<String, Long> stats = mrc.getStats(mbeanName); 66 aggregateStats.put(mbeanName, stats); 67 } 68 69 // store the data in a DB 70 (new SnapshotDBHelper()).addSnapshotToDB(aggregateStats); 71 72 for (String mbean : aggregateStats.keySet()) { 73 HashMap<String, Long> stats = aggregateStats.get(mbean); 74 log.info(mbean); 75 for (String key : stats.keySet()) { 76 Long value = stats.get(key); 77 log.info(key + ": " + value); 78 } 79 } 80 } catch(Exception e) { 81 log.error(e.getMessage(), e); 82 } 83 } 84 85 /** 86 * Turns all statistics on for each mbean in the list. 87 * 88 * @param mbeanList 89 */ 90 private static void setStatsOn(ArrayList<String> mbeanList, MasterRemoteControl mrc) { 91 // for each mbean name in the list 92 for (String aMbeanList : mbeanList) { 93 // turn the statistics collection on 94 String methodName = "setStatsOn"; 95 Object[] params = new Object[]{Boolean.TRUE}; 96 String[] signatures = new String[]{"boolean"}; 97 try { 98 ObjectName objName = new ObjectName(aMbeanList); 99 mrc.invoke(objName, methodName, params, signatures); 100 log.info("Stats for " + aMbeanList + " was turned on."); 101 } catch (UndeclaredThrowableException e) { 102 // HACK : this will happen for components that always collect statistics 103 // and do not have StatsOn method. 104 } catch (javax.management.ReflectionException e) { 105 if (!(e.getCause() instanceof java.lang.NoSuchMethodException) || !(e.getCause().getCause() instanceof NoSuchOperationException)) { 106 log.error("unexpected jmx exception", e); 107 } 108 //othewise ignore -- presumably something changed in exception handling. 109 } catch (Exception e) { 110 log.error(e.getMessage(), e); 111 } 112 } 113 } 114 115 /** 116 * @return A list of all default mbeans; namely, all connector or container mbean names 117 * Prereq: in order to be a connector or container mbean the name must contain "Connector"/"Container" 118 * and "Tomcat"/"Jetty" or JVM. 119 */ 120 private static ArrayList<String> getDefaultMBeanList(MasterRemoteControl mrc) { 121 Set<String> mbeans = MBeanHelper.getStatsProvidersMBeans( mrc.getAllMBeanNames() ); 122 ArrayList<String> retval = new ArrayList<String>(); 123 for (Object mbean : mbeans) { 124 String name = (String) mbean; 125 if (((name.contains("Connector") || name.contains("Container")) && (name.contains("Jetty") || name.contains("Tomcat"))) 126 || name.contains("JVM")) { 127 // this is a connector or JVM, so add to the list 128 retval.add(name); 129 // update the snapshot-config.xml to include these 130 SnapshotConfigXMLBuilder.addMBeanName(name); 131 } 132 } 133 return retval; 134 } 135 136 /** 137 * Checks to see if the GERONIMO_HOME/var/monitoring/ directory was made. 138 * If not, the method creates it. 139 */ 140 public static void ensureMonitorDir() { 141 final String pathToDir = 142 System.getProperty("org.apache.geronimo.home.dir") + "/var/monitoring/"; 143 File dir = new File(pathToDir); 144 if(dir.exists() && dir.isDirectory()) { 145 // all good 146 return; 147 } else { 148 // make a directory 149 if(dir.mkdir()) { 150 // directory was successfully created 151 log.info("/var/monitoring directory created."); 152 return; 153 } else { 154 log.error("Could not make the directory " + pathToDir); 155 } 156 } 157 } 158 159 }