【日志框架】

日志打印

  • 建议用{}占位而不是字符串拼接
  • 打日志前先判断日志级别是否可用:
  1. 先根据等级过滤规则再决定写不写;
  2. 先往一个管道写了内容,但再经等级过滤丢弃,徒增开销。

日志框架

Slf4J

Slf4J 不是底层日志框架,只是门面框架(抽象),需要配合jul、log4j、logback、log4j2等底层框架(真正干活的)使用。

  1. 避免日志对代码的耦合,更换日志框架时也不需改动任何代码。不论使用哪种底层框架时,在代码层面都一样。
  2. 避免引入第三方jar而其中日志框架不一致时需要同时维护不同的日志框架对应的配置文件。

在这里插入图片描述
补充:更老的门面框架还有jcl, 所以会看到有程序应用 jcl + log4j 这种搭配。Slf4J 后采用 Slf4J + log4j,但一些 jcl + log4j 项目也想用Slf4J 时,可以通过引入 jcl-over-slf4j log桥接工具的依赖,将原本输出到jcl的日志输出重定向到 SLF4J。

如果只用了slf4j,而没有使用任何底层框架,就会出现以下错误:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
log4j
  • 依赖
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency> 
    
  • 配置文件 log4j.properties
    log4j.rootLogger=info, stdout
    
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
    log4j.appender.logfile=org.apache.log4j.FileAppender
    log4j.appender.logfile.File=target/spring.log
    log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
    log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
    
  • 代码
    import org.apache.log4j.Logger;
    //更多请阅读:https://www.yiibai.com/log4j/log4j_sample_program.html
    
    public class log4jExample{
    
    	static Logger log = Logger.getLogger(log4jExample.class.getName());
    
    	public static void main(String[] args) {
     	 if (log.isDebugEnabled()) {
             log.debug("### Hello this is an debug message");
    	 }
    	 log.info("### Hello this is an info message"); // 不支持占位符
    
    	 }
    }
    
    输出
    2022-07-27 21:10:03,358 INFO [org.example.log4jExample] - ### Hello this is an info message
    
logback (原生实现 SLF4J)

Logback 旨在作为流行的 log4j 项目的继承者,在 log4j 1.x 停止的地方接手。

Logback 的架构非常通用,可以在不同的情况下应用。 目前,logback 分为三个模块,logback-core、logback-classic 和 logback-access。

logback-core 模块为其他两个模块奠定了基础。

logback-classic 模块可以同化为 log4j 1.x 的显着改进版本。 此外,logback-classic 原生实现了 SLF4J API。

logback-access 模块与 Tomcat 和 Jetty 等 Servlet 容器集成,以提供 HTTP 访问日志功能。 请注意,您可以轻松地在 logback-core 之上构建自己的模块。

  • 依赖

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
    
  • 默认配置

    Logback 默认配置的步骤 参考:https://www.cnblogs.com/warking/p/5710303.html

    1. 尝试在 classpath下查找文件logback-test.xml;
    2. 如果文件不存在,则查找文件logback.xml;
    3. 如果两个文件都不存在,logback用BasicConfigurator自动对自己进行配置,这会导致记录输出到控制台。

    logback.xml

 	<configuration>
 		<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 
     	<encoder> 
          <pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern> 
     	</encoder> 
   	</appender> 
   	
   	<root level="INFO"> 
      <appender-ref ref="STDOUT" /> 
   	</root> 

		<logger name="com.apache.ibatis" level="DEBUG"/>
	</configuration>
  • 代码

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class LogbackExample {
    
    	static Logger log = LoggerFactory.getLogger(LogbackExample.class);
    
    	public static void main(String[] args) {
        	if (log.isDebugEnabled()) {
            	log.debug("### Hello this is an debug message");
        	}
        	log.info("### Hello this is an info message"); // 不支持占位符
    
    	}
    }
    

    输出

    129  [main] INFO  org.example.LogbackExample - ### Hello this is an info message
    

    如果需要将日志按规则生成到文件,也可以在logback.xml中配置;logback.xml中各标签的含义,查阅上文。
    如图可以配置将日志信息同时实时输出到终端和离线输出到日志文件。
    在这里插入图片描述

  • @Slf4j 注解

能够少写两行代码,不用每次都在类的最前边写上:

	private static final Logger logger = LoggerFactory.getLogger(this.XXX.class);

需要 lombok依赖。如果是基于SpringBoot,因为默认加入了Slf4j-api和logback的依赖,所以只需要添加lombok的依赖即可。

   <dependency>
       <groupId>org.projectlombok</groupId>
       <artifactId>lombok</artifactId>
       <version>1.16.10</version>
   </dependency>
  • 代码
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class SLF4JExample {

    public static void main(String[] args) {
        if (log.isDebugEnabled()) {
            log.debug("### Hello this is an debug message");
        }
        log.info("### Hello this is an info message"); // log 由lombok提供,如报错是idea的问题
    }
}
log4j 适配 Slf4j
  • 依赖
   <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-log4j12</artifactId>
       <version>1.7.28</version>
   </dependency>

只需要依赖 slf4j-log4j12,它自身依赖log4j 和 slf4j-api 两个包。

  • 配置
    由于底层框架仍然使用的是log4j,仍然需要 配置文件: log4j.properties

    log4j.rootLogger=info, stdout
    
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
    log4j.appender.logfile=org.apache.log4j.FileAppender
    log4j.appender.logfile.File=target/spring.log
    log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
    log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
    
  • 代码

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class LogSlf4jExample {
    
        static Logger log = LoggerFactory.getLogger(LogSlf4jExample.class);
    
        public static void main(String[] args) {
            if (log.isDebugEnabled()) {
                log.debug("### Hello this is an debug message");
            }
            log.info("### Hello this is an info message"); // 不支持占位符
    
        }
    }
    

在代码层面已经实现和使用logback时一样了,都是从 org.slf4j.LoggerFactory 这个包下 getLogger来获取 Logger 对象。
当然也可以使用 @Slf4j 注解的方法。代码是一样的,无法看出底层框架是log4j还是logback。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

STL_list

一、有关list的介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向其前一个元素和后一个元素。Ii…

elasticsearch8.x版本docker部署说明和集成springboot

前提&#xff0c;当前部署没有涉及证书和https访问 1、环境说明,我采用三个节点&#xff0c;每个节点启动两个es&#xff0c;用端口区分 主机角色ip和端口服务器Amaster192.168.2.223:9200服务器Adata192.168.2.223:9201服务器Bdata,master192.168.2.224:9200服务器Bdata192.1…

Nodejs基础5之网络基础概念的IP、端口,HTTP模块的创建HTTP服务、HTTP服务注意事项、浏览器查看HTTP报文

Nodejs基础 网络基础概念IPIP的介绍IP的作用IP的分类共享IP-公网家庭共享——局域网公网 本地回环IP地址总结 IP标准分类 端口端口举例端口介绍总结 HTTP模块创建HTTP服务HTTP服务注意事项浏览器查看HTTP报文查看请求报文查看请求体url当中的查询字符串查看响应报文 网络基础概…

Qt开源版 vs 商业版 详细比较!!!!

简单整理Qt开源版与商业版有哪些差别&#xff0c;仅供参考。 简单对比 开源版商业版许可证大部分采用对商业使用不友好的LGPLv3具备商业许可证保护代码专有许可证相关大部分模块使用LGPLv3和部分模块使用GPL组成仅第三方开源组件使用Qt的其他许可证Qt模块功能支持支持技术支持…

Java把列表数据导出为PDF文件,同时加上PDF水印

一、实现效果 二、遇到的问题 实现导出PDF主体代码参考&#xff1a;Java纯代码实现导出PDF功能&#xff0c;下图是原作者实现的效果 导出报错Font STSong-Light with UniGB-UCS2-H is not recognized.。参考&#xff1a;itext 生成 PDF(五) 使用外部字体 网上都是说jar包的版本…

翻译: GPT-4 Vision通过量身定制的推荐来增强应用的用户体验 升级Streamlit五

GPT-4 Vision 系列: 翻译: GPT-4 with Vision 升级 Streamlit 应用程序的 7 种方式一翻译: GPT-4 with Vision 升级 Streamlit 应用程序的 7 种方式二翻译: GPT-4 Vision静态图表转换为动态数据可视化 升级Streamlit 三翻译: GPT-4 Vision从图像转换为完全可编辑的表格 升级St…

SpringBoot使用OpenCV

SpringBoot使用OpenCV Spring boot 整合 OpenCV 4.5环境安装配置spring boot项目 OpenCV 训练自己的模型&#xff0c;实现特定物体的识别环境安装前期准备总结 Spring boot 整合 OpenCV 4.5 本文展示Windows下Spring Boot 整合Opencv 4.5 进行对图片中的人脸提取&#xff0c;开…

防火墙到防火墙的高可用知识汇总

目录​​​​​​​ 防火墙 防火墙的分类&#xff1a; 防火墙的发展史 传统防火墙&#xff08;包过滤防火墙&#xff09;—— 一个严格的规则表 传统防火墙&#xff08;应用代理防火墙&#xff09;—— 每个应用添加代理 传统防火墙&#xff08;状态检测防火墙&#xff09…

责任链模式在java中的实现

