Package org.collectd.mx

Source Code of org.collectd.mx.MBeanCollector

/*
* jcollectd
* Copyright (C) 2009 Hyperic, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; only version 2 of the License is applicable.
*
* This program 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
*/

package org.collectd.mx;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.management.Descriptor;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.openmbean.CompositeData;

import org.collectd.api.ValueList;
import org.collectd.protocol.Network;
import org.collectd.protocol.TypesDB;

/**
* Query MBeans and dispatch results upstream.
*/
public class MBeanCollector implements Runnable {

    private static final Logger _log =
        Logger.getLogger(MBeanCollector.class.getName());
    private static boolean _useDescriptors =
        "true".equals(Network.getProperty("mx.descriptors", "true"));
    private static Method _getDescriptor;
    private static final String _metricTypeField =
        Network.getProperty("mx.metricTypeField", "metricType");
    private MBeanSender _sender;
    private long _interval = 60;
    private Map<String,MBeanQuery> _queries =
        new HashMap<String,MBeanQuery>();

    static {
        if (_useDescriptors) {
            try {
                _getDescriptor = //1.6+
                    MBeanAttributeInfo.class.getMethod("getDescriptor",
                                                       (Class[])null);
            } catch (Exception e) {
                _useDescriptors = false;
            }
        }
    }
    public MBeanSender getSender() {
        return _sender;
    }

    public void setSender(MBeanSender sender) {
        _sender = sender;
    }

    public long getInterval() {
        return _interval;
    }

    public void setInterval(long interval) {
        _interval = interval;
    }

    public Map<String,MBeanQuery> getQueries() {
        return _queries;
    }

    public MBeanQuery addMBean(String objectName) {
        MBeanQuery query = _queries.get(objectName);
        if (query == null) {
            try {
                query = new MBeanQuery(new ObjectName(objectName));
            } catch (Exception e) {
                throw new IllegalArgumentException(objectName);
            }
            _queries.put(objectName, query);
        }
        return query;
    }

    public MBeanAttribute addMBeanAttribute(String objectName,
                                            String attributeName) {
        MBeanQuery query = addMBean(objectName);
        if (attributeName != null) {
            MBeanAttribute attr = new MBeanAttribute(attributeName);
            query.addAttribute(attr);
            return attr;
        }
        else {
            return null;
        }
    }

    private boolean isNumber(Object obj) {
        if (obj == null) {
            return false;
        }
        return Number.class.isAssignableFrom(obj.getClass());
    }

    private String getBeanName(ObjectName query, ObjectName name) {
        Map<String,String> skip;
        if (query == null) {
            skip = new HashMap<String,String>();
        }
        else {
            skip = query.getKeyPropertyList();
        }
        StringBuffer iname = new StringBuffer();
        for (Object key : name.getKeyPropertyList().keySet()) {
            if (skip.get(key) != null) {
                continue;
            }
            if (iname.length() > 0) {
                iname.append(' ');
            }
            iname.append(name.getKeyProperty((String)key));
        }
        return iname.toString();
    }

    private void dispatch(MBeanQuery query, String plugin,
                          String typeInstance,
                          ObjectName name, MBeanAttribute attr,
                          Number val) {
        if (attr.getDataType() == Network.DS_TYPE_GAUGE) {
            val = new Double(val.doubleValue());
        }
        else {
            val = new Long(val.longValue());
        }

        String pluginInstance = query.getPluginInstance();
        if (pluginInstance == null) {
            pluginInstance = _sender.getInstanceName();
        }
        String beanName = query.getAlias();
        ValueList vl = new ValueList();
        vl.setInterval(getInterval());
        vl.setPlugin(plugin);
        if (beanName == null){
            beanName = getBeanName(null, name);
        }
        else if (query.getName().isPattern()) {
            String instName = getBeanName(query.getName(), name);
            if (instName != null) {
                beanName += " " + instName;
            }
        }
        vl.setPluginInstance(pluginInstance + "-" + beanName);
        vl.setType(attr.getTypeName());
        vl.setTypeInstance(typeInstance);
        vl.addValue(val);
        _sender.dispatch(vl);
    }

