java⽇志体系

news2024/9/20 10:37:28

⽇志体系

  • 1.体系概述
  • 2.日志的使用
    • 1.上古时代的sout
    • 2.开创先驱的log4j
    • 3.搞事情的JUL
    • 4.应运⽽⽣的JCL
    • 5.再起波澜的logback
    • 6.再度⻘春的log4j2

本篇在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战役基本就结束了


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

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

相关文章

视频做成二维码查看?多格式视频二维码生成器的使用方法

现在音视频是工作和生活中经常需要使用的一种内容表现形式&#xff0c;很多人都通过这种方式来查看视频内容&#xff0c;比如产品介绍、使用说明、安装教程等。通过一个二维码就可以来承载视频内容&#xff0c;与传统的方式相比拥有更快的内容传播速度&#xff0c;简化用户获取…

[蓝桥杯学习] 线段树

学习blibli 定义 线段树是一种特殊的平衡二叉查找树&#xff0c;使用线段树&#xff0c;可以实现数据的添加、查找和删除。 树的根结点表示了一个完整的单元区间&#xff0c;左右孩子的区间是将父结点的区间进行二分&#xff0c;左右孩子的区间之和&#xff0c;就是他们的根…

三菱plc学习入门(二,三菱plc指令,触点比较,计数器,交替,四则运算,转换数据类型)

今天&#xff0c;进行总结对plc的学习&#xff0c;下面是对plc基础的学习&#xff0c;希望对读者有帮助&#xff0c;欢迎点赞&#xff0c;评论&#xff0c;收藏&#xff01;&#xff01;&#xff01; 目录 触点比较 当数据太大了的时候&#xff08;LDD32位&#xff09; CMP比…

@Transactional注解的一个很容易被忽略的错误用法

Transactional注解的一个很容易被忽略的错误用法 今日审查代码时发现对Transactional注解的一个如下用法&#xff1a; //StockController.javaAutoWired private StockService stockService//商品出库 PostMapping("/product/stock/out-stock") public Boolean pro…

输入输出流、字符字节流、NIO

1、对输入输出流、字符字节流的学习&#xff0c;以之前做的批量下载功能为例 批量下载指的是&#xff0c;将多个文件打包到zip文件中&#xff0c;然后下载该zip文件。 1.1下载网络上的文件 代码参考如下&#xff1a; import java.io.*; import java.net.URL; import java.n…

TS 36.211 V12.0.0-下行(8)-调制和上变频

本文的内容主要涉及TS 36.211&#xff0c;版本是C00&#xff0c;也就是V12.0.0。

2023 年精选:每个 DevOps 团队都应该了解的 5 种微服务设计模式

微服务彻底改变了应用程序开发世界&#xff0c;将大型整体系统分解为更小、更易于管理的组件。这种架构风格的特点是独立、松散耦合的服务&#xff0c;带来了从可扩展性、模块化到更高的灵活性等众多优势。 DevOps 团队如何最好地利用这种方法来实现最高效率&#xff1f;答案在…

小游戏实战丨基于PyGame的贪吃蛇小游戏

文章目录 写在前面PyGame贪吃蛇注意事项系列文章写在后面 写在前面 本期内容&#xff1a;基于pygame的贪吃蛇小游戏 下载地址&#xff1a;https://download.csdn.net/download/m0_68111267/88700188 实验环境 python3.11及以上pycharmpygame 安装pygame的命令&#xff1a;…

【Spring Cloud 】进阶之Config配置中心

目录 config大致的一个思路&#xff1a; 二&#xff0c;前期准备 2.1导入依赖 2.2编写bootstrop.yml&#xff1a; 三&#xff0c;编写Controller类 3.1获取单个配置类信息 3.2获取多个配置类信息 &#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f3…

【开源GPT项目 - 在问】让知识无界,智能触手可及

