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