You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@velocity.apache.org by Neeme Praks <ne...@apache.org> on 2004/02/11 13:07:42 UTC

Re: logging again

I've been reading this thread for a while now and I figured to drop a 
note now as things start to be a bit confusing (in my mind at least).

Geir Magnusson Jr wrote:

[..snip..]

> This is not what I mean by injection, and I'm sorry I wasn't clearer.  I 
> see the whole problem now.
> 
> There are two aspects to logging that we have to think about, the 
> internal aspect, how things inside the core of Vel and around it (like 
> tools) get loggers.  There also is the the external aspect, how Velocity 
> as a single component behaves wrt the environment it's used it.
> 
> When I talk about injection, I am thinking of the latter - the external 
> aspect - in that I mean that the user of velocity gets to dictate what 
> logger the whole of the log flow will go into.  It's how it works now.  
>  IOW, I don't care how Velocity will log internally, just that I get a 
> say on where the stuff goes.  I know it's actually properties, but for 
> the sake of this discussion, it's equivalent to :
> 
> VelEngine ve = new VelEngine();
> 
> ve.setLogger( somethingThatImplementsLogsystem);
> 
> vs.init();
> 
> with the default being the search for logkit and log4j automatically if 
> I don't specify something.
> 
> You are correct that *internally*, we have the model of having to set 
> the logger in classes, 'injecting' the logger into things, and we can 
> improve that by switching to a static factory model.  But that's not 
> what I mean when I say I want to keep injection.  I mean I want the 
> 'external' configuration injection.  Internally, there is nothing wrong 
> with using a static factory to grab a logger for any class inside that 
> wants one.  Doing that has no effect on the external behavior of 
> velocity, I will argue, as long as we don't use c-l directly, because 
> then we lose control over the static factory, control of which is 
> critical for keeping the external injection.
> 
> So that's the key to this misunderstanding -> there is an internal 
> aspect (i.e. w/in velocity, we have the pattern of static factory to 
> pull a logger, what you might call the "c-l pattern"), but what I am 
> defending so rigidly is the external aspect.
> 
> I've explained that I always (almost) use the static factory approach 
> myself, and think it's generally just peachy.  It will be very 
> convenient for programmers developing *inside* Velocity.
> 
> But externally, I like having the ability to set the logging adapter 
> from the outside.  This is very convenient for programmers developing 
> *with* Velocity.

Maybe it's me but I don't get it how can you have injection pattern 
externally and static factory pattern internally?

Example:
(We are in a container that has a common classloader for all 
applications and components)

We inject the logger in application A:

VelocityEngine ve = new VelocityEngine();
ve.setLogger(somethingThatImplementsLogsystemForApplicationA);
vs.init();

And, we inject the logger in application B:

VelocityEngine ve = new VelocityEngine();
ve.setLogger(somethingThatImplementsLogsystemForApplicationB);
vs.init();

If I understand correctly then (internally) classes in Velocity would be 
using something like this to get a logger:

private Logger logger = LogSystem.getLogger("my.log.category");

In order to make this work, there has to be something like this 
somewhere in VelocityEngine initialization code:

LogSystem.setRootLogger(somethingThatImplementsLogsystemForApplicationAorB);

and then getLogger() implementation would be something like this:

public static Logger getLogger(String categoryName) {
     return rootLogger.getChildLogger(categoryName);
}

So... if we have the application A initalization and then application B 
initialization, the end result is that all logging goes to the logger 
from application B (as the logger is set on a static level and we have a 
common classloader)...

To conclude, my point is that if you are going to take the injection 
route then you cannot really use static factory pattern internally. Then 
you have to use injection all the way, otherwise it doesn't really work.

And I would support the injection pattern 100% as it would make it 
much-much easier to use more than one instance of Velocity as a 
component in managed environments like Avalon containers or 
PicoContainer or any other out there.

Finally, if you take the injection route, you can just as well use the 
commons-logging interfaces for injecting the logger (as nobody, not even 
Geir :-), really had anything against the interface, it opposition was 
just for the discovery mechanism and that really is a PITA in managed 
environments).

Rgds,
Neeme


---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-dev-help@jakarta.apache.org


Re: logging again

Posted by Geir Magnusson Jr <ge...@4quarters.com>.
On Feb 11, 2004, at 7:07 AM, Neeme Praks wrote:

