All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.pcp.parfait.jmx.MonitoredMBeanAttributeFactory Maven / Gradle / Ivy

Go to download

Library to allow Parfait to import metric values from, and export results to, JMX

There is a newer version: 1.2.0
Show newest version
/*
 * Copyright 2009-2017 Aconex
 *
 * Licensed under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.  See the License for the specific language governing
 * permissions and limitations under the License.
 */

package io.pcp.parfait.jmx;

import static tec.uom.se.AbstractUnit.ONE;

import java.io.IOException;

import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.openmbean.CompositeData;
import javax.measure.Unit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.jmx.support.JmxUtils;

import io.pcp.parfait.Monitorable;
import io.pcp.parfait.MonitorableRegistry;
import io.pcp.parfait.MonitoredConstant;
import io.pcp.parfait.MonitoredValue;
import io.pcp.parfait.PollingMonitoredValue;
import io.pcp.parfait.ValueSemantics;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.base.Supplier;

/**
 * Factory bean that generates a monitor which tracks the value of the provided MBean attribute.
 * 

* Support is provided for monitoring simple attributes and also the data items of attributes that * are of type {@link CompositeData}. */ public class MonitoredMBeanAttributeFactory implements FactoryBean> { public static final Logger LOG = LoggerFactory.getLogger(MonitoredMBeanAttributeFactory.class.getName()); /** * May be passed as the update interval to indicate that no updates are required. This is useful * for tracking attributes which will never change in value. */ public static final int DO_NOT_UPDATE_VALUE = -1; private final String name; private final String description; private final ObjectName mBeanName; private final String attributeName; private final String compositeDataItem; private MBeanServerConnection server; private int updateInterval = DO_NOT_UPDATE_VALUE; private Unit unit = ONE; private ValueSemantics semantics = ValueSemantics.FREE_RUNNING; private MonitorableRegistry monitorableRegistry = MonitorableRegistry.DEFAULT_REGISTRY; public MonitoredMBeanAttributeFactory(String name, String description, String mBeanName, String attributeName) { this(name, description, mBeanName, attributeName, null, JmxUtils.locateMBeanServer()); } public MonitoredMBeanAttributeFactory(String name, String description, String mBeanName, String attributeName, String compositeDataItem) { this(name, description, mBeanName, attributeName, compositeDataItem, JmxUtils.locateMBeanServer()); } public MonitoredMBeanAttributeFactory(String name, String description, String mBeanName, String attributeName, String compositeDataItem, MBeanServerConnection server) { this.name = name; this.server = server; this.description = description; this.attributeName = attributeName; this.compositeDataItem = compositeDataItem; String beanName = registerBeanName(server, mBeanName); try { this.mBeanName = new ObjectName(beanName); } catch (Exception e) { throw new RuntimeException("Unexpected exception mBeanName name [" + mBeanName + "]", e); } } public void setMonitorableRegistry(MonitorableRegistry registry) { this.monitorableRegistry = Preconditions.checkNotNull(registry); } public void setUpdateInterval(int updateInterval) { this.updateInterval = updateInterval; } public void setValueSemantics(ValueSemantics semantics) { this.semantics = Preconditions.checkNotNull(semantics); } public void setUnit(Unit unit) { this.unit = unit; } public Monitorable getObject() throws InstanceNotFoundException, IntrospectionException, ReflectionException, AttributeNotFoundException, MBeanException, IOException { MBeanInfo beanInfo = server.getMBeanInfo(mBeanName); MBeanAttributeInfo monitoredAttribute = null; MBeanAttributeInfo[] attributes = beanInfo.getAttributes(); for (MBeanAttributeInfo attribute : attributes) { if (attribute.getName().equals(attributeName)) { monitoredAttribute = attribute; break; } } if (monitoredAttribute == null) { throw new UnsupportedOperationException("MBean [" + mBeanName + "] does not have an attribute named [" + attributeName + "]"); } if (!Strings.isNullOrEmpty(compositeDataItem)) { Preconditions .checkState( CompositeData.class.getName().equals( monitoredAttribute.getType()), "MBean [%s] attribute [%s] must be of type CompositeData if compositeDataItem is provided", mBeanName, attributeName); CompositeData data = (CompositeData) server.getAttribute(mBeanName, attributeName); Preconditions .checkState( data.getCompositeType().getType(compositeDataItem) != null, "MBean [%s] attribute [%s] does not have a data item called [%s]", mBeanName, attributeName, compositeDataItem); } if (isConstant()) { return new MonitoredConstant(name, description, getAttributeValue()); } else { return new PollingMonitoredValue(name, description, monitorableRegistry, updateInterval, new Supplier() { public T get() { return getAttributeValue(); } }, semantics, unit); } } public Class getObjectType() { return isConstant() ? MonitoredConstant.class : MonitoredValue.class; } private boolean isConstant() { return updateInterval == DO_NOT_UPDATE_VALUE; } public boolean isSingleton() { return true; } @SuppressWarnings("unchecked") protected T getAttributeValue() { try { if (!Strings.isNullOrEmpty(compositeDataItem)) { CompositeData data = (CompositeData) server.getAttribute(mBeanName, attributeName); return (T) data.get(compositeDataItem); } else { return (T) server.getAttribute(mBeanName, attributeName); } } catch (Exception e) { throw new RuntimeException(e); } } private String registerBeanName(MBeanServerConnection server, String beanName) { int pos = beanName.lastIndexOf(",name="); if (pos > 0) { String baseString = beanName.substring(0, pos); Iterable namesString = Splitter.on('|').split(beanName.substring(beanName.lastIndexOf("=")+1)); for (String name : namesString) { try { String returnValue = baseString+",name="+name; ObjectName objectName = new ObjectName(returnValue); if (server.isRegistered(objectName)) { LOG.trace(this.name + " registered as " + returnValue); return returnValue; } } catch (MalformedObjectNameException mone) { throw new RuntimeException("Unexpected exception mBeanName name [" + beanName + "]", mone); } catch (IOException ioe) { throw new RuntimeException("Unexpected IO error, mBeanName name [" + beanName + "]", ioe); } } } return beanName; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy