Monday, November 14, 2011

JMX coding with weblogic

There are several ways to monitor and create alerts for weblogic based Oracle Fusion middleware infrastructure. Prime among these are: 1) Java JMX coding and custom development 2) WLDF/WLST Scripting  3) Loading open source frameworks such as Spring JMX into weblogic console and 4) FMW enterprise grid control weblogic plug-ins. In this article we discuss monitoring of weblogic using some samples. Please note that wlclient.jar, wlfullcleint.jar and wljmxclient.jar from your fusion middleware WL_HOME environment are required for this code to run. In the future i will discuss and provide some samples for options 2 and 3.

Please note that here t3 protocol is used. If you want to make your JMX code generic you must use RMI instead. But additional steps may be necessary for enabling this protocol on your FMW weblogic environment. Out of the box implementations of any of the above mentioned methods can only provide generic status of the services. The root cause analysis of issues that business line managers would like to be on top-of are always possible only with customization. Efforts of development depends on complexity of the modules deployed on weblogic domains, clusters, resources (JMS, JDBC etc).


1) Java JXM coding
package com.tns.ea.infra.monitor.jmx;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Hashtable;
import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.naming.Context;

public class MonitorOimServer {

    private static MBeanServerConnection connection;
    private static JMXConnector connector;
    private static final ObjectName service;

