作者:手机用户2502895987 | 来源:互联网 | 2022-12-10 13:02
从我在网上找到的许多示例,文档以及此处的Stack Overflow中,在slf4j中连接字符串的正确方法是使用内置的字符串格式。
例如 :
LOGGER.error("ExceptionHandler throws {}" , appException);
我也尝试了不格式化,并且产生了相同的结果:
LOGGER.error("ExceptionHandler throws " , appException);
由于某种原因,这对我不起作用,我也不知道自己缺少什么。如果传递对象,是否使用其他格式?
上面的示例正在打印以下日志消息:
2018-07-18 02:38:19 ERROR c.a.c.c.p.ExceptionProcessor:67 - ExceptionHandler throws {}
而不是使用常规串联时收到的预期消息:
LOGGER.error("ExceptionHandler throws " + appException);
或者当我手动调用.toString()时
LOGGER.error("ExceptionHandler throws {}" , appException.toString());
根据Sonar的说法,这最后一个选项不正确,因为:
因为printf样式的格式字符串是在运行时解释的,而不是由编译器验证的,所以它们可能包含导致创建错误字符串的错误。在调用java.util.Formatter,java.lang.String,java.io.PrintStream,MessageFormat和java.io的format(...)方法时,此规则静态验证printf样式格式字符串与其参数的相关性。 .PrintWriter类和java.io.PrintStream或java.io.PrintWriter类的printf(...)方法。
AppException类如下:
import java.io.Serializable;
import javax.ws.rs.core.Response.Status;
public class AppException extends Exception implements Serializable {
private static final long serialVersiOnUID= 1L;
private Error error;
private Status status;
public AppException(Error error, Status status) {
this.error = error;
this.status = status;
}
public AppException() {
}
public Error getError() {
return error;
}
public void setError(Error error) {
this.error = error;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
@Override
public String toString() {
return "AppException [error=" + error + ", status=" + status + "]";
}
}
我正在构建我的记录器,如下所示:
private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionProcessor.class);
我正在使用 slf4j-api 1.7.22
1> Andreas..:
您相信LOGGER.error("ExceptionHandler throws {}" , appException);
正在致电:
error(String format, Object arg)
但实际上是在调用:
error(String msg, Throwable t)
因为这更适合参数类型。
如果希望它调用第一个,则将参数强制转换为Object
:
LOGGER.error("ExceptionHandler throws {}" , (Object) appException);
或toString()
像您已经尝试过的那样打电话。
如果您使用好的IDE编写代码,那么IDE会帮助您解决这一问题。例如,在Eclipse中,如果将鼠标悬停在方法调用上,它将确切显示正在调用的方法。当有过载时非常有用。
我只是重新构建了代码,并添加了两个日志条目:一个包含对toString的调用,另一个包含您建议的强制转换。进行转换的人未按预期工作,并且产生了我最初发布的结果(无消息)
无法复制。这是MCVE(使用org.slf4j:slf4j-simple:1.7.25
):
Logger logger = LoggerFactory.getLogger("Test");
Exception e = new Exception("Test");
logger.error("Test 1: {}", e); // calls error(String, Throwable)
logger.error("Test 2: {}", (Object) e); // calls error(String, Object)
输出量
LOGGER.error("ExceptionHandler throws {}" , (Object) appException);
第一次调用按原样(带有{}
)和stacktrace 打印消息。用异常文本替换的
第二个呼叫打印消息{}
。