IBM BPM, V8.0.1, All platforms > Authoring services in Integration Designer > Services and service-related functions > Access external services with adapters > Configure and using adapters > IBM WebSphere Adapters > Adapter Toolkit > Implementing code from the IBM WebSphere Adapter Toolkit > Problem determination > Monitoring and measuring performance
First failure data capture (FFDC)
First failure data capture (FFDC) provides the instrumentation for exception handlers (catch blocks) to record exceptions that are thrown by a component.
To provide FFDC for your component, exception handlers can be instrumented by defining an aspect, which determines the packages, classes, methods, and exceptions types that will be supported by FFDC.
Users extend the abstract FFDCSupport aspect that captures the required context, such as method name and exception object, automatically. No additional configuration is required because the data provided by the aspect is the same data that would be provided from a hand-coded invocation.
FFDC processing overview
Instead of explicitly instrumenting catch blocks by calling FFDC directly, either manually or by using a tool, you can write a simple aspect using the AspectJ language, which encapsulates the FFDC policy for your code.
The FFDCSupport aspect is abstract. Like an abstract class, FFDCSupport cannot be instantiated and defers some of its implementation to a sub-aspect. It follows the standard library aspect pattern of declaring an abstract pointcut for which you must declare a concrete implementation. This concrete implementation of the pointcut can use the simple AspectJ scoping pointcut designators (PCD) such as within() and withincode() to determine the packages, classes, and methods to be included in the FFDC policy.
FFDC programming examples
The following examples assume a certain familiarity with the AspectJ language (see http://eclipse.org/aspectj/). In most cases a user of the FFDCSupport aspect will require knowledge of only a small subset of the AspectJ syntax. In particular they should know how to define a concrete aspect by extending an abstract one and how to declare a concrete pointcut typically using simple scoping primitive pointcuts.
Figure 1. Add FFDC to the sample package
import com.ibm.websphere.ffdc.FFDCSupport; public aspect Example_1 extends FFDCSupport { protected pointcut ffdcScope () : within(com.<AdapterPrefixName>.*); }Figure 1 illustrates the simple aspect Example_1 that adds FFDC to all classes in the com.<AdapterPrefixName> package. The example illustrates the following processing:
- On line 1, the FFDCSupport aspect is imported
- On line 3, the FFDCSupport aspect is extended and made concrete in a similar way to a Java™ class.
- On line 5, the inherited abstract pointcut ffdcScope()\ is made concrete.
This is done using the within() pointcut designator (PCD) and “*” wildcard that results in FFDC for all classes in the com.<AdapterPrefixName> package.
For example, com.<AdapterPrefixName>.Bar.
Figure 2. Add FFDC to com.<AdapterPrefixName> package and all sub-packages
import com.ibm.websphere.ffdc.FFDCSupport; public aspect Example_2 extends FFDCSupport { protected pointcut ffdcScope () : within(com.<AdapterPrefixName>..*); }Figure 2 illustrates aspect Example_2, which differs from Example_1 . Notice line 13, where the wildcard includes "double dots" (..) in the within() PCD, which means the includes all classes in the com.<AdapterPrefixName> package and sub-packages.
For example, com.<AdapterPrefixName>.impl.Bar.
Figure 3. Add FFDC to all classes in the com.<AdapterPrefixName> package excluding com.<AdapterPrefixName>.
import com.ibm.websphere.ffdc.FFDCSupport; public aspect Example_3 extends FFDCSupport { protected pointcut ffdcScope () : within(com.<AdapterPrefixName>.*) && !within(com.<AdapterPrefixName>);}In Figure 3 aspect Example_3 has the same effect as Example_1 except it excludes FFDC for class com.<AdapterPrefixName> by using the && and ! operators to form a pointcut expression.
Figure 4. Add FFDC to the com.<AdapterPrefixName> package but exclude aMethod
import com.ibm.websphere.ffdc.FFDCSupport; public aspect Example_3 extends FFDCSupport { protected pointcut ffdcScope () : within(com.<AdapterPrefixName>.*) && !withincode(* com.<AdapterPrefixName>.aMethod(..));}In Figure 4, aspect Example_4 is also similar to Example_1, however FFDC is excluded from a particular method on line 30 using the withincode() PCD.
Figure 5. Add FFDC to the com.<AdapterPrefixName> package but exclude catch blocks for ClassNotFoundException handling
import com.ibm.websphere.ffdc.FFDCSupport; public aspect Example_4 extends FFDCSupport { protected pointcut ffdcScope () : within(com.<AdapterPrefixName>.*) && !args(ClassNotFoundException);}In Figure 5 aspect Example_5 illustrates how to account for a programming by exception, where certain exceptions are not considered to be a failure and should not be reported. In the example, the handling of ClassNotFoundException will not be reported to FFDC. The args() PCD on line 39 selects a join points based on contextual information in this case the exception passed to the handler join point.
If you use the FFDCSupport aspect, you can ensure a consistent FFDC policy for your application by adding declare warning or error advice to your aspects While this capability is not explicitly provided by the FFDCSupport aspect, you can leverage the use of AspectJ and follow a standard pattern of enforcing a policy implemented using an aspect with compiler warnings or errors.
In Figure 6, aspect Example_6 illustrates how to prevent direct use of the FFDC API or undesired dumping of exception messages and stack traces to the console. The declare warning statements on lines 51 and 57 instruct the AspectJ compiler to issue warnings during weaving if join points are matched by the accompanying pointcuts on lines 48 and 54.
The statements are only evaluated during compilation and have no impact on the runtime.
Figure 6. Warn user about calling FFDC directly or dumping stack traces
import com.ibm.websphere.ffdc.FFDCSupport; public aspect Example_6 extends FFDCSupport { protected pointcut ffdcScope () : within(com.<AdapterPrefixName>.*); public pointcut ffdcCall () : call(* com.ibm.websphere.ffdc..*(..)); declare warning : ffdcCall() && ffdcScope() : "Don't call FFDC directly. Use FFDCSupport aspect."; public pointcut dumpException () : call(void Throwable.printStackTrace(..)); declare warning : dumpException() && ffdcScope() : "Don't dump exceptions to console. Use FFDCSupport aspect.";}When using FFDCSupport aspect you can control the data gathered. Two template methods getSourceId and getProbeId are provided to you for this purpose.
For example, you may want to limit the length of the source ID strings. In Figure 7, aspect Example_7 illustrates how to override the getSourceId method and return a short name.
Figure 7. Override default source ID generation to create short name
import com.ibm.websphere.ffdc.FFDCSupport; import org.aspectj.lang.JoinPoint; public aspect Example_7 extends FFDCSupport { protected pointcut ffdcScope () : within(com.<AdapterPrefixName>.*); protected String getSourceId (JoinPoint.StaticPart ejp) { String name = ejp.getSignature().getName(); return name; } }You can use FFDC to control how your classes are introspected by implementing the introspectSelf method. Class Person in Figure 8 illustrates how you can hide a sensitive field (in this example a password is hidden).
Figure 8. How to hide a sensitive field in this case a password
private class Person { private String userid = "USER"; private String password = "PASSW0RD"; public String[] introspectSelf () { String[] self = { "userid=" + userid, "password=XXXXXXXX" }; return self; } } Hide password field of Person class from introspection.
- First failure data capture (FFDC) support
The adapter supports first failure data capture (FFDC), which provides persistent records of failures and significant software incidents that occur during run time in IBM BPM or WebSphere Enterprise Service Bus.