Customizing jPOS event logs
/by apr/
The first few things that new jPOS users want to do within the first five minutes after downloading jPOS are:
- Build it in Eclipse/Netbeans/IDEA/your-favorite-IDE-here.
- Run it from a fifth-grade Java program with a lovely 10-page long main program where all components get initialized with hardcoded values for IPs and ports instead of using Q2
- Get rid of our event log subsystem and use commons logging or log4j
If you don´t recognize yourself in the previous list, then you might be interested to know that we have a nice new optional module in jPOS-EE called stloglistener. I came across StringTemplate just a few days ago after reading Florin´s blog and decided to give it a spin. StringTemplate is just great and learning it is addictive. Besides my plans to use it in our JPublish applications (we are currently using Velocity) and some of our mail-sending stuff I decided to give it a quick run, and it came out to be a very nice addition to jPOS. Now you can fully customize jPOS logs using the new org.jpos.util.STLogListener. In order to use it, you need to install the stloglistener module (available in the opt directory of the jposee subversion repository) and add it to your logger configuration:
<log-listener class="org.jpos.util.STLogListener">
<property name="path" value="cfg" />
<property name="skin" value="jpos.stg" />
</log-listener>
path is just the path to your template´s root directory (defaults to the cfg directory). skin can be either an ST group (*.stg
) or the base path where you place individual *.stg
files (i.e cfg/myskin/org/jpos/iso/ISOMsg.st) Here is an example of the configuration of a LogEvent:
org\_jpos\_util_LogEvent(realm,date,tag,evt) ::= <<
\### $date;format="dd/MM/yyyy hh:mm:ss.SSS"$ #############################
\# $realm$/$tag$
#
$evt:{ $it$$\\n$}$
This creates less XML-ish logs with a line of hashes separating each log event:
### 25/08/2007 07:22:42.664 #############################
# org.jpos.simulator.TestRunner/results
#
Echo Test [OK] 47ms.
Card not found [OK] 21961ms.
Invalid processing code [OK] 68ms.
Card ok - expiration mismatch [OK] 218ms.
Card ok - invalid account [OK] 460ms.
You can override how to render any component, just by adding a template for it. I tried a simple template for ISOMsg that would print the description of every field. Also tried a nice rfc822-like (mbox format) template that can be read by a mailer (nice to search, sort, etc.). You can easily create ANSI-coloured output, html output, protect some fields, whatever. ST works nice with Maps and Beans so we may have to add some getters to some of our classes in order to be able to customize them more easily. For example, I made org.jpos.transaction.Context.getMap() public so we could customize the output of the TransactionManager´s Context like this:
org\_jpos\_transaction_Context(o) ::= >>
$o.map.keys:{
k| $k$:$o.map.(k)$$\\n$}
$>>
Just for fun, I made a VMS skin (told you this is addictive) up to the point that I´m consider turning on our old MicroVAX just to see if I remember my SYSTEM password (not planning on reloading VMS off 20 TK50 tapes... :) I invite you to play with it and contribute some skins. For those of you not familiar with the jPOS logger subsystem, the main difference with other loggers is that we give the log listeners a reference to the live object, which usually contains multiple log entries associated with a given transaction. The listeners can act as filters by returning a new or modified log event (and that´s how we can tweak the content to make it for example PCI compliant). I have some ideas for new uses for our new friend. I think we could serialize ISOMsgs in IMF format (you have an IMF, right?) using for example YAML, apply ST templates based on the destination endpoint and re-load them off YAML (all the operation can be wrapped in an ISOFilter which could be less dangerous to customize by an end user than for example our BSHFilter).