Sun GlassFish Enterprise Server v3 Prelude Add-On Component Development Guide

Example of Adding Monitoring Capabilities

This example shows a component that monitors the number of requests that a container receives. The following table provides a cross-reference to the listing of each class or interface in the example.

Class or Interface 

Listing 

ModuleProbeProvider

Example 5–7

ModuleBootStrap

Example 5–8

ModuleStatsTelemetry

Example 5–9

Module

Example 5–10

ModuleMBean

Example 5–11


Example 5–7 Event Provider Interface

This example illustrates how to define an event provider as explained in Defining an Event Provider.

The example shows the definition of the ModuleProbeProvider interface. The event provider sends events when the request count is increased by 1 or decreased by 1.

This interface declares the following methods:

The name of each method is also the name of the event type that is associated with the method.

A parameter that is named count is passed to each method.

package com.example.count.monitoring;

import org.glassfish.flashlight.provider.annotations.ProbeParam;

/**
 * Monitoring count eventse
 * Provider interface for module specific probe events.
 *
 */
public interface ModuleProbeProvider {

    /**
     * Emits probe event whenever the count is incremented
     */
    public void moduleCountIncrementEvent(
        @ProbeParam("count") Integer count
    );

    /**
     * Emits probe event whenever the count is decremented
     */
    public void moduleCountDecrementEvent(
        @ProbeParam("count") Integer count
    );

}


Example 5–8 Bootstrap Class

This example illustrates how to perform the following tasks:

package com.example.count.monitoring;

import java.lang.management.ManagementFactory;
import org.jvnet.hk2.component.PostConstruct;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.jvnet.hk2.annotations.Inject;
import org.jvnet.hk2.annotations.Service;
import org.jvnet.hk2.annotations.Scoped;
import org.jvnet.hk2.component.Singleton;
import org.glassfish.flashlight.MonitoringRuntimeDataRegistry;
import org.glassfish.internal.api.Init;
import org.glassfish.flashlight.provider.ProbeProviderFactory;
import org.glassfish.flashlight.client.ProbeClientMediator;
import org.glassfish.flashlight.client.ProbeClientMethodHandle;
import java.util.Collection;
import org.glassfish.flashlight.datatree.TreeNode;
import org.glassfish.flashlight.datatree.factory.TreeNodeFactory;

/**
 * Monitoring Count Example
 * Bootstrap object for registering probe provider and listener
 *
 */
@Service
@Scoped(Singleton.class)
public class ModuleBootStrap implements Init, PostConstruct {

    @Inject
    private MonitoringRuntimeDataRegistry mrdr;

    @Inject
    protected ProbeProviderFactory probeProviderFactory;

    @Inject
    private ProbeClientMediator pcm;

    private TreeNode serverNode;

    public void postConstruct() {
        try {
            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
            ObjectName name = new ObjectName("count.example.monitoring:name=countMBean");
            Module mbean = new Module();
            mbs.registerMBean(mbean, name);

            ModuleProbeProvider mpp = probeProviderFactory.getProbeProvider(
                    "count", "example", "countapp", ModuleProbeProvider.class);
            mbean.setProbeProvider(mpp);

            TreeNode serverNode = getServerNode();
            TreeNode countNode = TreeNodeFactory.createTreeNode("count", null, "example");
            serverNode.addChild(countNode);

            ModuleStatsTelemetry modTM = new ModuleStatsTelemetry(countNode);
            Collection<ProbeClientMethodHandle> handles = pcm.registerListener(modTM);
            modTM.setProbeListenerHandles(handles);
        } catch (Exception e) {
            System.out.println("Caught exception in postconstruct");
            e.printStackTrace();
        }
    }

    private TreeNode getServerNode() {
        TreeNode serverNode = null;
        if (mrdr.get("server") != null) {
            serverNode = mrdr.get("server");
        } else {
            serverNode = TreeNodeFactory.createTreeNode("server", null, "server");
            mrdr.add("server", serverNode);
        }
        return serverNode;
    }
}


Example 5–9 Listener Class

This example shows how to perform the following tasks:

The example also shows the code for processing the events and updating the monitoring statistics. To enable the listener to update statistics in the monitorable object tree, the parent of statistics object in the tree is passed in the constructor of this class.

package com.example.count.monitoring;

import java.util.Collection;
import org.glassfish.flashlight.client.ProbeClientMethodHandle;
import org.glassfish.flashlight.statistics.*;
import org.glassfish.flashlight.statistics.factory.CounterFactory;
import org.glassfish.flashlight.datatree.TreeNode;
import org.glassfish.flashlight.datatree.factory.*;
import org.glassfish.flashlight.client.ProbeListener;
import org.glassfish.flashlight.provider.annotations.ProbeParam;
import org.glassfish.flashlight.provider.annotations.*;

/**
 * Monitoring counter example
 * Telemtry object which listens to probe events and updates
 * the monitoring stats
 *
 */
public class ModuleStatsTelemetry{

    private Counter k = CounterFactory.createCount();
    private Collection<ProbeClientMethodHandle> handles;
   
    
    public ModuleStatsTelemetry(TreeNode parent) {
        k.setName("countMBeanCount");
        parent.addChild(k);
    }


    @ProbeListener("count:example:countapp:moduleCountIncrementEvent")
    public void moduleCountIncrementEvent(
        @ProbeParam("count") Integer count) {
        k.increment();
    }

    @ProbeListener("count:example:countapp:moduleCountDecrementEvent")
    public void moduleCountDecrementEvent(
        @ProbeParam("count") Integer count) {
        k.decrement();
    }


    public void setProbeListenerHandles(Collection<ProbeClientMethodHandle> handles) {
        this.handles = handles;
        // by default, the handles are enabled
        // following template is provided to enable/disable
        /*
        for (ProbeClientMethodHandle handle : handles) {
               handle.enable();
        }
        */
    }
    
}


Example 5–10 MBean Interface

This example defines the interface for a simple standard MBean that has methods to increase and decrease a counter by 1.

package com.example.count.monitoring;

/**
 * Monitoring counter example
 * ModuleMBean interface 
 *
 */
public interface ModuleMBean {
    public Integer getCount() ;
    public void incrementCount() ;
    public void decrementCount() ;
}


Example 5–11 MBean Implementation

This example illustrates how to send an event as explained in Sending an Event. The example shows code for sending events as follows:

The methods incrementCount and decrementCount are invoked by an entity that is beyond the scope of this example, for example, JConsole.

package com.example.count.monitoring;

/**
 * Monitoring counter example
 * ModuleMBean implementation 
 *
 */
public class Module implements ModuleMBean {
    private int k = 0;
    private ModuleProbeProvider mpp = null;

    public Integer getCount() {
        return k;
    }

    public void incrementCount() {
        k++;
        if (mpp != null) {
            mpp.moduleCountIncrementEvent(k);
        }
    }

    public void decrementCount() {
        k--;
        if (mpp != null) {
            mpp.moduleCountDecrementEvent(k);
        }
    }

    void setProbeProvider(ModuleProbeProvider mpp) {
        this.mpp = mpp;
    }

}