Springboot中如何记录好日志

news2025/2/25 6:22:56

Springboot中如何记录日志

日志体系整体介绍

日志一直在系统中占据这十分重要的地位,他是我们在系统发生故障时用来排查问题的利器,也是我们做操作审计的重要依据。那么如何记录好日志呢?选择什么框架来记录日志,是不是日志打越多越好,带着这些问题我们今天一起来讨论下springboot应用如何记录好日志。

在我们java工程中,日志框架一般分为两层,日志门面和日志实现。

日志门面

日志门面是一个抽象层,它定义了一组统一的日志接口给用户使用。隐藏了底层日志实现的细节,提供了一种与具体日志实现解耦的方式。常见的日志门面有SLF4J(Simple Logging Facade for Java)和Apache Commons Logging等。日志门面的作用包括:

  • 提供统一的日志接口,方便在应用程序中记录日志。
  • 实现日志级别的控制,可以在不同环境中灵活地调整日志输出级别。
  • 提供日志消息的格式化和输出控制。

日志实现

日志实现是一种具体的日志框架,常见的包括Logback、Log4j、Java Util Logging等。不同的日志实现可能提供不同的功能和性能特性。最基础的都提供了以下共功能:

  • 实现日志门面定义的接口,提供日志记录的功能,可以将日志消息输出到指定的目标,如控制台、文件、数据库等
  • 提供灵活的日志配置选项,如输出格式、目标、日志级别等

总结一下,日志门面提供了统一的接口,让应用程序使用,而日志实现则负责将日志消息输出到具体的目标。那么我们可以直接用日志实现来记录日志吗,当然是可以的,但是使用日志门面,有他的优点:

  • 日志和代码解耦,每个不同的日志实现记录日志的api是不一样的,定义的日志级别可能也有差别,那么如果我们直接使用日志实现比如log4j在代码里记录日志,就需要用到log4j的api。这样将来有一天如果需要切换到logback,则需要将所有log4j的代码替换成logback。但是使用日志门面,我们只需要切换配置文件就可以了。
  • 兼容性:使用日志门面可以兼容不同的日志实现,因为大多数日志门面都支持多种日志实现。这样可以在项目中使用不同的日志库,以满足不同的开发环境和需求。
  • 统一接口:使用日志门面提供的统一接口,有利于维护和各个类的日志处理方式统一,提高代码的可读性和可维护性。
    在这里插入图片描述

springboot如何配置Logback做日志框架

  1. \src\main\resources目录下添加logback.xml的配置文件,
  2. 配置日志的输出路径、输出格式等
<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <!--定义日志文件的存储地址-->
    <property name="LOG_PATH" value="/home/app/logs" />

    <!-- 输出到控制台 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%logger{36}] - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 配置info级别日志的输出路径,滚动策略 -->
    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/info/info-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
            <maxHistory>30</maxHistory>
            <maxFileSize>50MB</maxFileSize>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%logger{36}] - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 配置error级别日志的输出路径,滚动策略 -->
    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/error/error-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
            <maxHistory>30</maxHistory>
            <maxFileSize>50MB</maxFileSize>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%logger{36}] - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 设置日志级别 -->
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="INFO_FILE" />
        <appender-ref ref="ERROR_FILE" />
    </root>
</configuration>

滚动策略

