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: */package org.apache.geronimo.monitoring.snapshot;
017:
018: import java.io.File;
019: import java.lang.reflect.UndeclaredThrowableException;
020: import java.util.ArrayList;
021: import java.util.HashMap;
022: import java.util.Iterator;
023: import java.util.Properties;
024: import java.util.Set;
025:
026: import javax.management.ObjectName;
027: import javax.management.ReflectionException;
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.MasterRemoteControlJMX;
035: import org.apache.geronimo.monitoring.snapshot.SnapshotConfigXMLBuilder;
036:
037: /**
038: * Thread that is in charge of executing every x milliseconds. Upon each
039: * iteration, a snapshot of the server's information is recorded.
040: */
041: public class SnapshotProcessor {
042:
043: private static Log log = LogFactory.getLog(SnapshotProcessor.class);
044:
045: /**
046: * Collects JSR-77 statistics for all mbeans that have been chosen to
047: * be monitored and stores it in a DB. Will also, archive snapshots
048: * if they have passed their retention period.
049: * @param username
050: * @param password
051: */
052: public static void takeSnapshot(/*String username, String password*/) {
053: // ensure that there is a 'monitoring' directory
054: SnapshotConfigXMLBuilder.ensureMonitorDir();
055: // get any saved mbean names from snapshot-config.xml
056: ArrayList<String> mbeanNames = SnapshotConfigXMLBuilder
057: .getMBeanNames();
058: // get a handle on the mrc
059: MasterRemoteControlJMX mrc = getMRC(/*username, password*/);
060: // in the case where nothing is present, grab a set of default mbeans
061: if (mbeanNames.size() <= 0) {
062: mbeanNames = getDefaultMBeanList(mrc);
063: }
064: // turn on all stats in the list
065: setStatsOn(mbeanNames, mrc);
066: try {
067: // take a snapshot
068: log.info("======SNAPSHOT======");
069: // instantiate map <mbean name, stats for mbean>
070: HashMap<String, HashMap<String, Long>> aggregateStats = new HashMap<String, HashMap<String, Long>>();
071: // for each mbean name in the list, get its stats
072: for (int i = 0; i < mbeanNames.size(); i++) {
073: String mbeanName = mbeanNames.get(i);
074: HashMap<String, Long> stats = (HashMap<String, Long>) mrc
075: .getStats(mbeanName);
076: aggregateStats.put(mbeanName, stats);
077: }
078:
079: // store the data in a DB
080: (new SnapshotDBHelper()).addSnapshotToDB(aggregateStats);
081:
082: for (Iterator itt = aggregateStats.keySet().iterator(); itt
083: .hasNext();) {
084: String mbean = (String) itt.next();
085: HashMap<String, Long> stats = aggregateStats.get(mbean);
086: log.info(mbean);
087: for (Iterator it = stats.keySet().iterator(); it
088: .hasNext();) {
089: String key = (String) it.next();
090: Long value = (Long) stats.get(key);
091: log.info(key + ": " + value);
092: }
093: }
094: } catch (Exception e) {
095: log.error(e.getMessage(), e);
096: }
097: }
098:
099: /**
100: * Turns all statistics on for each mbean in the list.
101: *
102: * @param mbeanList
103: */
104: private static void setStatsOn(ArrayList<String> mbeanList,
105: MasterRemoteControlJMX mrc) {
106: // for each mbean name in the list
107: for (int i = 0; i < mbeanList.size(); i++) {
108: // turn the statistics collection on
109: String methodName = "setStatsOn";
110: Object[] params = new Object[] { Boolean.TRUE };
111: String[] signatures = new String[] { "boolean" };
112: try {
113: ObjectName objName = new ObjectName(mbeanList.get(i));
114: mrc.invoke(objName, methodName, params, signatures);
115: log.info("Stats for " + mbeanList.get(i)
116: + " was turned on.");
117: } catch (UndeclaredThrowableException e) {
118: // HACK : this will happen for components that always collect statistics
119: // and do not have StatsOn method.
120: } catch (ReflectionException e) {
121: // HACK : this will happen for components that do not have setStatsOn()
122: } catch (Exception e) {
123: log.error(e.getMessage(), e);
124: }
125: }
126: }
127:
128: /**
129: * @return A list of all default mbeans; namely, all connector or container mbean names
130: * Prereq: in order to be a connector or container mbean the name must contain "Connector"/"Container"
131: * and "Tomcat"/"Jetty" or JVM.
132: */
133: private static ArrayList<String> getDefaultMBeanList(
134: MasterRemoteControlJMX mrc) {
135: Set<String> mbeans = MBeanHelper.getStatsProvidersMBeans(mrc
136: .getAllMBeanNames());
137: ArrayList<String> retval = new ArrayList<String>();
138: for (Iterator it = mbeans.iterator(); it.hasNext();) {
139: String name = (String) it.next();
140: if (((name.contains("Connector") || name
141: .contains("Container")) && (name.contains("Jetty") || name
142: .contains("Tomcat")))
143: || name.contains("JVM")) {
144: // this is a connector or JVM, so add to the list
145: retval.add(name);
146: // update the snapshot-config.xml to include these
147: SnapshotConfigXMLBuilder.addMBeanName(name);
148: }
149: }
150: return retval;
151: }
152:
153: /**
154: * @return An instance of a MRC.
155: */
156: public static MasterRemoteControlJMX getMRC(/*String username, String password*/) {
157: return new MasterRemoteControlJMX();
158: }
159: }
|