Thursday Dec 10, 2009

How to use GlassFish v3 DTrace probes on Solaris

Use of  Enterprise Manager DTrace Monitoring 3.0 beta value-add, exposes GlassFish v3 monitoring probes as DTrace probes on solaris platforms. D scripts can span multiple layers. In a given application, some of the modules might take too much time. You want to know how much time each module is taking so that you can quickly isolate the slow module. The following example shows the amount of time taken by each module. This can be easily extended to other modules/layers like MySQL, Solaris OS, etc. In future articles, I'll blog about this.
  • Install JDK7 and set JAVA_HOME to point to this location.
  • Download and install GlassFish v3, let us call the install location <gfv3>
  • Download DTrace value-add: DTrace Monitoring is available under an evaluation licence from the Sun GlassFish Enterprise Manager DTrace Monitoring download page.
  • cd <dtrace download directory>
  • unzip monitoring_dtrace-3_0-beta.zip
  • cp monitoring_dtrace/lib/glassfish-dtrace.jar <gfv3>/modules
  • Start GlassFish v3 using asadmin start-domain domain
  • Enable dtrace using asadmin set configs.config.server-config.monitoring-service.dtrace-enabled=true
  • Download and Deploy the sample ejb-web application using asadmin deploy stateless-converter.ear
  • In another terminal, login as super user or any user who is privileged to work with dtrace commands
  • Determine the process id (pid) for the application server (GlassFish v3) using jps -l
    munnangi[212]: jps -l
    1978 com.sun.enterprise.glassfish.bootstrap.ASMain
    2513 sun.tools.jps.Jps
  • Download and start the gfv3_web_ejb.d script using ./gfv3_web_ejb.d 1978
  • Now using browser, access the application http://localhost:8080/converter
  • You'll see the following output in dtrace terminal showing the time taken by each module.
    munnangi[213]: ./gfv3_web_ejb.d 1978
    dtrace: script './gfv3_web_ejb.d' matched 6 probes
    CPU ID FUNCTION:NAME
    1 1 :BEGIN Collecting data, press \^c to end...

    1 76185 http-service:requestStartEvent requestStartEvent
    1 76723 bean:containerEnteringEvent time taken in micro sec. = 923
    1 76724 bean:containerLeavingEvent time taken in micro sec. = 1700
    1 76723 bean:containerEnteringEvent time taken in micro sec. = 188
    1 76724 bean:containerLeavingEvent time taken in micro sec. = 1263
    1 76184 http-service:requestEndEvent time taken in micro sec. = 4364
  • From the above one can easily how much time is spent in each module.
Refer to Sun GlassFish Enterprise Manager DTrace Monitoring 3.0 Beta Installation and Quick Start Guide  for detailed instructions.

Wednesday Dec 09, 2009

Monitoring in GlassFih v3 - It's Different and Cool!

It is different from previous version as it has become light by using light weight probe based architecture. This enables us to perform ad hoc monitoring in production with minimal impact. One does not have to restart the server, just start monitoring the specific issue at hand, very similar to DTrace on Solaris. In fact, GlassFish v3 monitoring exposes monitoring probes as DTrace probes on Solaris and Mac.This combined with native dtrace probes of Solaris provide an opportunity to monitor attributes which was not possible earlier. Don't worry, for non-solaris platforms, we have client-scripting. Determine the probes you want to monitor and write a java script using these probes, deploy the script to server and start receiving monitoring events. Isn't that Cool!

Friday Sep 11, 2009

How to create pluggable container-monitoring element in GlassFish v3

For new modules like JRuby which can be added at runtime, it is possible to use v3 monitoring config using pluggability as given in the sample code below.
import org.glassfish.internal.api.Init;
import org.jvnet.hk2.annotations.Service;
import org.jvnet.hk2.component.PostConstruct;
import org.jvnet.hk2.annotations.Inject;
import org.glassfish.api.Startup;
import com.sun.enterprise.config.serverbeans.MonitoringService;
import org.jvnet.hk2.config.SingleConfigCode;
import org.jvnet.hk2.config.ConfigSupport;
import org.glassfish.api.monitoring.ContainerMonitoring;
import org.jvnet.hk2.config.TransactionFailure;
import java.beans.PropertyVetoException;

@Service
public class AddonInit implements PostConstruct {

    @Inject
    MonitoringService ms;

    public void postConstruct() {
        mprint("addon init postConstruct() ...");
        if (ms.getContainerMonitoring("jruby") == null) {
            try {
                ConfigSupport.apply(new SingleConfigCode<MonitoringService>() {
                    public Object run(MonitoringService param)
                    throws PropertyVetoException, TransactionFailure {
                        ContainerMonitoring newItem = param.createChild(ContainerMonitoring.class);
                        newItem.setName("jruby");
                        newItem.setLevel("HIGH");
                        param.getContainerMonitoring().add(newItem);
                        return newItem;
                    }
                }, ms);
            } catch (TransactionFailure tf) {
                // log warning
                // handle exception
            }
        }
    }

