• 【转载】structlog4j介绍


    源文章:structlog4j介绍

    结构化日志对于日志的收集的作用挺大的,根据自身的业务场景,基于SLF4J实现了structlog4j

    相关引用

    Gradle

    // 基础包
    compile 'tech.ibit:structlog4j-api:latest'
    
    // 支持json, yaml格式等扩展
    compile 'tech.ibit:structlog4j-extend:latest'
    
    

    Maven

    <!--基础包-->
    <dependency>
        <groupId>tech.ibit</groupId>
        <artifactId>structlog4j-api</artifactId>
        <version>latest</version>
    </dependency>
        
    <!--扩展包-->
    <dependency>
        <groupId>tech.ibit</groupId>
        <artifactId>structlog4j-extend</artifactId>
        <version>latest</version>
    </dependency>
    

    概述

    structlog4j的核心思想就是将日志已key-value的方式呈现,方便日期切分。

    日志保留字段

    _message: 消息内容
    _errorMessage: 异常信息
    _stackTrace: 异常stack trace信息
    

    引入logger

    import tech.ibit.structlog4j.Logger;
    import tech.ibit.structlog4j.StructLoggerFactory;
    private static final Logger log = StructLoggerFactory.getLogger(Test.class);
    

    字符串处理

    业务需要,将日志单行输入,所以对以下字符进行了处理, ":"前原字符串,":" 后的是处理后的字符

    	: \t
    
    : \r
    
    : \n
    

    默认日志格式(key-value)

    _message=Something error!&user=ibit-tech_errorMessage=Test Exception
    

    说明

    • 默认方式引入structlog4j-api即可
    • key-value的方式通过&进行分割,将&转为'%26'

    json日志格式

    {"_message":"Something error!","user":"ibit-tech","_errorMessage":"Test Exception"}
    

    修改全局formatter方法

    方法1(java代码):
    StructLog4J.setFormatter(JsonFormatter.getInstance());
    
    方法2(classpath:/structlog4j.properties):
    formatter=tech.ibit.structlog4j.extend.JsonFormatter#getInstance
    

    说明

    • 需要引入structlog4j-extend
    • "#"后面为获取实例方法

    yaml日志格式

    hostname: localhost
    ip: 127.0.0.1
    

    修改全局formatter方法

    方法1(java代码):
    StructLog4J.setFormatter(YamlFormatter.getInstance());
    
    方法2(classpath:/structlog4j.properties):
    formatter=tech.ibit.structlog4j.extend.YamlFormatter#getInstance
    

    说明

    • 需要引入structlog4j-extend
    • " ":表示换行符号,读取到日志之后,需要将" "转为" "才能正确显示
    • "#"后面为获取实例方法

    自定义日志格式

    实现tech.ibit.structlog4j.Formatter#format方法即可

    tech.ibit.structlog4j.Formatter {
        /**
         * 格式化(待实现)
         *
         * @param kvMap 兼职map
         * @return 格式化后的文本
         */
        String format(Map<String, ?> kvMap);
    }
    

    异常信息处理

    • 默认方式,StructLog4J.isTransStackTrace() == true, 日志中会出现_errorMessage_stackTrace字段,_stackTrace进行了转义,单行显示
    • StructLog4J.isTransStackTrace() == false, 日志中只出现_errorMessage,然后之后就将异常信息在接下来的日志打印出来(多行)

    eg:

    # 单行打印stackTrace
    _message=Something error&user=ibit-tech&_errorMessage=Test Exception&_stackTrace=java.lang.RuntimeException: Test Exception
    	at tech.ibit.demo.structlog4j.Demo.main(Demo.java:32)
    
    
    # 多行打印stackTrace
    _message=Something error&user=ibit-tech&_errorMessage=Test Exception
    java.lang.RuntimeException: Test Exception
    	at tech.ibit.demo.structlog4j.Demo.main(Demo.java:33)
    

    修改全局transStackTrace方法

    方法1(java代码):
    StructLog4J.setTransStackTrace(true|false);
    
    方法2(classpath:/structlog4j.properties):
    transStackTrace=true|false
    

    structlog4j.properties说明:

    # 指定formatter 创建方式(工厂方法)
    formatter=tech.ibit.structlog4j.extend.JsonFormatter#getInstance
    
    # 指定异常的stackTrace日志是否需要转化
    transStackTrace=true
    

    用法

    _message说明(以error为例子)

    Logger存在一下方法支持error级别日志

    /**
     * ERROR日志
     *
     * @param message 消息
     * @param params  参数
     */
    void error(String message, Object... params);
    
    
    /**
     * ERROR日志
     *
     * @param messages 消息片段
     * @param params   参数
     */
    void error(Object[] messages, Object... params);
    

    其中message和messages的区别在于,messages支持传入占位符,eg:

    logger.error("Something error, id: 12, username: ibit-tech");
    
    等价于:
    
    logger.error(new Object[] {"Something error, id: {}, username: {}", 12, "ibit-tech"});
    

    使用key-value的方式

    log.error("Something error", "user", "ibit-tech", "age", 100);
    

    实现ToLog对key-value进行包装

    log.error("Something error", (ToLog) () -> new Object[] {"user", "ibit-tech", "age", 101});
    

    异常处理

    log.error("Something error", "user", "ibit-tech", "age", 100, new RuntimeException("Test Exception"));
    

    混合使用

    log.error("Something error", (ToLog) () -> new Object[] {"user", "ibit-tech"}, "age", 101);
    
    log.error("Something error", (ToLog) () -> new Object[] {"user", "ibit-tech"}, "age", 101, (ToLog) () -> new Object[] {"city", "sz"}, new RuntimeException("Test Exception"));
    

    POJO实现MapToLog,toLog()会返回POJO中所有字段

    @Test
    public void toLog() {
        User user = new User("ibit-tech", 21);
        Assert.assertEquals("[name, ibit-tech, age, 21]", Arrays.asList(user.toLog()).toString());
    }
    	
    @Value
    public class User implements MapToLog {
        private String name;
        private int age;
    }
    

    说明

    • 需要引入structlog4j-extend

    License

    Apache License 2.0

  • 相关阅读:
    centos8下安装Dlib
    如何在CentOS7上安装桌面环境
    PIL、Pillow安装使用方法
    Linux -ls-列出文件的详细信息
    ValueError: Object arrays cannot be loaded when allow_pickle=False
    AttributeError: module 'keras.backend' has no attribute 'set_image_dim_ordering'
    CentOS安装CMake
    ValueError: Object arrays cannot be loaded when allow_pickle=False
    Keras requires TensorFlow 2.2 or higher
    importError: libSM.so.6: cannot open shared object file: No such file or directory
  • 原文地址:https://www.cnblogs.com/javaDeveloper/p/11983001.html
Copyright © 2020-2023  润新知