我们希望使用SLF4J,但我们发现的一件事是您不能将该级别指定为参数,即
Logger.log(Level.INFO, "messsage");
你必须这样做
logger.info("message");
这可以防止能够通过方法传递所有内容,因此您可以将其他属性添加到类中的所有日志消息中。
public class Test
{
public Test(SomeObj obj)
{
log(Level.INFO, "message");
}
public void anotherMethod()
{
log(Level.DEBUG, "another message");
}
private void log(Level level, String message)
{
logger.log(level, message + obj.someString());
}
}
有没有办法用SLF4j实现这个目标?
答案 0 :(得分:8)
围绕slf4j调用编写一个包装器,并为六个日志级别创建自己的枚举。然后在你的包装器中,使用一个开关来调用正确的slf4j调用。
void myLog(Level level, String message)
{
switch (level)
{
case FATAL:
log.fatal(message);
break;
case ERROR:
log.error(message);
break;
....
}
}
答案 1 :(得分:6)
答案是否定。请参阅this discussion。
答案 2 :(得分:3)
你的用例尖叫代表模式。基本上你在代码和SLF4J之间楔入自己的Logger
实现并“扩展”相关方法:
class MyLogger implements Logger {
Logger realLogger;
Object userData;
MyLogger(Class clazz, Object userData){
this.realLogger = LoggerFactory.getLogger(clazz);
}
public void debug(String msg) {
realLogger.debug(msg + userData.someString());
}
// many more methods, perhaps per java.lang.reflect.Proxy
}
这在商业代码中使用如下:
public class Test
{
Logger log;
public Test(SomeObj obj)
{
log = new MyLogger(Test.class, obj);
log.logInfo("message");
}
public void anotherMethod()
{
logDebug("another message");
}
}
为了MyLogger
类SomeObj
的最佳可重用性,应该使用Object.toString()
,或者它应该实现MyLogger
可用于获取消息附录的接口。
答案 3 :(得分:1)
嗯,从技术上讲,SLF4J没有为您提供logger.log(级别,消息)方法。但我找到了解决方法。 [编辑:使用内省]
使用下面的代码片段,您可以获得slf4j在运行时找到并包装的本机记录器。如果你还记得,slf4j只是来自另一个提供者的slf4j实现的包装器(jdkLogging,Log4J,JCL等......)。所以这里:
public Object getNativeLogger( org.slf4j.Logger logger ) {
Object result = null;
if ( logger.getClass().getName().equals("org.slf4j.impl.Log4jLoggerAdapter")) {
try {
Field f = Log4jLoggerAdapter.class.getDeclaredField("logger");
f.setAccessible( true );
result = (org.apache.log4j.Logger)f.get(logger);
}
catch( Exception e ) {
System.out.println("Unable to access native log4j logger");
}
}
else if ( logger.getClass().getName().equals("org.slf4j.impl.JDK14LoggerAdapter")) {
try {
Field f = Jdk14Logger.class.getDeclaredField("logger");
f.setAccessible( true );
result = (Jdk14Logger)f.get(logger);
}
catch( Exception e ) {
System.out.println("Unable to access native log4j logger");
}
}
else if (..... other native loggers slf4j supports)....
}
return result;
}
然后你可以像这样使用它:
Object l = getNativeLogger(mySlf4jLogger);
if ( l instanceof org.apache.log4j.Logger ) {
org.apache.log4j.Logger logger = (org.apache.log4j.Logger) l;
logger.log( CUSTOMLog4JLevel, message);
}
else if( .... other implementations that you care about ...)...
因此虽然技术上并不在slf4j中,但可以使用slf4j作为主要的日志记录界面。