常见日志框架使用及日志打印规范设计

news2024/11/17 20:18:33

文章目录

      • 一、slf4j 简介
      • 二、常用日志框架
        • 1)log4j
          • pom 依赖
          • log4j.properties 文件配置
          • 测试
          • 参考
        • 2)logback
          • pom 依赖
          • logback.xml 配置
          • 测试
          • 参考
        • 3) java.util.logging
        • 4)commons logging
          • pom 依赖
          • 配置
          • 测试
          • 参考
        • 5)slf4j-simple
          • pom 依赖
          • simplelogger.properties
          • 测试
          • 参考
      • 三、日志打印规范
        • 核心 UML 设计
          • 1)Logger 模块
          • 2)业务打印内容 Schema 模块
          • 3)日志打印器模块
        • 日志打印示例
      • 四、总结

一、slf4j 简介

​ slf4j,全称 Simple Logging Facade for Java,是一个开源项目,对各种日志框架的进行 facade 抽象,允许最终用户在部署时插入所需的日志框架。slf4j 为不同的日志框架提供了不同的绑定,下图所示(图来自于 slf4j 官网:https://www.slf4j.org/manual.html):
在这里插入图片描述

上图包含了很多信息,简要介绍下:

  • SLF4J unbound: slf4j 提供了未绑定任何日志框架 slf4j-api.jar,该 jar 单纯定义了抽象日志 api
  • SLF4J bound to logback-classic: logback 项目提供了slf4j API 的实现 logback-classic.jar,使用 logback 还需要logback-core.jar
  • SLF4J bound to log4j: 图中 slf4j-log412.jar 是绑定了 1.2 版本的 log4j 日志框架,核心实现在 log4j.jar 中,所以使用 log4j 框架要引入 log4j.jar
  • SLF4J bound to java.util.logging: 用来绑定 jdk 提供的 logger 日志框架 java.util.logging(常被称为jdk1.4 logging),不需要额外依赖其他 jar 包
  • SLF4J bound to simple:绑定的日志框架 slf4j-simple,slf4j 提供的简单实现
  • SLF4J bound to no-operation: 绑定的日志框架为不执行任何操作

二、常用日志框架

​ 以下简单介绍一下 log4j、logback、 java.util.logging、commons logging 和 slf4j-simple 的使用方式,关系如下图:

在这里插入图片描述

slf4j 是各种日志框架的 facade 抽象,log4j、logback、java.util.logging 是 slf4j 不同的实现方式,另外 slf4j-simple 是 slf4j 提供的简单实现。commons-logging 和 slf4j 类似,是 apache 最早提供的日志的门面接口,log4j 和 java.util.logging 也提供了相应的实现方式。

1)log4j

log4j 是 Apache 的一个开源项目,代码中有两个示例模块(配置类似)供参考:slf4j-log4j12 和单纯使用 log4j。下面示例代码以 slf4j-log4j12 为例:
在这里插入图片描述

pom 依赖
<!--     slf4j-log4j12       -->
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-log4j12</artifactId>
  <version>${slf4j-log4j12.version}</version>
</dependency>
log4j.properties 文件配置
# 日志级别配置
log4j.rootLogger=DEBUG,Console

# 控制台输出
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
测试
import org.apache.log4j.Logger;
public class TestSlf4jLog4J {
    public static void main(String[] args) {
        Logger logger = Logger.getLogger(TestSlf4jLog4J.class);
        logger.info("this is info");
        logger.warn("this is warn");
        logger.error("this is error");
        logger.fatal("this is fatal");
    }
}
参考
  • Log4J 官网:https://logging.apache.org/
  • 示例代码 github:https://github.com/zhuqiuhui/log-demo

2)logback

logback 也是由 log4j 的作者设计完成的,拥有更好的特性,用来取代 log4j 的一个日志框架,实现了简单日志门面 slf4j。其中 logback-core 是其它模块的基础设施,其它模块基于它构建。使用示例工程如下:

pom 依赖
<!--注意:这里需要注意要选择合适的版本:jdk、slf4j-api、logback -->
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
</dependency>

<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-core</artifactId>
</dependency>

<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
</dependency>
logback.xml 配置
    <!-- 输出到控制台 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender" >
        <!-- 输出的格式 -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:  %msg%n</pattern>
        </encoder>
    </appender>
  
    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
