Logback日志格式优化,解决输出***@2b193f2d问题
原文出处:Java之道
原文地址:http://www.hollischuang.com/archives/3689
我们在开发的时候,经常要打印日志,有的时候会在一些代码的关键节点处进行日志输出。使用logback/log4j等原生的日志框架,在日志输出的时候可能会遇到一个问题,那就是经常我们要打印对象的时候,如以下代码:
log.info("req = {}", aRequest);
打印结果却是以下形式:
req = com.hollis.java.ways.ApplyRequest@39ddf169
其实原因比较简单,那就是要打印的对象没有重写toString方法,这样无法将该对象的参数打印出来。
所以,为了可以把对象的值都打印出来,我们一般要求对于自己定义的入参、出参等定义toString方法。但是有些时候,我们使用的是外部定义的request和response对象,他们并没有覆盖toString,当对这些对象打印的时候,就会出现以上问题。
一般简单的解决办法是,可以通过JSON把对象转成String,如:
log.info("req = {}", JSON.toJSONString(aRequest));
日志输出:
req = {"name":"Hollis","wechat":"hollischuang","javaways":"Java之道"}
但是,这样的话,就需要在每一个日志记录的地方人为的要处理下,很不高效,而且也容易遗忘。作为程序员,要想办法干掉这种手动操作,有一个好的办法,可以一劳永逸:借助logback(log4j也有类似的功能)的MessageConverter。无侵入性的解决这个问题
1. 定义一个MessageConverter
public class ArgumentJsonFormatLayout extends MessageConverter { @Override public String convert(ILoggingEvent event) { try { return MessageFormatter.arrayFormat(event.getMessage(), Stream.of(event.getArgumentArray()) .map(JSON::toJSONString).toArray()).getMessage(); } catch (Exception e) { return event.getMessage(); } } }
上面这段代码,会把所有的需要打印的内容全部JSON格式化,但如果遇到已经格式化的JSON,或者String类型的内容,打印日志时,会多一层双引号,所以下面做了优化。
public class LogJsonConverter extends MessageConverter { @Override public String convert(ILoggingEvent event) { try { Object[] objects = Stream.of(event.getArgumentArray()).map(t -> { String str; if (t instanceof String) { // String类型直接打印 str = t.toString(); } else { str = JSON.toJSONString(t); } return str; }).toArray(); return MessageFormatter.arrayFormat(event.getMessage(), objects).getMessage(); } catch (Exception e) { return event.getMessage(); } } }
2. 在logback的配置文件中加上配置上这个类
<configuration> …… <conversionRule conversionWord="m" converterClass="com.ha.java.ways.ArgumentJsonFormatLayout"/> …… </configuration>
注意:conversionWord里的值m不是随便写的,要和logback里的日志输出格式里的信息参数相同。比如:
[%-5level] [%d{yyyy-MM-dd HH:mm:ss.SSS}] [%t] [%logger.%method:%line] -- %m%n
补充:我在查阅网上资料时,发现很多金融、电商项目会用这个类实现对用户名、密码、交易密码等信息的脱敏处理,也很方便,不过实现逻辑比较复杂,大家可以自己查阅。
补充资料:
https://www.jianshu.com/p/ade8b7c220df
https://blog.csdn.net/fywfengyanwei/article/details/78484590
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通