rollingPolicy 用于配置日志文件的滚动策略,决定何时创建新的日志文件或对现有日志文件进行归档。常见的日志滚动策略有以下几种:

  1. TimeBasedRollingPolicy:按时间滚动日志文件。该策略会根据指定的时间模式,如日期或时间间隔,创建新的日志文件。可配置属性有:

    • fileNamePattern:指定日志文件的命名模式。可以使用日期格式和/或通配符来表示日志文件的命名规则。例如,logs/app-%d{yyyy-MM-dd}.log 表示按日期切割日志文件,并以app-2022-01-01.log的格式命名。
    • maxHistory:指定保留的历史日志文件的数量。当滚动发生时,将保留最大数量的历史日志文件,较旧的日志文件将被删除。例如,7 表示最多保留 7 个历史日志文件。
    • cleanHistoryOnStart:指定在启动时是否清除历史日志文件。为 true,即在启动时删除所有历史日志文件,只保留当前日志文件。如果设置为 false,则会保留历史日志文件,但仍按照日期规则创建新的日志文件。
    • totalSizeCap:指定所有历史日志文件的总大小上限。当滚动发生时,如果历史日志文件的总大小超过了这个上限,较旧的日志文件将被删除,以保持总大小在限制范围内。可以使用B、 KB、 MB、 GB作为单位。
  2. SizeAndTimeBasedRollingPolicy:继承自TimeBasedRollingPolicy,支持按照文件大小滚动的特性,可以通过maxFileSize来配置:

    • maxFileSize:指定单个日志文件的最大大小。当日志文件达到或超过这个大小时,将触发滚动操作。可以使用可以使用B、 KB、 MB、 GB作为单位。
  3. FixedWindowRollingPolicy:按指定的固定窗口大小滚动日志文件。该策略会创建固定数量的日志文件,并在写满一个日志文件后,将日志写入下一个文件,循环使用这些日志文件。可以通过 minIndexmaxIndex 属性指定日志文件的索引范围。

    • minIndex:指定最小索引值。当滚动时,索引将从这个值开始递增。默认值为1。
    • maxIndex:指定最大索引值。当索引达到这个值时,最旧的日志文件将被删除。默认值为7。

过滤器

在Logback中,可以使用Filter来对日志事件进行筛选和过滤。常用的过滤器有:ThresholdFilterLevelFilter

  1. ThresholdFilter:基于日志级别进行过滤,只有达到或超过指定级别的日志事件才会被接受。以下是一个示例配置:

    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
      <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>WARN</level>
      </filter>
    </appender>
    
  2. LevelFilter:LevelFilter也是基于日志级别进行过滤,可以根据指定的最低日志级别(level)来决定是否接受或拒绝日志事件,允许更细粒度地控制不同appender或logger的过滤行为。以下是一个示例配置:

    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
      <filter class="ch.qos.logback.classic.filter.LevelFilter">
        <level>WARN</level>
        <onMatch>DENY</onMatch>
        <onMismatch>ACCEPT</onMismatch>
      </filter>
    </appender>
    

    <onMatch>标签指定了满足过滤条件时的操作为DENY(拒绝),<onMismatch>标签指定了未满足过滤条件时的操作为ACCEPT(接受)。

springboot中如何通过日志切面将业务和日志进行解耦

在我们的应用中,经常需要记录每一次请求的参数、请求的结果、耗时以及请求异常时需要记录异常堆栈,用来在必要的时候排查问题。如果直接记录的话,存在日志和代码耦合,日志风格不统一,日志排查困难等问题,所以我们往往通过AOP的方式将日志和代码进行解耦,让程序员可以专注在业务的开发上。

@Aspect
@Component
@Slf4j
public class LogAspect {

    @Around(value = "execution(* com.pinellia.framework.controller.*.*(..))")
    public Object logRequest(ProceedingJoinPoint joinPoint) throws Throwable {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        String requestUrl = request.getRequestURL().toString();

        Object result = null;
        try {
            result = joinPoint.proceed();
        } catch (Throwable e) {
            log.error("Request url: {} failed...", requestUrl, e);
            throw e;
        } finally {
            stopWatch.stop();
            log.info("Request url: {}, params: {}, response: {}, cost: {}",
                    requestUrl, joinPoint.getArgs(), GsonUtil.toJson(result), stopWatch.getTotalTimeMillis());
        }

        return result;
    }
}

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

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

相关文章

MySQL之 数据库操作管理/开发规范【附件world可下载】