测试
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TestLogback {
    public static void main(String[] args) {
        Logger logger = LoggerFactory.getLogger(TestLogback.class);
        logger.trace("this is trace");
        logger.debug("this is debug");
        logger.info("this is info");
        logger.warn("this is warn");
        logger.error("this is error");
    }
}
参考
  • 官网:https://logback.qos.ch/
  • logback github 开源代码:https://github.com/qos-ch/logback
  • 示例代码 github:https://github.com/zhuqiuhui/log-demo

3) java.util.logging

java.util.logging 是 jdk 1.4 自带的 logger,使用直接按 api 介绍来即可,易上手(使用 slf4j-jdk 框架的详细参考 github 示例代码):

import java.util.logging.Logger;
public class TestLogging {
    public static void main(String[] args) {
        Logger logger = Logger.getLogger("TestLogging");
        logger.severe("this is severe"); // 严重
        logger.info("this is info");
        logger.warning("this is warn");
        logger.config("this is config");
        logger.fine("this is fine");
        //......
    }
}

4)commons logging

Jakarta Commons-logging(JCL)是 apache 最早提供的日志的门面接口,提供简单的日志实现以及日志解耦功能。JCL 能够选择使用 Log4j 还是 JDK Logging,以使用 Log4j 示例如下:

pom 依赖
<dependency>
  <groupId>commons-logging</groupId>
  <artifactId>commons-logging</artifactId>
</dependency>

<dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
</dependency>
配置
  • commons-logging.properties
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger
  • log4j.properties
# 日志级别配置
log4j.rootLogger=DEBUG,Console

# 控制台输出
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
测试
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class TestCommonLogging {
    public static void main(String[] args) {
        Log logger = LogFactory.getLog(TestCommonLogging.class);
        logger.info("this is info");
        logger.warn("this is warn");
        logger.error("this is error");
        logger.fatal("this is fatal");
    }
}
参考
  • commons-logging github 开源代码:https://github.com/apache/commons-logging
  • 示例代码 github:https://github.com/zhuqiuhui/log-demo

5)slf4j-simple

slf4j-simple 是 slf4j 提供的简单实现,使用示例如下:

pom 依赖
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-simple</artifactId>
</dependency>
simplelogger.properties
org.slf4j.simpleLogger.showDateTime = true
org.slf4j.simpleLogger.dateTimeFormat = HH:mm:ss:SSSS
org.slf4j.simpleLogger.defaultLogLevel = warn
测试
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TestSlf4jSimple {
    public static void main(String[] args) {
        // 生成 SimpleLogger 实例
        Logger logger = LoggerFactory.getLogger(TestSlf4jSimple.class);
        logger.info("this is info");
        logger.warn("this is warn");
        logger.error("this is error");
        logger.debug("this is debug");
    }
}
参考
  • 示例代码 github:https://github.com/zhuqiuhui/log-demo

三、日志打印规范

在工程中经常会出现日志随意打印的现象,比如:

log.info("[TestServiceImpl-apply] request:{}", JSON.toJSONString(request));
log.info("success")
//......

如果要使用日志做数据分析,则很难提取到规整的数据,以下提供一种思路来规范日志打印,达到格式化输出。

核心 UML 设计

在这里插入图片描述

上述是日志规范的一个 uml 图示例,可围绕以下几点来设计:

1)Logger 模块
  • 日志按业务 module 和 subModule 进行分类

    日志打印中可按照 moduleName 和 subModuleName 拆分不同的业务子文件夹做日志分类,其中模块日志属性配置(如模块名称、日志级别、是否需要结构化等)可使用 Spring 注解 @EnableConfigurationProperties 做成文件配置形式,达到 Spring 启动时自动生成各模块日志文件夹,配置简要示例如下:

logging.business[0].moduleName=student
logging.business[0].subModuleName=biz,error
logging.business[0].level=info
  • Logger 实例创建

    Spring Boot 启动时可使用 logback api 来自动创建 Logger 实例存放到 LoggerContext 中,同时并创建各 module 下的文件夹,代码可通过如下方式来获取 Logger 实例:

BusinessLogger businessLogger = BusinessLogger.getLogger("student", "query");

而 BusinessLogger 是从 LoggerContext 来获取的:

