Package org.collectd.mx

Source Code of org.collectd.mx.MBeanSender

/*
* 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.io.IOException;
import java.lang.instrument.Instrumentation;
import java.lang.management.ManagementFactory;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;

import org.collectd.protocol.Network;
import org.collectd.api.Notification;
import org.collectd.protocol.Dispatcher;
import org.collectd.protocol.Sender;
import org.collectd.protocol.UdpSender;
import org.collectd.api.ValueList;

/**
* Process -javaagent configuration and schedule MBeanCollector objects.
*/
public class MBeanSender implements Dispatcher {
    private static final Logger _log =
        Logger.getLogger(MBeanSender.class.getName());
    private static final String UDP = "udp";
    private static final String PSEP = "://";
    private static final String RUNTIME_NAME =
        "java.lang:type=Runtime";

    private MBeanServerConnection _bs =
        ManagementFactory.getPlatformMBeanServer();

    private ScheduledExecutorService _scheduler =
        Executors.newScheduledThreadPool(1, new ThreadFactory() {
            public Thread newThread(Runnable task) {
                Thread thread = new Thread(task);
                thread.setName("jcollectd");
                thread.setDaemon(true);
                return thread;
            }
        });

    private Map<String,Sender> _senders =
        new HashMap<String,Sender>();

    private MBeanConfig _config = new MBeanConfig();

    private String _instanceName;

    public void setMBeanServerConnection(MBeanServerConnection server) {
        _bs = server;
    }

    public MBeanServerConnection getMBeanServerConnection() {
        return _bs;
    }

    private String getRuntimeName() {
        try {
            ObjectName name = new ObjectName(RUNTIME_NAME);
            return (String)getMBeanServerConnection().getAttribute(name, "Name");
        } catch (Exception e) {
            return ManagementFactory.getRuntimeMXBean().getName();
        }   
    }

    public String getInstanceName() {
        if (_instanceName == null) {
            _instanceName = Network.getProperty("instance", getRuntimeName());
        }
        return _instanceName;
    }

    public void setInstanceName(String instanceName) {
        _instanceName = instanceName;
    }

    public void schedule(MBeanCollector collector) {
        collector.setSender(this);
        _scheduler.scheduleAtFixedRate(collector, 0,
                                       collector.getInterval(),
                                       TimeUnit.SECONDS);
    }

    public void addSender(String protocol, Sender sender) {
        _senders.put(protocol, sender);
    }

    public void addDestination(String url) {
        int ix = url.indexOf(PSEP);
        if (ix == -1) {
            throw new IllegalArgumentException("Malformed url: " + url);
        }
        String protocol = url.substring(0, ix);
        String server = url.substring(ix + PSEP.length());
        Sender sender = _senders.get(protocol);
        if (sender == null) {
            if (protocol.equals(UDP)) {
                sender = new UdpSender();
                addSender(UDP, sender);
            }
            else {
                throw new IllegalArgumentException("Unsupported protocol: " + protocol);
            }
        }
        sender.addServer(server);
    }

    public MBeanCollector scheduleTemplate(String name) {
        MBeanCollector collector = null;
        try {
            //check for file via path and classpath,
            //e.g. "javalang", "javalang-jcollectd.xml"
            collector = _config.add(name);
        } catch (Exception e) {
            _log.log(Level.WARNING, "add template " + name +
                     ": " + e.getMessage(), e);
        }
        if (collector != null) {
            schedule(collector);
        }
        return collector;
    }

    public MBeanCollector scheduleMBean(String name) {
        try {
            new ObjectName(name);
        } catch (MalformedObjectNameException e) {
            _log.log(Level.WARNING, "add MBean " + name +
                     ": " + e.getMessage(), e);
            return null;
        }
        MBeanCollector collector = new MBeanCollector();
        collector.addMBean(name);
        schedule(collector);
        return collector;
    }

    public MBeanCollector schedule(String name) {
        MBeanCollector collector = scheduleTemplate(name);
        if (collector == null) {
            //assume ObjectName, e.g. "sigar:*"
            collector = scheduleMBean(name);
        }
        return collector;
    }
   
    public void dispatch(Notification notification) {
        for (Sender sender : _senders.values()) {
            sender.dispatch(notification);
        }
    }

    public void dispatch(ValueList values) {
        for (Sender sender : _senders.values()) {
            sender.dispatch(values);
        }
    }

    public void flush() throws IOException {
        for (Sender sender : _senders.values()) {
            sender.flush();
        }
    }

    public void shutdown() {
        _scheduler.shutdownNow();
    }

    private void addShutdownHook() {
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                shutdown();
            }
        });
    }

    public void configure(Properties props) {
        //java -Djcd.dest=udp://localhost -Djcd.tmpl=javalang -Djcd.beans=sigar:*
        String dest = props.getProperty("jcd.dest");
        if (dest != null) {
            addDestination(dest);
        }
        String tmpl = props.getProperty("jcd.tmpl");
        if (tmpl != null) {
            for (String t : tmpl.split(",")) {
                scheduleTemplate(t);
            }
        }
        String beans = props.getProperty("jcd.beans");
        if (beans != null) {
            for (String b : beans.split("#")) {
                scheduleMBean(b);
            }
        }
    }

    protected void init(String args) {
        if (args == null) {
            return;
        }
        //java -javaagent:collectd.jar="udp://localhost#javalang" -jar sigar.jar
        String[] argv = args.split("#");
        for (int i=0; i<argv.length; i++) {
            String arg = argv[i];
            if (arg.indexOf(PSEP) != -1) {
                //e.g. "udp://address:port"
                addDestination(arg);
            }
            else {
                schedule(arg);
            }
        }       
    }

    protected void premainConfigure(String args) {
        addShutdownHook();
        configure(System.getProperties());
        init(args);
        if (_senders.size() == 0) {
            String dest = UDP + PSEP + Network.DEFAULT_V4_ADDR;
            _log.fine("Adding default destination: " + dest);
            addDestination(dest);
        }
    }

    public static void premain(String args, Instrumentation instr) {
        MBeanSender sender = new MBeanSender();
        sender.premainConfigure(args);
    }
}
TOP

Related Classes of org.collectd.mx.MBeanSender

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.