Troubleshoot > Work with Diagnostic Providers > Create a Diagnostic Provider > Implement a Diagnostic Provider

Diagnostic Provider method implementation

To create a Diagnostic Provider (DP) we must have an MBean that includes the required methods in its deployment XML file. These methods define the operations, attributes, and aggregators necessary for an MBean to be a Diagnostic Provider.

Adding these methods can be accomplished by adding the parentType directive to your existing XML file (see Implement a Diagnostic Provider), or by including the operations directly into your deployment XML file. The definitions needed are included in Diagnostic Provider registered attributes and registered tests. The next step is for the MBean to actually implement these methods. The methods to implement include:


getRegisteredDiagnostics

This method exposes the registration information for this Diagnostic Provider. It is commonly used by the DP Utility in the administration console to gather information about Diagnostic Providers that are to be displayed in the console. This method returns a DiagnosticProviderInfo object that is usually attained by passing the appropriate XML to a DiagnosticProviderHelper helper class. Here is an example:

public DiagnosticProviderInfo getRegisteredDiagnostics() {
  InputStream regIS= Thread.currentThread().getContextClassLoader().getResourceAsStream(
   "com/ibm/ws/xxx/SampleDP2DiagnosticProvider.xml");
  dpInfo = DiagnosticProviderHelper.loadRegistry(regIS, sDPName) ;

         if (dpInfo == null) {
            sSampleDP2MBeanLogger.logp(Level.WARNING, sThisClass, "getRegisteredDiagnostics",
             "RasDiag.DPInfo.NoGotz") ;
  }
    return dpInfo ;
 }

Notice the XML is packaged and available in the classpath of the current classloader. The Registration XML contains crucial information the Diagnostic Provider uses to Populate the payload and localize results.


getDiagnosticProviderName

This is usually a pretty simple return of a constant as the following example shows

public String getDiagnosticProviderName() { 
  return sDPName;
 }


getDiagnosticProviderID

This is usually a pretty simple return of a JMX object ID that MBeans can pull out of the base class method. For example:

public String getDiagnosticProviderId() { 
  return getObjectName().toString() ;
 }


configDump

The configDump method enables the Diagnostic Provider to expose the configuration data that was in place when this Diagnostic Provider started (or the current values of them). The DiagnosticEvent objects that this method returns include a Payload containing the core data. The following is an excerpt from a configDump method:

public DiagnosticEvent [] configDump(String aAttributeIdSpec, boolean aRegisteredOnly) {
    HashMap cdHash = new HashMap(64) ;

  // Populate the payload

    DiagnosticEvent [] diagnosticEvent = new DiagnosticEvent[1] ;
    diagnosticEvent[0] = DiagnosticEventFactory.createConfigDump(getObjectName().toString(), 
     "ThisClassName", "configDump", cdHash) ;

    return diagnosticEvent ;
 }

This returns an array of DiagnosticEvent objects. Normally, configDump and stateDump return only one object. However, the method accepts an array because on z/OS systems a server can have multiple servants, and aggregation of the output from the servants is stored in the array.


stateDump

The stateDump method enables the Diagnostic Provider to expose the current state data, or data about the current operating conditions of the Diagnostic Provider. The data made available can be anything likely to assist a customer, an IBM support person, or automated tooling in analyzing the health of the component and problem determination if there is an issue. The amount of data available is impacted by the State Collection Specification in effect at the time. If the current State Collection Specification involves the collection of additional data by the Diagnostic Provider, then this additional data can be exposed in the stateDump. The DiagnosticEvent objects that this method returns include a Payload containing the core data. The following is an excerpt from a stateDump method:

public DiagnosticEvent [] stateDump(String aAttributeIdSpec, boolean aRegisteredOnly) {
    HashMap sdHash = new HashMap(64) ;

  // Populate the payload

    DiagnosticEvent [] diagnosticEvent = new DiagnosticEvent[1] ;
    diagnosticEvent[0] = DiagnosticEventFactory.createStateDump(getObjectName().toString(), 
     "ThisClassName", "stateDump", sdHash) ;

    return diagnosticEvent ;
 }

This returns an array of DiagnosticEvent objects. Normally, configDump and stateDump return only one object.


selfDiagnostic

The selfDiagnostic method enables the Diagnostic Provider to perform certain predefined activities to test key functionalities of your system. These tests should not have a lasting effect on the system. For example, if the test is to create a TCP/IP connection to a remote host, the test should also break that connection before returning its results so the state of the component is unchanged by the test. The information returned by the test is determined by the attributes included in the test section of the XML file. The following is an excerpt from a selfDiagnostic method:

public DiagnosticEvent [] selfDiagnostic(String aAttributeIdSpec, boolean aRegisteredOnly) {
  TestInfo [] testInfo = dpInfo.selfDiagnosticInfo.testInfo ; // Retrieve the test registry information   Pattern testChecker = Pattern.compile(aAttributeIdSpec) ; // Compile test regexp parm for faster checking
  ArrayList deList = new ArrayList(8) ;    // Allocate expandable list of DiagnosticEvents
  for (int i = 0; i < testInfo.length; i++) {
   if (testChecker.matcher(testInfo[i].id).matches()) {
      HashMap deHash = new HashMap(32) ;

    // Populate the payload

      deList.add(DiagnosticEventFactory.createDiagnosticEvent(getObjectName().toString(), 
       DiagnosticEvent.EVENT_TYPE_SELF_DIAGNOSTIC, DiagnosticEvent.LEVEL_INFO,
       "ThisClassName", "selfDiagnostic", dpInfo.resourceBundleName,
     "RasDiag.SDP2.createDE3",   // MsgKey for localization
           // Parms to incorporate in msg
     new Object [] { "OneParm", "TwoParm", "RedParm", "BlueParm"}, deHash)) ;
   }
  }

    DiagnosticEvent [] diagnosticEvent = new DiagnosticEvent[deList.size()] ;
  diagnosticEvent = (DiagnosticEvent [])deList.toArray(diagnosticEvent) ;
 
    return diagnosticEvent ;
 }