1 总览 2 概念 避免请求发送者与接收者耦合在一起&#xff0c;让多个对象都有可能接收请求&#xff0c;将这些对象连接成一条链&#xff0c;并且沿着这条链传递请求&#xff0c;直到有对象处理它为止。职责链模式是一种对象行为型模式。 3 实现 公共部分&#xff0c;一个系…

Windows、Linux、Mac数据库的安装(mysql、MongoDB、Redis)

数据库的安装 作为数据存储的重要部分&#xff0c;数据库同样是必不可少的&#xff0c;数据库可以分为关系型数据库和非关系型数据库。 关系型数据库如 SQLite、MySQL、Oracle、SQL Server、DB2 等&#xff0c;其数据库是以表的形式存储&#xff1b;非关系型数据库如 MongoDB…

wsl-ubuntu 安装 nginx

wsl-ubuntu 安装 nginx 1. 安装 nginx2. 确认 nginx 启动状态3. 重启 nginx4. 停止 nginx 1. 安装 nginx sudo apt install nginx2. 确认 nginx 启动状态 systemctl status nginx3. 重启 nginx systemctl restart nginx4. 停止 nginx systemctl stop nginx完成&#xff01;…

CRM系统多少钱一套?

CRM系统多少钱一套&#xff1f; 相信这是企业普遍关心的一个问题。 我们公司也使用过CRM客户关系管理系统&#xff0c;经验就是&#xff0c;建议在开发前先进行一次详细的需求分析&#xff0c;确定采用哪种开发方式&#xff0c;估量所需的工作量&#xff1b;然后在此基础上&a…

【软考问题】-- 5 - 知识精讲 - 项目进度管理

一、基本问题 项目进度管理&#xff08;按时完成&#xff09; 1&#xff1a;紧前关系绘图法&#xff1f; 定义&#xff1a;它是创建进度模型的一种技术。别称&#xff1a; PDM、前导图法、单代号网络图&#xff08;只有节点需要编号&#xff09;、活动节点图&#xff08;AON&a…

Habitat环境学习二:导航任务中的Habitat-sim基础Habitat-sim Basics for Navigation

导航任务在Habitat-sim任务中的实现 官方教程概述重要概念1、Hello World程序1.0.1 基础设置Basic settings1.0.2 模拟器设置Configurations for the simulator1.0.3 创建模拟器实例1.0.4 初始化Agent1.0.5 导航和探索 官方教程 Habitat是一个高效的真实的3D模拟器&#xff0c…

iTunes Connect 中修改后的内购(IPA)审核所需的时间

引言 在 iOS 开发过程中&#xff0c;将应用上传到 App Store 是一个重要的步骤。应用审核和 IAP 商品审核是分开的&#xff0c;审核一般需要等待一周左右。如果审核通过&#xff0c;我们会收到 Apple 发来的反馈邮件&#xff0c;根据邮件中的指示进行后续操作。如果已经上架的…

客户点赞,“信”任满满 | 竹云喜获近百封感谢信!

玉兔辞旧岁&#xff0c;威龙迎新春 在新春佳节来临之际 一封封感谢信、表扬信 纷至沓来 纸短情长 每一封感谢信的背后 都记载着一个动人的故事 字里行间情真意切 激励着竹云继续前行&#xff01; 国家电投 竹云项目组成员凭借丰富的业务、技术经验、专业的职业素养和较…

从换脸到克隆:IP Adapter FaceID的技术突破与应用

引言 换脸技术&#xff0c;一直以来都是数字图像处理领域的热门话题。从最早的传统方法到现在的AI驱动技术&#xff0c;换脸技术已经经历了多次重大的技术革新。近年来&#xff0c;随着深度学习和计算机视觉技术的发展&#xff0c;换脸技术开始向更加智能化、自动化的方向演进…

Springboot自定义线程池实现多线程任务

1. 在启动类添加EnableAsync注解 2.自定义线程池 package com.bt.springboot.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.concurrent.ThreadPoolTask…

移动端深度编辑产品技术解决方案

视频编辑已经成为企业宣传、教育、娱乐等多个领域的重要工具。美摄科技凭借其深厚的技术积累和对市场需求的敏锐洞察&#xff0c;开发出业界领先的移动端深度编辑产品&#xff0c;为企业提供高效、专业的视频编辑解决方案。 美摄科技移动端深度编辑产品方案&#xff0c;基于多…

思维导图:大神教你如何画思维导图

思维导图是什么&#xff1f; 思维导图是一种图形化的工具&#xff0c;用于组织和展示思维过程、概念关系和信息结构。它以一个中心主题为起点&#xff0c;通过分支和连接的方式&#xff0c;将相关的想法、概念、关键词等呈现在一个图形化的结构中。 思维导图通常以中心节点开始…