What about the following API:
public class LogRecordFactory {
private final Level level;
public LogRecordFactory(Level level) {
this.level = level;
}
public LogRecord create(String msg) {
return new LogRecord(level, msg);
}
public LogRecord create(String msg, Object... parameters) {
LogRecord lr = create(msg);
lr.setParameters(parameters);
return lr;
}
// ...etc...
}
and then in the Logger...
public void log(Level level, Function<LogRecordFactory, LogRecord>
logRecordProducer) {
if (level.intValue() < levelValue || levelValue == offValue) {
return;
}
LogRecord lr = logRecordProducer.apply(new
LogRecordFactory(level));
doLog(lr);
}
which would be used as:
logger.log(Level.INFO, lrp -> lrp.create("Status is: %s",
getStatus()));
Regards, Peter
On 12/27/2012 01:23 AM, Henry Jen wrote:
On 12/22/2012 07:30 AM, Jason Mehrens wrote:
The msg argument in most cases is a string literal because it is either
a resource bundle key or a MessageFormat literal. The established best
practice is to convert on the fly construction of messages to use
the MessageFormat syle logging. This current patch is kind of
anti-pattern of that practice. I would think the real win would be to
delay construction of the 'params' argument in the logging framework.
Allowing the callers to write logger.log(level, "{0}", Foo::bar) and
have the call to bar be lazy eval would be the best of both the logging
world and the lambda world.
For messages not just only for developer, they should be localized as
you suggested and in such cases, it is possible to achieve the laziness
via Object.toString(), less straightforward than using a lambda, but is
possible.
Cheers,
Henry