Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / January 2006

Tip: Looking for answers? Try searching our database.

Log4j - dealing with multithreaded invocations?

Thread view: 
Piper707@hotmail.com - 09 Jan 2006 06:07 GMT
Hi,

I have a class with 4 methods. I want to use Log4j to log messages for
each of these methods to a common log file.

Ideally I would like the log messages for each method to be seperated
from the others. But if multiple users were to invoke the methods at
the same time, then the messages in my log file would be jumbled up
with the others.

I can probably try making the methods synchronized so i dont get into
this sort of trouble, but logging by itself doesn't seem to be a good
enough reason to be making methods synchronized.

What approach can I use to deal with this?

Thank you,
Rohit.
hilz - 09 Jan 2006 06:45 GMT
> Hi,
>
[quoted text clipped - 14 lines]
> Thank you,
> Rohit.

How about having the username and the method name as part of the log
message, and then filter the log file by user or by method name or by
anything else... you can even write a small program that reads the log
file and filter it to your liking.

HTH
Piper707@hotmail.com - 09 Jan 2006 08:23 GMT
Hi,

I do have the username and method name as part of the log message, but
then imagine within each method call, the log looks like this:

username: john method: a()
aaaaaaaaaaaaa
aaaaaaaaaaaaa
end:a()

if someone else invokes b() it should look like this:

username: peter method: b()
bbbbbbbbbbbbbbb
bbbbbbbbbbbbbbb
end:b()

This still doesnt solve my problem, because if I'm writing to a single
file it may come out like this:

username: john method: a()
aaaaaaaaaaaaa
username: peter method: b()
bbbbbbbbbbbbbbb
aaaaaaaaaaaaa
bbbbbbbbbbbbbbb
end:b()
end:a()
Nigel Wade - 10 Jan 2006 11:45 GMT
> Hi,
>
[quoted text clipped - 24 lines]
> end:b()
> end:a()

If you insist on logging all the information to the same file this is bound to
happen; it's a fact of life. It leaves you with two alternatives. One, you
synchronize the methods, which slows everything down. Two, you include in every
log message an identifier which allows you to post-filter the log file to get
just the output you want.

As a very trivial example, if you append a string including the thread id in
every message all you need do is filter for that string to see messages from
that thread:

username: john method: a()  // thread A
aaaaaaaaaaaaa               // thread A
username: peter method: b() // thread B
bbbbbbbbbbbbbbb             // thread B
aaaaaaaaaaaaa               // thread A
bbbbbbbbbbbbbbb             // thread B
end:b()                     // thread B
end:a()                     // thread A

To see the output from thread B filter the log file to just show lines which end
in the string "// thread B".

Your log file contains a time sequence of events, which is good, but you can
alter your view of that log file to suit your requirements. In the UNIX world
you could use grep, or one of its close friends. In the Windows world I'm sure
there is some equivalent.

Signature

Nigel Wade, System Administrator, Space Plasma Physics Group,
           University of Leicester, Leicester, LE1 7RH, UK
E-mail :    nmw@ion.le.ac.uk
Phone :     +44 (0)116 2523548, Fax : +44 (0)116 2523555

Oliver Wong - 11 Jan 2006 17:32 GMT
> Hi,
>
[quoted text clipped - 24 lines]
> end:b()
> end:a()

   You need to define what the atomic logging actions are. It sounds like
you don't want the stuff between "username:" and "end:" to get interrupted,
so consider this your atomic unit of a single log entry.

   Write your own custom log handlers to receive the logging events and
buffer them. Then have the handler, upon receiving the end of an entry,
acquire a synchronization lock on the file to write to, and then empty its
buffer into the file. So the sequence of events will look like this:

