Hi
On 24 Aug., 18:22, J <
ja...@sumall.com> wrote:
> > With respect that wrong. %F:%L has nothing to do with the decision to create a logger per class. This would works fine even if you only have one log4j-Logger-instance.
>
> Now you're confusing me again. You said that %F:%L (and other
> uppercase letters) wasn't working correctly for you because it would
> always display play.Logger. I'm telling you that this is correct
> because you are using a single global Logger. And the reason they
> work for me (by "work" I mean they display information from calling
> code, not my wrapper class), is because I'm using a static logger per
> class. I believe it is precisely why it works for me, and not you.
Yes and I can give you an example which shows the opposite. I would
repair it in play, but I don't know if it wanted to refactor such a
central class, from a nobody like me. Furthermore the JULI-support
makes it difficult.
The reason why you example works is, that you wrote your own logger,
which calls directly log4j-Logger I assume. There you can give the
FQCN to the log-method. So what must be done in plays Logger:
OldCode
/**
* Log with DEBUG level
* @param message The message pattern
* @param args Pattern arguments
*/
public static void debug(String message, Object... args) {
if (forceJuli || log4j == null) {
try {
juli.fine(format(message, args));
} catch (Throwable ex) {
juli.log(Level.SEVERE, "Oops. Error in Logger !", ex);
}
} else {
try {
if (recordCaller) {
org.apache.log4j.Logger.getLogger(getCallerClassName()).debug(format(message,
args));
} else {
log4j.debug(format(message, args));
}
} catch (Throwable ex) {
log4j.error("Oops. Error in Logger !", ex);
}
}
}
should be
/**
* Log with DEBUG level
* @param message The message pattern
* @param args Pattern arguments
*/
public static void debug(String message, Object... args) {
if (forceJuli || log4j == null) {
try {
juli.fine(format(message, args));
} catch (Throwable ex) {
juli.log(Level.SEVERE, "Oops. Error in Logger !", ex);
}
} else {
try {
org.apache.log4j.Logger currentLogger = log4j;
if (recordCaller) {
currentLogger =
org.apache.log4j.Logger.getLogger(getCallerClassName());
}
if (currentLogger.isDebugEnabled())
{
currentLogger.log(Logger.class.getName(),
org.apache.log4j.Level.DEBUG, format(message, args), null);
}
} catch (Throwable ex) {
log4j.error("Oops. Error in Logger !", ex);
}
}
}
Then %F%L would work perfectly. The key to enable this is to give
Logger.class.getName() to the log-method. Unfortunately neither
logback nor slf4j has such a functionality. Which makes a correct
implementation of plays Logger impossible.
> As for my wrapper, it's really irrelevant. It ONLY provides Java 5
> varargs support. If I dont' care about varargs, then I just use SLF4J
> directly and everything still works the same. I would still define a
> static logger per class because that's the recommended approach.
>
> My wrapper class is too long to paste (also because it spans 3
> classes) but here's a quick overview:
>
> 1) public interface Logger extends org.slf4j.Logger - this interface
> defines 5 methods (trace, error, warn, debug, info) with varargs
> arguments
>
> 2) public class LoggerImpl implements Logger - implementation of above
> interface. Constructor takes in a org.slf4j.Logger instance, which I
> use to delegate all logging calls.
>
> 3) public class LoggerFactory - this is analogous to
> org.slf4j.LoggerFactory. I use this LoggerFactory in order to create
> the LoggerImpl instances, and I create one PER CLASS.
>
> That's it. Again, this is ONLY for Java 5 varargs. Otherwise, I
> would just use org.slf4j.LoggerFactory to create my logger instances,
> and everything should work.
>
> Hope this helps!
>
So if you send the code of one method of your LoggerImpl which calls
the delegater-class. I think it will become clear.
Niels