Re: Aspect questions?
markspace wrote:
Arne Vajh??j wrote:
That looks as if you are almost building your own logging framework
on top of a logging framework.
That does not make much sense to me.
I can think of a use case for it though. Let's say you haven't decided which
logging framework to use, or you want to be flexible as to which one to use.
(Different customers of yours prefer different loggers.)
That's what Apache Commons logging is for.
(Not syntax checked or tested.)
abstract class MyLogger {
public static MyLogger getLogger( String name ) {
MyLogger logger = Class.forName(
System.getProperty("me.mystuff.MyLogger.logImpl",
"me.mystuff.MyDefaultLogger" ).newInstance());
return logger;
}
public abstract void logStuff(Object...);
}
It's actually common for libraries to use either ju.logging or log4j without
regard for your preference, with the result that both frameworks wind up in
the same program.
So the idea is that you wrap the logging framework in your own, and then
you're free to provide an implementation that matches whatever logging
framework you choose to use in the future. Maybe this is not for everyone, but
I could see its advantages. Some folks might like java.util.Logger, some folks
like log4j. And some might like things that I don't know about yet.
I think in Java those two pretty much have it sewn up.
In any event, there's already
A couple of other things.
Lew wrote:
public class Foo
{
final Logger logger = getLogger(getClass());
[...]
}
This requires that a logger is instantiated for each object as it is created.
No, it doesn't.
It only creates one per class.
Potentially this is a lot of work, and each logger may not be used. (Even
declaring the logger to be static still requires a logger per class loaded.)
That's not important overhead at all. It's a feature, not a bug.
The logger being tied to the class (or its name) gives you class-level control
over the logger behavior at deployment time by adjustment of the logging
properties (or XML) configuration file. This is desirable.
The logging object size pays for itself in spades with its functionality.
Whereas this:
...
try {
... some stuff...
} catch (Exception ex) {
getLogger(getClass()).log( ... );
}
creates the logger lazily and therefore doesn't spend any resources if logging
happens to be never required.
Lazy initialization is waaay overrated.
First prove you have an optimization problem before you present an
optimization solution.
Lastly, I don't know about log4j, but I don't think the java.util.logging
package uses threads when logging. Any IO operations the logger makes will
block the calling thread. I've heard this is undesirable in most cases. So
Loggers are designed to be very fast unless used. So calls below the logging
threshold add very, very little overhead.
Calls above the threshold are usually warning or error logging, so the
overhead there is masked by the exception mechanism and the fact that things
are crashing.
First prove you have an optimization problem before you present an
optimization solution.
rolling your own framework also gives you control over threading issues too,
which again might be important for some customers.
Unlikely, but remotely possible.
That doesn't apply to the OP's situation, of course.
But your analysis ignores the care that goes into those two logging frameworks
to minimize the overhead of logging calls, and the substantial functionality
that you either sacrifice or spend a fortune recreating in a roll-your-own. It
also ignores the difficulty of beating their performance. You'd be
hard-pressed to exceed the efficiency of these frameworks.
Think long and hard before deciding to forego these two logging frameworks,
then stick with them anyway.
If you really, really, really, really, really, really need to spawn a thread
to make logging faster, which you don't, you can do that over a regular
ju.logging or log4j call. You don't have to throw out the baby with the bath
water.
--
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg