Log In Action
0. 生产环境要关闭 debug 日志,严禁在生产环境打 debug 级别日志
1. trace/debug/info 日志输出采用占位符的方式,禁止使用字符串拼接的方式
说明:logger.debug("=====" + b)
,如果当前的日志级别是 warn,上述日志不会打印,但会执行字符串拼接操作,如果 b 是对象,会调用 b 的 toString()方法,这样会非常浪费系统资源,特别是当 b 是个大对象的时候。
bad case:
log.info("finish import seller" + sellerId)
# 有现成的占位符的方式,不要使用 String.format(),代码复杂
log.info(String.format("group_id=%s",groupId))
good case:
logger.info("modify audit status, noteId: [{}], creativityId: [{}]", noteId, creativity.getId());
个人也不推荐条件输出形式,用这种 if 的方式判断,显然不够优雅
if (logger.isDebugEnabled()) {logger.debug("Processing trade with id:" + id + "and symbol:" + symbol);
}
2. 使用 [] 进行参数变量隔离
这样的格式写法,可读性更好,对于排查问题又帮助。
good case:
logger.info("modify audit status, noteId: [{}], creativityId: [{}]", noteId, creativity.getId())
3. 使用 warn 级别日志记录用户输入参数错误的情况,不要使用 error 级别日志记录此类错误,避免频繁报警
bad case:
log.error("Porch: 创建账号失败:传入参数有误:email={}, name={}", email, name)
good case:
logger.warn("创建单元名称重复,unit_name={}", req.getUnitName())
4. 异常信息应该包含两类信息:案发现场和异常堆栈信息
bad case:
log.error("调用 sellerCenter 服务异常")
good case:
logger.error("RPC 调用 [inventory.multi_get_available] 失败", e);
如果抛出异常,不要记录 error 日志,由上层进行处理
如果既打错误日志,又抛出异常,会导致错误日志的重复打印。
bad case:
try {...} catch (TException e) {logger.error("RPC 调用 [item_center.multi_get_item_union] 失败", e);
throw new IisException(IisResponseCode.ITEM_SYSTEM_ERROR);
}
good case:
try {...} catch (TException e) {throw new IisException(IisResponseCode.ITEM_SYSTEM_ERROR);
}
logback VS log4j2 性能对比
linux:
8 核 2.4Hz
32G 内存
50 个线程,每个线程写 2W 行日志
logback:
100W 行日志总计耗时:7419 ms
100W 行日志总计耗时:7337 ms
100W 行日志总计耗时:7345 ms
100W 行日志总计耗时:7263 ms
100W 行日志总计耗时:7084 ms
log4j2:
100W 行日志总计耗时:3815 ms
100W 行日志总计耗时:3904 ms
100W 行日志总计耗时:3743 ms
100W 行日志总计耗时:3766 ms
100W 行日志总计耗时:3755 ms
总结
未来是 log4j2 的。
原文链接
https://segmentfault.com/a/11…