[slf4j-dev] Category of Logger vs. name of containing class.

Endre Stølsvik Endre at Stolsvik.com
Tue Jul 12 01:02:30 CEST 2005


On Mon, 11 Jul 2005, Ceki [iso-8859-1] Gülcü wrote:

| At 02:54 PM 7/11/2005, Endre Stølsvik wrote:
| 
| > | But as I think you realize, it is not necessarily the best hierarchy for
| > | production environments.
| > 
| > I've never used the classname.
| 
| You have never user class names to limit the scope of loggers to their
| declaring class? Representation-wise, where do you reckon your usage
| pattern falls?

I must admit that I didn't quite get the question, but I'll try to answer 
it nonetheless..!

Since I feel that the class names already can be extracted for each event, 
then I try to give the logger's name a more "contextual meaning" than 
simply from which class the log entry is emitted from.
  My primary use with logging (since that is my primary job) is with a 
portal server. This portal server have several subsystems, for example a 
rather complex authentication system, a database pool, a thread worker 
pool, a bunch of servlets sharing some features etc. The loggers are 
created with names that reflect such subsystems, even though some parts 
are situated in different classes. Thus some classes have several loggers, 
e.g. both an AUTH logger, a CORE logger and a SERVLET logger - some log 
statements go to the AUTH logger, some to the CORE logger and some to the 
SERVLET logger (or children of these, obviously. The capital names are 
"roots" in this hierarchy). Some might even go to several of them..

| 
| > If I could attach one Logger to "several names", so that if I do
| > httpRedUserAuthLog.info("Red User ["+user.getName()+"] has
| > authenticated."), the log statement would be injected both on the auth
| > category ("Septim.AUTH.user" or whatever, "Septim" being my imaginary
| > server), on the server-core category ("Septim.CORE.httphandler" or
| > whatever), and on the color category ("Septim.Color.red"), then that might
| > be a cool new feature without introducing much extra complexity.
| > 
| >  // Make Logger, with primary, mandatory category
| >  Logger httpUserRedAuthLog = Logger.getLogger("Septim.AUTH.user")
| >  // Additional categories
| >  httpUserRedAuthLog.addCategory("Septim.CORE.httphandler")
| >  httpUserRedAuthLog.addCategory("Septim.Color.red")
| > 
| > Logger.addCategory(String extraCat) would thus be the only new API-level
| > method..
| 
| > The first element here, that this log-statement would end up in three
| > different files, is already solved in at least log4j by instead of
| > injecting into three categories, one would inject to only the one
| > category, and configuring that category to append to all three Appenders.
| >   But, with some clever log-configuration and the multiple category
| > attachment feature above, I could ALSO state more specifically that I want
| > only all "Colored Auth" statements to go to this particluar file.
| >   The example might be useless, but in any case, it would maybe solve some
| > of the axes-problems? - You basically introduce a new axis by adding a new
| > category to several loggers.
| > 
| > However, I realize that this solution has limitation that the Marker
| > approach would fix: you cannot switch that easily between red and green
| > users, w/o making a lot different colored loggers. So Marker is a nice
| > idea, but what about not introducing a new concept, and instead just
| > enabling method-specific injections of additional categories?
| 
| Given that the two concepts are very similar, if Marker is a new
| concept then so is attaching multiple categories to a logger, and vice
| versa.

Of course "my idea" is also a new concept, but my point is that it doesn't 
introduce a new -thing-. Ehhr.. A new -element-, an entirely new 
-feature-. It just reuses the alread existing notion of 
logger/category/name: A logger's single log-statement (.debug, .info) can 
have one -OR SEVERAL- categories.

| 
| 
| >  // Make Logger, with primary, mandatory category
| >  Logger httpUserAuthLog = Logger.getLogger("Septim.AUTH.user")
| >  // Additional categories
| >  httpUserAuthLog.addCategory("Septim.CORE.httphandler")
| > 
| >  // log line
| >  httpUserAuthLog.info("Septim.Color.red", "User ["+user.getName()+"] has
| > authenticated.");
| > 
| > .. basically the exact same idea as the current "Marker" approach, but
| > that the markers are just additional categories? If there is a problem
| > with the log method signatures, then by all means keep the Marker
| > interface / simple class, but just as a wrapper around a String denoting
| > the category.
| 
| That's the idea.

Okay, then I might have misunderstood heavily here. I thought that you 
wanted to introduce a new feature, namely "The Marker". So a log statement 
would have -one- category, and optionally one or several markers. The 
logging system configuration would thus need extra features to take this 
into account. Lets take log4j: one now sets the level threshold, the 
"additivity", and which Appenders to emit output to, for at least one (the 
root), several or all of the categories used in the system. The Markers 
approach, as I understood it, would thus need a new feature, namely the 
for the Markers a log statement was logged with. This would have to go on 
as an additional thing to configure for the categories (or some other 
place), e.g. that you set the level, and which Markers, should "go 
through". Or you state that such and such Marked events should go to this 
log-file (for a category, or for the entire system).. or something 
similar. I presumed that this wasn't quite worked out yet?
  Anyway, the multiple categories wouldn't need any extra features in the 
logging configuration, GIVEN that you didn't want to use "cross sections": 
one single log statement on a multiple-attached-category logger would 
simply be emitted as if the exact same log-statement was outputted to a 
set of loggers "instantiated" with different categories. However, since it 
really is the same log-event, and can thus be tracked as such, one -could- 
also have "logic statements" in the logging configuration that took this 
multi-category-attachment into account, and stated that IF both this and 
this category was "activated" by the -same- log-event, THEN a special 
appender should be invoked.

| 
| >   It would require versions with 'Marker marker' and 'Marker[] markers' to
| > all the log methods - thus obviously multiplying the existing methods by
| > three!
| 
| If Marker is a composite, then the number of existing methods is
| multiplied by two, not three.

Yes, but that would complicate the logic and ease-of-understanding - 
instead of simply deciding which extra categories the log-statement should 
go to, one would have to understand the new Marker feature.

| Although two is still a non-negligible factor, the impact on existing 
| implementations can be small and localized, in particular because 
| markers are almost entirely orthogonal to the current hierarchical 
| logger/level paradigm.

I don't think they're orthogonal to the logger axis. They're actually 
totally parallel, as I've understood them, that's why I'm suggesting to 
simply reuse the already existing logger (category/name) axis.
  Even the level can be viewed as a parallel axis, but as I've stated, I 
feel that they are so important that the API should actually have 
them predefined.

By the way, I don't think that heavy method overloading is that bad - even 
if there is 20 versions of the same method, this isn't overly complicating 
if each of them have good javadoc, and are basically just variations of 
what to put in. One could have one single large method signature, where 
you simply put null in for each of the non-used parts - seen this way, all 
the other versions are just convenience. Most IDEs will, when you write 
"log.debug(" show some kind of menu of all the overloaded signatures, and 
at least with my beloved CodeGuide I can scroll up and down between these 
and get the javadoc for each of them.
  So if you have 20 debugs, 20 infos etc, this would only be bad in the 
sense that the implementation would have to do a bunch of copy and paste 
between each of them - the users of the API wouldn't notice much, except 
that one doesn't have to input null in a lot of places when you don't need 
the feature that the given paramenter represent.

By the way 2: the logger hierarchy (the categories) doesn't really define 
-one axis-: Since it is a tree, it defines as many axes you want to view 
it as - you can just make several "roots", as I do in the example at the 
top of this message.

Regards,
Endre.


More information about the slf4j-dev mailing list