谢谢

log.error("Request to {} failed, uuid is {}.", uri, uuid, exception)==========这样异常堆栈也能打印出来

楼主写法给我看笑了。。。log 本来就有格式化功能,再格式化一次。。

其实如果是 100% 会打印出来的 log ,就不需要 format 了,直接 + 拼接就行想优雅点就按照经验先 new 一个长度差不多够用的 StringBuilder 避免扩容再优雅点就把这个 StringBuilder 扔 ThreadLocal 里缓存住(不一定有性能提升,可能 ThreadLocal 查找的时间都够把字符串拼出来了另外就是格式问题,楼主目前的格式只考虑给人看没考虑给机器解析,可以考虑调整一下,加一些特殊的分隔符,便于统一处理日志做数据分析和预警之类的

使用 slf4j, log.info("Request to {} failed,uuid is {}",uri,uuid)自带占位符

竟无语凝噎

楼主从 C 那边转过来的?

uuid 如果是追踪调用链用的话可以存在 MDC, 那日志直接就

log.error("Request to {} failed.", uri, exception)

绷不住了

log.error($"Request to {uri} failed, uuid is {uuid}.", exception)c#真的是越用越先进!

java public StringFormattedMessage(final Locale locale, final String messagePattern, final Object... arguments) { this.locale = locale; this.messagePattern = messagePattern; this.argArray = arguments; if (arguments != null && arguments.length > 0 && arguments[arguments.length - 1] instanceof Throwable) { this.throwable = (Throwable) arguments[arguments.length - 1]; } }log4j 的 log.error 的实现中,找到 StringFormattedMessage 类,会判断最后一个是不是 Throwable 。所以调用 这个接口也是可以打印异常堆栈 public void error(String format, Object... arguments);调用这个也行 public void error(String msg, Throwable t);

log.error(() -> String.format("Request to %s failed, uuid is %s.", uri, uuid), exception);chatgpt 回答的

请求入口设置 uuid 到 MDC ,logback 配置好,该请求所有日志都会带上 uuid 。更方便排查。
不怎么写 Java ,但是 idea 会提示你这写法可以优化吧??

/t/984299前两天不是就有帖子讨论过了吗,这个帖子还能回答为啥不能像你这样写

这种警告基本要 sonar lint 这种才会有,idea 本身没管到这一层

#14我使用的 idea 2023.2.2 版本,没有这种提示。楼主的问题主要是:(个人猜测)看到 error 接口,以为只有这个才会打印异常堆栈, public void error(String msg, Throwable t);以为这个接口 public void error(String format, Object... arguments);没有 Throwable 作为入参,认为不会打印异常堆栈。包括我以前也是这样认为。同样很多年前也遇到过 log.error 不打印异常堆栈的情况。

是来钓鱼的吗。。。

c#也不要这么写,每一次调用都会有额外的字符串分配。把前面$去掉,log 框架会帮你格式化的log.error(exception, "Request to {uri} failed, uuid is {uuid}.", uri, uuid);

%s 这个看了就头疼,不知道当初谁设计的这 api 写法

你可以看下反编译的代码,事实上 字符串模板不仅写着舒服,性能还算是任何语言最高的字符串拼接做法。在很老的版本做法简单本质就是,string.format("{} aa{}", uri, uuid)这样。而较新版本已经做到没有任何一次额外的临时分配了。

不明白。俩花括号怎么输出三个变量呢?

#22 第三个是 print 了 stacktrace ,上面有人贴了源码,throwable ,源码里用的 object... 对象数组的

%s,%d,%l ,这些不是通用的 format 占位符吗?

#1 #2 #4 Slf4j 没有这种重载方式。 #11 Log4j 的实现,不能代表 Slf4j 的接口定义,除非你明确用得是 Log4j 不是 Slf4j 事实上来说,没有比楼主原来那个语句更优雅的了。当然,如果再极限追求性能,还是得改成 if(log.isErrorEnable()){ log.error ....}

代码怎么写不重要,因为你看的是日志,不是打印日志的代码,我习惯是每个链路加一个跟踪号。排查起来简单。

补充一下,Slf4j void error(String var1, Throwable var2); 会自动格式化,输出堆栈信息,log.error("aa:{},bb{},id,data,e" 就可以了。当然你不确定你的日志框架是啥,可以自己写个 utils 。还是上边那句话,怎么写不重要。你就+拼问题也不大。保证日志输出标准,是给人看的就可以了。