Forums Register Login

Naming logger instances

+Pie Number of slices to send: Send
I would like to create individual logger instances for each of my subclasses, so I can turn logging on/off class-by-class. I could do it like this:

However, after someone does some cut-and-paste, it'll wind up looking like this:

(note how Child2 accidently uses Child1's logger).
To protect against this, I would like the "boilerplate" needed to be as small as possible, and as static as possible. My ideal scenario would be to have code in Parent which ensured that all Child classes would have a logger based on their class name... with NO code required in the child class. I can come CLOSE with this design:

Using that design, no boilerplate is needed in the Child classes. Unfortunately, now "log" is an instance variable instead of a static variable, and can't be used within static functions. That's unacceptable, so I conclude that I'm forced to have at least a declaration in the child class. So I'm hoping for something like this:

...except that I'm not sure how to write setUpLogger(). Is there any (portable) way to find out what my parent class is? I was thinking of some trick with throwing an exception and examining it's stack trace, but it seems like there must be a better way.
Any suggestions?
-- Michael Chermside
+Pie Number of slices to send: Send
Not really answering your question, but I've often set up loggers with a conditional switch.

The logger checks a static (choke, global) set of switches to see if the switch is set. If not, no logging.
Risk: If it is expensive to build the message, we have to build it before deciding not to log. I heard of a system that was using 90% CPU formatting dates for messages that were never written. Bad. Forces developer to sometimes write

Feature: All classes write to same logger, logfile. Is this good or bad for you?
Donno if that helped ...
+Pie Number of slices to send: Send
I'm using Java's logging (java.util.logging.*, java 1.3+). It all gets fed to a single file if you want, a "Logger" object is really a particular log identifier, for which the log level and log distribution can be controlled independently.
The issue of building the string is, indeed, a very real one. I've measured x5 slowdowns in code due to logging in real code... within a factor of 2 of your 90% figure. The standard solution in java's logging framework is for all log lines lines to look like this:

Frankly, I think that's a BIG PAIN... before java's system existed I built my own and had it down to a managable:

which is enough shorter to be significantly more usable. But Sun didn't consult me.
+Pie Number of slices to send: Send
Back to the original question....
Try this:

This is a little bit better, since a cut-and-paste of the if(log == null){...} section would throw a compile time error if the Test class cannot be found--of course, if you are in the same package or in a subclass, then you still have the problem.
I would therefore have the boilerplate in a separate text file and have a holder inplace of the new Test() command -- possibly: new _some_class_(). That way, it would garunteedly not compile. Unfortunately (or fortunately?) the developers of Java did not see the need for a way to access the class name inside of a static context. As only cut-and-paste coding would require this, perhaps its a good thing. But it assuredly makes things more difficult.
Note that this can also get expensive if the constructor takes a lot of resources--you are essentially creating a "throw-away" object here. I suggest having a separate init() method if you do do this, so that your calls to the constructor are not so expensive.
[ July 22, 2003: Message edited by: Joel McNary ]
+Pie Number of slices to send: Send
The problem with this suggestion is that I now need to do something special every time I call the logger (or at least at the top of every method that uses it). This is completely unacceptable... far worse than a one-line not-quite-boilerplate in each class.
I did a little research on my own and found that as of java 1.4, Throwable has grown a getStackTrace() method which allows access to the stack trace in a "safe" manner (parsing the string from printStackTrace() is NOT portable and was NOT safe). So I could write setUpLogger() to throw an exception, catch it, then examine the stack trace to pull out the value. Something like this:

Unfortunately, I'm using java 1.3, so I won't be able to use this.
This cake looks terrible, but it tastes great! Now take a bite out of this tiny ad:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com


reply
reply
This thread has been viewed 995 times.
Similar Threads
Inheritance doubt
Serialization, Heap and Objects
Thread
Inheritance in Java
Basic question on objects and references to objects
More...

All times above are in ranch (not your local) time.
The current ranch time is
Mar 28, 2024 18:42:27.