• 轻量级 Java 日志组件


    日志记录功能在开发中很常用,不仅可以记录程序运行的细节,方便调试,也可以记录用户的行为,是框架中不可或缺的组件。为最大程度复用现有的组件,我们就地取材使用了 JDK 自带的 JUL(java.util.logging)作为日志组件,并对其进行功能上的增强。这是笔者 17 年的时候就研究过了(见博客《100 行代码打造日志组件》)。时至今日,感觉还是使用 Slf4J API 的人群多,顺应潮流,决定打造兼容 Slf4J 风格的整合,使用上也更便捷,可结合 Lombok 强大的功能,在类身上施加一个注解即可。

    使用方式

    该组件是笔者框架里的一部分,当然单独拎出来有很简单。笔者的框架依赖:

    <dependency>
        <groupId>com.ajaxjsgroupId>
        <artifactId>ajaxjs-frameworkartifactId>
        <version>1.1.3version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    依赖 Slf4J 到你的工程,或者已经有了就不用依赖(大的概率有,因为整合 Slf4J 很普遍)。当前还是可以 1.7.x 版本的,2.x 版到时再升级。

    <dependency>
        <groupId>org.slf4jgroupId>
        <artifactId>slf4j-apiartifactId>
        <version>1.7.36version>
        <scope>compilescope>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    组件源码在:https://gitee.com/sp42_admin/ajaxjs/tree/master/aj-backend/aj-framework/aj-framework/src/main/java/com/ajaxjs/util/logger

    调用例子

    import lombok.extern.slf4j.Slf4j;
    import org.junit.Test;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    @Slf4j
    public class TestSlf4J {
        @Test
        public void test() {
            Logger logger = LoggerFactory.getLogger(TestSlf4J.class);
            logger.info("Hello World 1");
    
            log.info("Hello World 2");
            log.info("Hello {}, it's {} day.2", "Frank", "good");
            log.info("Hello {}, it's {} day{}2", "Frank", "good", "?");
    
            log.debug("Hello World3");
            log.debug("Hello {}, it's {} day.3", "Frank", "good");
            log.debug("Hello {}, it's {} day{}3", "Frank", "good", "?");
    
            log.warn("Hello {}, it's {} day{}4", "Frank", "good", "?");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    在这里插入图片描述

    功能回顾

    之前组件的要点如下

    在这里插入图片描述

    现在某些地方会根据 Slf4J 有所调整。

    • 参数插值。默认 JUL 就有,是这样子的LOGGER.info("Hello {0}, it's {1} day{2}", "Frank", "good", "?");; Slf4J 的更简单,是 log.info("Hello {}, it's {} day{}", "Frank", "good", "?");,不要求填序号。如下例,是调用 Slf4J 的MessageFormatter.arrayFormat(format, arguments).getMessage()完成。
      在这里插入图片描述
    • 不同颜色的输出日志。这个照旧,要自己封装,Slf4J 不管这个。实质就是加入 ANSI 的颜色代码,哪怕System.out.println()都可以有颜色。值得二提的是:目前新版的 Eclipse/IDEA 都直接支持 ANSI 彩色日志,不需要另外安装插件;推荐一个 SSH 工具 WindTerm,很多 SSH 客户端没彩色效果,它就有。
    • 获取日志所在调用类、行数。这个照旧,要自己封装,Slf4J 不管这个。实质就是调用运行栈的信息了。
    • 另外保存日志文件。这个照旧,还增加适合 ELK 的 JSON 输出。

    具体实现原理可参见博客《100 行代码打造日志组件》,这里不再赘述。

    整合 Slf4J

    最开始的时候,我想少敲点键盘,把原来声明日志的:

    在这里插入图片描述

    通过强大的 Lombok 改为这样的:

    在这里插入图片描述

    其中一个途径是配置 Lombok 自定义日志,但这样涉及 Lombok 的全局配置,比较底层和麻烦,后来就考查这个 Slf4J,发现整合自己的日志组件也不是太麻烦,两者权衡于是就决定采用后者。调用者是无感知的,他只要会 Slf4J 打日志就行。

    通过这几篇文章(官方 JUL 适配)的学习,得知这是一种桥接的方式引入日志组件,过程不算复杂。而且更重要的是,学习了如何静态化去引入配置,这在我设计 JSON 序列化适配就遇到的难题,如何无需复杂配置就可以提供一个 static 门面——看来我要好好学习才是,而且 Slf4J 1.x 和 2.x 的方法又不同,2.x 的 好像是 SPI 去适配第三方日志库。

    增加 ELK 日志输出

    ELK 读取的日志为本地磁盘的一个 JSON 文件,我们只要配置好 JUL 的 Handler 和 Formatter 即可完成。

    • JsonHandler,保存 JSON 日志的处理器
    • JsonFormatter,日志格式转换到 JSON,源码如下。

    在这里插入图片描述

  • 相关阅读:
    单商户商城系统功能拆解17—供应商分类
    CKA、CKAD、CKS、KCNA、CFCD考试
    C++函数总结,看这一篇就够了
    DiffusionDet:Diffusion Model for Object Detection
    Nginx正向代理,反向代理,负载均衡
    django开发个人博客系统
    剑指 Offer 04. 二维数组中的查找
    大数据Hadoop入门之集群的搭建
    Linux系统安装Ruby语言
    Azure DevOps 介绍
  • 原文地址:https://blog.csdn.net/zhangxin09/article/details/134070649