一、 目的 为了在软件生命周期内规范数据库相关的设计、开发、运维工作,便于不同团队之间的沟通及协调,制定此文档,以期在相关规范上达成共识和默契,提升相关环节的工作效率及系统的可维护性。同时好的规范,在执行的时候可以培养出好的习惯,好的习惯是软件质量的很好保证…

简单聊聊现在的AI

简单聊聊现在的AI 前言主要的AI模型和形式LLM - Large Language Model&#xff08;大语言模型&#xff09;BOT&#xff08;机器人&#xff09;LAM - Large Action Models&#xff08;大行动模型&#xff09;Agent&#xff08;智能体&#xff09; 结尾 前言 好久没回来写博客&a…

java 通过 microsoft graph 调用outlook

废话不多说 一 官方文档 先看一下官方文档&#xff0c;https://learn.microsoft.com/zh-cn/graph/tutorials/java?contextoutlook%2Fcontext&tabsaad&tutorial-step1 其中的代码&#xff0c;可以通过地址下载&#xff1a;https://developer.microsoft.com/en-us/gra…

基于uniapp框架的古汉语学习考试系统 微信小程序python+java+node.js+php

1、一般用户的功能及权限 所谓一般用户就是指还没有注册的过客,他们可以浏览主页面上的信息。但如果需要其它操作时&#xff0c;要登录注册&#xff0c;只有注册成功才有的权限。 2、管理员的功能及权限 用户信息的添加和管理&#xff0c;古汉语信息加和管理和学习视频添加和管…

下载 axios.js 文件到本地【linux】

方式一 npm install axios在$NODE_PATH/node_modules/axios/dist路径下即可找到axios.js。 方式二 1、百度搜索 GitHub 官网&#xff1a;https://github.com/ 2、搜索 axios 3、点击 axios/axios 4、下载到本地 5、解压&#xff0c;进入到 dist 文件夹** 参考&#x…

代码随想录算法训练营第四天

● 自己看到题目的第一想法 24.两两交换链表中的节点 方法&#xff1a;虚拟头节点 思路&#xff1a; 设置虚拟头节点dummyhead 设置临时指针cur dummyhead; cur每次向前移动两步 循环条件&#xff1a; cur ! nullptr && cur->next ! nullptr && cur->…

springBoot整合Redis(一、Jedis操作Redis)

在springboot环境下连接redis的方法有很多&#xff0c;首先最简单的就是直接通过jedis类来连接&#xff0c;jedis类就相当于是redis的客户端表示。 但是因为现在比较常用的是&#xff1a;StringRedisTemplate和RedisTemplate&#xff0c;所以jedis只做简单的介绍。 一、Jedis…

3D生成式AI模型与工具

当谈到技术炒作时&#xff0c;人工智能正在超越虚拟世界&#xff0c;吸引世界各地企业和消费者的注意力。 但人工智能可以进一步增强虚拟世界&#xff0c;至少在某种意义上&#xff1a;资产创造。 AI 有潜力扩大用于虚拟环境的 3D 资产的创建。 AI 3D生成使用人工智能生成3D模…

【pytorch】常用便捷代码

文章目录 条件与概率torch.tensor()torch.rand()torch.randn()torch.randint()torch.multinominal() 逻辑运算torch.argmax()torch.max()torch.sum()torch.tanh()torch.pow() 功能性操作 torch.nn.functionalF.normalize()F.elu()F.relu()F.softmax() 张量计算torch.zeros()tor…

CentOS7 Hive2.3.8安装

CentOS7 Hive2.3.8 安装 建议从头用我的博客&#xff0c;如果用外教的文件到 一、9)步骤了&#xff0c;就用他的弄完&#xff0c;数据库不一样&#xff0c;在9步骤前还能继续看我的 一、 安装MySQL 0.0&#xff09;查询mariadb,有就去0.1&#xff09;&#xff0c;没有就不管…

kuka协作机器人LBR系列 issy15R930导入到ros2_rviz(带外观文件)

