17 Configuring and Using WLDF Programmatically

As an alternative to using the WebLogic Server Administration Console or Fusion Middleware Control to enable, configure, and monitor the WebLogic Diagnostics Framework (WLDF), you can also use the JMX API or the WebLogic Scripting Tool (WLST) to perform these tasks programmatically.

See the following for additional information about how to develop and deploy JMX applications and to use WLST:

How WLDF Generates and Retrieves Data

The process WLDF uses to generate and retrieve diagnostic data largely depends on how its main components are configured.

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

  • The WLDF XML descriptor file settings for the Harvester, Instrumentation, Image Capture, and Policies and Actions components determine the type and amount of diagnostic data generated while a server is running.

  • The diagnostic context and instrumentation settings filter and monitor this data as it flows through the system. Data is harvested, actions are executed, events are generated, and configured notifications are sent.

  • The Archive component stores the data.

  • The Accessor component retrieves the data.

Configuration is primarily an administrative task, accomplished either through the WebLogic Server 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 about 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 diagnostic system modules using the WebLogic Server Administration Console or WLST, WebLogic Server creates MBeans (managed beans) for each module. You can access these MBeans using JMX or WLST. Because WLST is a JMX client; any task you can perform using WLST you can also perform programmatically through JMX.

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

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

Description of Figure 17-1 follows
Description of "Figure 17-1 WLDF Configuration MBeans, Runtime MBeans, and System Module Beans"

Programming Tools

WLDF supports the use of multiple tools, such as WLST, JMX, and REST, for performing tasks programmatically.

For example, you can use these tools to do the following:

  • Create and modify diagnostic descriptor files to configure the WLDF Harvester, Instrumentation, and Policies and Actions components at the server level.

  • Use JMX to access WLDF operations and attributes.

  • Use JMX to create custom MBeans that contain harvestable data. You can then configure the Harvester to collect that data and configure policies and actions to monitor the values.

  • Write Java programs that perform the following tasks:

    • Capture notifications using JMX listeners.

    • Capture notifications using JMS.

    • Retrieve archived data through the Accessor. (The Accessor, as are the other components, is surfaced as JMX; you can use WLST or straight JMX programming to retrieve diagnostic data.)

Configuration and Runtime APIs

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

  • The configuration MBeans and system module Beans create and configure WLDF resources, and determine their runtime behavior.

  • The runtime MBeans monitor the runtime state and the operations defined for the different components.

You can use the APIs to configure, activate, and deactivate data collection; to configure policies, actions, 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:

  • Data Collectors: You can use the configuration APIs to configure and control Instrumentation, Harvesting, and Image Capture.

    • For the Instrumentation component, you can enable, disable, create, and destroy server-level instrumentation and instrumentation monitors.


      The configuration APIs do not support configuration of application-level instrumentation. However, configuration changes for application-level instrumentation can be effected using Java Specification Request (JSR) 88 APIs.

    • For the Harvester component, you can add and remove types to be harvested, specify which attributes and instances of those types are to be harvested, and set the sample period for the Harvester.

    • For the Diagnostic Image Capture component, you can set the name and path of the directory in which the image capture is to be stored and the events image capture interval, that is, the time interval during which recently archived events are captured in the diagnostic image.

  • Policies and Actions: You can use the configuration APIs to enable, disable, create, and destroy policies and actions. You can also use the configuration APIs to:

    • Set the policy type, policy expressions, and severity for policies

    • Set alarm type and alarm reset period for actions

    • Configure a policy to execute a diagnostic image capture

    • Add and remove actions from policies

  • Archive: Set the archive type and the archive directory

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:

  • Data Collectors—You can use the runtime APIs to monitor the Instrumentation, Harvester, and the Image Capture components.

    • For the Instrumentation component, you can monitor joinpoint count statistics, the number of classes inspected for instrumentation monitors, the number of classes modified, and the time it takes to inspect a class for instrumentation monitors.

    • For the Harvester component, you can query the set of harvestable types, harvestable attributes, and harvestable instances (that is, the instances that are currently harvestable for specific types). And, you can also query which types, attributes, and instances are currently configured for harvesting. The sampling interval and various runtime statistics pertaining to the harvesting process are also available.

    • For the Image Capture component, you can specify the destination and lockout period for diagnostic images and initiate image captures.

  • Policies and Actions: You can use the runtime APIs to monitor the Policies and Actions and Archive components.

    • For the Policies and Actions component, you can reset policy alarms and monitor statistics about policy expression evaluations and policies triggered, including information about the analysis of alarms, events, log records, and harvested metrics.

  • Archive: You can monitor information about the archive, such as file name and archive statistics.

  • Data Accessor—You can use the runtime APIs to retrieve the diagnostic data persisted in the different archives. The runtime APIs also support data filtering by allowing you to specify a query expression to search the data from the underlying archive. You can monitor information about column type maps (a map relating column names to the corresponding type names for the diagnostic data), statistics about data record counts and timestamps, and cursors (cursors are used by clients to fetch data records).

WLDF Packages

WLDF provides two packages you can use to perform select operations programmatically.

  • weblogic.diagnostics.context contains:

    • DiagnosticContextConstants, which defines the indices of dye flags supported by the WebLogic diagnostics system.

    • DiagnosticContextHelper, which provides applications limited access to the diagnostic context.

  • weblogic.diagnostics.watch contains:

    • JMXWatchNotification, an extended JMX notification object which includes additional information about the notification. This information is contained in the referenced WatchNotification object returned from method getExtendedInfo.

    • WatchNotification, which defines an action for a policy.

