view src/net/scatterspace/blitz/jmx/JmxAgent.java @ 0:e59e6471ce44

Initial version of a Blitz colocated agent to provide JMX MXBeans access to its statistics
author Dominic Cleal <dominic@computerkb.co.uk>
date Thu, 11 Dec 2008 00:49:28 +0000
parents
children 1850f751d9de
line wrap: on
line source

/**
 * Copyright (c) 2008 CDO2 Limited.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of CDO2 Limited nor the names of its contributors
 *       may be used to endorse or promote products derived from this
 *       software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY CDO2 LIMITED ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package net.scatterspace.blitz.jmx;

import java.lang.management.ManagementFactory;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.management.MBeanServer;
import javax.management.ObjectName;

import net.jini.admin.Administrable;
import net.jini.space.JavaSpace;

import org.dancres.blitz.remote.StatsAdmin;
import org.dancres.blitz.remote.user.ColocatedAgent;
import org.dancres.blitz.stats.OpStat;
import org.dancres.blitz.stats.Stat;

/**
 * Agent colocated inside Blitz JavaSpaces that provides JMX beans to monitor
 * the space statistics and entry statistics.
 */
public class JmxAgent implements ColocatedAgent
{
    private Logger log_ = Logger.getLogger(getClass().getName());
    
    private StatsAdmin stats_;

    private static final long UPDATE_INTERVAL__ = 60000;
    private Timer updateTimer_ = new Timer("JmxAgent-timer", true);
    private EntryUpdateTask updateTask_ = new EntryUpdateTask();
    
    private MBeanServer mbs_ = ManagementFactory.getPlatformMBeanServer();
    
    public void init(JavaSpace space) throws Exception
    {
        if (space instanceof Administrable)
        {
            Object admin = ((Administrable) space).getAdmin();
            if (admin instanceof StatsAdmin)
            {
                stats_ = (StatsAdmin) admin;
                log_.log(Level.INFO, "JMX agent loaded with the StatsAdmin");
                
                initialiseBeans();
                updateTimer_.schedule(updateTask_, 0, UPDATE_INTERVAL__);
            }
            else
            {
                log_.log(Level.SEVERE,
                         "Admin object is not Blitz StatsAdmin: " + admin);
            }
        }
        else
        {
            log_.log(Level.SEVERE,
                     "Space object is not Administrable: " + space);
        }
    }
    
    private void initialiseBeans() throws RemoteException
    {
        register(new BlockingOpsImpl(stats_));
        register(new EventQueueImpl(stats_));
        register(new IOImpl(stats_));
        register(new MissedOpsImpl(stats_));
        register(new TaskQueueImpl(stats_, "Events"));
        register(new TxnImpl(stats_));
    }

    private void register(Object bean)
    {
        try
        {
            mbs_.registerMBean(bean,
                    new ObjectName("BlitzJS:" + bean.toString()));
        }
        catch (Exception e)
        {
            log_.log(Level.WARNING, "Unable to register bean " + bean, e);
        }
    }

    /**
     * Creates new MXBeans and register them if new entries appear in the stats
     * interface.
     */
    private class EntryUpdateTask extends TimerTask
    {
        private Collection<String> knownTypes_ = new ArrayList<String>();
        
        @Override
        public void run()
        {
            try
            {
                for (Stat stat : stats_.getStats())
                {
                    if (stat instanceof OpStat)
                    {
                        String type = ((OpStat) stat).getType();
                        if (!knownTypes_.contains(type))
                        {
                            registerType(type);
                            knownTypes_.add(type);
                        }
                    }
                }
            }
            catch (RemoteException e)
            {
                log_.log(Level.WARNING,
                         "Remote exception while updating MXBean types", e);
            }
        }
        
        public void registerType(String type)
        {
            register(new OpImpl(stats_, type));
            register(new InstanceCountImpl(stats_, type));
        }
    }
}