    // Initializing the object name for DomainRuntimeServiceMBean
    // so it can be used throughout the class.
    static {
        try {
            service = new ObjectName(
                    "com.bea:Name=DomainRuntimeService,Type=weblogic.management.mbeanservers.domainruntime.DomainRuntimeServiceMBean");
        } catch (MalformedObjectNameException e) {
            throw new AssertionError(e.getMessage());
        }
    }
   
   
    /* * Initialize connection to the Domain Runtime MBean Server */
    public static void initConnection(String hostname, String portString,
            String username, String password) throws IOException,
            MalformedURLException {
        String protocol = "t3";
        Integer portInteger = Integer.valueOf(portString);
        int port = portInteger.intValue();
        String jndiroot = "/jndi/";
        String mserver = "weblogic.management.mbeanservers.domainruntime";
        JMXServiceURL serviceURL = new JMXServiceURL(protocol, hostname, port,
                jndiroot + mserver);
        Hashtable h = new Hashtable();
        h.put(Context.SECURITY_PRINCIPAL, username);
        h.put(Context.SECURITY_CREDENTIALS, password);
        h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES,
                "weblogic.management.remote");
        connector = JMXConnectorFactory.connect(serviceURL, h);
        connection = connector.getMBeanServerConnection();
    } /*
     *  * Print an array of ServerRuntimeMBeans. * This MBean is the root of the
     * runtime MBean hierarchy, and * each server in the domain hosts its own
     * instance.
     */

    public static ObjectName[] getServerRuntimes() throws Exception {
        return (ObjectName[]) connection
                .getAttribute(service, "ServerRuntimes");
    }
  
    public static ObjectName getObjectName(ObjectName obName, String attName)
            throws AttributeNotFoundException, InstanceNotFoundException,
            MBeanException, ReflectionException, IOException {
        return (ObjectName) connection.getAttribute(obName, attName);
    }
   
    public static String getObjectNameAsString(ObjectName obName, String attName)
            throws AttributeNotFoundException, InstanceNotFoundException,
            MBeanException, ReflectionException, IOException {
        return (String) connection.getAttribute(obName, attName);
    }

    public static ObjectName[] getObjectNames(ObjectName obName, String attName)
            throws AttributeNotFoundException, InstanceNotFoundException,
            MBeanException, ReflectionException, IOException {
        return (ObjectName[]) connection.getAttribute(obName, attName);
    }

    /* * Iterate through ServerRuntimeMBeans and get the name and state */
    public void printOimServerInformation() throws Exception {
        ObjectName[] serverRT = getServerRuntimes();
        System.out.println("got server runtimes");
        int length = (int) serverRT.length;
        for (int i = 0; i < length; i++) {
            String name = (String) connection.getAttribute(serverRT[i], "Name");
            String state = (String) connection.getAttribute(serverRT[i],
                    "State");
            System.out.println("Server name: " + name + ".   Server state: "
                    + state);
        }
    }

     public void printDataSources () throws Exception {
        ObjectName[] serverRT = getServerRuntimes();
        System.out.println("got server runtimes");
        int length = (int) serverRT.length;
        for (int i = 0; i < length; i++)
 {
            String name = (String) connection.getAttribute(serverRT[i], "Name");
            ObjectName[] appRT = (ObjectName[]) connection.getAttribute(
                    new ObjectName("com.bea:Name=" + name + ",ServerRuntime="
                            + name + ",Location=" + name
                            + ",Type=JDBCServiceRuntime"),
                    "JDBCDataSourceRuntimeMBeans");
            int appLength = (int) appRT.length;
            for (int x = 0; x < appLength; x++) {
                System.out.println("\n……..           .<" + name
                        + "   : JDBCDataSourceRuntimeMBeans>"
                        + (String) connection.getAttribute(appRT[x], "Name")
                        + "……….");
                System.out.println("ActiveConnectionsCurrentCount : "
                        + connection.getAttribute(appRT[x],
                                "ActiveConnectionsCurrentCount"));
                System.out.println("ActiveConnectionsAverageCount : "
                        + connection.getAttribute(appRT[x],
                                "ActiveConnectionsAverageCount"));
                System.out.println("ActiveConnectionsAverageCount : "
                        + connection.getAttribute(appRT[x],
                                "ActiveConnectionsAverageCount"));
                System.out.println("ConnectionsTotalCount         : "
                        + connection.getAttribute(appRT[x],
                                "ConnectionsTotalCount"));
                System.out.println("CurrCapacity                    : "
                        + connection.getAttribute(appRT[x], "CurrCapacity"));
                System.out.println("CurrCapacityHighCount         : "
                        + connection.getAttribute(appRT[x],
                                "CurrCapacityHighCount"));
                System.out.println("HighestNumAvailable           : "
                        + connection.getAttribute(appRT[x],
                                "HighestNumAvailable"));
                System.out.println("HighestNumAvailable           : "
                        + connection.getAttribute(appRT[x],
                                "HighestNumAvailable"));
                System.out.println("LeakedConnectionCount         : "
                        + connection.getAttribute(appRT[x],
                                "LeakedConnectionCount"));
                System.out.println("WaitSecondsHighCount          : "
                        + connection.getAttribute(appRT[x],
                                "WaitSecondsHighCount"));
                System.out.println("WaitingForConnectionCurrentCount: "
                        + connection.getAttribute(appRT[x],
                                "WaitingForConnectionCurrentCount"));
                System.out.println("WaitingForConnectionFailureTotal: "
                        + connection.getAttribute(appRT[x],
                                "WaitingForConnectionFailureTotal"));
                System.out.println("WaitingForConnectionTotal     : "
                        + connection.getAttribute(appRT[x],
                                "WaitingForConnectionTotal"));
                System.out.println("WaitingForConnectionHighCount : "
                        + connection.getAttribute(appRT[x],
                                "WaitingForConnectionHighCount"));
                System.out.println("…………………………………………………………………..\n");
                String poolName = (String) connection.getAttribute(appRT[x],
                        "Name");
                ObjectName jdbcSystemResource = new ObjectName("com.bea:Name="
                        + poolName + ",Type=JDBCSystemResource");
                ObjectName jdbcDataSourceBean =  getObjectName(
                        jdbcSystemResource, "JDBCResource");
                ObjectName jdbcDriverParams =  getObjectName(
                        jdbcDataSourceBean, "JDBCDriverParams");
                ObjectName jdbcProperties =  getObjectName(
                        jdbcDriverParams, "Properties");
                ObjectName[] jdbcPropertyBeans = getObjectNames(
                        jdbcProperties, "Properties");
                for (int j = 0; j < jdbcPropertyBeans.length; j++) {
                    ObjectName jdbcPropertyBean = null;
                    jdbcPropertyBean = jdbcPropertyBeans[j];
                    String jdbcPropertyName = getObjectNameAsString(
                            jdbcPropertyBean, "Name");
                    String jdbcPropertyValue = getObjectNameAsString(
                            jdbcPropertyBean, "Value");
                    System.out.println("\n\t===== j " + j + "\t"
                            + jdbcPropertyName + "\t" + jdbcPropertyValue);
                }
            }
        }
      
    }

     public void printApplicationStatus() throws Exception {
        ObjectName[] serverRT = getServerRuntimes();
        Hashtable server_states = new Hashtable();
        for (ObjectName ser : serverRT) {
            String serverName = (String) connection.getAttribute(ser, "Name");
            System.out.print("\tSERVER NAME: " + serverName);
            System.out.println("\t SERVER STATE: "
                    + (String) connection.getAttribute(ser, "State"));
            ObjectName[] appRT = (ObjectName[]) connection.getAttribute(ser,
                    "ApplicationRuntimes");
            // ApplicationRuntimeMBean appRun=(ApplicationRuntimeMBean)
            // connection.getAttribute(ser,"ApplicationRuntimes");
            System.out.println("\n\tTotal Applications Targeted On # "
                    + serverName + " # : " + appRT.length);
            for (ObjectName app : appRT) {
                String appName = (String) connection.getAttribute(app, "Name");
                // weblogic.health.HealthState healthState =
                // (weblogic.health.HealthState)
                // connection.getAttribute(app,"HealthState");
                // System.out.println("\t Health ="+healthState.getState());
                ObjectName[] componentRT = (ObjectName[]) connection
                        .getAttribute(app, "ComponentRuntimes");
                for (ObjectName compRT : componentRT) {
                    Integer stateInt = (Integer) connection.getAttribute(
                            compRT, "DeploymentState");
                    String name = (String) connection.getAttribute(compRT,
                            "Name");
                    String stateString = "" + stateInt;
                    if (stateInt == ComponentRuntimeMBean.ACTIVATED)
                        stateString = "ACTIVATED ";
                    if (stateInt == ComponentRuntimeMBean.NEW)
                        stateString = "NEW";
                    if (stateInt == ComponentRuntimeMBean.PREPARED)
                        stateString = "PREPARED ";
                    if (stateInt == ComponentRuntimeMBean.UNPREPARED)
                        stateString = "UNPREPARED ";
                    System.out.println("\n\tSTATE: " + stateString
                            + "      AppName: " + name);
                }
            }
        }

    }
  
    public static void main(String[] args) throws Exception {
        String hostname = "prasad.thekpsoft.com";
        String portString = "7001";
        String username = "weblogic";
        String password = "xxxx";
        MonitorOimServer s = new MonitorOimServer();
        initConnection(hostname, portString, username, password);
        s.printOimServerInformation();
        connector.close();
    }
}

