NLS in Logger (Re: [slf4j-dev] Logger.debug(String, Object[])?)
Curt Arnold
carnold at houston.rr.com
Sat Aug 6 00:07:46 CEST 2005
> I actually got on the list with a very specific issue and my focus
> lies
> on commons-logging, but anyways I want to point something out.
> You might find it strage that I, who proposed the need for additional
> methods in the Logger API, am saying this but:
> In my opinion a logger API should be very simple and focus on logging.
> What you are doing here is mixing logging with native language support
> (NLS, i18n or however you call it).
I don't believe that it has anything particular to do with NLS or
i18n, just a desire to be able to bypass the cost of message
construction when logging is disabled without having to add a whole
lot of logger.isDebugEnabled() cruft.
> In my oppinion this is misplaced in
> a Logging API (I mean all the formatting methods). A logger should
> take
> an Object and if the according loglevel is enabled it should log
> Object.toString() (checking for NULL of cause and these things).
> The Object can be an NlsMessage that contains the internationalized
> message with parameter objects to fill in.
> Did you ever implement NLS in a multi-user server application?
> The static way to access a default Locale is all you get from the
> JDK to
> get the right ResourceBundle picked.
> So the NlsMessage could use a translation service in its toString()
> method where a ThreadLocal is used to get the context of the according
> user and get the desired Locale.
> You do not want to have logic like this inside a logger, right?
> This is all about "separation of concerns".
> But again you see I am one of these IoC container guyz and care very
> much seperation of components and decoupled logic - maybe too much :)
> Other people just want to have things done quickly and without
> using and
> understanding frameworks or stuff like this and they might like to
> type
> it like suggested above.
>
I agree that the number of methods and code duplication is
undesirable. Maybe it would be better to isolate all the formatting
variants into a single concrete LogFormat class and have the Logger
interface only supply the most basic of the log methods that the
actual implementation would need to provide. Something like:
// direct use of org.slf4j.Logger
logger.debug("Hello, world");
or
LogFormat.debug(logger, "Hello, {}.", location);
which could be implemented:
public static void debug(Logger logger, String format, Object param1) {
if (logger.isDebugEnabled()) {
logger.debug(MessageFormat.format(format, param1));
}
}
I'd guess a JIT could effectively inline that code.
> Anyways if you make it this way: the syntax with "{}" for me looks
> like
> you are NOT using java.text.MessageFormat. Why is that? You do not
> need
> to reinvent the wheel here. But maybe I am missing something.
I was assuming that SLF4J was using java.text.MessageFormat
internally, but a code review suggests that is not the case.
MessageFormat seems to have been around forever so it does not appear
to be an attempt to support some earlier JVM's. I'd be interested to
know the motivation for not using MessageFormat in SLF4j. However,
it is my impression that the org.slf4j.MessageFormatter is trying to
mimic java.text.MessageFormat, at least on the pattern syntax.
Currently org.slf4j.Logger had a lot of special case signatures (0
parameter, 1 parameter, 2 parameter, etc) but did not have the
general case (the Object[] case). The special cases are likely only
justified for the debug variants since info, warn and error messages
should be sufficiently rare that you could afford an array creation
on a call.
More information about the slf4j-dev
mailing list