Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Looking for a Multi-Layer "Architecture" pattern for Log4J

Reply
Thread Tools

Looking for a Multi-Layer "Architecture" pattern for Log4J

 
 
etienno@gmail.com
Guest
Posts: n/a
 
      07-11-2006
Hi,

I have a issu to solve regarding Log4J (or any other logger). This
problem is probably quite common in a multi-layer architecture. I have
a multilayer software, running on the same JVM (not really multilayer
here thaugh, anyway).

Lets say my layers are : View (HttpRequest), Business, Delegates, web
service...

The problem is that the logger from the View knows well the "UserId"
using the system, but from the Business to the Web Service Layers it
lost the "UserId" data because it doesn't need it for its process. But
I would like the logger at the Web Service Layer to log a debug trace
with the "UserId"! A need that because my system admin need a nice log
to do his job efficiently.

View (HttpRequest), [doJob(UserId);]
Business, [doJob()]
Delegates, [doJob()]
web service... [doJob()] -->logger.debug("My userId is..." + "doing web
service job");

I have checked many possibility, I want to know what would be the best
pattern for this issu:

1- Pass the UserId in the parameter: This is obviouly bad.
--- theses next solutions has not be thinked a lot...
2- Put the a kind of ThreadId as a key in a static Map and store
UserData...: I dont like that at first glance.
3- Use some listener and Event handling to get the logs events from the
lower layer and log it from the upper layer. Use ThreadId as a key of
some sort. I prefer that...

It must be a very common problem. There is not common library for this
issue?
I will check at TheServerSide.com...

Thanks for answering

Etienne
Paris

 
Reply With Quote
 
 
 
 
pranshu
Guest
Posts: n/a
 
      07-11-2006
Ho Etienne,

The least you have to do is to change the method signatures to pass a
GUID or some other unique key down from the web layer to subsequent
layers.
This way, you can associate different log outputs for the same request
- by logging and searching for the unique key.
Of course you will still need to do a lot of work while analysing the
logs as the lines will be spread across different log files in
different machines ( if you chose to distribute it) and you will need
to do a find/grep across files to create a complete flow.

I would love to see a good implementation for the same - If anyone
finds one.

Pranshu

 
Reply With Quote
 
 
 
 
etienno@gmail.com
Guest
Posts: n/a
 
      07-11-2006
Thanks Pranshu,

I agree with you, this would be the logical way to do it. But I tend to
say that the logging requirement is the not a real business
requirement, it should not affect the signature of all methods. In a
AOP way of looking at it, it is a transversal requirement that do not
affect the "base" application behavior. So I think it would be an
anti-pattern to pass the UID in all method signature in a _logical_
multi-layer environement.

I agree also that in a (physical) distributed environment this solution
(pass the GUID) could be the only way to do resolve the problem.

Etienne.

wrote:
> Ho Etienne,
>
> The least you have to do is to change the method signatures to pass a
> GUID or some other unique key down from the web layer to subsequent
> layers.
> This way, you can associate different log outputs for the same request
> - by logging and searching for the unique key.
> Of course you will still need to do a lot of work while analysing the
> logs as the lines will be spread across different log files in
> different machines ( if you chose to distribute it) and you will need
> to do a find/grep across files to create a complete flow.
>
> I would love to see a good implementation for the same - If anyone
> finds one.
>
> Pranshu


 
Reply With Quote
 
etienno@gmail.com
Guest
Posts: n/a
 
      07-11-2006
I have ask and rephrase a bit this question at The Server Side:

http://www.theserverside.com/discuss...hread_id=41277

 
Reply With Quote
 
Chris Uppal
Guest
Posts: n/a
 
      07-11-2006
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:

> The problem is that the logger from the View knows well the "UserId"
> using the system, but from the Business to the Web Service Layers it
> lost the "UserId" data because it doesn't need it for its process. But
> I would like the logger at the Web Service Layer to log a debug trace
> with the "UserId"! A need that because my system admin need a nice log
> to do his job efficiently.
>
> View (HttpRequest), [doJob(UserId);]
> Business, [doJob()]
> Delegates, [doJob()]
> web service... [doJob()] -->logger.debug("My userId is..." + "doing web
> service job");


If you pass some sort of object from the top of the stack to the bottom, then
each layer can use only the data from that object which it needs, and will be
unaware of (and thus decoupled from) the other data which it doesn't need.

Such an object might contain a complete description of the job -- thus
replacing all other parameters to the invocation methods at each layer. Or it
might only contain some sort of description of the job intended primarily for
logging purposes.

BTW, it's a mistake, IMO, to think of logging as "not a real business
requirement". Try removing the logging and see what happens to the business


-- chris


 
Reply With Quote
 
etienno@gmail.com
Guest
Posts: n/a
 
      07-11-2006
Thanks Chris,

here I must also disagree, I think that if we remove the logging, the
application (might) still run. The transaction are not affected, the
security, the business or persistence functional requirement neither.

So, I still do not think we must design an application and the method
signature according to the logging functionality (non-functional
requirement). This is one reason it is a good practice not to pass the
Log4J logger in the method fields. Classically, the logger instance is
a (static) local field of the class using it.

Also, in a IOC or AOP way of saying it (i.e. Spring Framework), we
would inject a logger (interface) inside the class, or even do the
logging outside the methods using Aspects. This is why in my sens the
logging is not part of the business requirements.

Regards,

Etienne

Chris Uppal wrote:
> (E-Mail Removed) wrote:
>
> > The problem is that the logger from the View knows well the "UserId"
> > using the system, but from the Business to the Web Service Layers it
> > lost the "UserId" data because it doesn't need it for its process. But
> > I would like the logger at the Web Service Layer to log a debug trace
> > with the "UserId"! A need that because my system admin need a nice log
> > to do his job efficiently.
> >
> > View (HttpRequest), [doJob(UserId);]
> > Business, [doJob()]
> > Delegates, [doJob()]
> > web service... [doJob()] -->logger.debug("My userId is..." + "doing web
> > service job");

>
> If you pass some sort of object from the top of the stack to the bottom, then
> each layer can use only the data from that object which it needs, and will be
> unaware of (and thus decoupled from) the other data which it doesn't need.
>
> Such an object might contain a complete description of the job -- thus
> replacing all other parameters to the invocation methods at each layer. Or it
> might only contain some sort of description of the job intended primarily for
> logging purposes.
>
> BTW, it's a mistake, IMO, to think of logging as "not a real business
> requirement". Try removing the logging and see what happens to the business
>
>
> -- chris


 
Reply With Quote
 
Chris Uppal
Guest
Posts: n/a
 
      07-11-2006
(E-Mail Removed) wrote:

> here I must also disagree, I think that if we remove the logging, the
> application (might) still run. The transaction are not affected, the
> security, the business or persistence functional requirement neither.


Well, if logging's not a business requirement, why the Hell are you wasting
time implementing it ?



But, OK yes, I have some sympathy with the idea that it's not a /domain/
requirement.

Anyway, my real point is that you can pass a /job/ or /job description/ from
top to bottom of the stack without messing up your domain code. That object
can contain logging-specific information, just as it can (and would) contain
other information -- it's up to each layer what information it adds to the
object and what information it takes out.

-- chris


 
Reply With Quote
 
etienno@gmail.com
Guest
Posts: n/a
 
      07-11-2006
So, we agree a bit. Logging is not part of the "domain requirement" (or
domain model). I think that I could build a "logging" API that would be
able to use peripherical way (outside the domain model) to do
thisfeature. This logging API (implementing Logger, or the Log4J
logger) would be transparent to the system.

I am looking to use ThreadLocal to store the UserData (one per thread),
the UserData would be available by the loggers at the lower levels. If
I do not use a Web Application, I just hope the thread die at the end
of the process (the chain of command).

Regards,

Etienne

Chris Uppal wrote:
> (E-Mail Removed) wrote:
>
> > here I must also disagree, I think that if we remove the logging, the
> > application (might) still run. The transaction are not affected, the
> > security, the business or persistence functional requirement neither.

>
> Well, if logging's not a business requirement, why the Hell are you wasting
> time implementing it ?
>
>
>
> But, OK yes, I have some sympathy with the idea that it's not a /domain/
> requirement.
>
> Anyway, my real point is that you can pass a /job/ or /job description/ from
> top to bottom of the stack without messing up your domain code. That object
> can contain logging-specific information, just as it can (and would) contain
> other information -- it's up to each layer what information it adds to the
> object and what information it takes out.
>
> -- chris


 
Reply With Quote
 
pranshu
Guest
Posts: n/a
 
      07-11-2006
Hello Etienne

I have looked at logging variants and even custom code available, and
none of them seem to solve the problem of relating messages from
different threads or different machines - leaving it the responsibility
of the application to provide the "association".

Some of the variant implementations - have solved it for the same JVM
- by registering event listeners and invoking events. However the
application has been essentially designed that way, and I think passing
a GUID is easier and will work across JVMs.

Are you using a particular AOP implementaiton?

This was the first article on googling for AspectJ + Log4J
http://www.developer.com/java/other/...0936_3109831_1

- I must put a disclaimer that I dont understand it fully before
commenting further -

It looks like even with aspects if you are crossing multiple levels,
the least you need to change in your code is to introduce new instance
variables across all objects to store the Association ID. The aspects
might just be able to copy it over from caller to calee object. The
reason I say might is because, I dont know if it will work and its
definitely not going to work when you call static methods.

I would definitely love to see this thread reach a conclusion.

Pranshu

 
Reply With Quote
 
pranshu
Guest
Posts: n/a
 
      07-11-2006
Looking at the options you have proposed:

Using Threadid to sort: It may not work if you have more than 1 log
levels. Lets say you log the UserID as a "INFO" or "DEBUG" level in the
web layer. And you have the log level set to "ERROR" for a production
deployment. Now, in this case, if there is an error in an inner layer,
and you get an ERROR log, you will never be able to associate it with a
User ID as the useid is never logged (being INFO) and the association
/ thread id is not going to help.

Among other implementations that you have mentioned
- using a Static map - will take a lot of work to make it work across
JVMs.
- Use some sort of listener and Event handling - will be very difficult
to work across JVMs.

Looks like there is no viable solution at all apart from the "bad"
option 1- to Pass the UserId/user object in the parameter!!

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Does "additivity" flag in log4j.properties work only with log4j or with Apache Commons Logging as well? Gianni Galore Java 0 09-08-2010 09:26 AM
Log4j configuration: how to suppress internal logs from Log4j? joes Java 1 08-06-2005 04:31 PM
Using log4j with Tomcat 4.1.30 problems with log4j.properties Rodolfo Java 0 07-12-2004 08:56 AM
log4j: locating log4j.proprties in same folder as jar Alex Hunsley Java 2 05-28-2004 09:57 PM
eclipse, junit, log4j, & finding log4j.xml Alexandra Stehman Java 0 01-19-2004 03:25 PM



Advertisments