In this recipe, we will define a custom logger for a BPEL process. We will define a custom logger as an addition to the already existing loggers available for BPEL processes. The custom loggers are used in a scenario where there is a special requirement that ODL cannot fulfill, for example, if some logging information needs to be sent over the TCP socket, or if we want to provide special formatting types for logging.
Before we start with the recipe, we need to deploy a BPEL process. We will use the BPEL process from the Calling web services in sequence recipe defined in Chapter 2, Calling Services from BPEL. We defined two web services. The first one gives us the list of available hotels in the predefined date range. With a call to the next web service, we receive the price for the room in the hotel. Finally, we check for the car reservation.
In the following steps, we define the actions that need to be performed in order to define a custom logger in a BPEL process:
JUL
. We name the class LogTheBpel
and put it into the org.packt.log
package. We retrieve the logger by using name criteria:private static final Logger logger = Logger.getLogger("oracle.soa.Logger");
oracle.soa.Logger
is a standard Oracle logger where we can log the messages and then inspect them among other messages. Loggers are organized in hierarchies, which provide higher flexibility for filtering that we can set in order to reduce or increase the verbosity of loggers. The loggers are organized in a parent-child relationship. The parent of the logger oracle.soa.Logger
we use in our example is oracle.soa
. However, our logger might also have its child logger with the name oracle.soa.Logger.Process
.
public static final void log(String message) { logger.log(Level.WARNING, message); }
The log method can be defined in different ways. We define one method with two parameters; that is, log_level
and message
. Then, we call the method using log(Level.INFO, "TEST")
. Another approach is to prepare a set of methods for each log level and with only one message parameter. In this case, the call might be like logInfo("TEST")
or logWarning("TEST")
. We also need to configure the formatter by issuing the static statement:
static { LogFormatter.configFormatter(logger); }
@Test public void testLog() { LogTheBpel.log("Test message"); }
If we run the test case, we see that the run is successful.
<import location="java.util.logging.Logger" importType="http://schemas.oracle.com/bpel/extension/java"/> <import location="java.util.logging.Level" importType="http://schemas.oracle.com/bpel/extension/java"/> <import location="oracle.fabric.logging.LogFormatter" importType="http://schemas.oracle.com/bpel/extension/java"/>
With this preceding code, we import the classes that need to be loaded that we can use in our custom logger.
<extensionActivity> <bpelx:exec name="Java_Embedding1" language="java"> <![CDATA[org.packt.log.LogTheBpel.log("Hello from process with id: " + getInstanceId());]]> </bpelx:exec> </extensionActivity>
In this recipe, we utilize the JUL functionality. We use the logger that is standard to the Oracle SOA Suite. Therefore, when we run the BPEL process, we see that our message appears among other log messages.
Note that the recipe is targeted at BPEL 2.0 processes. If we want to use logging in BPEL 1.1 processes, we must follow the following guidelines:
<import>
tag in the BPEL definition file, we use the <bpelx:exec>
tag. This is shown in the following code:<bpelx:exec import="java.util.logging.Logger" /> <bpelx:exec import="java.util.logging.Level" /> <bpelx:exec import="oracle.fabric.logging.LogFormatter" />
<bpelx:exec name="Java_Embedding1" language="java" version="1.5"> <![CDATA[org.packt.log.LogTheBpel.log("Hello from process with id: " + getInstanceId());]]> </bpelx:exec>
In this recipe, we reused the logger from the Oracle SOA Suite. Sometimes, especially in a hurry, such a log presents us with too much information to diagnose. Consequently, we might find ourselves having a trouble identifying the root cause of the problem. To define our own named logger, we first need to change the source of the LogForBpel
class file as shown in the following steps:
private static final Logger logger = Logger.getLogger("org.packt.log.Logger");
<domain_home>configfmwconfigserversAdminServerlogging.xml
file and register our logger:<logger name="org.packt.log" level="WARNING:1"> <handler name="odl-handler" /> </logger>
Also, if we want, there is a possibility to filter the messages coming only from our logger, which can be done by a defining proper filter in the Oracle Enterprise Manager Console.
One of the logging methods that the Oracle SOA Suite provides is adding information to the audit trail of the BPEL process. The command is basically a one-liner and is added into the Java Embedding activity:
addAuditTrailEntry
command as shown in the following code:<extensionActivity> <bpelx:exec name="Java_Log_JUL" language="java"> <![CDATA[ org.packt.log.LogDynamic.log("Hello from Log4J process with id: " + getInstanceId()); addAuditTrailEntry("Info from Java activity. " + getInstanceId());]]> </bpelx:exec> </extensionActivity>