The instrumentation specified in an application's
weblogic-diagnostics.xml file will not be applied unless there is a system diagnostic module with instrumentation enabled, and the system diagnostic module is targeted to the WebLogic Server instance. This is a feature; it allows you to enable or disable the instrumentation without having to alter your application, and it also allows instrumentation to be enabled on a server-by-server basis.
If you change the targeting of the system diagnostic module, or change whether instrumentation is enabled, you must fully redeploy your application for the change to take effect. Only a full redeployment will perform the AOP weaving process and change the instrumentation. Stopping and starting the application through the WebLogic console is not sufficient. Instead, do one of the following:
Whenever you change
weblogic-diagnostics.xml, you must also do a full redeployment.
You can create a system diagnostic module using the WebLogic console. This results in a file in the
config/diagnostics directory of your domain which you can compare with the following example:
<?xml version='1.0' encoding='UTF-8'?> <wldf-resource xmlns="http://www.bea.com/ns/weblogic/90/diagnostics" xmlns:sec="http://www.bea.com/ns/weblogic/90/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wls="http://www.bea.com/ns/weblogic/90/security/wls" xsi:schemaLocation="http://www.bea.com/ns/weblogic/90/diagnostics http://www.bea.com/ns/weblogic/920/diagnostics.xsd"> <name>MySystemDiagnosticModule</name> <instrumentation> <enabled>true</enabled> </instrumentation> <harvester> <enabled>true</enabled> <sample-period>10000</sample-period> <harvested-type> <name>weblogic.management.runtime.WorkManagerRuntimeMBean</name> <harvested-attribute>CompletedRequests</harvested-attribute> <harvested-attribute>PendingRequests</harvested-attribute> <harvested-attribute>StuckThreadCount</harvested-attribute> <harvested-instance>com.bea:ApplicationRuntime=WLDF,Name=default,ServerRuntime=AdminServer,Type=WorkManagerRuntime</harvested-instance> </harvested-type> <harvested-type> <name>weblogic.management.runtime.JTAStatisticsRuntimeMBean</name> <harvested-attribute>TransactionCommittedTotalCount</harvested-attribute> <harvested-attribute>TransactionRolledBackTotalCount</harvested-attribute> <harvested-instance>com.bea:Name=JTARuntime,ServerRuntime=AdminServer,Type=JTARuntime</harvested-instance> </harvested-type> </harvester> <watch-notification></watch-notification> </wldf-resource>
As well as enabling instrumentation, I've specified that various MBean attributes should be harvested. We'll play around with some of this harvested data later.
An interesting feature of WLDF not commonly found in other tools is its ability to create and propagate a diagnostic context. This diagnostic context uniquely identifies a particular request, and flows across synchronous calls to other WebLogic Server instances. The diagnostic context includes a unique ID (for example,
583c10bfdbd326ba:-43487c71:112bda0af31:-7ff4-00000000000001b7). You can use this ID to trace event flows across servers.
Related to the diagnostic context is the notion of requesting dyeing. A DyeInjectionMonitor can be used to filter the events that are recorded based on various request characteristics (user identity, protocol type, IP address, and so on). This is a powerful way of focusing what you record, but I won't be using this feature in the course of this article. For more information, please refer to the WebLogic documentation.
The diagnostic context adds a very small processing overhead: essentially, it's the cost of generating the unique ID, and passing it around with every request. I consider the overhead to be negligible. However, since the WLDF works on the principle of "Only pay for what you use," the diagnostic context is generated only if any of the following is true:
The behavior of diagnostic context generation was rationalized to follow these rules in WebLogic Server 9.2. If you are using WebLogic Server 9.0 or 9.1, you might find you have to enable the diagnostic context through the console, and that doing this overrides any inbound context, so be careful to make this change only on the servers that receive initial requests.
WebLogic stores diagnostics in a diagnostic archive local to each server.
The diagnostic archive contains event and harvested metric data in a binary format. As shown in Figure 3, the data can be exported to an XML format using the WebLogic Scripting Tool (WLST), using either the exportDiagnosticData or exportDiagnosticDataFromServer commands. For example:
exportDiagnosticData(storeDir="/work/domain/servers/server1/data/store/diagnostics", logicalName="EventsDataArchive", exportFileName="server1-events.xml")
I'll be using two types of data, event data (
logicalName="EventsDataArchive") and harvested metric data (
exportDiagnosticDataFromServer have options that allow you to filter data, by time or through a full WLDF query. You should use these filter options to limit the size of the exported XML files. This is particularly important as the Java XSLT implementation that we will use does not scale well with large input files. Here's an example of filtering by a particular diagnostic context ID:
exportDiagnosticData(storeDir="/work/domain/servers/server1/data/store/diagnostics", logicalName="EventsDataArchive", exportFileName="events.xml", query="CONTEXTID='583c10bfdbd326ba:58f87d21:1126b53f6ec:-7ff3-0000000000000c2a'")
Beware when trying to use
exportDiagnosticData multiple times from the same WLST process to access archive files from different servers. There's a minor problem with this command; the second and subsequent times it is used, it will continue to refer to the original archive file that was opened. Work around this problem by using a separate WLST process to access each archive.
If you look at the exported XML data, you'll see the XML conforms to an abstract schema that models a set of
DataRecords consisting of
ColumnData values for various columns. The XML file starts with a
DataInfo element that contains the names of the columns and their Java types. These columns are slightly different for the event and harvested data files in which we are interested.
So now we have some XML. Before we get to our first XSLT stylesheet, here's a useful Jython script you can use to process an XML document with a stylesheet:
import sys from java.io import FileReader, PrintWriter from java.lang import System from javax.xml.transform import TransformerFactory, Transformer from javax.xml.transform.stream import StreamSource, StreamResult def transform(source, stylesheet, result, parameters): transformer = TransformerFactory.newInstance().newTransformer(stylesheet) for (p, v) in parameters: transformer.setParameter(p, v) transformer.transform(source, result) if __name__ == '__main__': args = sys.argv[1:] parameters =  while args and args.startswith('-'): try: i = args.index('=') except ValueError: parameters.append((args, "")) else: parameters.append((args[1:i], args[i+1:])) args = args[1:] if len(args) == 1: source = StreamSource(System.in) elif len(args) == 2: source = StreamSource(FileReader(args)) else: raise "Usage: <jython|wlst> process.py -<parameter>=<value> <stylesheetfile> [inputfile]" stylesheet = StreamSource(FileReader(args)) result = StreamResult(PrintWriter(System.out)) transform(source, stylesheet, result, parameters) stylesheet.reader.close() source.reader and source.reader.close() result.writer.close()
You can call this directly from Jython, but as WLST comes with WebLogic Server 9, I'll show you an example of using WLST to start this script. First, set your environment (for example, source
setDomainEnv.sh). Then run
java weblogic.WLST process.py stylesheet.xsl input.xml > output.xml
The output will go to
stdout, so we use shell redirection to send it to
output.xml. Alternatively, you might use the shell pipe operator to chain multiple
process.py processes together. If you have Jython installed, you'll get a faster start-up time by using
jython in place of
Some of our stylesheets take parameters that control their behavior.
process.py lets you specify stylesheet parameters as follows:
java weblogic.WLST process.py -myparameter=value stylesheet.xsl input.xml > output.xml
If you are using a Microsoft Windows shell, you'll need to quote the parameters, for example,