诊断提供程序方法实现
要创建诊断提供程序 (DP),必须具有 Mbean,并且该 MBean 的部署可扩展标记语言 (XML) 文件中应包括必需的方法。这些方法定义使 MBean 成为诊断提供程序所需的操作、属性和聚集器。
getRegisteredDiagnostics
此方法用于向此诊断提供程序提供注册信息。在管理控制台中,DP 实用程序通常使用此方法来收集有关要显示在控制台中的诊断提供程序的信息。 此方法将返回 DiagnosticProviderInfo 对象,而该对象通常是通过将适当 XML 传递至 DiagnosticProviderHelper 辅助类来获得的。以下是一个示例:
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 ;
}
注意,XML 已打包,可从当前类装入器的类路径中获得。注册 XML 包含诊断提供程序用来对结果进行填充有效内容和本地化的至关重要信息。
getDiagnosticProviderName
这通常只是返回一个常量,如以下示例中所示:
public String getDiagnosticProviderName() {
return sDPName;
}
getDiagnosticProviderID
这通常只是返回一个 Java™ 管理扩展 (JMX) 对象标识,MBean 可以从基类方法中拉出该对象标识。例如:
public String getDiagnosticProviderId() {
return getObjectName().toString() ;
}
configDump
configDump 方法使诊断提供程序能够显示它在启动时所具备的配置数据(或者这些数据的当前值)。此方法返回的 DiagnosticEvent 对象包括一个具有核心数据的有效内容。以下内容摘录自 configDump 方法:
public DiagnosticEvent [] configDump(String aAttributeIdSpec, boolean aRegisteredOnly) {
HashMap cdHash = new HashMap(64) ;
// 填充有效内容
DiagnosticEvent [] diagnosticEvent = new DiagnosticEvent[1] ;
diagnosticEvent[0] = DiagnosticEventFactory.createConfigDump(getObjectName().toString(),
"ThisClassName", "configDump", cdHash) ;
return diagnosticEvent ;
}
这将返回一组 DiagnosticEvent 对象。通常,configDump 和 stateDump 将只返回一个对象。但是,该方法接受数组,因为在 z/OS® 系统上,一个服务器可以具有多个服务方,并且服务方的输出聚集存储在该数组中。
stateDump
stateDump 方法使诊断提供程序能够显示当前状态数据或者显示有关诊断提供程序的当前运行情况的数据。可用数据是可以帮助客户、IBM® 支持机构人员或自动运行的工具分析组件运行状况和进行问题确定(如果存在问题的话)的任何数据。可用数据的数量会受到当时有效的状态收集规范的影响。如果当前的“状态收集规范”涉及到使用诊断提供程序来收集更多数据,那么可以在 stateDump 中显示这些数据。此方法返回的 DiagnosticEvent 对象包括一个具有核心数据的有效内容。以下内容摘录自 stateDump 方法:
public DiagnosticEvent [] stateDump(String aAttributeIdSpec, boolean aRegisteredOnly) {
HashMap sdHash = new HashMap(64) ;
// 填充有效内容
DiagnosticEvent [] diagnosticEvent = new DiagnosticEvent[1] ;
diagnosticEvent[0] = DiagnosticEventFactory.createStateDump(getObjectName().toString(),
"ThisClassName", "stateDump", sdHash) ;
return diagnosticEvent ;
}
这将返回一组 DiagnosticEvent 对象。通常,configDump 和 stateDump 将只返回一个对象。
该方法接受数组,因为 z/OS
服务器可以有多个服务方,并且服务方的输出聚集存储在该数组中。
selfDiagnostic
selfDiagnostic 方法使诊断提供程序能够通过执行预定义的某些活动来测试系统的关键功能。但是,这些测试不应在系统上具有持久效果。例如,如果测试操作是与远程主机建立 TCP/IP 连接,那么测试应在断开该连接之后才返回测试结果,以使组件的状态不会因执行测试而改变。测试返回的信息由 XML 文件的测试部分包含的属性来确定。以下内容摘录自 selfDiagnostic 方法:
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) ;
// 填充有效内容
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 ;
}
这将返回一组 DiagnosticEvent 对象。在此示例中,每个测试都创建了一个与参数正则表达式相匹配的 DiagnosticEvent。并没有要求诊断提供程序只为每个测试生成一个 DiagnosticEvent。生成有效内容与 configDump 和 stateDump 情况下相似。
对单个服务器的多个 z/OS 服务方执行聚集会将每个服务方的数组都并置在一起。
本地化
方法返回的 DiagnosticEvents 包含有效内容 HashMaps,该有效内容包含 MessageKeys 和 ResourceBundles。由于这些事件的最终使用者通常并不在服务器上,因此可能没有适当的类路径来解析此信息。为此,通过回调诊断提供程序来将变量本地化。但是,helper 方法使它成为一个要编写的简单方法,如以下示例所示:
public String [] localize(String [] aKeys, Locale aLocale) {
return DiagnosticProviderHelper.localize(dpInfo.resourceBundleName, aKeys, aLocale) ;
}
注意,需要 dpInfo (DiagnosticProviderInfo) 对象,因为此对象包含对 ResourceBundle 的引用。
有效内容
这些方法中重现的主题是能够在返回对象中包含有效内容。这是一组 name=value 对,它们包含由方法显示的信息。从 configDump、stateDump 或selfDiagnostic 测试返回的诊断事件是相对来说比较复杂的 Java 对象。返回的大多数信息包含在 DiagnosticEvent 对象的 DiagnosticData 部分。诊断提供程序返回的每个属性都存储在散列映射中的一个条目中。(如果将数据分成多个子组有意义的话)单个 DiagnosticEvent 对象中可能存在级联的散列映射。每个散列映射条目都包含对子散列映射的引用或者包含 DiagnosticTypedValue(它包含值、数据类型和 MsgKey,以进行标签或名称的本地化)。应使用下列各项来对返回的值进行过滤:
- 方法的类型(即,configDump、stateDump 或 selfDiagnostic)
- 所发送的用来对值进行过滤的 AttributeIdSpec
- 当前的“状态收集规范”(它会影响可用数据的数量)。
填充有效内容
DiagnosticProviderHelper.queryMatchingDPInfoAttributes 的 API 文档说明在检索数据之前如何执行过滤。在某些情况下,先让诊断提供程序将所有数据检索到有效内容中,然后再对散列映射进行过滤,这样做会更容易并且有利于提高性能。可以通过 DiagnosticProviderHelper.filterEventPayload 方法来完成填充后过滤。有关使用 JavaBeans 类型方法的信息,请参阅有关 AttributeBeanInfo.populateMap 方法的 API 文档。
注册 XML
注册 XML 使诊断提供程序需要的大部分信息外部化。它还可以使测试的本地化和使用通用化(这样有助于自动化)。从样本诊断提供程序中摘录的此 XML 为如下所示:
<!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>
要了解如何将此信息存储到 DiagnosticProviderInfo 对象中,请参阅 DiagnosticProviderInfo 的 API 文档。有关注册 XML 的用途的概念性信息,请参阅诊断提供程序已注册的属性和已注册的测试。