Configuring and Using the WebLogic Diagnostics Framework

     Previous  Next    Open TOC in new window    View as PDF - New Window  Get Adobe Reader - New Window
Content starts here

Configuring and Using WLDF Programmatically

As discussed in previous chapters, you can use the WebLogic Server Administration Console to enable, configure, and monitor features of WebLogic Server, including the WebLogic Diagnostic Framework (WLDF). You can do the same tasks programmatically using the JMX API and the WebLogic Scripting Tool (WLST).

The following sections provide information about configuring WLDF programatically:

In addition to the information provided in those sections, use the information in the following manuals to develop and deploy applications, and to use WLST:

 


How WLDF Generates and Retrieves Data

In general, diagnostic data is generated and retrieved by WLDF components following this process:

Configuration is primarily an administrative task, accomplished either through the Administration Console or through WLST scripts. Deployable descriptor modules, XML configuration files, are the primary method for configuring diagnostic resources at both the system level (servers and clusters) and at the application level. (For information on configuring WLDF resources, see Understanding WLDF Configuration.)

Output retrieval via the Accessor component can be either an administrative or a programmatic task.

 


Mapping WLDF Components to Beans and Packages

When you create WLDF resources using the Administration Console or WLST, WebLogic Server creates MBeans (managed beans=) for each resource. You can then access these MBeans using JMX or WLST. Because weblogic.WLST is a JMX client; any task you can perform using WLST you can also perform programmatically through JMX.

Table 14-1 lists the beans and packages associated with WLDF and its components. Figure 14-1 groups the beans by type.

Table 14-1 Mapping WLDF Components to Beans and Packages 
Component
Beans / Packages
WLDF
Diagnostic Image
Instrumentation
Diagnostic Context
Harvester
Watch & Notification
Archive
Accessor

Figure 14-1 WLDF Configuration MBeans, Runtime MBeans, and System Module Beans

WLDF Configuration MBeans, Runtime MBeans, and System Module Beans

 


Programming Tools

The WebLogic Diagnostic Framework enables you to perform the following tasks programmatically:

Configuration and Runtime APIs

The configuration and runtime APIs configure and monitor WLDF. Both the configuration and runtime APIs are exposed as MBeans.

You can use the APIs to configure, activate, and deactivate data collection; to configure watches, notifications, alarms, and diagnostic image captures; and to access data.

Configuration APIs

The Configuration APIs define interfaces that are used to configure the following WLDF components:

Runtime APIs

The runtime APIs define interfaces that are used to monitor the runtime state of the WLDF components. Instances of these APIs are instantiated on instances of individually managed servers. These APIs are defined as runtime MBeans, so JMX clients can easily access them.

The Runtime APIs encapsulate all other runtime interfaces for the individual WLDF components. These APIs are included in the weblogic.management.runtime package.

You can use the runtime APIs to monitor the following WLDF components:

 


WLDF Packages

The following two packages are provided:

 


Programming WLDF: Examples

The following examples use WLDF beans and packages to access and modify information on a running server:

In addition, see the WLST and JMX examples in WebLogic Scripting Tool Examples.

Example: DiagnosticContextExample.java

The following example uses the DiagnosticContextHelper class from the weblogic.diagnostics.context package to get and set the value of the DYE_0 flag. (For information on diagnostic contexts, see Configuring the DyeInjection Monitor to Manage Diagnostic Contexts.)

To compile and run the program:

  1. Copy the DiagnosticContextExample.java example (Listing 14-2) to a directory and compile it with:
  2. javac -d . DiagnosticContextExample.java

    This will create the ./weblogic/diagnostics/examples directory and populate it with DiagnosticContextExample.class.

  3. Run the program. The command syntax is:
  4. java weblogic.diagnostics.examples.DiagnosticContextExample

    Sample output is similar to:

    # java weblogic.diagnostics.examples.DiagnosticContextExample
    ContextId=5b7898f93bf010ce:40305614:1048582efd4:-8000-0000000000000001
    isDyedWith(DYE_0)=false
    isDyedWith(DYE_0)=true
    Listing 14-1 Example: DiagnosticContextExample.java
    package weblogic.diagnostics.examples;
    import weblogic.diagnostics.context.DiagnosticContextHelper;
    public class DiagnosticContextExample {  
      public static void main(String args[]) throws Exception {
    System.out.println("ContextId=" +
            DiagnosticContextHelper.getContextId());
    System.out.println("isDyedWith(DYE_0)=" +
    DiagnosticContextHelper.isDyedWith(DiagnosticContextHelper.DYE_0));
        DiagnosticContextHelper.setDye(DiagnosticContextHelper.DYE_0, true);
    System.out.println("isDyedWith(DYE_0)=" +
       DiagnosticContextHelper.isDyedWith(DiagnosticContextHelper.DYE_0));
    }
    }

