Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

One AL logging to different files

122 views
Skip to first unread message

Deepak Gowda

unread,
Sep 23, 2011, 11:40:43 AM9/23/11
to
I havea situation where I will be using one instance of RMI running
which will be handling multiple instances of the same adapter. Like a
generic adapter, which will have different services but same AL. I
need to log to different files based on the service name. Any thoughts
on how this is best done?

Thanks in advance.

Eddie Hartman

unread,
Sep 24, 2011, 11:13:43 AM9/24/11
to
Unfortunately, since logging is set up early in the Initialization
phase of your AL, you can't use substitution (TDI Expressions) to set
the log file name. So you'll have to script a little.

The simplest approach would be something along the lines of this:

AL Prolog Hook (e.g. Before Initialize)
---
logfile = system.openFileForOutput("logs/"
+ work.serviceName + "_"
+ system.formatDate(new java.util.Date(),"YYYY-MM-DD hh:mm"))
---
Assuming there is an Attribute in work called 'serviceName'. Then when
you want to log something, instead of task.logmsg() you do:
---
logfile.write("some message")
logfile.newLine() // adds newline char(s), depending on platform
---
You could even wrap this in your own scripted function, and then write
messages out to the console so that when the solution is deployed, the
admin will see log messages:
---
function log(msg) {
// using 'lazy init' here: create logfile if it doesn't exist, e.g.
first call to log()
if (typeof(logfile) == "undefined") {
logfile = system.openFileForOutput("logs/"
+ work.serviceName + "_"
+ system.formatDate(new java.util.Date(),"YYYY-MM-DD
hh:mm"))
}
logfile.write(msg)
logfile.newLine()
java.lang.System.out.println(msg)
}
---
With the 'lazy init' approach above, you don't need the Prolog script
at the top of this post. Instead, this last snippet could either be in
a Prolog Hook, or in a Resources library script that you include as a
'Global Prolog' for the AL.

Hope this helps!
-Eddie

Eddie Hartman

unread,
Sep 26, 2011, 4:15:43 AM9/26/11
to
Or not. It turns out that I was wrong: you can absolutely use substitution and/or javascript for setting logAppender parameters. However, since logging is set up very early, not everything works.

Note that logging is initialized before the ALs Script Engine, so some otherwise valid javascript will NOT work, for example:

return "logs/" + task.getShortName() + ".log"

Our intrepid code-meister, Jens, has shown me that there is a workaround:

return "logs/" + params.get("task").getShortName() + ".log"

In this way you can ensure that an AL's log file carries its name. I would assume there is some way to use data passed into your adapter AL from ITIM to specify the logfile name. I'll keep bugging smart people around me and will let you know what else I learn.

-Eddie

Eddie Hartman

unread,
Sep 26, 2011, 4:38:06 AM9/26/11
to
Hi again, Deepak. I have just learned that the Work Entry is not yet available for scripting or substitution. However, there may be a work around. Try something like this to get at the data:

initWork = params.get("task").getWork()

or maybe this

initWork = params.get("task").getTCB()

and let me know if (and how) you are able to solve your challenge.

Thanks!
-Eddie

Deepak Gowda

unread,
Sep 26, 2011, 11:12:15 AM9/26/11
to
Thanks for the suggestions Eddie. The problem with first suggestion is
that it further complicates the problem, by each AL instance logging
into 2 different files. I'll try the third suggestion and reply when I
have something worth sharing.

Deepak Gowda

unread,
Sep 26, 2011, 11:21:14 AM9/26/11
to

Using your third suggestion, I am able to get the log, but still
unable to set it. I am contemplating another AL that will first set
the logfile (by adding the service name as passed by TIM) and then
call the actual adapter assembly line. Might look ugly, but guess it
works.

Eddie Hartman

unread,
Sep 26, 2011, 3:59:07 PM9/26/11
to
Can you start/call other ALs in a TIM adapter? I thought their
'dispatcher' prevented launching new threads...?

-Eddie

Jon Embrey

unread,
Nov 11, 2011, 8:51:53 AM11/11/11
to
// Adding this to the AL "Prolog - Before Initialization" script
allows a new log file to be added. The example here adds an error
level log named dynamic.log

var level = "ERROR";
var enabled = "true";
var file = "dynamic.log";

// Setup the specifics of the log4j logger/appender - change these as
you see fit
var append = "true";
var datePattern = "'.'yyyy-MM-dd";
var conversionPattern = "%d{ISO8601} %-5p [%c] - %m%n";
var appender = "DailyRollingFile";
var layout = "Pattern";

var configItem = com.ibm.di.config.base.LogConfigItemImpl();
configItem.setStringParameter("DailyRollingFile.Append", append);
configItem.setStringParameter("DailyRollingFile.DatePattern",
datePattern);
configItem.setStringParameter("Pattern.ConversionPattern",
conversionPattern);
configItem.setStringParameter("com.ibm.di.log.appender", appender);
configItem.setStringParameter("com.ibm.di.log.layout", layout);
configItem.setStringParameter("com.ibm.di.log.level", level);
configItem.setStringParameter("enabled", enabled);
configItem.setStringParameter("DailyRollingFile.File", file);

var config = com.ibm.di.config.base.LogConfigImpl(); // Variable to
hold all of the logging configuration details
config.addItem(configItem);

var type = "adapter"; // Can be any string - depends how you want the
log entries to be written
var name = "name"; // Can be any string - depends how you want the log
entries to be written
var log = task.getLog();
var configInstance = task.getParent();
com.ibm.di.log.LogUtils.addLoggers(type, name, log, config,
configInstance); // The new log file is created at this point and can
be used

task.logmsg("ERROR", "Test log entry")
0 new messages