从我在网上找到的许多示例、文档和此处的堆栈溢出中,在 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