Java CAPSoggingadditionaldestinations
Java CAPSoggingadditionaldestinations
3 Notes
Logging
Michael Czapski, January 2008
Introduction
By default, the Sun SeeBeyond Integration Server domain uses a single log to log all
events, whether arising out of execution of the Integration Server or arising out of
execution of Java CAPS solutions deployed to it. This log is named server.log and
is kept in the <JavaVACPInstallRoot>/logicalhost/is/domains/<domainroot>/logs directory.
This note discusses how the Integration Server can be configured to deliver all or
selected events to an additional log handler and how XML-formatted event
information can be obtained. This note also presents some ideas on multiple logging
destinations and notification.
Note
The writing of this note, and the underlying development and configuration work, were
prompted by repeated questions about logging in Java CAPS, in particular how it could be
made to behave like it used to in the non-J2EE versions of the SeeBeyond EAI products. For
these readers who are still waiting for the answer they like – there will be no such answer
coming. It is not possible to configure logging for ‘your interface’ separately from logging for
all other ‘interfaces’ since there is no notion of ‘your interface’ as a separate component in
Java CAPS. There is no way to collect logging information pertaining to a specific project or
deployment in such a way that all relevant information is collected, no information is lost and
no information on unrelated components is included.
The default runtime platform for the Integration Server is Java 5 Standard Edition, or
JDK 1.5. Java 5 Standard Edition provides logging support through the Java Logging
APIs. Typically, logging in Java 5 SE is configured through the
logging.properties configuration file in the platform’s jre/lib directory. In a
default Sun SeeBeyond Integration Server domain this configuration file is largely
ignored.
Since the Application Server 8.0 uses the Java Logging APIs for logging so too does
Java CAPS. By default, each Java CAPS domain logs to a server.log in the
<JavaVACPInstallRoot>/logicalhost/is/domains/<domainroot>/logs
directory.
Some of the resulting Integration Server logging behaviour can still be modified
through the logging.properties configuration file. This will be discussed later in
this note.
The Java Logging API allows the user to specify multiple “handlers” so that logging
records can be handled in different ways. Users can develop their own handlers that
comply with the Java Logging APIs.
Fortunately, one can specify a MemoryHandler instead of another Handler and then
configure the MemoryHandler to pass log records to that other Handler. The other
Handler can then use all configuration file properties that pertain to it. This gives a
handler indirection that overcomes the issue with inability to specify a formatter for
directly configured handler, for example.
Preliminaries
Discussion below assumes that there is a Java CAPS 5.1.3 domain created and
running. This domain will be started and stopped lots of times. It has a series of
projects deployed and ready to exercise logging, most notably, projects discussed in
the blog entry Java CAPS 5.1.3 - JCD-based Programmatic log manipulation
(http://blogs.sun.com/javacapsfieldtech/entry/java_caps_5_1_311).
Commenting the first handlers line and uncommenting the second handlers line will
add the FileHandler.
to ALL
Let’s leave the rest of the original logging.properties file as is.
Let’s re-start the domain, wait for it to go quiet and inspect the extra log file in the
“user.home” directory. In this example the file will contain a series of records that
look similar to the one shown below.
<record>
<date>2008-01-11T12:10:15</date>
<millis>1200013815828</millis>
<sequence>1978</sequence>
<logger>sun.rmi.client.ref</logger>
<level>FINE</level>
<class>sun.rmi.server.UnicastRef</class>
<method>invoke</method>
<thread>10</thread>
<message>main: free connection (reuse = true)</message>
</record>
Because we have a global logging level set to ALL and we did not restrict the
FileHandler there are a lot of logging records in the file. None of them, however, are
identifiable as relating to out Java CAPS solutions. To make sure, let’s exercise the
project ListLogCategories discussed in the blog mentioned before.
The regular Java CAPS log, the server.log, shows the following log entry (most
omitted for brevity):
[#|2008-01-
11T12:15:08.906+1100|WARNING|IS5.1.3|STC.eGate.CMap.Collabs.ListLogCategories.cmListLo
gCategories_jcdListLogCategories1.LoggingListLogCategories.jcdListLogCategories|_Threa
dID=16; ThreadName=Worker: 3;
Context=project=ListLogCategories,deployment=dpListLogCategories,collab=cmListLogCateg
ories_jcdListLogCategories1,external=cListLogCategories;|
Loggers currently registered, with configured logging levels:
=INFO
ListLogCategories.cmListLogCategories_jcdListLogCategories1.jcdListLogCategories_Runti
me_Handler=INFO
STC.JMS.com.stc.jms.client.ConnectionImpl=INFO
STC.JMS.com.stc.jms.client.ObjectFactory=INFO
STC.JMS.com.stc.jms.client.QueueObjectFactory=INFO
STC.JMS.com.stc.jms.client.STCConnection=INFO
STC.JMS.com.stc.jms.client.STCConnectionFactory=INFO
STC.JMS.com.stc.jms.client.STCDestination=INFO
The additional log shown nothing – pretty useless. The IS fails to use the handler
specified this way.
Let’s comment out the handlers property with two handlers and uncomment the
original handlers property for the next exercise. Let’s leave the global logging level at
ALL.
Let’s re-start the IS and see what the additional log file shows.
Use a differences utility to see the differences between the java<nnn>.log and the
server.log. The java<nnn>.log is a log smaller, because the FileHandler.limit property
is set at 50000 bytes, however the last 50,000 bytes of both files are identical.
Let’s exercise the ListLogCategories project. Where in the previous example none of
the Java CAPS logging records went to the additional log, in this exercise, with the
handler configured through the IS Administrator console, all records went to both
logs.
Notice that the java<nnn>.log file no longer contains XML records. The
FileHandler.formatter property in the logging.properties file, which was used to
configure the formatter in the previous example, was completely ignored.
Let’s set the file name to /temp/logging/additional<nnn>.log and re-start the IS.
Obligingly, the new log file with the name of additional0.log was created in the
specified directory, still in the same format as the server.log and still logging
exactly the same information.
We can restrict the entries that are logged to the additional log by specifying the
FileHandler.level property and setting it to the appropriate value. Let’s add the
property and set it to the WARNING Level. The expectation is that only WARNING
and more severe records will be logged to the additional log regardless of what gets
logged to the server.log.
Let’s re-start the IS. Notice that the additional0.log is empty. No information was
logged (assuming there were no warning when the IS was starting☺)
The ultimate handler is the FileHandler. We expect all log records to be pushed to the
FileHandler and be filtered by it to WARNING or more sever, as before.
Let’s re-start the IS and observe the additional0.log log file configured to receive log
records from the MemoryHandler. As in previous section, if no WARNING messages
were logged during IS startup the additional log will be empty.
Let’s exercise the ListLogCategories project. Notice that now a WARNING-level
message was logged in the additional0.log. This is because the project emits a
WARNING message. Notice, too, that the log record in the additional0.log is in XML
format. The FileHandler.formatter property setting has been recognised and used.
Discussion about development of Formatters is beyond the scope of this Note. See
Other Handlers
Using the MemoryHandler as the directly specified additional handler for the Sun
SeeBeyond Integration Server, allows one to specify a different target Handler in such
a way that all its properties are recognized and acted upon at runtime.
I have come across a couple of articles that some might find interesting.
Using a SMTPHandler
Let’s download the SMTPHandler from SourceForge
(http://sourceforge.net/projects/smtphandler/), unzip to a convenient directory and
copy the smtphandler-0.6.jar archive to the logicalhost/is/lib/endorsed
directory. We could put it elsewhere but the archive must be in the IS’s classpath.
SMTPHandler seems to require permissions to read and write system properties. Let’s
add the following stanza to the end of the server.policy file.
Let’s add SMTPHandler properties to the logging.properties configuration file and
configure as appropriate for your SMTP server. Property values below are an example
only.
If all is configured correctly, the Electronic Mail Client will receive a message similar
to the following.
All log records of severity WARNING and SEVERE will be sent, by electronic mail,
to a configured mail recipient.
Some Ideas
With the ability to replicate logging information to an alternative destination all
manner of possibilities open up to a Java programmers who don’t mind getting their
hands a bit dirty.
With a suitable handler one could send replicas of messages to multiple destinations.
Modifying the MemoryHandler that comes with the java.util.logging could lead to a
new MultiDestinationMemoryHandler that sends messages to multiple other handlers
and implements independent configuration properties for each of the configured
handlers.
Whereas filtering log records by specifying a logging level for a handler is useful but
very coarse-grained, java.util.logging and the Sun SeeBeyond Integration Server
support specification of a Filter class that determines which log records to pass on log.
This may or may not become a subject of a separate note ☺
Other References
JavaTM Logging Overview -
http://java.sun.com/j2se/1.4.2/docs/guide/util/logging/overview.html