public static BusinessLogger getLogger(String moduleName, String subModuleName) {
  return new BusinessLogger(LoggerFactory.getLogger(PREFIX + moduleName + "-" + subModuleName));
}
2)业务打印内容 Schema 模块

业务打印内容通常包括以下内容:

  • bizCode
  • 异常
  • message
  • 自定义 key,如 traceId、rt、userId 等
3)日志打印器模块

日志打印器的职责是负责将业务打印内容 Schema 按指定分隔符拼接成一个长的字符串,最终将能 Logger 实例来打印。

日志打印示例

在这里插入图片描述

四、总结

​ 上述几种日志框架中使用比较广泛的是 log4j 和 logback,而 logback 整体性能比 log4j 更好,建议选择 slf4j 和 logback 结合使用。另外为了规范日志打印,简述了一种日志打印规范设计方式,有兴趣同学可以实现下做一个简单小工具。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/107484.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MFC UI控件相关

文章目录UI控件相关CDialog::OnInitDialog() 对话框初始化手动添加UpdateData() 刷新窗口数据DoDataExchange()数据与控件动态绑定afx_msg: 声明一个消息响应函数void AFXAPI DDX_Control( CDataExchange* pDX, int nIDC, CWnd& rControl );DDV_MaxChars()UI控件相关 CDia…

20天学会Rust第一天之Helloword

阿sir今天开始学习Rust了&#xff0c;至于为什么学习呢&#xff1f; 以后再说 我们都知道&#xff0c;程序设计 数据结构 算法。 因此&#xff0c;我们依次学习Rust中数据结构的定义&算法的实现&#xff0c;然后用它们实现一个简单的“hello world” 数据结构 Rust提供…

什么是IoC和AOP

IoC是什么&#xff1f; 控制反转&#xff1a;面向对象的设计的理念。上层建筑依赖下层建筑 理解&#xff1a;行李箱设计 轮子 --> 底盘 --> 箱体 --> 行李箱 如果改动轮子&#xff0c;则底盘、箱体、行李箱都需要进行调整。 依赖注入&#xff1a;将底层类作为参数…

Spring之底层架构核心概念-BeanFactory 与ApplicationContext

目录1.BeanFactory2.ApplicationContext3.关系4.总结1.BeanFactory BeanFactory是一个接口 public interface BeanFactory {xxx... }2.ApplicationContext ApplicationContext 也是一个接口&#xff0c;继承自ListableBeanFactory, HierarchicalBeanFactory public interfa…

非零基础自学Golang 第15章 Go命令行工具 15.2 代码获取(get) 15.3 格式化代码(fmt)

非零基础自学Golang 文章目录非零基础自学Golang第15章 Go命令行工具15.2 代码获取(get)15.3 格式化代码(fmt)第15章 Go命令行工具 15.2 代码获取(get) go get命令用于从远程仓库中下载安装远程代码包&#xff0c;这是我们常用且非常重要的指令。 我们在开发程序时往往需要引…

Gateway网关-网关作用介绍

为什么需要网关&#xff1f; 如果允许任何人访问微服务&#xff0c;查看我们的敏感业务&#xff0c;这样数据是不是不安全。如果是我们的工作人员并且有相应的查看权限&#xff0c;我们才提供访问权限。那谁来做这件事呢&#xff1f;就是我们的网关。 网关的功能作用 1&#xf…

鼎镁科技冲刺上交所:年营收18亿 拟募资13亿

雷递网 雷建平 12月21日鼎镁新材料科技股份有限公司&#xff08;简称&#xff1a;“鼎镁科技”&#xff09;日前递交招股书&#xff0c;准备在上交所主板上市。鼎镁科技计划募资12.86亿元。其中&#xff0c;8.84亿元用于轻量化新材料生产、研发建设项目&#xff0c;2.53亿元用于…

消息号F5155处理办法

消息号F5155&#xff08;没有公司代码XDJT中买卖双方的资金权限&#xff09;处理办法 OBA4先检查用户的FI容差组 OB57查看分配用户给容差组&#xff0c;确认是否书写正确的容差组。

《疫情下的编程岁月》序言导读目录

导读 《疫情下的编程岁月》是一部为初学者编写的编程指南&#xff0c;作者是一名 13 岁的编程学习者和优质技术博主。在这部指南中&#xff0c;作者分享了自己在过去 5 年里学习编程技术的经历&#xff0c;并提供了宝贵的建议和技巧&#xff0c;帮助初学者更好地了解编程学习的…

