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

3 篇文章 0 订阅

一、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");
    }
}
参考
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");
    }
}
参考
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");
    }
}
参考
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");
    }
}
参考

三、日志打印规范

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

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 结合使用。另外为了规范日志打印,简述了一种日志打印规范设计方式,有兴趣同学可以实现下做一个简单小工具。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在GLib中,可以使用`g_log()`函数来打印日志。`g_log()`函数的原型如下: ```c void g_log(const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, ...); ``` 其中,`log_domain`参数指定日志的域名,`log_level`参数指定日志的级别,`format`参数指定日志的格式,后面可以跟上可变参数列表。 GLib定义了五个日志级别: - `G_LOG_LEVEL_ERROR`:错误级别 - `G_LOG_LEVEL_CRITICAL`:严重级别 - `G_LOG_LEVEL_WARNING`:警告级别 - `G_LOG_LEVEL_MESSAGE`:消息级别 - `G_LOG_LEVEL_INFO`:信息级别 - `G_LOG_LEVEL_DEBUG`:调试级别 默认情况下,只有等于或高于`G_LOG_LEVEL_WARNING`级别的日志才会被输出。可以通过`g_log_set_handler()`函数来改变日志输出的行为。例如,可以使用以下代码将日志输出到控制台: ```c #include <glib.h> void my_log_handler(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) { g_print("%s: %s\n", log_domain, message); } int main(void) { g_log_set_handler(NULL, G_LOG_LEVEL_MASK, my_log_handler, NULL); g_log(NULL, G_LOG_LEVEL_INFO, "Hello, world!"); return 0; } ``` 上面的代码中,`g_log_set_handler()`函数指定了一个新的日志处理函数`my_log_handler`。该函数将日志输出到控制台。然后,使用`g_log()`函数输出一条日志。由于日志级别为`G_LOG_LEVEL_INFO`,因此该日志将被输出到控制台中。 除了上述示例中的`g_print()`函数外,也可以使用其他输出函数来输出日志,例如`printf()`函数、`fprintf()`函数等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bboyzqh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值