yourCode.sentToHandler("john", "method: a()");
yourCode.sentToHandler("john", "aaaaaaaaaaaaa");
yourCode.sentToHandler("peter", "method: b()");
yourCode.sentToHandler("peter", "bbbbbbbbbbbbbbb");
yourCode.sentToHandler("john", "aaaaaaaaaaaaa");
yourCode.sentToHandler("peter", "bbbbbbbbbbbbbbb");
yourCode.sentToHandler("peter", "end:b()");
handler.locks(logFile);
handler.writes(logFile, "username: peter method: b()");
handler.writes(logFile, "bbbbbbbbbbbbbbb");
yourCode.sentToHandler("john", "end:a()");
handler.writes(logFile, "bbbbbbbbbbbbbbb");
handler.writes(logFile, "end:b()");
handler.releases(logFile);
handler.locks(logFile);
handler.writes(logFile, "username: john method: a()");
handler.writes(logFile, "aaaaaaaaaaaaa");
handler.writes(logFile, "aaaaaaaaaaaaa");
handler.writes(logFile, "end:a()");
handler.releases(logFile);

   - Oliver
Piper707@hotmail.com - 13 Jan 2006 03:25 GMT
Oliver,

I never thought of that approach. That sounds really good. Let me see
how i can put it together.

Thanks
Rohit.
Piper707@hotmail.com - 09 Jan 2006 08:31 GMT
Hi,

I dont think that would solve my problem. Imagine the logging within my
methods looked like this:

method: a() user: john
sometext
sometext
end: a()

if at the same time, someone else invoked a method b(), since they both
end up writing to a common log file - my log may end up looking like
this:

method: a() user: john
sometext
sometext
method: a() user: john
sometext
sometext
end: b()
end: a()

Then i wont be able to differentiate if "sometext" comes from the call
to a() or that to b()..
Piper707@hotmail.com - 09 Jan 2006 08:38 GMT
Sorry for the multiple posts. IE's giving me trouble.

----------------------------------------------------------------------------

Hi,

I dont think that would solve my problem. Imagine the logging within my
methods looked like this:

method: a() user: john
sometext
sometext
end: a()

if at the same time, someone else invoked a method b(), since they both
end up writing to a common log file - my log may end up looking like
this:

method: a() user: john
sometext
sometext
method: b() user: peter
sometext
sometext
end: b()
end: a()

Then i wont be able to differentiate if "sometext" comes from the call
to a() or that to b()..
hilz - 09 Jan 2006 15:41 GMT
> Sorry for the multiple posts. IE's giving me trouble.
>
[quoted text clipped - 25 lines]
> Then i wont be able to differentiate if "sometext" comes from the call
> to a() or that to b()..

how about doing it this way:

method: a() user: john begin
method: a() user: john sometext
method: a() user: john sometext
method: a() user: john end

this way, if the two users called the same method at the same time, you
will still be able to filter them and see what you want.
the only other option i can think of is to synchronize the methods,
which you already mentioned you wanted to avoid.
HTH
Raymond DeCampo - 10 Jan 2006 13:40 GMT
> Hi,
>
[quoted text clipped - 11 lines]
>
> What approach can I use to deal with this?

Rohit,

FYI, almost all of the suggestions I've seen in this thread (add
timestamp to log, add thread id to log, add method name to log) are
achievable via log4j configuration.  I.e., you do not need to change
your code.  For the username thing, you may want to use NDC (nested
diagnostic context), which requires minimal code changes.

If you need to know more, I suggest you contact the log4j users list.
(I think it is log4j-users@logging.apache.org and you should subscribe
first.  Check on http://logging.apache.org to be sure.)

HTH,
Ray

Signature

This signature intentionally left blank.

Piper707@hotmail.com - 11 Jan 2006 03:47 GMT
Thanks for the replies. Looks like adding some sort of an identifier to
the log might be the way to go. This will eventually run on unix, so
i'll probably have awk/grep to sort the file for me.

Ray, thanks for the tip. I'll dig in a little more into log4j to see
what it can do and check out the log4j users list too.

- Rohit.
MattC - 11 Jan 2006 13:30 GMT
Checkout

http://logging.apache.org/log4j/docs/chainsaw.html.

It's a companion program to Log4j that handles filtering and a lot
more. It's a much more flexible option than grep and the like.

- MattC


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.