1
stranchong 2023-10-25 00:12:27 +08:00 5
log.error("Request to {} failed, uuid is {}.", uri, uuid, exception)
========== 这样异常堆栈也能打印出来 |
2
iminto 364 天前 via Android
楼主写法给我看笑了。。。log 本来就有格式化功能,再格式化一次。。
|
3
chendy 364 天前
其实如果是 100% 会打印出来的 log ,就不需要 format 了,直接 + 拼接就行
想优雅点就按照经验先 new 一个长度差不多够用的 StringBuilder 避免扩容 再优雅点就把这个 StringBuilder 扔 ThreadLocal 里缓存住(不一定有性能提升,可能 ThreadLocal 查找的时间都够把字符串拼出来了 另外就是格式问题,楼主目前的格式只考虑给人看没考虑给机器解析,可以考虑调整一下,加一些特殊的分隔符,便于统一处理日志做数据分析和预警之类的 |
5
N9f8Pmek6m8iRWYe 364 天前
竟无语凝噎
|
6
tramm 364 天前
楼主从 C 那边转过来的?
|
7
ZhanLangCN 364 天前 1
uuid 如果是追踪调用链用的话可以存在 MDC, 那日志直接就
|
8
ZhanLangCN 364 天前
log.error("Request to {} failed.", uri, exception)
|
9
workingonescape 364 天前
绷不住了
|
10
qcbf111 364 天前 1
log.error($"Request to {uri} failed, uuid is {uuid}.", exception)
c#真的是越用越先进! |
11
tedzhou1221 364 天前 4
```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); |
12
liaopen123 364 天前 1
log.error(() -> String.format("Request to %s failed, uuid is %s.", uri, uuid), exception);
chatgpt 回答的 |
13
zhongjun96 364 天前 1
|
14
iold 364 天前
不怎么写 Java ,但是 idea 会提示你这写法可以优化吧??
|
17
tedzhou1221 364 天前 1
@iold #14
我使用的 idea 2023.2.2 版本,没有这种提示。 楼主的问题主要是:(个人猜测) 看到 error 接口,以为只有这个才会打印异常堆栈, public void error(String msg, Throwable t); 以为这个接口 public void error(String format, Object... arguments); 没有 Throwable 作为入参,认为不会打印异常堆栈。 包括我以前也是这样认为。同样很多年前也遇到过 log.error 不打印异常堆栈的情况。 |
18
gongxuanzhang 364 天前
是来钓鱼的吗。。。
|
19
kaedei 364 天前
@qcbf111 c#也不要这么写,每一次调用都会有额外的字符串分配。把前面$去掉,log 框架会帮你格式化的
log.error(exception, "Request to {uri} failed, uuid is {uuid}.", uri, uuid); |
20
bk201 364 天前
%s 这个看了就头疼,不知道当初谁设计的这 api 写法
|
21
qcbf111 364 天前
@kaedei 你可以看下反编译的代码,事实上 字符串模板不仅写着舒服,性能还算是任何语言最高的字符串拼接做法。在很老的版本做法简单本质就是,string.format("{} aa{}", uri, uuid)这样。
而较新版本已经做到没有任何一次额外的临时分配了。 |
22
julyclyde 364 天前
@stranchong 不明白。俩花括号怎么输出三个变量呢?
|
23
BaseException 364 天前 via iPhone
@julyclyde #22 第三个是 print 了 stacktrace ,上面有人贴了源码,throwable ,源码里用的 object... 对象数组的
|
25
nothingistrue 364 天前
@stranchong #1
@iminto #2 @cslive #4 Slf4j 没有这种重载方式。 @tedzhou1221 #11 Log4j 的实现,不能代表 Slf4j 的接口定义,除非你明确用得是 Log4j 不是 Slf4j 事实上来说,没有比楼主原来那个语句更优雅的了。当然,如果再极限追求性能,还是得改成 if(log.isErrorEnable()){ log.error ....} |
26
Richared 364 天前
代码怎么写不重要,因为你看的是日志,不是打印日志的代码,我习惯是每个链路加一个跟踪号。排查起来简单。
|
27
Richared 364 天前
@Richared 补充一下,Slf4j void error(String var1, Throwable var2); 会自动格式化,输出堆栈信息,log.error("aa:{},bb{},id,data,e" 就可以了。当然你不确定你的日志框架是啥,可以自己写个 utils 。还是上边那句话,怎么写不重要。你就+拼问题也不大。保证日志输出标准,是给人看的就可以了。
|
28
lleiwang 363 天前
@liaopen123 这 GTP 还怪好嘞,异步打印。。^_^
|