commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Richard Sitze <>
Subject Re: Enterprise Logging - API Proposal
Date Mon, 13 Dec 2004 21:46:09 GMT
Matt Sgarlata <> wrote on 12/13/2004 
02:26:41 PM:

> >>Then calling code that wants to make use of localized logging would 
> >> 
> >>
> >>this call:
> >>
> >>private static final LocalizedLog log = (LocalizedLog) 
> >>LogFactory.getLog(MyClass.class);
> >> 
> >>
> >
> >Not sufficient.
> >a) Leaving the existing LogFactory alone allows a minimal 
> >to be obtained, if that is appropriate, for Log.  It also allows an 
> >EnterpriseLog/LocalizedLog to be obtained.
> >b) Use of an alternate factory, as opposed to type-casts which might 
> >represents a programmatic "contract".  It assures the developer that 
> >*will* get an Enterprise/Localized Log class back.  Not something that 
> >or may not typecase.
> > 
> >
> I advocate that the type cast above *never* fail, because LogFactory 
> will (in JavaDoc, not in its actual interface) guarantee a LocalizedLog 
> will be returned.  If the underlying logging implementation doesn't 

Reasonable, but overly restrictive.  getLog() should be allowed to return 
a Log instance only.  I understand we have a difference in opinion here. 
I'd like to hear other opinions on this.  In addition, the proposed 
EnterpriseLogFactory.getEnterpriseLog() method takes two parameters:

1.  logger [category] name
2.  resourceBundleName

Without something identifying the resourceBundle, we have no way to 
resolve the messages, or to help the underlying logger implementation 
determine how to find these resources.

Could we introduce the 'Log getLog(String name, String 
resourceBundleName)' method on the existing Factory?  Sure... but if it's 
ALWAYS going to return an EntLog, then let's make it contractual and 
change the return type to EntLog.... and we're starting down a road that 
brought the orginal proposal to introduce this on a subclass: 

Matt, I'm not going to claim that the original proposal is "the only way 
to do things."  I only want to make it clear that the simple solution(s) 
have inherent implications that not everyone might agree with, and we must 
be aware of them.

> support internationalization, then the messages are just passed through 
> unresolved.  I will argue why I like this approach below...
> >Not sufficient.  Again, commons logging, though minimal, must be 
> >It is trivial work for a wrapper to use the Java tools to do the 
> >translation.  If the translation still fails, then agree: dump the 
> >directly.
> >
> >We *are* working on an assumption that
> >a) the component using logging *owns* the message resource bundle(s)
> >b) the general "scheme" for accessing/translating fits ONE paradigm, 
> >said paradigm must be mappable to the target implementation [if 
> >directly], or resolved by the wrapper [if not].
> >
> >
> >>(4) It is inappropriate for any type of message key resolution to be 
> >>implemented in commons-logging.  Message key resolution is certainly 
> >>important though, and should definitely be implemented somewhere else 
> >> 
> >>
> >
> >I argue against this.  Please keep the focus on the expected target for 

> >making use of commons-logging: component, not hosting 
> >application/framework.
> >
> >Note that the message key resolution and message formatting must be 
> >directly exposed, the component developer must:
> >
> >a) write the message resources: key / text
> >b) assume and develope to some mechanism that enables translation, or 
> >multiple texts per key
> >c) assume some formatting mechanism, and embed formatting directives in 

> >the messages
> >
> >No matter the target environment, the extraction and formatting of 
> >messages must be performed as the component developer has planned. 
> >Therefore, for a common I18N logging, we must assume and adopt a 
> >"standard" translation and formatting mechanism that all components 
> >use.
> >
> >Ideally, such a standard would be supported by all, or at least a 
> >majority, of the target logger implementations.  Also, minimal is 
> >prefered.  We believe that the mechanisms provided by the JDK core 
> >classes, as per the original proposal, satisfy both of these.
> >
> >Is this minimal?  depends on your definition of minimal.  Do I see any 
> >alternatives?  No.
> > 
> >
> Ah but I do see alternatives : )
> First, I'm sure everyone will agree: messages should be parameterizable 
> in this standard format shown below.
> messageKeyNumberOne=This is an {0} message from {1}


Now, were does the *component* developer 'place' this content?  I claim we 
need a standard approach for this, based on the 'resource bundle name' 
parameters we pass into the 
EnterpriseLogFactory.getEnterpriseLog(loggerName, resourceBundleName);

> So I can plug in "ignorant" and "Matt" or "insightful" and "God", as the 

> case may be.
> The goal of "standardizing on a format" is satisfied just by what I have 

> written previously.

We agree on this point.

> There is no need to specify any mechanisms for 
> retrieving the message template based on a key like 
> "messageKeyNumberOne".  That retrieval could happen through the file 
> system or a database or whatever.

We disagree on this point.  The *component* developer owns the resource. 
The developer has a right to expect that this will be respected by the 
hosting environment.  Yes, someone might extract the resources from the 
component as part of their build, and drop them into a database... one 
might imagine that the resourceBundleName would be [part of] a key to 
same...  that the underlying implementation would know how to work with 
this.  Doesn't change a thing: the component developer expects the key to 
be found, the application developer/packager must know where the source 
for these can be found.

> I do think that *falling back* on the 
> java.util.ResourceBundle functionality is a valid approach, but we need 
> to take account the case when that resolution doesn't work (e.g. - I am 
> pulling my resource from a DB instead, but haven't configured that 
> yet).  If java.util.ResourceBundle fails, we have to be prepared to pass 

> unresolved messages straight through to the underlying logging system. 

For loggers that support I18N:  pass the resourceBundleName, key, and 
formatting parameters straight through.  No fall back, logger 
implementation assumes responsibility.

For loggers that do not support I18N: use the Java tooling to resolve the 
key to a message.  If this fails, use the key as the message.  Format the 
message, and pass it onto the logger.
> I'm pretty sure the Commons team will agree that throwing an exception 
> is not an option.  Commons logging already made the choice that broken 
> logging will *never* bring a system to its knees (if someone disputes 
> this, please start a new thread).

No argument.

> So if java.util.ResourceBundle fails, I think we have two alternatives:
> A. Pass unresolved messages to the underlying logging implementation if 
> the implementation doesn't support internationalization.  This is the 
> approach I advocated before.  I still think it's reasonable because if 
> you want internationalization of your log messages, I think you should 
> pick a logging implementation that supports it!  However, (B) below may 

The component owner must be able to "globalize" and instrument their code 
for the EnterpriseLog interface without knowledge of what logger is in 
effect.  They have no control if the host environment will support it 
directly or not.

> be a better, more middle-of-the-road alternative:
> B.  Define an interface similar to Spring's MessageSource 
> (http://www.springframework.
> org/docs/api/org/springframework/context/MessageSource.html) 
> interface.  That way, people can plug in whatever resource bundle 
> implementation they want to use (java.util.ResourcesBundle directly, 
> Struts'  resource bundle mechanism, Commons Resources, Spring, to name a 

> few).  This allows you to mix-and-match logging implementations and 
> message key resolution implementations.
> A is more minimal, B is more functional.

Pluggable is cool.. BUT!!   You bring in ComponentA that *depends* on 
message resolver MR-A, and componentB that depends on resolver MR-B... 
which one do you *plug* in?  Or do you plug by component?  We've left the 
realm of simple, and for no positive reason.

> Matt
> ---------------------------------------------------------------------
> To unsubscribe, e-mail:
> For additional commands, e-mail:

Richard A. Sitze
IBM WebSphere WebServices Development

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message