Hi,
I want to know the best way to log the messages in the application.
Is it a good idea to use log.debug provided by webMethods or create some flow services which use log4j to do the stuff and call the custom log4j flow services to log the messages.
I’m sure you will start a firestorm of discussion on this one.
I think it will depend ultimately on your needs. For quick and dirty, I like to use the pub.flow:debugLog. This is handy because you can set it to adhere to a log level. So, if you run prod in 0 or 1, and you set the call to pub.flow:debugLog to 4, then it will only log if you raise the over all server logging level to 4.
In other cases, I had a need to track transactions (for those customer who did not have/or did not want to use monitor) in and out of adapters. For this, I wrote to a custom log file and/or db table.
This is the route that I normally take, that is, to write to a custom storage mechanism. I have some base code that I always use. The base code allows for reading and writing to a flat file (pipe delimited), to an XML file, and to a database table. I have a extended setting in the server.cnf file that I use to define the storage type.
Then, I use a couple of DSP files to invoke and display results.
They are crude, but very effective in times of dire need (i.e., system down, people breathing down your neck.)
The fact that the logging exists is transparent to most of my customers.
One improvement I made in the logging was to publish a document containing the logging information.
I don’t have the benchmark answer for you. Mark Carlson is the “Resident” log4j expert. He can tell you specifics on it as he implemented log4j in his code prior to webMethods actually using it in earlier versions. Also, if you perform a search here on wmusers for log4j, you should find some comments.
In fact, Mark was so gracious as to upload a package for all of us here:
Maybe a bit off topic now but probably of important once you have decided what to use for logging, you might want to use this piece of code to do some additional magic with the error stack:
ByteArrayOutputStream bout = new ByteArrayOutputStream();
PrintStream pout = new PrintStream(bout);
e.printStackTrace(pout);
pout.close();
result = bout.toString();
You need to implement this service for each package you want to use the stack printing in.
Create a new Java service. Input is an object named “exception”. Output is a string named “stack”.
Imports:
java.io.*
The code:
IDataCursor pc = pipeline.getCursor();
Exception e = (Exception)IDataUtil.get(pc, "exception");
IDataUtil.put(pc, "stack", getStackJ(e));
pc.destroy();
The shared code:
public static String getStackJ(Exception e) {
String result = "No stack";
if (e != null) {
try {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
PrintStream pout = new PrintStream(bout);
e.printStackTrace(pout);
pout.close();
catch (Exception e) {}
result = bout.toString();
}
return result;
}}
I typed the code by hand so if it doesn’t compile, I prob made a type and will correct that when mentioned…
As the core of the function is in the Shared part, you can call this services from a services but also from any other Java service in the same package without doInvoke(). Using namespace.namespace.getStackJ(Exception) you can shortcut to this functionality.
Hi Chris,
I tried your code. I need some more clarifications.
I am calling the method in the Catch block and passing the lastError as input. In java service, I am getting it as null.
I am not sure, if I am missing anything. Can you please clarify.