Example: HarvesterMonitor.java

The HarvesterMonitor program uses the Harvester JMX notification to identify when a harvest cycle has occurred. It then retrieves the new values using the Accessor. All access is performed through JMX. This section includes a description of notification listeners followed by the HarvesterMonitor.java code:

For information on the Harvester component, see Configuring the Harvester for Metric Collection.

Notification Listeners

Notification listeners provide an appropriate implementation for a particular transport medium. For example, SMTP notification listeners provide the mechanism to establish an SMTP connection with a mail server and trigger an e-mail with the notification instance that it receives. JMX, SNMP, JMS and other types of listeners provide their respective implementations as well.

Note: You can develop plug-ins that propagate events generated by the WebLogic Diagnostic Framework using transport mediums other than SMTP, JMX, SNMP, or JMS. One approach is to use the JMX NotificationListener interface to implement an object, and then propagate the notification according to the requirements of the selected transport medium.

Table 14-2 describes each notification listener type that is provided with WebLogic Server and the relevant configuration settings for each type.

Table 14-2 Notification Listener Types 
Notification Medium

Description

Configuration Parameter Requirements
JMS
Propagated via JMS Message queues or topics.
Required: Destination JNDI name.
Optional: Connection factory JNDI name (use the default JMS connection factory if not present).
JMX
Propagated via standard JMX notifications.
None required. Uses predefined singleton for posting the event.
SMTP
Propagated via regular e-mail.
Required: MailSession JNDI name and Destination e-mail.
Optional: Subject and body (if not specified, use default)
SNMP
Propagated via SNMP traps and the WebLogic Server SNMP Agent.
None required, but the SNMPTrapDestination MBean must be defined in the WebLogic SNMP agent.

By default, all notifications fired from watch rules are stored in the server log file in addition to being fired through the configured medium.

HarvesterMonitor.java

