• 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. 在logbacb的配置文件中加上配置上这个类

    <configuration>
        ……
        <conversionRule conversionWord="m" converterClass="com.hollis.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

  • 相关阅读:
    C# DataConstruct 数据结构关于 Array,ArrayList,List,HashTable,Dictionnary的学习记录
    Moq 在.net Core 单元测试中的使用
    记录一些 APM 仓储
    .net core Swagger 过滤部分Api
    C# Conversion Keywords
    (转载)C# 枚举 FlagsAttribute用法
    [慢更]Sublime Text 快捷键及使用过的插件
    Docker发布程序那些事
    RabbitMQ 学习日记
    Linux Tomcat7.0安装配置实践总结
  • 原文地址:https://www.cnblogs.com/huanshilang/p/11983679.html
Copyright © 2020-2023  润新知