    public void collect(MBeanQuery query, ObjectName name) throws Exception {
        MBeanServerConnection conn = _sender.getMBeanServerConnection();
        String plugin = query.getPlugin();
        if (plugin == null) {
            plugin = name.getDomain();
        }

        Map<String,MBeanAttributeInfo> attrInfo = null;
        if (_useDescriptors) {
            MBeanInfo info = conn.getMBeanInfo(name);
            attrInfo = new HashMap<String,MBeanAttributeInfo>();
            for (MBeanAttributeInfo ainfo : info.getAttributes()) {
                attrInfo.put(ainfo.getName(), ainfo);
            }
        }

        for (MBeanAttribute attr : query.getAttributes()) {
            String attrName = attr.getAttributeName();
            Object obj;

            try {
                obj = conn.getAttribute(name, attrName);
            } catch (Exception e) {
                //XXX remove attr for future collection e.g. UnsupportedOperation
                continue;
            }

            if (_useDescriptors) {
                //e.g. spring @ManagedMetric(metricType = MetricType.COUNTER)
                try {
                    Descriptor descriptor =
                        (Descriptor)_getDescriptor.invoke(attrInfo.get(attrName),
                                                          (Object[])null);
                    Object type = descriptor.getFieldValue(_metricTypeField);
                    if (TypesDB.NAME_COUNTER.equals(type)) {
                        if (attr.getTypeName().equals(TypesDB.NAME_GAUGE)) {
                            attr.setTypeName(TypesDB.NAME_COUNTER);
                        }
                        attr.setDataType(Network.DS_TYPE_COUNTER);
                    }
                } catch (Exception e) {
                }
            }

            if (obj instanceof CompositeData) {
                CompositeData data = (CompositeData)obj;
                String key = attr.getCompositeKey();
                if (key == null) {
                    //no key specified; collect all
                    Set<String> keys = data.getCompositeType().keySet();
                    for (String ckey : keys) {
                        obj = data.get(ckey);
                        if (!isNumber(obj)) {
                            continue;
                        }
                        dispatch(query, plugin,
                                 attrName + "." + ckey,
                                 name, attr, (Number)obj);
                    }
                    continue;
                }
                else {
                    obj = data.get(key);
                }
            }
            if (!isNumber(obj)) {
                continue;
            }
            dispatch(query, plugin,
                     attr.getName(),
                     name, attr, (Number)obj);
        }
        _sender.flush();
    }

    private void run(MBeanQuery query, ObjectName name) {
        try {
            if (query.getAttributes().size() == 0) {
                query = queryAll(name);
            }
            collect(query, name);
        } catch (Exception e) {
            //MBean might not be registered yet
            _log.log(Level.FINE, "collect " + name, e);
        }
    }

    private MBeanQuery queryAll(ObjectName name)
        throws Exception {
        MBeanQuery query = new MBeanQuery(name);
        MBeanInfo info = _sender.getMBeanServerConnection().getMBeanInfo(name);
        MBeanAttributeInfo[] attrs = info.getAttributes();
        for (int i=0; i<attrs.length; i++) {
            query.addAttribute(new MBeanAttribute(attrs[i].getName()));
        }
        return query;
    }

    public void run() {
        for (MBeanQuery query : _queries.values()) {
            ObjectName name = query.getName();
            if (name.isPattern()) {
                Set<ObjectName> beans;
                try {
                    beans =
                        _sender.getMBeanServerConnection().queryNames(name, null);
                } catch (Exception e) {
                    _log.warning("queryNames(" + name + "): " + e);
                    return;
                }
                for (ObjectName oname : beans) {
                    run(query, oname);
                }
            }
            else {
                run(query, name);
            }
        }
    }
}
TOP

Related Classes of org.collectd.mx.MBeanCollector

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.