• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Frits Walraven

Naming logger instances

 
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 ...
 
Michael Chermside
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Bartender
Posts: 1844
Eclipse IDE Ruby Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 ]
 
Michael Chermside
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
The knights of nee want a shrubbery. And a tiny ad:
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
reply
    Bookmark Topic Watch Topic
  • New Topic