Chatanywhere: chatAnywhere 在问 | 让知识无界&#xff0c;智能触手可及 项目简介 这是一个免费的在线聊天工具&#xff0c;旨在让用户更方便地享受科技带来的便利。用户可以使用我们的工具来获取答案、寻求建议、进行翻译和计算等等。这是由一位个人开发者创建的&#xff…

MyBatisPlus学习一:快速入门

前言 前面快速学习了Mybatis&#xff0c;现在开始快速学习MyBatisPlus 学习教程&#xff1a; 黑马mybatis教程全套视频教程&#xff0c;2天Mybatis框架从入门到精通 黑马程序员最新MybatisPlus全套视频教程&#xff0c;4小时快速精通mybatis-plus框架 简介 MyBatisPlus 是…

python对常见的激活函数绘图操作(详细代码讲解)

写论文的时候需要做一些激活函数的图像&#xff0c;为此将常见的激活函数进行整理汇总了一下&#xff0c;方便后续的复习 激活函数的作用是为让模型处理非线性问题&#xff0c;故次激活函数都是非线性的 生活中&#xff0c;非线性问题占大多数&#xff0c;而模型的训练通常都是…

Fiddler工具 — 9.命令行和状态栏

1、命令行 命令行在Fiddler的左下方的黑色窗口&#xff0c;也叫QuickExec&#xff0c;可以调用 Fiddler的内置命令。 这一系列内置的函数用于筛选和操作会话列表中的session&#xff08;会话&#xff09;。 虽然它不是很显眼&#xff0c;但用好它&#xff0c;会让你的工作效率…

听GPT 讲Rust源代码--compiler(40)

File: rust/compiler/rustc_borrowck/src/region_infer/mod.rs 文件rust/compiler/rustc_borrowck/src/region_infer/mod.rs是Rust编译器中用于区域推断的模块文件。该文件中定义了一些类型和枚举&#xff0c;用于帮助编译器分析和推断代码中的生命周期和借用关系&#xff0c;以…

【霹雳吧啦】手把手带你入门语义分割の番外13:U2-Net 源码讲解(PyTorch)—— 损失的计算

目录 前言 Preparation 一、U2-Net 网络结构图 二、U2-Net 网络源代码 1、损失计算 2、model.py 3、train_and_eval.py 附&#xff1a;train_and_eval.py 源代码 前言 文章性质&#xff1a;学习笔记 &#x1f4d6; 视频教程&#xff1a;U2-Net 源码讲解&#xff08;PyT…

HTML JavaScript 康威生命游戏

<!DOCTYPE html> <html> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>康威生命游戏</title><style>body {font-family: Arial, sa…

CompletableFuture超详解与实践

0.背景 一个接口可能需要调用 N 个其他服务的接口&#xff0c;这在项目开发中还是挺常见的。举个例子&#xff1a;用户请求获取订单信息&#xff0c;可能需要调用用户信息、商品详情、物流信息、商品推荐等接口&#xff0c;最后再汇总数据统一返回。 如果是串行&#xff08;按…

SpringBoot项目的三种创建方式

手动创建方式&#xff1a; ①&#xff1a;新建maven项目 ②&#xff1a;引入依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.10.RELEASE</version>&l…

近似的同态比较:简单多项式的迭代计算

参考文献&#xff1a; [Gold64] Goldschmidt R E. Applications of division by convergence[D]. Massachusetts Institute of Technology, 1964.[CKKLL19] Cheon J H, Kim D, Kim D, et al. Numerical method for comparison on homomorphically encrypted numbers[C]//Inter…

普通人开视频号小店可以吗?

我是电商珠珠 我做电商也有五六年时间了&#xff0c;天猫、快手、抖店我都做过。 其中做抖店的时间最长&#xff0c;三年的时间&#xff0c;让我从个人化做到了团队化。 在22年的时候&#xff0c;发现了视频号小店这个项目&#xff0c;并开始投入进去。 一开始&#xff0c;…