    private void mprint(String str) {
        if (debug) {
            System.out.println("... MSR: " + str);
        }
    }

    private final boolean debug = true;
}

Wednesday Sep 09, 2009

How to enable/disable monitoring and attach btrace-agent in GlassFish v3

The monitoring funcationality including attaching btrace-agent is done based on the 'monitoring-enabled' attribute of 'monitoring-service' element. If monitoring-enabled is true then the btrace-agent is attached as part of startup. When monitoring-enabled is false, btrace-agent is not attached at startup time. However when user changes monitoring-enabled to true while the server is running, it should be possible to attach the btrace-agent and start monitoring functionality.

Purpose of this pair of commands is to provide enable /disable monitoring during run time without having to restart the server (Alternatively user should be able to use asadmin set command to enbale/disable the monitoring-enabled flag, but have to restart the server to take effect). It does attach btrace-agent based on the given pid and optionally sets the monitoring level for given modules.

enable-monitoring

enable-monitoring [--mbean=false] [--dtrace\*=true] [--level web-container="LOW":ejb-container="HIGH"] [--options="debug=true"] [--pid=<pid>]

  • enable-monitoring
    sets the attribute 'monitoring-enabled' to 'true'
  • enable-monitoring --mbean=true --dtrace\*=false
    sets the attribute 'monitoring-enabled' to 'true', mbean-enabled to true and dtrace-enabled to false
  • enable-monitoring --options="debug=true" --pid=<pid>
    sets the attribute 'monitoring-enabled' to 'true' and attaches btrace agent using --options
  • enable-monitoring --level web-container="LOW":ejb="HIGH"
    sets the levels for given modules in addition to 'monitoring-enabled'
disable-monitoring

disable-monitoring --modules="web-container,ejb-container"

  • disable-monitoring
    sets the attribute 'monitoring-enabled' to 'false'
  • disable-monitoring --modules="web-container,ejb-container"
    this command will just set the levels for given modules to 'OFF' and it does not change the value for 'monitoring-enabled'

\*- Available as a value-add feature, made available only to the paid customers.

Above also caters an important use case of adhoc monitoring, i.e. turning monitoring on in production while server is running, for ex. enable dtrace on the fly.

Thursday Feb 19, 2009

How to make Grizzly Comet work with Java Client instead of Web Client

comet_client There are many examples illustrating the usage of Grizzly Comet for Web Client but not for Stand alone java client. I needed one and with help from Jeanfrancois Arcand, users@grizzly.dev.java.net and my colleague Prashant Abbagani, I came up with the following example.

Conventionally the client either polls or pulls the message from server periodically, the draw back with this approach is that the client wastes the resources and the messages may not be received in real time. Instead, in comet approach, the server pushes the messages to client in real time. For this example, I have used GlassFish v3 which comes bundled with Grizzly and Comet. Here are the steps:

  • Download and install GlassFish v3.
     
  • Enable comet support in GlassFish v3.
            ...
            <http-listener port="8080" id="http-listener-1" address="0.0.0.0" default-virtual-server="server" server-name="">
              <property name="cometSupport" value="true" />
            <http-listener>
            ...
    
  • Develop and deploy comet.war to push messages from server to client. You may like to refer to MyCometServlet.java source code.
     
  • Code the client CometClient.java and listen for server messages.

    Start the client.

    punit[105]: java CometClient
    init ...
    
  • Simulate posting messages to server using Post2CometServlet.java.

    Post message to server

    punit[54]: java Post2CometServlet
    punit[55]: java Post2CometServlet
    punit[56]: java Post2CometServlet
    punit[57]: java Post2CometServlet
    punit[58]: java Post2CometServlet
    
    The client output gets updated in real time as the messages are posted to the servlet.
    punit[105]: java CometClient
    init ...my message sent at 1235082867986
    my message sent at 1235082891002
    my message sent at 1235082892018
    my message sent at 1235082893714
    my message sent at 1235082894420
    

Wednesday Feb 18, 2009

Proxy pattern for exposing jsr77 api and internal api using common implementation

GlassFish v3 is designed to be modular not only in architecture but in distribution as well. The distributions range from compact version 'Nucleus' to full blown version 'Enterprise' through 'Web', and 'PE' distributions.

We need to support jsr77 in Enterprise version so we'll need jsr77 interfaces to be available only in Enterprise version and not the lower versions like 'Web' and 'PE'. However we need to use jsr77 like monitoring data types for exposing monitoring data in 'Web' and 'PE' distributions. This poses a challenge of maintaining same data types but in two different packages. To avoid this maintenance hassle, we can use proxy pattern as described below.