kuka协作机器人LBR系列 issy15R930导入到ros2_rviz(带外观文件&#xff09;外观文件未调整好&#xff0c;外观仍需进一步研究&#xff0c;外观文件dae与轮廓&#xff08;碰撞&#xff09;文件STL并未完全对应起来。在blender里面看了一下UR机器人的文件&#xff0c;是对应的&am…

Springboot教程(二)——过滤器、拦截器

过滤器 过滤器可以在调用控制器方法之前进行一些操作&#xff0c;过滤器类一般放在filter包下。 配置类注册 使用过滤器时&#xff0c;要实现Filter接口&#xff0c;并重写doFilter方法&#xff1a; class TestFilter : Filter {override fun doFilter(request: ServletReq…

苹果发布iPhone 16:革命性创新重新定义智能手机体验

&#xff08;苹果总部&#xff0c;加利福尼亚州&#xff0c;2024年2月23日&#xff09;——今天&#xff0c;全球领先的科技公司苹果公司再次震撼世界&#xff0c;宣布推出iPhone 16&#xff0c;这款革命性的智能手机重新定义了人们对于手机的期望和体验。 iPhone 16的发布代表…

数字孪生的技术开发平台

数字孪生的开发平台可以基于各种软件和硬件工具来实现&#xff0c;这些平台提供了丰富的功能和工具&#xff0c;帮助开发人员构建、部署和管理数字孪生系统&#xff0c;根据具体的需求和技术要求&#xff0c;开发人员可以选择合适的平台进行开发工作。以下列举了一些常见的数字…

再探二分法

推荐阅读 智能化校园&#xff1a;深入探讨云端管理系统设计与实现&#xff08;一&#xff09; 智能化校园&#xff1a;深入探讨云端管理系统设计与实现&#xff08;二&#xff09; 文章目录 推荐阅读二分查找题目思路解法左闭右闭式写法左闭右开式写法 二分查找 题目 给定一个…

十六:网络编程

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 01、网络编程概述02、网络通信要素概述03、通信要素1&#xff1a;IP和端口号3.1、IP的理解与InetAddress类的实例化3.2、端口号的理解 04、通信要素2&#xff1a;网…

主从复制实现Redis集群

主从复制实现Redis集群实验 (一主二从): 实验环境: 使用Docker 搭建 Redis 版本 5.0.5 打开一个终端窗口&#xff0c;在其中运行如下命令创建一个名为redis-master的Redis容器。注意&#xff0c;它的端口是6379 (本地的端口:映射到容器的端口) docker run -itd--name redis-m…

【wails】(6):使用wails做桌面应用开发,使用gin+go-chatglm.cpp进行本地模型运行,在windows上运行成功

1&#xff0c;整体架构说明 主要使用&#xff0c;参考的开源项目是&#xff1a; https://github.com/wailsapp/wails 前端项目&#xff1a; https://github.com/Chanzhaoyu/chatgpt-web 运行模型&#xff1a; https://github.com/Weaxs/go-chatglm.cpp 参考代码&#xff1a; h…

【VSCode】SSH Remote 通过跳板机连开发机提示“bash行1 powershell未找到命令”

需求背景 因为需要&#xff0c;在家我需要挂上公司VPN然后SSH连到跳板机&#xff0c;然后再从跳板机SSH进开发机。 问题背景 跳板机进开发机输入完密码显示 bash行1 powershell未找到命令VSCode SSH Remote跳板机配置请自行搜素其他文章config配置 注意其中ssh.exe地址请根据…

消息中间件篇之RabbitMQ-延时队列

一、延时队列 延迟队列&#xff1a;进入队列的消息会被延迟消费的队列。 场景&#xff1a;超时订单、限时优惠、定时发布。 延迟队列死信交换机TTL&#xff08;生存时间&#xff09;。 二、死信交换机 当一个队列中的消息满足下列情况之一时&#xff0c;可以成为死信&#xf…