java?志体系

发布时间:2024年01月08日

本篇在jdk21下测试通过

1.体系概述

在这里插入图片描述
1.日志接口

  • JCL:Apache基?会所属的项?,是?套Java?志接?,之前叫Jakarta Commons Logging,后更名为Commons Logging,简称JCL
  • SLF4J:Simple Logging Facade for Java,缩写Slf4j,是?套简易Java?志??,只提供相关接?,和其他?志?具之间需要桥接

2.?志实现

  • JUL:JDK中的?志?具,也称为jdklog、jdk-logging,?Java1.4以来sun的官?提供
  • Log4j:?属于Apache基?会的?套?志框架,现已不再维护
  • Log4j2:Log4j的升级版本,与Log4j变化很?,不兼容
  • Logback:?个具体的?志实现框架,和Slf4j是同?个作者,性能很好

2.日志的使用

1.上古时代的sout

在JDK 1.3及以前,Java打?志依赖System.out.println(), System.err.println()或者
e.printStackTrace(),Debug?志被写到STDOUT流,错误?志被写到STDERR流。这样打?志有?个?常?的缺陷,?常机械,?法定制,且?志粒度不够细分

System.out.println("123");
System.err.println("456");

2.开创先驱的log4j

注意了:这里案例采用的是log4j2的写法

2001年发布了Log4j,并将其捐献给了Apache软件基?会,成为Apache 基?会的顶级项?。Log4j 在设计上?常优秀,它定义的Logger、Appender、Level等概念对后续的 Java Log 框架有深远的影响,如今的很多?志框架基本沿?了这种思想

1.导入坐标

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.22.1</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.22.1</version>
</dependency>

2.编写配置文件 log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
        <File name="MyFile" fileName="logs/app.log">
            <PatternLayout>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %c{1} - %msg%n</pattern>
            </PatternLayout>
        </File>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="MyFile"/>
        </Root>
    </Loggers>
</Configuration>

3.测试类

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class MyLog4j {
    private static final Logger logger = LogManager.getLogger(MyLog4j.class);

    public static void main(String[] args) {
        int i = 1;
        String msg = "测试";
        String s = null;
        // 记录不同级别的日志
        logger.debug("Debug message:{},{},{}", i, msg, s);
        logger.info("Info message:{},{},{}", i, msg, s);
        logger.warn("Warning message:{},{},{}", i, msg, s);
        logger.error("Error message:{},{},{}", i, msg, s);
        logger.fatal("Fatal error message:{},{},{}", i, msg, s);
    }
}

3.搞事情的JUL

sun公司对于log4j的出现内?隐隐表示嫉妒。于是在jdk1.4版本后,开始搞事情,增加了?个包为java.util.logging,简称为JUL,?以对抗log4j ,但是却给开发造成了麻烦。相互引?的项?之间可能使?了不同的?志框架,经常将代码搞得??混乱

import java.util.logging.Logger;

public class MyJul {
    static Logger logger = Logger.getLogger(MyJul.class.getName());

    public static void main(String[] args) {
        int i = 1;
        String msg = "测试";
        String s = null;
        logger.info( "Info message  :"  + i + " " + "s" + " " + msg);  
    }
}

4.应运??的JCL

从上?可以看出,JUL的api与log4j是完全不同的(参数只接受String)。由于?志系统互相没有关联,彼此没有约定,不同?的代码使?不同?志,替换和统?也就变成了?较棘?的?件事。假如你的应?使?log4j,然后项?引?了?个其他团队的库,他们使?了JUL,你的应?就得使?两个?志系统了,然后其他团队?使?了simplelog……这个时候如果要调整?志的输出级别,?于跟踪某个信息,简直就是?场灾难
  那这个状况该如何解决呢?答案就是进?抽象,抽象出?个接?层,对每个?志实现都适配或者转接,这样这些提供给别?的库都直接使?抽象层即可 ,以后调?的时候,就调?这些接?。(?向接?思想)
  于是,JCL(Jakarta Commons Logging)应运??,也就是commons-logging-xx.jar组件。JCL 只提供 log 接?,具体的实现则在运?时动态寻找。这样?来组件开发者只需要针对 JCL 接?开发,?调?组件的应?程序则可以在运?时搭配??喜好的?志实践?具

1.导入坐标

<dependency>
   <groupId>commons-logging</groupId>
   <artifactId>commons-logging</artifactId>
   <version>1.3.0</version>
</dependency>

2.测试代码

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class MyJul {
    private  static Log logger = LogFactory.getLog(MyJul.class);

    public static void main(String[] args) {
        int i = 1;
        String msg = "测试";
        String s = null;
        logger.info( "Info message  :" + i + " " + "s" + " " + msg);
        logger.debug("Debug message :" + i + " " + "s" + " " + msg);
        logger.fatal("Fatal message :" + i + " " + "s" + " " + msg);
        logger.error("Error message :" + i + " " + "s" + " " + msg);
    }

}

5.再起波澜的logback

针对以上情况,log4j的作者再次出?,他觉得JCL不好?,???写了?个新的接?api,就是slf4j,并且为了追求更极致的性能,新增了?套?志的实现,就是logback,?时间烽烟?起……

1.导入坐标

 <dependency>
     <groupId>org.slf4j</groupId>
     <artifactId>slf4j-api</artifactId>
     <version>2.0.10</version>
 </dependency>

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

2.编写配置文件logback.xml

<configuration>

    <!-- 定义日志输出格式 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>[%-5level] [%date{yyyy-MM-dd HH:mm:ss.SSS}] %logger{96} [%line] [%thread]- %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 定义日志文件输出 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logs/app.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 按天滚动,每天生成一个新的日志文件 -->
            <fileNamePattern>logs/app.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 文件保留策略,只保留最近30天的日志文件 -->
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 设置全局日志级别 -->
    <root level="debug">
        <!-- 将控制台和文件Appender关联到根Logger -->
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILE" />
    </root>

    <!-- 针对特定包或类设置不同的日志级别 -->
    <!-- <logger name="com.andy.log.logback.*" level="debug" /> -->

</configuration>

3.测试代码

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyLogback {

    static final  Logger logger = LoggerFactory.getLogger(MyLogback.class);

    public static void main(String[] args) {
        int i = 1;
        String msg = "测试";
        String s = null;
        // 记录不同级别的日志
        logger.debug("Debug message:{}:{}:{}", i, msg, s);
        logger.info("Info message:{}:{}:{}", i, msg, s);
        logger.warn("Warning message:{},{},{}", i, msg, s);
        logger.error("Error message:{}:{}:{}", i, msg, s);
    }
}

6.再度?春的log4j2

请参考 “开创先驱的log4j” 的写法

log4j2以性能著称,它?其前身Log4j 1.x提供了重?改进,同时类?logback,它提供了Logback中可?的许多改进,同时修复了Logback架构中的?些固有问题。功能上,它有着和Logback相同的基本操作,同时?有??独特的部分,?如:插件式结构、配置?件优化、异步?志等


到log4j2,轰轰烈烈的java log战役基本就结束了


文章来源:https://blog.csdn.net/weixin_44702984/article/details/135457258
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。