Assume that we need to expose two interfaces with different package names but with same method signatures. Let us call them javax.management.j2ee.statistics.Statistic and org.glassfish.internal.api.Statistic. The corresponding implementations are javax.management.j2ee.statistics.JSR77StatisticImpl and org.glassfish.internal.api.IntStatisticImpl respectively. Recall that our idea of using proxy pattern is to avoid the maintenance hassle and for that we make JSR77StatisticImpl extend IntStatisticImpl and implement javax.management.j2ee.statistics.Statistic. This makes it reuse the common implementation.

Using dynamic proxy api, we can expose the required interface at runtime as shown below with working example.

  • Create glassfish internal Statistic interface under <stats_proxy_pattern>/internal-api
     
  • Create glassfish internal Statistic implementation IntStatisticImpl under <stats_proxy_pattern>/internal-api
     
  • Create jsr77 Statistic interface under <stats_proxy_pattern>/jsr77
     
  • Create jsr77 Statistic implementation JSR77StatisticImpl under <stats_proxy_pattern>/jsr77
     
  • Create StatsProxy under <stats_proxy_pattern>/monitor
     
  • First let us test the internal Statistic data type using the following code under <stats_proxy_pattern>.
    import org.glassfish.internal.api.\*;
    import com.sun.enterprise.monitor.\*;
    
    /\*\*
     \* Verify the stat types at runtime
     \* @author Sreenivas Munnangi
     \*/
    
    public class TestStatInterface {
        public static void main (String args[]) {
            System.out.println("TestStatInterface");
            try {
                //interanl Statistic
                Statistic stat = (Statistic) StatsProxy.newInstance(new IntStatisticImpl());
                System.out.println("TestStatInterface: before calling method getName on proxy ...");
                System.out.println("TestStatInterface: stat.getName() = " + stat.getName());
                System.out.println("TestStatInterface: after calling method getName on proxy ...");
                System.out.println("TestStatInterface: before calling method getStartTime on proxy ...");
                System.out.println("TestStatInterface: stat.getStartTime() = " + stat.getStartTime());
                System.out.println("TestStatInterface: after calling method getStartTime on proxy ...");
            } catch (Exception e) {
                System.out.println("Caught exception ...");
                e.printStackTrace();
            }
        }
    }
    
    When we build and run the above code, we see the following output. 
    I have used build.xml from the attached example, 
    link is provided at the end of this blog.
    
    run:
         [java] TestStatInterface
         [java] TestStatInterface: before calling method getName on proxy ...
         [java] statsproxy before method getName
         [java] result = called getName() ...
         [java] statsproxy after method getName
    
         [java] TestStatInterface: stat.getName() = called getName() ...
         [java] TestStatInterface: after calling method getName on proxy ...
         [java] TestStatInterface: before calling method getStartTime on proxy ...
         [java] statsproxy before method getStartTime
         [java] result = 1234985924526
         [java] statsproxy after method getStartTime
         [java] TestStatInterface: stat.getStartTime() = 1234985924526
         [java] TestStatInterface: after calling method getStartTime on proxy ...
    
    BUILD SUCCESSFUL
    
  • Now test for jsr77 Statistic type. Notice the change in imports.
    import javax.management.j2ee.statistics.\*;
    import com.sun.enterprise.monitor.\*;
    
    /\*\*
     \* Verify the stat types at runtime
     \* @author Sreenivas Munnangi
     \*/
    
    public class TestStatInterface {
        public static void main (String args[]) {
            System.out.println("TestStatInterface");
            try {
                //jsr77 Statistic
                Statistic stat = (Statistic) StatsProxy.newInstance(new JSR77StatisticImpl());
                System.out.println("TestStatInterface: before calling method getName on proxy ...");
                System.out.println("TestStatInterface: stat.getName() = " + stat.getName());
                System.out.println("TestStatInterface: after calling method getName on proxy ...");
                System.out.println("TestStatInterface: before calling method getStartTime on proxy ...");
                System.out.println("TestStatInterface: stat.getStartTime() = " + stat.getStartTime());
                System.out.println("TestStatInterface: after calling method getStartTime on proxy ...");
            } catch (Exception e) {
                System.out.println("Caught exception ...");
                e.printStackTrace();
            }
        }
    }
    
    Following is the output which will be similar to what 
    we have seen earlier since they both use common implementation.
    
    run:
         [java] TestStatInterface
         [java] TestStatInterface: before calling method getName on proxy ...
         [java] statsproxy before method getName
         [java] result = called getName() ...
         [java] statsproxy after method getName
         [java] TestStatInterface: stat.getName() = called getName() ...
         [java] TestStatInterface: after calling method getName on proxy ...
         [java] TestStatInterface: before calling method getStartTime on proxy ...
         [java] statsproxy before method getStartTime
         [java] result = 1234986155422
         [java] statsproxy after method getStartTime
         [java] TestStatInterface: stat.getStartTime() = 1234986155422
         [java] TestStatInterface: after calling method getStartTime on proxy ...
    
    BUILD SUCCESSFUL
    
Download the complete example.
About

msreddy

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today