To compile and run the HarvesterMonitor program:

  1. Copy the HarvesterMonitor.java example (Listing 14-2) to a directory and compile it with:
  2. javac -d . HarvesterMonitor.java

    This will create the ./weblogic/diagnostics/examples directory and populate it with HarvesterMonitor.class and HarvesterMonitor$HarvestCycleHandler.class.

  3. Start the monitor. The command syntax is:
  4. java HarvesterMonitor <server> <port> <uname> <pw> [<types>]

    You will need access to a WebLogic Server instance, and will need to know the server’s name, port number, administrator’s login name, and the administrator’s password.

    You can provide an optional list of harvested type names. If provided, the program will display only the values for those types. However, for each selected type, the monitor displays the complete set of collected values; there is no way to constrain the values that are displayed for a selected type.

    Only values that are explicitly configured for harvesting are displayed. Values collected solely to support watch rules (implicit values) are not displayed.

    The following command requires that ’.’ is in the CLASSPATH variable, and that you run the command from the directory where you compiled the program. The command connects to the myserver server, at port 7001, as user weblogic, with a password of weblogic:

    java weblogic.diagnostics.examples.HarvesterMonitor myserver 7001
    weblogic weblogic

    See Listing 14-3 for an example of output from the HarvesterMonitor.

    Listing 14-2 Example: HarvesterMonitor.java
    package weblogic.diagnostics.examples;
    import weblogic.management.mbeanservers.runtime.RuntimeServiceMBean;
    import javax.management.*;
    import javax.management.remote.*;
    import javax.naming.Context;
    import java.util.*;
    public class HarvesterMonitor {
      
      private static String accessorRuntimeMBeanName;
       private static ObjectName accessorRuntimeMBeanObjectName;
      private static String harvRuntimeMBeanName;
       private static ObjectName harvRuntimeMBeanObjectName;
      private static MBeanServerConnection rmbs;
      private static ObjectName getObjectName(String objectNameStr) {
         try { return new ObjectName(getCanonicalName(objectNameStr)); }
         catch (RuntimeException x) { throw x; }
         catch (Exception x) { x.printStackTrace(); throw new
                                    RuntimeException(x); }
      }
      private static String getCanonicalName(String objectNameStr) {
         try { return new ObjectName(objectNameStr).getCanonicalName(); }
         catch (RuntimeException x) { throw x; }
         catch (Exception x) { x.printStackTrace(); throw new
                                     RuntimeException(x); }
      }
      private static String serverName;
       private static int port;
       private static String userName;
       private static String password;
      private static ArrayList typesToMonitor = null;
      public static void main(String[] args) throws Exception {
        if (args.length < 4) {
            System.out.println(
                 "Usage: java weblogic.diagnostics.harvester.HarvesterMonitor " +
                 "<serverName> <port> <userName> <password> [<types>]" +
                  weblogic.utils.PlatformConstants.EOL +
                  "   where <types> (optional) is a comma-separated list " +
                  "of types to monitor.");
            System.exit(1);
    }
        serverName = args[0];
         port = Integer.parseInt(args[1]);
         userName = args[2];
         password = args[3];
        accessorRuntimeMBeanName = getCanonicalName(
             "com.bea:ServerRuntime=" + serverName +          ",Name=HarvestedDataArchive,Type=WLDFDataAccessRuntime" +          ",WLDFAccessRuntime=Accessor,WLDFRuntime=WLDFRuntime");
        accessorRuntimeMBeanObjectName = 
              getObjectName(accessorRuntimeMBeanName);
        harvRuntimeMBeanName = getCanonicalName(
    "com.bea:ServerRuntime=" + serverName +
    ",Name=WLDFHarvesterRuntime,Type=WLDFHarvesterRuntime" +
    ",WLDFRuntime=WLDFRuntime");
    harvRuntimeMBeanObjectName = getObjectName(harvRuntimeMBeanName);
        if (args.length > 4) {
    String typesStr = args[4];
    typesToMonitor = new ArrayList();
    int index;
    while ((index = typesStr.indexOf(",")) > 0) {
    String typeName = typesStr.substring(0,index).trim();
    typesToMonitor.add(typeName);
    typesStr = typesStr.substring(index+1);
    }
    typesToMonitor.add(typesStr.trim());
    }
        rmbs = getRuntimeMBeanServerConnection();
        new HarvesterMonitor().new HarvestCycleHandler();
    while(true) {Thread.sleep(100000);}
    }
      static protected String JNDI = "/jndi/";
    static public MBeanServerConnection getRuntimeMBeanServerConnection()
    throws Exception {
        JMXServiceURL serviceURL;
    serviceURL =
    new JMXServiceURL("t3",
    "localhost",
    port,
    JNDI + RuntimeServiceMBean.MBEANSERVER_JNDI_NAME);
    System.out.println("ServerName=" + serverName);
    System.out.println("URL=" + serviceURL);
        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");
    JMXConnector connector = JMXConnectorFactory.connect(serviceURL,h);
    return connector.getMBeanServerConnection();
    }
      class HarvestCycleHandler implements NotificationListener {
    // used to track harvest cycles
        private int timestampIndex;
    private int domainIndex;
    private int serverIndex;
    private int typeIndex;
    private int instNameIndex;
    private int attrNameIndex;
    private int attrTypeIndex;
    private int attrValueIndex;
        long lastSampleTime = System.currentTimeMillis();
        HarvestCycleHandler() throws Exception{
    System.out.println("Harvester monitor started...");
    try {
    setUpRecordIndices();
    rmbs.addNotificationListener(harvRuntimeMBeanObjectName,
    this, null, null);
    }
    catch (javax.management.InstanceNotFoundException x) {
    System.out.println("Cannot find JMX data. " +
    "Is the server name correct?");
    System.exit(1);
    }
    }
        private void setUpRecordIndices() throws Exception {
          Map columnIndexMap = (Map)rmbs.getAttribute(
    accessorRuntimeMBeanObjectName, "ColumnIndexMap");
          timestampIndex =              ((Integer)columnIndexMap.get("TIMESTAMP")).intValue();
    domainIndex =
                ((Integer)columnIndexMap.get("DOMAIN")).intValue();
    serverIndex =
                ((Integer)columnIndexMap.get("SERVER")).intValue();
    typeIndex =
                ((Integer)columnIndexMap.get("TYPE")).intValue();
    instNameIndex =
                ((Integer)columnIndexMap.get("NAME")).intValue();
    attrNameIndex =
                ((Integer)columnIndexMap.get("ATTRNAME")).intValue();
    attrTypeIndex =
                ((Integer)columnIndexMap.get("ATTRTYPE")).intValue();
    attrValueIndex =              ((Integer)columnIndexMap.get("ATTRVALUE")).intValue();
    }
        public synchronized void handleNotification(Notification notification,
    Object handback) {
            System.out.println("\n------------------------------------------");
    long thisSampleTime = System.currentTimeMillis()+1;
    try {
    String lastTypeName = null;
    String lastInstName = null;
    String cursor = (String)rmbs.invoke(accessorRuntimeMBeanObjectName,
    "openCursor",
    new Object[]{new Long(lastSampleTime),
    new Long(thisSampleTime), null},
    new String[]{ "java.lang.Long",
    "java.lang.Long", "java.lang.String" } );
    while (((Boolean)rmbs.invoke(accessorRuntimeMBeanObjectName,
    "hasMoreData",
    new Object[]{cursor},
    new String[]{"java.lang.String"})).booleanValue()) {
    Object[] os = (Object[])rmbs.invoke(accessorRuntimeMBeanObjectName,
    "fetch",
    new Object[]{cursor},
    new String[]{"java.lang.String"});
    for (int i = 0; i < os.length; i++) {
    Object[] values = (Object[])os[i];
    String typeName = (String)values[typeIndex];
    String instName = (String)values[instNameIndex];
    String attrName = (String)values[attrNameIndex];
    if (!typeName.equals(lastTypeName)) {
    if (typesToMonitor != null &&
    !typesToMonitor.contains(typeName)) continue;
    System.out.println("\nType " + typeName);
    lastTypeName = typeName;
    }
    if (!instName.equals(lastInstName)) {
    System.out.println("\n Instance " + instName);
    lastInstName = instName;
    }
    Object attrValue = values[attrValueIndex];
    System.out.println(" - " + attrName + "=" + attrValue);
    }
    }
    lastSampleTime = thisSampleTime;
    }
    catch (Exception e) {e.printStackTrace();}
    }
    }
    }