math@间断点@微积分基本定理@变限积分求导公式

文章目录间断点第一类间断点跳跃间断点可去间断点例第二类间断点微积分定理第一基本定理变上限积分函数的导数定积分的角度原函数存在定理&#x1f60a;应用例例微积分第二基本定理变限积分求导公式例math间断点微积分基本定理变限积分的求导公式 间断点 第一类间断点 跳跃间…

SwiftUI开源库之 什么是 Lottie?Airbnb 的跨平台开源库,用于渲染矢量运动图形

什么是 Lottie Lottie是 Airbnb 的跨平台开源库,用于渲染矢量运动图形。我们在 Airbnb 广泛使用 Lottie,它还为整个行业的数千个其他应用程序中的动画提供支持。 发布了适用于 iOS 的Lottie 4.0 。这个主要的新版本通过由 Core Animation 提供支持的全新渲染引擎,为所有 L…

Flutter开发:仿iOS侧滑删除效果的实现

前言 在Flutter开发中&#xff0c;基于原生移动端开发的思想也会运用到混合开发中&#xff0c;尤其是原生移动的的好的特性和交互效果更是如此。在现在的发展情况下&#xff0c;Flutter下的混合开发已经越来越替代原生移动的开发&#xff0c;同时也会继承原生开发的优点&#x…

5年Java经验,定级阿里P7,所有经验全在这份Java核心知识笔记里了

前言 今年的大环境非常差&#xff0c;互联网企业裁员的现象比往年更严重了&#xff0c;可今年刚好是我的第一个“五年计划”截止的时间点&#xff0c;说什么也不能够耽搁了&#xff0c;所以早早准备的跳槽也在疫情好转之后开始进行了。但是&#xff0c;不得不说&#xff0c;这次…

编译和使用hadoop遇到的问题——问题随手记【持续更新】

文章目录编译hadoop遇到的问题java.lang.NoClassDefFoundError: org/apache/hadoop/util/PlatformNamejava.lang.ClassNotFoundException: org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos\$MasterService\$BlockingInterfacejava.lang.ClassNotFoundExceptio…

坚持长期主义 上汽大众ID.纯电品牌迎来加速发展阶段

那些真正能够引领行业发展和变革&#xff0c;并能够持续存活下去的企业&#xff0c;一定是以长期主义作为导向的。 2022年11月&#xff0c;上汽大众ID.纯电家族以月销近万辆、累计销量超10万辆的数据&#xff0c;演绎了一个坚持长期主义汽车大厂的“英雄本色”。长期主义是对抗…

R语言LME4混合效应模型研究教师的受欢迎程度

介绍 最近我们被客户要求撰写关于混合效应模型的研究报告&#xff0c;包括一些图形和统计输出。本教程对多层回归模型进行了基本介绍 。 相关视频&#xff1a;线性混合效应模型(LMM,Linear Mixed Models)和R语言实现 线性混合效应模型(LMM,Linear Mixed Models)和R语言实现…

结构化思维的理解与思考

结构化思维是一种将信息要素从无效转化为有序&#xff0c;提炼核心要点&#xff0c;将信息转化为有结构的知识&#xff0c;更好的帮助大脑理解和记忆&#xff0c;并支持我们清晰表达的通用能力。前言首先&#xff0c;我们先来完成一个游戏&#xff0c;以下有9个计算式&#xff…

微服务应用视角解读如何选择K8S的弹性策略

前言 微服务架构的出现&#xff0c;拆分了庞大的单体应用&#xff0c;让业务之间的开发与协作变得更加灵活。当面临业务流量增加的场景时&#xff0c;往往需要对一些应用组件进行扩容。K8S在应用层面提供了HPA&#xff0c;围绕HPA开源社区延伸出了KEDA这样的弹性组件&#xff…

Compose使用OpenGL+CameraX快速实现相机“拍视频实时滤镜“、”拍照+滤镜“

一、前言 短视频热潮还没有褪去&#xff0c;写这篇文章主要是帮助大部分人&#xff0c;能快速上手实现类似效果&#xff0c;实际上是&#xff1a; CameraX拿相机数据&#xff0c;OpenGL给CameraX提供一个Surface&#xff0c;数据放到OpenGL渲染的线程上去做图像相关操作 Open…