This returns an array of DiagnosticEvent objects. In this example, one DiagnosticEvent was created from each test that matched the parameter regular expression. The Diagnostic Provider is not required to produce only one per test. The generation of Payload is similar to that of configDump and stateDump.


localize

The DiagnosticEvents that methods return contain payload HashMaps containing MessageKeys and ResourceBundles. The final consumer of these events is often not on the server, and thus may not have the appropriate classpath to resolve this. For this purpose, a callback to the Diagnostic Provider to localize the variables is done. A helper method, however, makes it a simple method to write, as this example demonstrates:

public String [] localize(String [] aKeys, Locale aLocale) {
  return DiagnosticProviderHelper.localize(dpInfo.resourceBundleName, aKeys, aLocale) ;
 }

Note the dpInfo (DiagnosticProviderInfo) object is needed as this object includes a reference to the ResourceBundle.


Payload

A recurring theme in these methods is the ability to include a payload in return objects. This is a set of name=value pairs that include the information being exposed by the method. Diagnostic Events returned from a configDump, stateDump, or selfDiagnostic test are relatively complex Java objects. The majority of the information that is returned is contained in the DiagnosticData portion of the DiagnosticEvent object. Each attribute returned by the Diagnostic Provider is stored in an entry in a HashMap.

There can be cascading HashMaps within a single DiagnosticEvent object (if breaking the data down into subGroups makes sense). Each HashMap entry contains either a reference to a child HashMap, or a DiagnosticTypedValue (which contains the value, the type of data, and a MsgKey for localization of the label or /name). The values to be returned should be filtered with:


Populate the payload

The API documentation for DiagnosticProviderHelper.queryMatchingDPInfoAttributes explains how to do the filtering before retrieving the data. In some cases, it is easier and helps performance for a Diagnostic Provider to retrieve all data into the Payload and then filter the HashMap after the fact. The post-population filtering can be done with the method DiagnosticProviderHelper.filterEventPayload. For information on use of the JavaBeans type approach, see the API documentation for the AttributeBeanInfo.populateMap method.


Registration XML

Registration XML enables much of the information needed by the Diagnostic Provider to be externalized. It also provides a means of commonizing localization and consumption of the tests (thus aiding automation). An excerpt of this XML from a sample Diagnostic Provider follows:

<!DOCTYPE diagnosticProvider PUBLIC "RasDiag" "/DiagnosticProvider.dtd"> 
<diagnosticProvider>     <resourceBundleName> com.ibm.ws.rasdiag.resources.RasDiagSample</resourceBundleName>     <state>  <attribute>   <id>Leg-Foot</id>   <descriptionKey>SampleDiagnostic.LegFoot.descriptionKey</descriptionKey>   <registered>true</registered>  </attribute>  <attribute>   <id>Leg-Ankle</id>   <descriptionKey>SampleDiagnostic.LegAnkle.descriptionKey</descriptionKey>   <registered>true</registered>         </attribute>     </state>     <config>         <attribute>   <id>Arm-Hand-Size</id>   <descriptionKey>SampleDiagnostic.HandSize.descriptionKey</descriptionKey>   <registered>true</registered>         </attribute>         <attribute>   <id>Leg-Foot-Size</id>   <descriptionKey>SampleDiagnostic.FootSize.descriptionKey</descriptionKey>   <registered>true</registered>         </attribute>     </config>     <selfDiagnostic>         <test>   <id>Kick</id>   <descriptionKey>SampleDiagnostic.Kick.descriptionKey</descriptionKey>   <attribute>    <id>Kick-Pain</id>    <descriptionKey>SampleDiagnostic.KickPain.descriptionKey</descriptionKey>   </attribute>   <attribute>    <id>Kick-Length</id>    <descriptionKey>SampleDiagnostic.KickLength.descriptionKey</descriptionKey>   </attribute>         </test>  <test>   <id>Throw</id>   <descriptionKey>SampleDiagnostic.Throw.descriptionKey</descriptionKey>          <attribute>    <id>Throw-Pain</id>    <descriptionKey>SampleDiagnostic.ThrowPain.descriptionKey</descriptionKey>    <registered>true</registered>   </attribute>   <attribute>    <id>Throw-Length</id>    <descriptionKey>SampleDiagnostic.ThrowLength.descriptionKey</descriptionKey>    <registered>true</registered>   </attribute>         </test>     </selfDiagnostic> </diagnosticProvider>

For understanding the storage of this information into a DiagnosticProviderInfo object, see the API documentation for DiagnosticProviderInfo. For conceptual information about the purpose of the registration XML, see Diagnostic Provider registered attributes and registered tests.


Subtopics


Related

  • Create a Diagnostic Provider
  • Diagnostic Providers (selection)


    +

    Search Tips   |   Advanced Search