Listing 14-3 contains sample output from the HarvesterMonitor program:

Listing 14-3 Sample Output from HarvesterMonitor
ServerName=myserver
URL=service:jmx:t3://localhost:7001/jndi/weblogic.management.mbeanservers.runtime
Harvester monitor started...
------------------------------------------------------
Type weblogic.management.runtime.WLDFHarvesterRuntimeMBean
Instance com.bea:Name=WLDFHarvesterRuntime,ServerRuntime=myserver,Type=WLDFHarvesterRuntime,WLDFRuntime=WLDFRuntime
- TotalSamplingTime=202048863
- CurrentSnapshotElapsedTime=1839619
Type weblogic.management.runtime.ServerRuntimeMBean
  Instance com.bea:Name=myserver,Type=ServerRuntime
- RestartRequired=false
- ListenPortEnabled=true
- ActivationTime=1118319317071
- ServerStartupTime=40671
- ServerClasspath= [deleted long classpath listing]
- CurrentMachine=
- SocketsOpenedTotalCount=1
- State=RUNNING
- RestartsTotalCount=0
- AdminServer=true
- AdminServerListenPort=7001
- ClusterMaster=false
- StateVal=2
- CurrentDirectory=C:\testdomain\.
- AdminServerHost=10.40.8.123
- OpenSocketsCurrentCount=1
- ShuttingDown=false
- SSLListenPortEnabled=false
- AdministrationPortEnabled=false
- AdminServerListenPortSecure=false
- Registered=true

Example: JMXAccessorExample.java

The following example program uses JMX to print log entries to standard out. All access is performed through JMX. (For information on the Accessor component, see Accessing Diagnostic Data With the Data Accessor.)

To compile and run the program:

  1. Copy the JMXAccessorExample.java example (Listing 14-4) to a directory and compile it with:
  2. javac -d . JMXAccessorExample.java

    This will create the ./weblogic/diagnostics/examples directory and populate it with JMXAccessorExample.class.

  3. Start the program. The command syntax is:
  4. java weblogic.diagnostics.example.JMXAccessor <logicalName> <query>

    You will need access to a WebLogic Server instance, and will need to know the server’s name, port number, administrator’s login name, and the administrator’s password.

    The logicalName is the name of the log. Valid names are: HarvestedDataArchive, EventsDataArchive, ServerLog, DomainLog, HTTPAccessLog, ServletAccessorHelper.WEBAPP_LOG, RAUtil.CONNECTOR_LOG, JMSMessageLog, and CUSTOM.

    The query is constructed using the syntax described in WLDF Query Language. For the JMXAccessorExample program, an empty query (an empty pair of double quotation marks, "") returns all entries in the log.

    The following command requires that ’.’ is in the CLASSPATH variable, and that you run the command from the directory where you compiled the program. The program uses the IIOP (Internet Inter-ORB Protocol) protocol to connect to port 7001, as user weblogic, with a password of weblogic, and prints all entries in the ServerLog to standard out:

    java weblogic.diagnostics.examples.JMXAccessorExample ServerLog ""

    You can modify the example to use a username/password combination for your site.

    Listing 14-4 JMXAccessorExample.java
    package weblogic.diagnostics.examples;
    import java.io.IOException;
    import java.net.MalformedURLException;
    import java.util.Hashtable;
    import java.util.Iterator;
    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 JMXAccessorExample {
      private static final String JNDI = "/jndi/";
      public static void main(String[] args) {
    try {
    if (args.length != 2) {
    System.err.println("Incorrect invocation. Correct usage is:\n" +
    "java weblogic.diagnostics.examples.JMXAccessorExample " +
    "<logicalName> <query>");
    System.exit(1);
    }
    String logicalName = args[0];
    String query = args[1];
          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", "localhost", 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,"weblogic");
    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
    }


  Back to Top       Previous  Next