> I've been reading this thread for a while now and I figured to drop a  
> note now as things start to be a bit confusing (in my mind at least).
>
> Geir Magnusson Jr wrote:
>
> [..snip..]
>
>> This is not what I mean by injection, and I'm sorry I wasn't clearer.  
>>  I see the whole problem now.
>> There are two aspects to logging that we have to think about, the  
>> internal aspect, how things inside the core of Vel and around it  
>> (like tools) get loggers.  There also is the the external aspect, how  
>> Velocity as a single component behaves wrt the environment it's used  
>> it.
>> When I talk about injection, I am thinking of the latter - the  
>> external aspect - in that I mean that the user of velocity gets to  
>> dictate what logger the whole of the log flow will go into.  It's how  
>> it works now.   IOW, I don't care how Velocity will log internally,  
>> just that I get a say on where the stuff goes.  I know it's actually  
>> properties, but for the sake of this discussion, it's equivalent to :
>> VelEngine ve = new VelEngine();
>> ve.setLogger( somethingThatImplementsLogsystem);
>> vs.init();
>> with the default being the search for logkit and log4j automatically  
>> if I don't specify something.
>> You are correct that *internally*, we have the model of having to set  
>> the logger in classes, 'injecting' the logger into things, and we can  
>> improve that by switching to a static factory model.  But that's not  
>> what I mean when I say I want to keep injection.  I mean I want the  
>> 'external' configuration injection.  Internally, there is nothing  
>> wrong with using a static factory to grab a logger for any class  
>> inside that wants one.  Doing that has no effect on the external  
>> behavior of velocity, I will argue, as long as we don't use c-l  
>> directly, because then we lose control over the static factory,  
>> control of which is critical for keeping the external injection.
>> So that's the key to this misunderstanding -> there is an internal  
>> aspect (i.e. w/in velocity, we have the pattern of static factory to  
>> pull a logger, what you might call the "c-l pattern"), but what I am  
>> defending so rigidly is the external aspect.
>> I've explained that I always (almost) use the static factory approach  
>> myself, and think it's generally just peachy.  It will be very  
>> convenient for programmers developing *inside* Velocity.
>> But externally, I like having the ability to set the logging adapter  
>> from the outside.  This is very convenient for programmers developing  
>> *with* Velocity.
>
> Maybe it's me but I don't get it how can you have injection pattern  
> externally and static factory pattern internally?
>
> Example:
> (We are in a container that has a common classloader for all  
> applications and components)
>
> We inject the logger in application A:
>
> VelocityEngine ve = new VelocityEngine();
> ve.setLogger(somethingThatImplementsLogsystemForApplicationA);
> vs.init();
>
> And, we inject the logger in application B:
>
> VelocityEngine ve = new VelocityEngine();
> ve.setLogger(somethingThatImplementsLogsystemForApplicationB);
> vs.init();
>
> If I understand correctly then (internally) classes in Velocity would  
> be using something like this to get a logger:
>
> private Logger logger = LogSystem.getLogger("my.log.category");
>
> In order to make this work, there has to be something like this  
> somewhere in VelocityEngine initialization code:
>
> LogSystem.setRootLogger(somethingThatImplementsLogsystemForApplicationA 
> orB);
>
> and then getLogger() implementation would be something like this:
>
> public static Logger getLogger(String categoryName) {
>     return rootLogger.getChildLogger(categoryName);
> }
>
> So... if we have the application A initalization and then application  
> B initialization, the end result is that all logging goes to the  
> logger from application B (as the logger is set on a static level and  
> we have a common classloader)...

Yes, that is a wrinkle that occurred to me,  but I thought the solution  
would be a context classloader.   Though as I think about it, we could  
be screwed.  Yet another example of why singletons suck.

Have I ever emphasized how much I think the whole subject of logging  
really sucks?

>
> To conclude, my point is that if you are going to take the injection  
> route then you cannot really use static factory pattern internally.  
> Then you have to use injection all the way, otherwise it doesn't  
> really work.

Hopefully we can figure this out.  Right now we have injection all the  
way, but there is darn good reason to augment or replace it w/ the  
static factory.

>
> And I would support the injection pattern 100% as it would make it  
> much-much easier to use more than one instance of Velocity as a  
> component in managed environments like Avalon containers or  
> PicoContainer or any other out there.

That was my motivation, to ensure that container models like that will  
be supported.  They are still yet not mainstream but are getting there,  
and will be much more prevalent in the future, I am sure.

>
> Finally, if you take the injection route, you can just as well use the  
> commons-logging interfaces for injecting the logger (as nobody, not  
> even Geir :-), really had anything against the interface, it  
> opposition was just for the discovery mechanism and that really is a  
> PITA in managed environments).

That's right, and thanks for the support!  Now there's two of us!

Here is where I get to invoke the dependency argument - I will argue  
that for something so simple, the interface, there is no reason to bind  
ourselves to the machinations of an external project, no matter how  
good the project and its participants.

I really take and took this issue seriously - I was chatting about it  
as a sanity check w/ someone I greatly respect (a J2EE container  
author) who said the following [and who's identity will remain secret  
for his protection from the c-l cabal :)  ] :

[22:26] 	<xxxxx>	geir: if it is just for your consumption, I'd vote for  
writing a simple custom interface
[22:27] 	<xxxxx>	everything out their has too much baggage and you can  
write something that makes you internal code easy

Not that an appeal to authority by an unnamed source should be  
considered a reason to do anything, but I least had comforting  
confirmation that I wasn't totally nuts...

:)

geir


>
> Rgds,
> Neeme
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: velocity-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: velocity-dev-help@jakarta.apache.org
>
>
-- 
Geir Magnusson Jr                                   203-247-1713(m)
geir@4quarters.com


---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-dev-help@jakarta.apache.org