/**
* Helios, OpenSource Monitoring
* Brought to you by the Helios Development Group
*
* Copyright 2007, Helios Development Group and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*
*/
package org.helios.collector.jmx;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryUsage;
import java.lang.management.ThreadInfo;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeDataSupport;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.helios.apmrouter.jmx.JMXHelper;
import org.helios.apmrouter.metric.MetricType;
import org.helios.apmrouter.server.tracing.virtual.VirtualTracer;
import org.helios.apmrouter.trace.TracerFactory;
import org.helios.apmrouter.util.StringHelper;
import org.helios.collector.core.AbstractCollector;
import org.helios.collector.core.CollectionResult;
import org.helios.collector.core.CollectorException;
import org.helios.collector.jmx.connection.IMBeanServerConnectionFactory;
import org.helios.collector.jmx.connection.MBeanServerConnectionFactoryException;
import org.helios.collector.jmx.tracers.IObjectFormatter;
import org.helios.collector.jmx.tracers.IObjectTracer;
import org.helios.collector.jmx.tracers.JMXAttributeTrace;
import org.helios.collector.jmx.tracers.JMXObject;
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedResource;
/**
* <p>Title: JMXCollector</p>
* <p>Description: Collect and Trace JMX Attributes</p>
* <p>Company: Helios Development Group</p>
* @author Sandeep Malhotra (smalhotra@heliosdev.org)
* Whitehead (whitehead.nicholas@gmail.com)
*/
//TODO
// Support VirtualTracers
@ManagedResource
public class JMXCollector extends AbstractCollector {
/** The properties to make the MBean Server Connection */
protected Properties properties = new Properties();
/** The JMX Service URL for making an MBean Server Connection */
protected String jmxServiceURL = null;
/** The MBeanServerConnectionFactory to get a JMX Connection From */
protected IMBeanServerConnectionFactory connectionFactory = null;
/** The MBeanServerConnectionFactory to get a JMX Connection From */
protected MBeanServerConnection mBeanServerConnection = null;
/** JMXCollector Version*/
private static final String JMX_COLLECTOR_VERSION="0.1";
/** The availability MBean Object Name */
protected ObjectName availabilityMBean = null;
/** The availability MBean Attribute */
protected String availabilityAttribute = null;
/** Indicates if mapped metrics should be used for mxbeans */
protected boolean mappedMetrics = true;
/** The availability segments */
protected String[] availabilitySegment = null;
/** List that stores all JMXObjects fed from the config file */
protected List<JMXObject> jmxObjects = new ArrayList<JMXObject>();
/** List that stores all processed JMXObjects with resolved segment names */
protected Map<String, JMXObject> resolvedJMXObjects = new HashMap<String, JMXObject>();
/** Flag to indicate whether MXBeans should be traced */
protected boolean traceMXBeans = false;
/** The MXBean compiled segment */
protected String mxBeanSegment = null;
/** The composite type compound name delimeter. Defaults to "/" */
protected String compoundNameDelimeter = "/";
/** A map of MXBean ObjectNames keyed by the ObjectName string */
protected Map<String, ObjectName> mxBeanObjectNames = new HashMap<String, ObjectName>();
/** MXBean ObjectNames that should be included in MXBean Collection */
protected Set<ObjectName> includeMXBeans = new HashSet<ObjectName>();
/** MXBean ObjectNames that should be excluded in MXBean Collection */
protected Set<ObjectName> excludeMXBeans = new HashSet<ObjectName>();
/** MXBean ObjectNames and a boolean for ObjectNames that have been examined and included or excluded. */
protected Map<ObjectName, Boolean> tracedMXBeans = new HashMap<ObjectName, Boolean>(30);
/** Indicates if the one time collection of Runtime attributes has completed */
protected boolean runtimeCollected = false;
/** Indicates if compiler time monitoring is supported in the target VM */
protected Boolean supportsCompilerTime = null;
/** A map of GC ObjectNames keyed by the gc name */
protected Map<String, ObjectName> gcObjectNames = null;
/** GC MXBean Mask Object Name */
protected ObjectName gcMXBean = null;
/** The number of times subsidiary mbeans should be queried for before stopping */
protected int mbeanQueryAttempts = 5;
/** The number of times subsidiary mbeans have been queried for */
protected int mbeanQueryAttempted = 0;
/** The number of elapsed collections that should occur before GC % time is calculated */
protected int gCPollCycles = 5;
/** The number of elapsed collections that have occured since GC % time was calculated */
protected int gCPolledCycles = 0;
/** A map of GC Collection and Elapsed Times keyed by the gc name */
protected Map<String, long[]> gcTimes = new HashMap<String, long[]>();
/** An objectName / Attribute name for a virtual tracer host name */
protected String virtualHostLocator = null;
/** An objectName / Attribute name for a virtual tracer agent name */
protected String virtualAgentLocator = null;
/** The virtual tracer host */
protected String virtualHost = null;
/** The virtual tracer agent */
protected String virtualAgent = null;
/** A map of MemoryPool ObjectNames keyed by the memory pool name */
protected Map<String, ObjectName> memoryPoolObjectNames = null;
/** Memory Pool MXBean Mask Object Name */
protected ObjectName memoryPoolMXBean = null;
/** Indicates if thread deadlocking should be monitored */
protected boolean deadLockMonitor = false;
/** Indicates if thread contention monitoring is supported in the target VM */
protected Boolean supportsThreadContention = null;
/** Indicates if thread status aggregate summary should be monitored */
protected boolean threadMonitor = false;
public static final String[] NULL_SIG = new String[]{};
public static final Object[] NULL_ARG = new Object[]{};
protected static final String[] CLASS_LOADING_STATS = new String[]{"LoadedClassCount", "TotalLoadedClassCount", "UnloadedClassCount"};
protected static final String[] THREAD_STATS = new String[]{"ThreadCount", "DaemonThreadCount", "TotalStartedThreadCount", "PeakThreadCount"};
/** Thread State aggregator */
protected Map<Thread.State, Integer> threadStates = new HashMap<Thread.State, Integer>(12);
protected Context ctx = null;
/**
* The constructor for passing an instance of IMBeanServerConnectionFactory
*
* @param connectionFactory
*/
public JMXCollector(IMBeanServerConnectionFactory connectionFactory) {
this.connectionFactory=connectionFactory;
}
/**
* @param resetRequired
* false indicates that it's the initial startup of this collector so no reset required.
* true indicates that the original MBeanServerConnection has got invalid and
* needs to be recreated based on initial jndi properties or JMX Service URL passed
* through the bean configuration.
* @throws Exception
*/
protected void initMBeanServerConnection(boolean resetRequired) throws Exception {
try {
// first time connection creation
if(!resetRequired)
mBeanServerConnection = connectionFactory.getConnection();
//broken connection - try to recreate now...
else
mBeanServerConnection = connectionFactory.resetConnection();
if(ctx==null) {
ctx = new InitialContext();
}
if(this.virtualHostLocator!=null) {
virtualHost = (String)JMXHelper.getAttribute(mBeanServerConnection, virtualHostLocator);
if(virtualHost==null) {
warn("A virtual host locator [" + virtualHostLocator + "] was supplied but could not be resolved. A virtual tracer will not be used." );
}
}
if(this.virtualAgentLocator!=null && this.virtualHostLocator!=null) {
virtualAgent = (String)JMXHelper.getAttribute(mBeanServerConnection, virtualAgentLocator);
if(virtualHost==null) {
warn("A virtual agent locator [" + virtualAgentLocator + "] was supplied but could not be resolved. A virtual tracer will not be used." );
}
}
if(virtualHost!=null && virtualAgent!=null) {
//this.tracer = this.tracer.getVirtualTracer(virtualHost, virtualAgent);
this.tracer = TracerFactory.getTracer(virtualHost, virtualAgent, "JMXCollector", (int)(getCollectionPeriod()*2));
}
}catch(MBeanServerConnectionFactoryException mex){
throw new Exception("Unable to get MBeanServerConnection for JMXCollector",mex);
}catch(NamingException nex){
throw new Exception("Unable to initialize context",nex);
}catch(Exception ex){
throw new Exception("Unable to get MBeanServerConnection",ex);
}
}
public CollectionResult collectCallback() {
//long st = System.currentTimeMillis();
CollectionResult collectionResult = new CollectionResult();
resetProcessingFlag();
// Check the status of MBeanServerConnection
if(checkMBeanServerConnection(collectionResult)==false){
// Error getting MBean Server connection so no reason to proceed further
// Return the CollectionResult object back
return collectionResult;
}
// Run an additional availability check (if provided)
if(availabilityMBean != null && availabilityAttribute != null) {
if(availibilityCheck(collectionResult)==false){
// User MBean Server availability check failed so no reason to proceed further
// Return the CollectionResult object back
return collectionResult;
}
}
boolean anySuccess = false;
boolean anyFailure = false;
for(JMXObject tr: jmxObjects) {
try {
List<JMXAttributeTrace> jmxAttributeTraces = tr.getTargetAttributeTraces();
if(anyAttributesToProcess(tr, jmxAttributeTraces)==false){
// There are no attribute defined to query for this target objectName
// Skip the processing for this object and continue to next JMXObject
anyFailure=true;
continue;
}
Iterator<ObjectName> mbeans = null;
Map<ObjectName, Map<String, Object>> mappedValues;
try{
mappedValues = JMXHelper.getMBeanAttributeMap(mBeanServerConnection, tr.targetObjectName, compoundNameDelimeter, tr.getAttributeNames());
mbeans = mappedValues.keySet().iterator();
} catch (Exception ioex){
// Error communicating with MBean Server
anyFailure=true;
mBeanServerConnection = null;
if(logErrors)
error("Failed to read results from MBeanServer", ioex);
traceDefaultsForOffline();
collectionResult.setAnyException(ioex);
return determineStatus(anySuccess, anyFailure, collectionResult);
}
while(mbeans.hasNext()) {
ObjectName on = mbeans.next();
if(tr.getAttributeNames().size()>0){
// get values for all attributes in one swipe for this MBean
Map<String,Object> explodedResults = mappedValues.get(on);
if(explodedResults == null){
// Error occured while processing attributes for this MBean
// skip this one and proceed processing OTHER MBeans
anyFailure=true;
continue;
}
// Check whether this MBean has been processed before. if yes, then used resolved
// metric/segment/segmentPrefixElements instead of resolving tokens again
if(resolvedJMXObjects.containsKey(on.getCanonicalName())){
trace("Already have the key in cache: "+on.getCanonicalName());
JMXObject cachedObject = resolvedJMXObjects.get(on.getCanonicalName());
if(cachedObject!=null){
processCachedObject(on, cachedObject, explodedResults);
anySuccess=true;
cachedObject.setProcessed(true);
JMXObject tempObject = new JMXObject(cachedObject);
resolvedJMXObjects.put(on.getCanonicalName(),tempObject);
}
} else {
// Either a new MBean popped up as part of the returned results
// or its the first poll of this JMXCollector
trace("**************** No entry in cache for key : "+on.getCanonicalName());
processNonCachedObject(on, tr, explodedResults,jmxAttributeTraces);
anySuccess=true;
// Mark Processing status to true - If this key already exist in the list, its status will be changed to true, if not
// it will be added to this list with status true.
tr.setProcessed(true);
JMXObject tempObject = new JMXObject(tr);
resolvedJMXObjects.put(on.getCanonicalName(),tempObject);
tr.clearResolvedAttributes();
}
}
}
} catch (Exception ex) {
anyFailure=true;
if(logErrors)
error("Exception occured while tracing JMX Attributes for MBean: "+tr.getTargetObjectName(), ex);
continue;
}
}
// Done with processing of all online MBeans that were returned by this query. Now check whether
// there are any MBean(s) that were online during the last collection but are offline this time
traceDefaultsForOffline();
try {
if(traceMXBeans){
long startMX = System.currentTimeMillis();
collectMXBeans();
//tracer.trace(System.currentTimeMillis()-startMX, "Elapsed Time for MXBeans", StringHelper.append(tracingNameSpace,true,mxBeanSegment));
tracer.getDirectTracer().traceGauge(System.currentTimeMillis()-startMX, "ElapsedTimeMXBeans", StringHelper.append(false, tracingNameSpace,mxBeanSegment));
}
} catch (Exception mxe) {
anyFailure=true;
if(logErrors) {
error("MXBean Collection Error", mxe);
}
}
return determineStatus(anySuccess, anyFailure, collectionResult);
}
/**
* Iterates through all registered attributes and traces the default, if defined.
*/
protected void traceDefaultsForOffline() {
// Check if it is the first run for this JMXCollector. If yes, skip tracing
// defaults as we never got an MBeanServerConnection. Otherwise proceed with tracing defaults.
if(resolvedJMXObjects!=null && !resolvedJMXObjects.isEmpty()){
Iterator<String> keys = resolvedJMXObjects.keySet().iterator();
while(keys.hasNext()){
String tempKey = keys.next();
JMXObject cachedObject = resolvedJMXObjects.get(tempKey);
if(! cachedObject.isProcessed()){
for(int b=0; b<cachedObject.getResolvedAttributes().size();b++){
JMXAttributeTrace cachedTrace = cachedObject.getResolvedAttributes().get(b);
if(cachedTrace!=null && cachedTrace.getDefaultValue()!=null){
//- tracer.smartTrace(cachedTrace.getTraceType(),cachedTrace.getDefaultValue(),cachedTrace.getMetricName(), StringHelper.append(tracingNameSpace,true,cachedTrace.getResolvedPrefix()), "");
tracer.trace(cachedTrace.getDefaultValue(), cachedTrace.getMetricName(), cachedTrace.getResolvedTraceMetricType(), StringHelper.append(false, tracingNameSpace,cachedTrace.getResolvedPrefix()));
}
}
}
}
}
}
/**
*
*/
protected boolean availibilityCheck(CollectionResult result) {
try {
mBeanServerConnection.getAttribute(availabilityMBean, availabilityAttribute);
//tracer.traceSticky(1, defaultAvailabilityLabel, availabilitySegment);
tracer.traceGauge(1, defaultAvailabilityLabel, availabilitySegment);
return true;
} catch (Exception e) {
mBeanServerConnection=null;
traceAvailability(0);
if(logErrors) {
error("Exception Running Availability Check for [" + availabilityMBean + "/" + availabilityAttribute, e);
}
result.setResultForLastCollection(CollectionResult.Result.FAILURE);
result.setAnyException(e);
return false;
}
}
// /**
// * Resets the environment on initial start and reconnect.
// * The assumption is that on start or reset, the target MXBeans may have changed.
// */
// protected void resetEnv() {
// mxBeanObjectNames.clear();
// memoryPoolObjectNames= null;
// gcObjectNames= null;
// gcTimes = new HashMap<String, long[]>();
// supportsCompilerTime= null;
// supportsThreadContention= null;
// tracedMXBeans.clear();
// mbeanQueryAttempted = 0;
// gCPolledCycles = 0;
// runtimeCollected = false;
// if(mxBeanSegment==null) {
// mxBeanSegment = "MXBeans";
// }
// }
/**
* Utility method that determines the overall status of the last collect call status.
* It could be Success, Failure or Partial "Success"
*
* @param anySuccess
* @param anyFailure
* @param result
* @return
*/
protected CollectionResult determineStatus(boolean anySuccess, boolean anyFailure,
CollectionResult result) {
if(anyFailure){
if(anySuccess){
result.setResultForLastCollection(CollectionResult.Result.PARTIAL);
}else{
result.setResultForLastCollection(CollectionResult.Result.FAILURE);
}
}else {
result.setResultForLastCollection(CollectionResult.Result.SUCCESSFUL);
}
return result;
}
/**
* Query the MBeanServer for matching Attributes
*
* @param on ObjectName of the target MBean(s) (supports wildcard characters)
* @param tr JMXObject
* @return
*/
protected HashMap<String,Object> queryAttributes(ObjectName on, JMXObject tr) {
HashMap<String,Object> explodedResults=null;
try{
AttributeList attributeResults = new AttributeList();
attributeResults = mBeanServerConnection.getAttributes(on, tr.getAttributeNames().toArray(new String[0]));
if(attributeResults.size()>0){
explodedResults = new HashMap<String,Object>();
}
for(int a=0; a<attributeResults.size();a++){
Attribute attribute = (Attribute)attributeResults.get(a);
explodedResults.put(attribute.getName(),attribute.getValue());
}
} catch (IOException ioe){
mBeanServerConnection = null;
if(logErrors)
error("Failed to read results from MBeanServer", ioe);
} catch (InstanceNotFoundException infex) {
if(logErrors)
error("The specified object name does not exist: "+on.getCanonicalName(), infex);
} catch (ReflectionException rex) {
if(logErrors)
error("Error occured while executing getAttributes on this MBean: "+on.getCanonicalName(), rex);
}
return explodedResults;
}
/**
* Determine whether there are any Attributes to process
*/
protected boolean anyAttributesToProcess(JMXObject tr, List<JMXAttributeTrace> jmxAttributeTraces) {
if(tr.getAttributeNames()==null){
// First run - so prepare and cache the list of attributes that needs to be traced for the MBean(s)
// returned by the querying targetObjectName property
ArrayList<String> attributes = new ArrayList<String>();
for(int i=0;i<jmxAttributeTraces.size();i++){
attributes.add(jmxAttributeTraces.get(i).getTargetAttributeName());
}
tr.setAttributeNames(attributes);
}
if(tr.getAttributeNames().size()<=0){
if(logErrors)
error("No target attributes defined for: "+tr.targetObjectName);
return false;
}
return true;
}
protected void process(ObjectName on, JMXAttributeTrace trace,
Map<String, Object> explodedResults) {
if ( trace.getObjectTracers().size()<1 && trace.getObjectFormatters().size()<1){
Object attrValue = explodedResults.get(trace.getTargetAttributeName());
if(attrValue!=null) {
//- tracer.smartTrace(trace.getTraceType(),attrValue.toString(),trace.getMetricName(), StringHelper.append(tracingNameSpace,true,trace.getResolvedPrefix()), "");
tracer.trace(attrValue.toString(), trace.getMetricName(), trace.getResolvedTraceMetricType(), StringHelper.append(false, tracingNameSpace,trace.getResolvedPrefix()));
}
}
for(IObjectFormatter oFormatter: trace.getObjectFormatters()){
//- tracer.smartTrace(trace.getTraceType(),oFormatter.format(explodedResults.get(trace.getTargetAttributeName())),oFormatter.getMetricName().equals("")?trace.getMetricName():oFormatter.getMetricName(), StringHelper.append(tracingNameSpace,true,trace.getResolvedPrefix()), "");
tracer.trace(oFormatter.format(explodedResults.get(trace.getTargetAttributeName())), oFormatter.getMetricName().equals("")?trace.getMetricName():oFormatter.getMetricName(), trace.getResolvedTraceMetricType(), StringHelper.append(false,tracingNameSpace,trace.getResolvedPrefix()));
}
for(IObjectTracer oTracer: trace.getObjectTracers()){
try{
long start = System.currentTimeMillis();
oTracer.prepareBindings("remoteMBeanServer", mBeanServerConnection, "remoteObjectName", on, "localObjectName", objectName, "tracer", tracer, "tracingNameSpace",tracingNameSpace, "jndi", ctx);
if(! oTracer.trace(explodedResults.get(trace.getTargetAttributeName()))){
throw new Exception();
}
debug("** OTracer call completed in: "+ (System.currentTimeMillis()-start)+" milliseconds." );
}catch(Exception ex){
if(logErrors)
error("There was an error rendering traces for object tracer: " + oTracer + " for Bean: " + this.getBeanName(),ex);
}
}
}
protected void processNonCachedObject(ObjectName on, JMXObject tr, Map<String, Object> explodedResults,
List<JMXAttributeTrace> jmxAttributeTraces) {
for(int k=0;k<jmxAttributeTraces.size();k++){
JMXAttributeTrace trace = new JMXAttributeTrace(jmxAttributeTraces.get(k));
trace.setSegmentPrefixElements(resolveSegmentPrefix(trace.getSegmentPrefixElements(),on));
// Metric name is optional so set it to AttributeName if it's not provided in config file
if(trace.getMetricName() == null){
trace.setMetricName(trace.getTargetAttributeName());
} else if(trace.getMetricName().contains("{TARGET")) {
trace.setMetricName(formatName(trace.getMetricName(), on));
}
if(trace.getSegment()!=null && trace.getSegment().contains("{TARGET")){
trace.setSegment(formatName(trace.getSegment(),on));
trace.setResolvedPrefix(StringHelper.append(trace.getSegmentPrefixElements(),trace.getSegment()));
} else {
trace.setResolvedPrefix(trace.getSegmentPrefixElements());
}
process(on, trace, explodedResults);
// Cache Resolved JMXAttributeTrace for subsequent use
tr.getResolvedAttributes().add(trace);
}
}
protected void processCachedObject(ObjectName on, JMXObject cachedObject, Map<String,Object> explodedResults) {
for(int b=0; b<cachedObject.getResolvedAttributes().size();b++){
JMXAttributeTrace cachedTrace = cachedObject.getResolvedAttributes().get(b);
if(cachedTrace!=null){
process(on, cachedTrace, explodedResults);
}
}
}
protected boolean checkMBeanServerConnection(CollectionResult result) {
try {
if(mBeanServerConnection==null) {
initMBeanServerConnection(true);
//resetEnv();
}
traceAvailability(1);
return true;
} catch (Exception e) {
if(logErrors) error("Failed to get an MBean Server Connection for bean: " + this.getBeanName() + e);
traceAvailability(0);
traceDefaultsForOffline();
result.setResultForLastCollection(CollectionResult.Result.FAILURE);
result.setAnyException(e);
return false;
}
}
// ==============================================================================================
// Turning off availability tracing unless tracer is a VirtualTracer.
// Otherwise, when using a regular tracer, it incorrectly keeps the virtual tracer and agent alive
// when it should be marked down.
// ==============================================================================================
/**
* Traces the availability through the virtual tracer
* @param availability 0 for down, 1 for up
*/
protected void traceAvailability(int availability) {
if(availabilitySegment!=null) {
tracer.getDirectTracer().traceGauge(availability, defaultAvailabilityLabel, availabilitySegment);
} else {
tracer.getDirectTracer().traceGauge(availability, defaultAvailabilityLabel, getTracingNameSpace());
}
}
/**
* Executes the default MXBean collection
* @throws Exception
*/
protected void collectMXBeans() throws Exception {
if(!traceMXBeans) return;
// Collect Heap and Non Heap
processMemory();
// Runtime Env
processRuntime();
// Compile Time
processCompiler();
// Collect Class Loading
processClassLoading();
// Collect GC
processGCStats();
// Collect Memory Pools
processMemoryPools();
// Threads
processThreads();
if(mbeanQueryAttempted<=mbeanQueryAttempts) {
mbeanQueryAttempted++;
}
}
/**
* Determines if a MXBean objectName should be collected based on the include and exclude constraints.
* If the target is neither included or excluded, it will default to include.
* @param target The MXBean ObjectName to test.
* @return true if it should be collected, false if it should not.
*/
protected boolean shouldBeCollected(ObjectName target) {
if(tracedMXBeans.containsKey(target)) {
return tracedMXBeans.get(target);
} else {
// first examine includes
if(includeMXBeans.contains(target)) {
tracedMXBeans.put(target, true);
return true;
}
for(ObjectName on: includeMXBeans) {
if(on.apply(target)) {
tracedMXBeans.put(target, true);
return true;
}
}
// examine excludes
if(excludeMXBeans.contains(target)) {
tracedMXBeans.put(target, false);
return false;
}
for(ObjectName on: excludeMXBeans) {
if(on.apply(target)) {
tracedMXBeans.put(target, false);
return false;
}
}
// default is to include
tracedMXBeans.put(target, true);
return true;
}
}
/**
* Collects Thread stats
*/
protected void processThreads() {
ObjectName threadMXBean = null;
long totalStartedThreads = 0;
long activeThreads = 0;
long daemonThreads = 0;
long nonDaemonThreads = 0;
Integer peakThreadCount = 0;
long monitorLockedThreads[] = null;
ThreadInfo threadInfo = null;
long totalBlockTime = 0;
long totalBlockCount = 0;
long totalWaitTime = 0;
long totalWaitCount = 0;
try {
threadMXBean = mxBeanObjectNames.get(ManagementFactory.THREAD_MXBEAN_NAME);
if(threadMXBean==null) {
threadMXBean = new ObjectName(ManagementFactory.THREAD_MXBEAN_NAME);
Set<ObjectName> beanSet = mBeanServerConnection.queryNames(threadMXBean, null);
if(beanSet.size()==1)
mxBeanObjectNames.put(ManagementFactory.THREAD_MXBEAN_NAME, new ObjectName(beanSet.iterator().next().getCanonicalName()));
}
if(!shouldBeCollected(threadMXBean)) return;
AttributeList attrs = mBeanServerConnection.getAttributes(threadMXBean, THREAD_STATS);
activeThreads = (Integer)getValue(attrs, THREAD_STATS[0]);
daemonThreads = (Integer)getValue(attrs, THREAD_STATS[1]);
totalStartedThreads = (Long)getValue(attrs, THREAD_STATS[2]);
nonDaemonThreads = activeThreads - daemonThreads;
peakThreadCount = (Integer)(getValue(attrs, THREAD_STATS[3]));
String[] rootSegment = null;
if(mappedMetrics) {
rootSegment = new String[]{ROOT_MXBEAN_SEGMENT ,"category=Threads"};
} else {
rootSegment = StringHelper.append(false,tracingNameSpace,mxBeanSegment,"Threads");
}
// tracer.traceStickyDelta(totalStartedThreads, "Threads Started (Delta)", rootSegment);
// tracer.traceSticky(activeThreads, "Active Threads", rootSegment);
// tracer.traceSticky(daemonThreads, "Daemon Threads", rootSegment);
// tracer.traceSticky(nonDaemonThreads, "Non Daemon Threads", rootSegment);
// tracer.traceSticky(peakThreadCount, "Peak Thread Count", rootSegment);
tracer.trace(totalStartedThreads, "ThreadsStarted(Delta)", MetricType.DELTA_COUNTER, rootSegment);
tracer.traceGauge(activeThreads, "ActiveThreads", rootSegment);
tracer.traceGauge(daemonThreads, "DaemonThreads", rootSegment);
tracer.traceGauge(nonDaemonThreads, "NonDaemonThreads", rootSegment);
tracer.traceGauge(peakThreadCount, "PeakThreadCount", rootSegment);
long tmStart = System.currentTimeMillis();
long tmElapsed = 0;
if(deadLockMonitor) {
monitorLockedThreads = (long[])mBeanServerConnection.invoke(threadMXBean, "findMonitorDeadlockedThreads", NULL_ARG, NULL_SIG);
if(monitorLockedThreads==null) {
tracer.traceGauge(0, "MonitorDeadlockedThreads", rootSegment);
} else {
tracer.traceGauge(monitorLockedThreads.length, "MonitorDeadlockedThreads", rootSegment);
if(supportsThreadContention==null) {
supportsThreadContention = (Boolean)mBeanServerConnection.getAttribute(threadMXBean, "ThreadContentionMonitoringSupported");
if(supportsThreadContention) {
boolean enabled = (Boolean)mBeanServerConnection.getAttribute(threadMXBean, "ThreadContentionMonitoringEnabled");
if(!enabled) {
try {
mBeanServerConnection.setAttribute(threadMXBean, new Attribute("ThreadContentionMonitoringEnabled", true));
} catch (Exception e) {
warn("Failed to enable ThreadContentionMonitoring for" + objectName, e);
supportsThreadContention = false;
}
}
}
}
if(supportsThreadContention) {
rootSegment = StringHelper.append(false, tracingNameSpace,mxBeanSegment,"Threads", "Deadlocks");
CompositeData[] infos = (CompositeData[])mBeanServerConnection.invoke(threadMXBean, "getThreadInfo", new Object[]{monitorLockedThreads}, new String[]{"[J"});
for(CompositeData info: infos) {
threadInfo = ThreadInfo.from(info);
totalBlockCount += threadInfo.getBlockedCount();
totalBlockTime += threadInfo.getBlockedTime();
totalWaitCount += threadInfo.getWaitedCount();
totalWaitTime += threadInfo.getWaitedTime();
}
tracer.trace(totalBlockCount, "BlockCount", MetricType.DELTA_COUNTER, rootSegment);
tracer.trace(totalBlockTime, "BlockTime", MetricType.DELTA_GAUGE, rootSegment);
tracer.trace(totalWaitCount, "WaitCount", MetricType.DELTA_COUNTER, rootSegment);
tracer.trace(totalWaitTime, "WaitTime", MetricType.DELTA_GAUGE, rootSegment);
}
}
tmElapsed = System.currentTimeMillis() - tmStart;
tracer.traceGauge(tmElapsed, "DeadlockMonitorElapsedTime", StringHelper.append(false,tracingNameSpace,mxBeanSegment));
}
if(threadMonitor) {
rootSegment = StringHelper.append(false,tracingNameSpace,mxBeanSegment, "Threads");
tmStart = System.currentTimeMillis();
long[] allThreads = (long[])mBeanServerConnection.getAttribute(threadMXBean, "AllThreadIds");
CompositeData[] infos = (CompositeData[])mBeanServerConnection.invoke(threadMXBean, "getThreadInfo", new Object[]{allThreads}, new String[]{"[J"});
tmElapsed = System.currentTimeMillis()-tmStart;
tracer.traceGauge(tmElapsed, "ThreadMonitorElapsedTime", StringHelper.append(false, tracingNameSpace,mxBeanSegment));
rootSegment = StringHelper.append(false,tracingNameSpace,mxBeanSegment, "Threads", "States");
resetThreadStatus();
for(CompositeData info: infos) {
threadInfo = ThreadInfo.from(info);
incrementThreadState(threadInfo.getThreadState());
}
for(Entry<Thread.State, Integer> entry: threadStates.entrySet()) {
tracer.traceGauge(entry.getValue(), entry.getKey().toString(), rootSegment);
}
}
} catch (InstanceNotFoundException ine) {
if(logErrors) { warn("MXBean Collector (" + objectName + ") Could Not Locate MBean " + threadMXBean); }
} catch (Exception e) {
if(logErrors) {
error("Failed to process MXBean Threading Stats", e);
}
}
}
/**
* Resets all thread counts.
*/
protected void resetThreadStatus() {
for(Thread.State state: threadStates.keySet()) {
threadStates.put(state, 0);
}
}
/**
* Increments the thread status counter.
* @param state The thread state to increment.
*/
protected void incrementThreadState(Thread.State state) {
threadStates.put(state, threadStates.get(state)+1);
}
/**
* Retreieves a named value from an attribute list.
* @param al
* @param s
* @return The attribute value, or null if it is not found.
*/
protected Object getValue(AttributeList al, String s) {
for(int i=0; i<=al.size();i++){
Attribute attr = (Attribute)al.get(i);
if(s.equals(attr.getName())) return attr.getValue();
}
return null;
}
/**
* Collects memory pool stats
*/
protected void processMemoryPools() {
String rootSegment[] = null;
String poolType = null;
CompositeDataSupport usage = null;
try {
if(memoryPoolObjectNames==null) {
memoryPoolObjectNames = new HashMap<String, ObjectName>();
try {
memoryPoolMXBean = new ObjectName(ManagementFactory.MEMORY_POOL_MXBEAN_DOMAIN_TYPE+",name=*");
if(!shouldBeCollected(memoryPoolMXBean)) return;
Set<ObjectName> memoryPools = mBeanServerConnection.queryNames(memoryPoolMXBean, null);
if(memoryPools.size()==0) {
if(mbeanQueryAttempted<mbeanQueryAttempts) {
memoryPoolObjectNames=null;
return;
// will retry
}
}
for(ObjectName on: memoryPools) {
if(shouldBeCollected(on)) {
memoryPoolObjectNames.put(on.getKeyProperty("name"), on);
}
}
} catch (Exception e) {
// If an error occurs finding matching MBeans, it is probably because the target MBean was not available.
// Set the collection to null and retry next time.
memoryPoolObjectNames=null;
return;
}
}
if(!shouldBeCollected(memoryPoolMXBean)) return;
for(Entry<String, ObjectName> entry: memoryPoolObjectNames.entrySet()) {
poolType = (String)mBeanServerConnection.getAttribute(entry.getValue(), "Type");
usage = (CompositeDataSupport)mBeanServerConnection.getAttribute(entry.getValue(), "Usage");
if(mappedMetrics) {
rootSegment = new String[]{ROOT_MXBEAN_SEGMENT ,"category=MemoryPools", "type=" + poolType, "pool=" + entry.getKey()};
} else {
rootSegment = StringHelper.append(false,tracingNameSpace,mxBeanSegment,"Memory Pools", poolType, entry.getKey());
}
for(String key: usage.getCompositeType().keySet()) {
tracer.traceGauge((Long)usage.get(key),key,rootSegment);
}
getPercentUsedOfCommited(usage, rootSegment);
getPercentUsedOfCapacity(usage, rootSegment);
}
} catch (InstanceNotFoundException ine) {
if(logErrors) { warn("MXBean Collector (" + objectName + ") Could Not Locate MBean " + memoryPoolMXBean); }
} catch (IOException ioex){
if(logErrors) { error("There are some issues connecting to the MBeanServer for bean " + this.getBeanName()); }
mBeanServerConnection=null;
} catch (Exception e) {
if(logErrors) {
error("Failed to process MXBean Memory Pool Stats", e);
}
}
}
/**
* Collects garbage collector stats.
*/
protected void processGCStats() {
String rootSegment[] = null;
//CompositeDataSupport usage = null;
long collectionCount = 0;
long collectionTime = 0;
long elapsedTime = 0;
long elapsedGCTime = 0;
long currentTime = 0;
long percentGCTime = 0;
boolean pollGCPercent = false;
try {
if(gcObjectNames==null) {
gcObjectNames = new HashMap<String, ObjectName>();
try {
gcMXBean = new ObjectName(ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE+",name=*");
if(!shouldBeCollected(gcMXBean)) return;
Set<ObjectName> gcs = mBeanServerConnection.queryNames(gcMXBean, null);
if(gcs.size()==0) {
if(mbeanQueryAttempted<mbeanQueryAttempts) {
gcObjectNames=null;
return;
// will retry
}
}
for(ObjectName on: gcs) {
if(shouldBeCollected(on)) {
gcObjectNames.put(on.getKeyProperty("name"), on);
}
}
} catch (Exception e) {
// If an error occurs finding matching MBeans, it is probably because the target MBean was not available.
// Set the collection to null and retry next time.
gcObjectNames=null;
return;
}
}
if(!shouldBeCollected(gcMXBean)) return;
gCPolledCycles++;
if(gCPolledCycles>gCPollCycles) {
pollGCPercent=true;
gCPolledCycles=0;
} else {
pollGCPercent=false;
}
for(Entry<String, ObjectName> entry: gcObjectNames.entrySet()) {
if(mappedMetrics) {
rootSegment = new String[]{ROOT_MXBEAN_SEGMENT ,"category=GarbageCollection", "collector=" + entry.getKey()};
} else {
rootSegment = StringHelper.append(false, tracingNameSpace,mxBeanSegment,"Garbage Collectors", entry.getKey());
}
collectionCount = (Long)mBeanServerConnection.getAttribute(entry.getValue(), "CollectionCount");
collectionTime = (Long)mBeanServerConnection.getAttribute(entry.getValue(), "CollectionTime");
currentTime = System.currentTimeMillis();
tracer.trace(collectionTime, "CollectionTime(Delta)", MetricType.DELTA_GAUGE, rootSegment);
tracer.trace(collectionCount, "CollectionCount(Delta)", MetricType.DELTA_COUNTER, rootSegment);
if(pollGCPercent) {
if(gcTimes.containsKey(entry.getKey())) {
long[] times = gcTimes.get(entry.getKey());
elapsedTime = times[0] - currentTime;
elapsedGCTime = times[1] - collectionTime;
try {
percentGCTime = percent(elapsedGCTime, elapsedTime);
tracer.traceGauge(percentGCTime, "%TimeSpentInGC",rootSegment);
} catch (Exception e) {}
}
gcTimes.put(entry.getKey(), new long[]{currentTime, collectionTime});
}
}
} catch (InstanceNotFoundException ine) {
if(logErrors) { warn("MXBean Collector (" + objectName + ") Could Not Locate MBean " + gcMXBean); }
} catch (IOException ioex){
if(logErrors) { error("There are some issues connecting to the MBeanServer for bean " + this.getBeanName()); }
mBeanServerConnection=null;
} catch (Exception e) {
if(logErrors) {
error("Failed to process MXBean Garbage Collector Stats", e);
}
}
}
/**
* Collects memory stats
*/
protected void processClassLoading() {
ObjectName clMXBean = null;
AttributeList stats = null;
try {
clMXBean = mxBeanObjectNames.get(ManagementFactory.CLASS_LOADING_MXBEAN_NAME);
if(clMXBean==null) {
clMXBean = new ObjectName(ManagementFactory.CLASS_LOADING_MXBEAN_NAME);
Set<ObjectName> beanSet = mBeanServerConnection.queryNames(clMXBean, null);
if(beanSet.size()==1)
mxBeanObjectNames.put(ManagementFactory.CLASS_LOADING_MXBEAN_NAME, new ObjectName(beanSet.iterator().next().getCanonicalName()));
}
if(!shouldBeCollected(clMXBean)) return;
String rootSegment[] = null;
if(mappedMetrics) {
rootSegment = new String[]{ROOT_MXBEAN_SEGMENT ,"category=ClassLoading"};
} else {
rootSegment = StringHelper.append(false, tracingNameSpace,mxBeanSegment,"Class Loading");
}
stats = mBeanServerConnection.getAttributes(clMXBean, CLASS_LOADING_STATS);
for (int i=0;i<stats.size();i++){
Attribute attr = (Attribute)stats.get(i);
if("LoadedClassCount".equals(attr.getName())) {
tracer.traceGauge((Integer)attr.getValue(), attr.getName(),rootSegment);
} else {
tracer.trace(attr.getValue(), attr.getName()+"(Delta)", MetricType.DELTA_COUNTER, rootSegment);
}
}
} catch (InstanceNotFoundException ine) {
if(logErrors) { warn("MXBean Collector (" + objectName + ") Could Not Locate MBean " + clMXBean); }
} catch (IOException ioex){
if(logErrors) { error("There are some issues connecting to the MBeanServer for bean " + this.getBeanName()); }
mBeanServerConnection=null;
} catch (Exception e) {
if(logErrors) {
error("Failed to process MXBean Class Loading Stats", e);
}
}
}
/**
* Collects JIT Compiler stats
*/
protected void processCompiler() {
ObjectName jitMXBean = null;
try {
if(supportsCompilerTime != null && !supportsCompilerTime) return;
jitMXBean = mxBeanObjectNames.get(ManagementFactory.COMPILATION_MXBEAN_NAME);
if(jitMXBean==null) {
jitMXBean = new ObjectName(ManagementFactory.COMPILATION_MXBEAN_NAME);
Set<ObjectName> beanSet = mBeanServerConnection.queryNames(jitMXBean, null);
if(beanSet.size()==1)
mxBeanObjectNames.put(ManagementFactory.COMPILATION_MXBEAN_NAME, new ObjectName(beanSet.iterator().next().getCanonicalName()));
}
if(!shouldBeCollected(jitMXBean)) return;
if(supportsCompilerTime==null) {
supportsCompilerTime = (Boolean)mBeanServerConnection.getAttribute(jitMXBean, "CompilationTimeMonitoringSupported");
}
if(!supportsCompilerTime) return;
String rootSegment[] = null;
if(mappedMetrics) {
rootSegment = new String[]{ROOT_MXBEAN_SEGMENT ,"category=Compilation"};
} else {
rootSegment = StringHelper.append(false, tracingNameSpace,mxBeanSegment,"JIT Compiler");
}
long totalComplilationTime = (Long)mBeanServerConnection.getAttribute(jitMXBean, "TotalCompilationTime");
//tracer.traceStickyDelta(totalComplilationTime, "CompileTime(Delta)", rootSegment);
tracer.trace(totalComplilationTime, "TotalCompileTime", MetricType.DELTA_GAUGE, rootSegment);
} catch (InstanceNotFoundException ine) {
if(logErrors) { warn("MXBean Collector (" + objectName + ") Could Not Locate MBean " + jitMXBean); }
} catch (IOException ioex){
if(logErrors) { error("There are some issues connecting to the MBeanServer for bean " + this.getBeanName()); }
mBeanServerConnection=null;
} catch (Exception e) {
if(logErrors) {
error("Failed to process MXBean Class Loading Stats", e);
}
}
}
/**
* One time collection of runtime MXBean stats
*/
protected void processRuntime() {
ObjectName runTimeMXBean = null;
try {
if(runtimeCollected) return;
runTimeMXBean = mxBeanObjectNames.get(ManagementFactory.RUNTIME_MXBEAN_NAME);
if(runTimeMXBean==null) {
runTimeMXBean = new ObjectName(ManagementFactory.RUNTIME_MXBEAN_NAME);
Set<ObjectName> beanSet = mBeanServerConnection.queryNames(runTimeMXBean, null);
if(beanSet.size()==1)
mxBeanObjectNames.put(ManagementFactory.RUNTIME_MXBEAN_NAME, new ObjectName(beanSet.iterator().next().getCanonicalName()));
}
if(!shouldBeCollected(runTimeMXBean)) {
runtimeCollected = true;
return;
}
String[] rootSegment = StringHelper.append(false, tracingNameSpace,mxBeanSegment,"Runtime");
long startTime = (Long)mBeanServerConnection.getAttribute(runTimeMXBean, "StartTime");
String[] inputArguments = (String[])mBeanServerConnection.getAttribute(runTimeMXBean, "InputArguments");
StringBuilder buff = new StringBuilder();
for(String s: inputArguments) {
buff.append(s).append("\n");
}
tracer.trace(new Date(startTime), "Start Time", rootSegment);
tracer.trace(buff.toString(), "JVM Input Arguments",rootSegment);
runtimeCollected = true;
} catch (InstanceNotFoundException ine) {
if(logErrors) { warn("MXBean Collector (" + objectName + ") Could Not Locate MBean " + runTimeMXBean); }
} catch (IOException ioex){
if(logErrors) { error("There are some issues connecting to the MBeanServer for bean " + this.getBeanName()); }
mBeanServerConnection=null;
} catch (Exception e) {
if(logErrors) {
error("Failed to process MXBean Runtime Stats", e);
}
runtimeCollected = false;
}
}
/** The root segment name for mxbean mapped metrics */
public static String ROOT_MXBEAN_SEGMENT = "platform=JVM";
/**
* Collects memory stats
*/
protected void processMemory() {
ObjectName memoryMXBean = null;
try {
String rootSegment[] = null;
memoryMXBean = mxBeanObjectNames.get(ManagementFactory.MEMORY_MXBEAN_NAME);
if(memoryMXBean==null) {
memoryMXBean = new ObjectName(ManagementFactory.MEMORY_MXBEAN_NAME);
Set<ObjectName> beanSet = mBeanServerConnection.queryNames(memoryMXBean, null);
if(beanSet.size()==1)
mxBeanObjectNames.put(ManagementFactory.MEMORY_MXBEAN_NAME, new ObjectName(beanSet.iterator().next().getCanonicalName()));
}
if(!shouldBeCollected(memoryMXBean)) return;
CompositeDataSupport heap = (CompositeDataSupport) mBeanServerConnection.getAttribute(memoryMXBean, "HeapMemoryUsage");
if(mappedMetrics) {
rootSegment = new String[]{ROOT_MXBEAN_SEGMENT ,"category=Memory", "type=Heap"};
} else {
rootSegment = StringHelper.append(false, tracingNameSpace,mxBeanSegment,"Memory", "Heap Memory Usage");
}
for(String key: heap.getCompositeType().keySet()) {
tracer.trace(heap.get(key),key,rootSegment);
}
getPercentUsedOfCommited(heap, rootSegment);
getPercentUsedOfCapacity(heap, rootSegment);
CompositeDataSupport nonHeap = (CompositeDataSupport) mBeanServerConnection.getAttribute(memoryMXBean, "NonHeapMemoryUsage");
if(mappedMetrics) {
rootSegment = new String[]{ROOT_MXBEAN_SEGMENT ,"category=Memory", "type=NonHeap"};
} else {
rootSegment = StringHelper.append(false, tracingNameSpace,mxBeanSegment, "Memory", "Non Heap Memory Usage");
}
for(String key: nonHeap.getCompositeType().keySet()) {
tracer.trace(heap.get(key),key,rootSegment);
}
getPercentUsedOfCommited(nonHeap, rootSegment);
getPercentUsedOfCapacity(nonHeap, rootSegment);
if(mappedMetrics) {
rootSegment = new String[]{ROOT_MXBEAN_SEGMENT ,"category=Memory"};
} else {
rootSegment = StringHelper.append(false, tracingNameSpace,mxBeanSegment, "Memory");
}
tracer.trace(mBeanServerConnection.getAttribute(memoryMXBean, "ObjectPendingFinalizationCount"), "Objects Pending Finalization",rootSegment);
} catch (InstanceNotFoundException ine) {
if(logErrors) { warn("MXBean Collector for bean collector " + this.getBeanName() + " could Not Locate MBean " + memoryMXBean); }
} catch (IOException ioex){
if(logErrors) { error("There are some issues connecting to the MBeanServer for bean " + this.getBeanName()); }
mBeanServerConnection=null;
}catch (Exception e) {
if(logErrors) {
error("Failed to process MXBean Memory Stats", e);
}
}
}
/**
* Calculates the percentage of commited memory in use.
* @param cd A CompositeDataSupport that can generate a MemoryUsage.
* @param rootSegment The root segment for the tracing. Will not trace if this is zero length.
* @return the percentage of commited memory in use
*/
protected long getPercentUsedOfCommited(CompositeDataSupport cd, String...rootSegment) {
long value = -1;
MemoryUsage memoryUsage = MemoryUsage.from(cd);
try {
value = percent(memoryUsage.getUsed(), memoryUsage.getCommitted());
if(rootSegment.length>0) {
tracer.trace(value,"Used %",rootSegment);
}
} catch (Exception e) {
value = -1;
}
return value;
}
/**
* Helper method to generate a percentage.
* @param part
* @param all
* @return A percentage value.
*/
protected static long percent(float part, float all) {
return (long)((part)/all*100);
}
/**
* Calculates the percentage of total capacity memory in use.
* @param cd A CompositeDataSupport that can generate a MemoryUsage.
* @param rootSegment The root segment for the tracing. Will not trace if this is zero length.
* @return percentage of total capacity memory in use.
*/
protected long getPercentUsedOfCapacity(CompositeDataSupport cd, String...rootSegment) {
long value = -1;
MemoryUsage memoryUsage = MemoryUsage.from(cd);
try {
value = percent(memoryUsage.getUsed(), memoryUsage.getMax());
if(rootSegment.length>0) {
tracer.trace(value, "Capacity %", rootSegment);
}
} catch (Exception e) {
value = -1;
}
return value;
}
/**
* Tokenizes segment prefix elements.
* Should be called on start() to ensure that the sequencing of attribute sets does not impact tokens.
*/
protected String[] resolveSegmentPrefix(String[] unresolvedSegmentPrefix, ObjectName on) {
if(unresolvedSegmentPrefix==null || unresolvedSegmentPrefix.length < 1) {
unresolvedSegmentPrefix = new String[0];
} else {
for(int i = 0; i < unresolvedSegmentPrefix.length; i++) {
unresolvedSegmentPrefix[i] = formatName(unresolvedSegmentPrefix[i],on);
}
}
return unresolvedSegmentPrefix;
}
/**
* Reset Processing Status for each resolved Object to false
*/
public void resetProcessingFlag(){
if(resolvedJMXObjects!=null && !resolvedJMXObjects.isEmpty()){
Iterator<String> keys = resolvedJMXObjects.keySet().iterator();
while(keys.hasNext()){
String tempKey = keys.next();
JMXObject tempObject = resolvedJMXObjects.get(tempKey);
tempObject.setProcessed(false);
resolvedJMXObjects.put(tempKey,tempObject);
}
}
}
@ManagedAttribute
public String getCollectorVersion() {
return "JMXCollector v. "+JMX_COLLECTOR_VERSION;
}
/**
*
*/
public void startCollector() throws CollectorException {
try{
initMBeanServerConnection(false);
}catch(Exception ex){
throw new CollectorException("An error occured while creating an MBean Server connection", ex);
}
}
/**
*
*/
public void stopCollector(){
if(mBeanServerConnection!=null){
mBeanServerConnection = null;
}
}
/**
* @param jndiProperties the jndiProperties to set
*/
public void setJndiProperties(Properties jndiProperties) {
this.properties = jndiProperties;
}
/**
* @return the connectionFactory
*/
public IMBeanServerConnectionFactory getConnectionFactory() {
return connectionFactory;
}
/**
* @param connectionFactory the connectionFactory to set
*/
public void setConnectionFactory(IMBeanServerConnectionFactory connectionFactory) {
this.connectionFactory = connectionFactory;
}
/**
* @return the availabilityMBean
*/
@ManagedAttribute
public String getAvailabilityMBean() {
if(availabilityMBean!=null)
return availabilityMBean.toString();
else
return "";
}
/**
* @param availabilityMBean the availabilityMBean to set
*/
public void setAvailabilityMBean(String availabilityMBean) {
try {
this.availabilityMBean = ObjectName.getInstance(availabilityMBean);
} catch (MalformedObjectNameException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
}
}
/**
* @return the availabilityAttribute
*/
@ManagedAttribute
public String getAvailabilityAttribute() {
return availabilityAttribute;
}
/**
* @param availabilityAttribute the availabilityAttribute to set
*/
public void setAvailabilityAttribute(String availabilityAttribute) {
this.availabilityAttribute = availabilityAttribute;
}
/**
* @return the availabilitySegment
*/
@SuppressWarnings("cast")
@ManagedAttribute
public String[] getAvailabilitySegment() {
return (String[])availabilitySegment.clone();
}
/**
* @param availabilitySegment the availabilitySegment to set
*/
public void setAvailabilitySegment(String[] availabilitySegment) {
this.availabilitySegment = availabilitySegment;
}
/**
* @return the jmxObjects
*/
public List<JMXObject> getJmxObjects() {
return jmxObjects;
}
/**
* @param jmxObjects the jmxObjects to set
*/
public void setJmxObjects(List<JMXObject> jmxObjects) {
this.jmxObjects = jmxObjects;
}
/**
* @return the traceMXBeans
*/
@ManagedAttribute
public boolean getTraceMXBeans() {
return traceMXBeans;
}
/**
* @param traceMXBeans the traceMXBeans to set
*/
public void setTraceMXBeans(boolean traceMXBeans) {
this.traceMXBeans = traceMXBeans;
}
/**
* @return the mXBeanSegment
*/
@ManagedAttribute
public String getMxBeanSegment() {
return mxBeanSegment;
}
/**
* @param beanSegment the mXBeanSegment to set
*/
public void setMxBeanSegment(String beanSegment) {
mxBeanSegment = beanSegment;
}
/**
* @return the deadLockMonitor
*/
@ManagedAttribute
public boolean getDeadLockMonitor() {
return deadLockMonitor;
}
/**
* @param deadLockMonitor the deadLockMonitor to set
*/
public void setDeadLockMonitor(boolean deadLockMonitor) {
this.deadLockMonitor = deadLockMonitor;
}
/**
* Returns the virtual host locator.
* @return the virtual host locator.
*/
@ManagedAttribute
public String getVirtualHostLocator() {
return virtualHostLocator;
}
/**
* Sets the virtual host locator
* @param virtualHostLocator
*/
public void setVirtualHostLocator(String virtualHostLocator) {
this.virtualHostLocator = virtualHostLocator;
}
/**
* Returns the virtual agent locator.
* @return the virtual agent locator.
*/
@ManagedAttribute
public String getVirtualAgentLocator() {
return virtualAgentLocator;
}
/**
* Sets the virtual agent locator.
* @param virtualAgentLocator
*/
public void setVirtualAgentLocator(String virtualAgentLocator) {
this.virtualAgentLocator = virtualAgentLocator;
}
/**
* Returns the virtual host for this target MBeanServer
* @return the virtual host for this target MBeanServer
*/
@ManagedAttribute
public String getVirtualHost() {
return virtualHost;
}
/**
* Sets the virtual host for the Target MBeanServer
* @param virtualHost
*/
@ManagedAttribute
public void setVirtualHost(String virtualHost){
this.virtualHost = virtualHost;
}
/**
* Returns the virtual agent for this target MBeanServer
* @return the virtual agent for this target MBeanServer
*/
@ManagedAttribute
public String getVirtualAgent() {
return virtualAgent;
}
/**
* Sets the virtual agent for the Target MBeanServer
* @param virtualAgent
*/
@ManagedAttribute
public void setVirtualAgent(String virtualAgent){
this.virtualAgent = virtualAgent;
}
/**
* Indicates if mapped metrics should be used for mxbean tracing
* @return true to use mapped metrics, false for flat
*/
@ManagedAttribute(description="Indicates if mapped metrics should be used for mxbean tracing")
public boolean isMappedMetrics() {
return mappedMetrics;
}
/**
* Sets the mapped metrics indicator for mxbean tracing
* @param mappedMetrics true to use mapped metrics, false for flat
*/
@ManagedAttribute(description="Indicates if mapped metrics should be used for mxbean tracing")
public void setMappedMetrics(boolean mappedMetrics) {
this.mappedMetrics = mappedMetrics;
}
}