Programming WLDF: Examples

WLDF provides a number of beans and packages you can use to access and modify information about a running server. The following examples show how to use these components:

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 about diagnostic contexts, see Configuring the DyeInjection Monitor to Manage Diagnostic Contexts.)

To compile and run the program:

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

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

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

    Sample output is similar to:

    # java weblogic.diagnostics.examples.DiagnosticContextExample

Example 17-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=" +
    System.out.println("isDyedWith(DYE_0)=" + 
    DiagnosticContextHelper.setDye(DiagnosticContextHelper.DYE_0, true);
    System.out.println("isDyedWith(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. A description of notification listeners and the HarvesterMonitor.java code are provided in the following sections:

For information about 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 send an e-mail with the notification instance that it receives. JMX, SNMP, JMS and other types of listeners provide their respective implementations as well.


You can develop plug-ins that propagate events generated by the WebLogic Diagnostics 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 17-2 describes each notification listener type that is provided with WebLogic Server and the relevant configuration settings for each type.

Table 17-2 Notification Listener Types

Notification Medium Description Configuration Parameter Requirements


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).


Propagated via standard JMX notifications.

None required. Uses predefined singleton for posting the event.


Propagated via regular e-mail.

Required: MailSession JNDI name and Destination e-mail.

Optional: Subject and body (if not specified, use default)


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 executed from policies are stored in the server log file in addition to being executed through the configured medium.


To compile and run the HarvesterMonitor program:

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

    This creates the ./weblogic/diagnostics/examples directory and populates it with HarvesterMonitor.class and HarvesterMonitor$HarvestCycleHandler.class.

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

    You need access to a WebLogic Server instance, and 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 displays 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 policies (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 (and also the password, shown as password):

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

    See Example 17-3 for an example of output from the HarvesterMonitor.

Example 17-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) {
             "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.");
    serverName = args[0];
     port = Integer.parseInt(args[1]);
     userName = args[2];
     password = args[3];
    accessorRuntimeMBeanName = getCanonicalName(
         "com.bea:ServerRuntime=" + serverName +
          ",Name=HarvestedDataArchive,Type=WLDFDataAccessRuntime" +
    accessorRuntimeMBeanObjectName = 
    harvRuntimeMBeanName = getCanonicalName(
        "com.bea:ServerRuntime=" + serverName +
        ",Name=WLDFHarvesterRuntime,Type=WLDFHarvesterRuntime" +
    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();
        typesStr = typesStr.substring(index+1);
    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",
        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);
    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 {
                                     this, null, null);
      catch (javax.management.InstanceNotFoundException x) {
        System.out.println("Cannot find JMX data. " +
                           "Is the server name correct?");
    private void setUpRecordIndices() throws Exception {
      Map columnIndexMap = (Map)rmbs.getAttribute(
          accessorRuntimeMBeanObjectName, "ColumnIndexMap");
      timestampIndex =              ((Integer)columnIndexMap.get("TIMESTAMP")).intValue();
      domainIndex = 
      serverIndex = 
      typeIndex = 
      instNameIndex = 
      attrNameIndex = 
      attrTypeIndex = 
      attrValueIndex =              ((Integer)columnIndexMap.get("ATTRVALUE")).intValue();
    public synchronized void handleNotification(Notification notification,
                                                Object handback) {
      long thisSampleTime = System.currentTimeMillis()+1;
      try {
        String lastTypeName = null;
        String lastInstName = null;
        String cursor = (String)rmbs.invoke(accessorRuntimeMBeanObjectName,
                        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,
                        new Object[]{cursor},
                        new String[]{"java.lang.String"})).booleanValue()) {
          Object[] os = (Object[])rmbs.invoke(accessorRuntimeMBeanObjectName,
                        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();}

Example 17-3 contains sample output from the HarvesterMonitor program:

Example 17-3 Sample Output from HarvesterMonitor

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=
    - 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 about the Accessor component, see Accessing Diagnostic Data With the Data Accessor.)

To compile and run the program:

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

    This creates the ./weblogic/diagnostics/examples directory and populates it with JMXAccessorExample.class.

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

    You need access to a WebLogic Server instance, and have 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.

    Construct the query 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 shown as password, 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.

Example 17-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>");
      String logicalName = args[0];
      String query = args[1];      
      MBeanServerConnection mbeanServerConnection =
      ObjectName service = new
      ObjectName serverRuntime =
        (ObjectName) mbeanServerConnection.getAttribute(service,
      ObjectName wldfRuntime =
        (ObjectName) mbeanServerConnection.getAttribute(serverRuntime,
      ObjectName wldfAccessRuntime =
        (ObjectName) mbeanServerConnection.getAttribute(wldfRuntime,
      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);
          "closeCursor", new Object[] {cursor},
          new String[] {"java.lang.String"});
      } catch(Throwable th) {
   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();
    // Get jmx connector 
    JMXConnector connector = JMXConnectorFactory.connect(serviceURL,h);
    // return MBean server connection class
    return connector.getMBeanServerConnection();
  } // End - lookupMBeanServerConnection