x------------------------------------------------------x

2) WLDF Accessor for accessing WLDF harvester logs, same can be achieved by WLST Scripting as well.

package com.tns.ea.infra.monitor.jmx;

import java.util.Hashtable;

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.naming.Context;

public class OimJmxAccessor {

    private static final String JNDI = "/jndi/";

    public static void main(String[] args) {

        String logicalName = "ServerLog";
        String query = "";

        try {
            MBeanServerConnection mbeanServerConnection = lookupMBeanServerConnection();
            ObjectName service = new ObjectName(
                    weblogic.management.mbeanservers.runtime.RuntimeServiceMBean.OBJECT_NAME);
            ObjectName serverRuntime = (ObjectName) mbeanServerConnection
                    .getAttribute(service, "ServerRuntime");
            ObjectName wldfRuntime = (ObjectName) mbeanServerConnection
                    .getAttribute(serverRuntime, "WLDFRuntime");
            ObjectName wldfAccessRuntime = (ObjectName) mbeanServerConnection
                    .getAttribute(wldfRuntime, "WLDFAccessRuntime");
            ObjectName wldfDataAccessRuntime = (ObjectName) mbeanServerConnection
                    .invoke(wldfAccessRuntime, "lookupWLDFDataAccessRuntime",
                            new Object[] { logicalName },
                            new String[] { "java.lang.String" });

            String cursor = (String) mbeanServerConnection
                    .invoke(wldfDataAccessRuntime, "openCursor",
                            new Object[] { query },
                            new String[] { "java.lang.String" });

            int fetchedCount = 0;
            do {
                Object[] rows = (Object[]) mbeanServerConnection.invoke(
                        wldfDataAccessRuntime, "fetch",
                        new Object[] { cursor },
                        new String[] { "java.lang.String" });

                fetchedCount = rows.length;

                for (int i = 0; i < rows.length; i++) {
                    StringBuffer sb = new StringBuffer();
                    Object[] cols = (Object[]) rows[i];
                    for (int j = 0; j < cols.length; j++) {
                        sb.append("Index " + j + "=" + cols[j].toString() + " ");
                    }
                    System.out.println("Found row = " + sb.toString());
                }
            } while (fetchedCount > 0);

            mbeanServerConnection.invoke(wldfDataAccessRuntime, "closeCursor",
                    new Object[] { cursor },
                    new String[] { "java.lang.String" });
        } catch (Throwable th) {
            th.printStackTrace();
            System.exit(1);
        }

    }

    private static MBeanServerConnection lookupMBeanServerConnection()
            throws Exception {

        // construct JMX service URL
        JMXServiceURL serviceURL;
        serviceURL = new JMXServiceURL("iiop", "prasad.thekpsoft.com", 7001,
                JNDI + "weblogic.management.mbeanservers.runtime");

        // Specify the user, password, and WebLogic provider package
        Hashtable h = new Hashtable();
        h.put(Context.SECURITY_PRINCIPAL, "weblogic");
        h.put(Context.SECURITY_CREDENTIALS, "xxxxxx");
        h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES,
                "weblogic.management.remote");
        // Get jmx connector
        JMXConnector connector = JMXConnectorFactory.connect(serviceURL, h);

        // return MBean server connection class
        return connector.getMBeanServerConnection();

    } // End - lookupMBeanServerConnection
}