springboot整合logback进行日志管理(下篇)

news2024/11/15 4:21:34

上一篇介绍了springboot整合logback的一些项目中用到的经验,本片文章继续介绍在项目中实际用到的工程经验

1、设想一下有这样一个场景:我想把我所有service层的日志单独打印到service.log中,那应该怎么做?

有人会说了可以配置一个service的appender,然后在每个service类中获取Logger实例进行打印

这样做当然可以,但是每个service中都获取一下Logger实例不繁琐吗?既然繁琐那有没有其他方式呢?接下来直接进行配置实践一下

首先配置日志文件路径和名字,然后配置appender

兄弟们看到了吗?直接配置service的扫描路径,这样所有service中的日志都会打印到service.log中

有一点就是我们不再是在root中添加,而是使用了子logger(因为不是所有的都需要打印到service.log中),子logger继承了root;

该标签有一个additivity属性,若是additivity设为true,则子logger不止会在自己的appender里输出,还会在root的logger的appender里输出;若是additivity设为false,则子logger只会在自己的appender里输出,不会在root的logger的appender里输出。

下面测试一下:我在service类中加一行打印

然后通过接口调用的时候看一下是否有service.log

可以看到是没有问题的

2、将一些特定场景的日志单独保存到一个日志文件中

比如有以下一个场景,我项目中有一个类是调用的外部服务,我想把调用外部服务的这个类中的日志单独记录到一个out-service.log中,那怎么实现呢?

首先配置日志文件路径和名字:

然后配置相关的appender

本次我是用获取Logger实例的方式来记录日志,为了方便我就直接在主启动类里面进行测试了

测试成功!!!

3、下面演示项目中常用到的通过切面将日志进行记录

如下所示我有一个切面类:

我这个切面用来记录controller每个方法的入参、出参、方法名、接口耗时等,下面编写切面代码:

package com.example.mybatisplus.config;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Aspect
@Component
public class HttpAspect {
    private static final Logger LOGGER = LoggerFactory.getLogger("http-aspect");

    @Pointcut("execution(* com.example.mybatisplus.controller..*.*(..))")
    public void pointCut() {
    }

    @Around(value = "pointCut()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

        // 获取目标参数
        long start = System.currentTimeMillis();
        String serviceUniqueName = proceedingJoinPoint.getSignature().getDeclaringTypeName();
        String methodName = proceedingJoinPoint.getSignature().getName();
        // 参数
        String args = Arrays.toString(proceedingJoinPoint.getArgs());
        boolean result = true;
        String errorMsg = "";
        long end = 0;
        try {
            // 执行目标方法
            Object proceed = proceedingJoinPoint.proceed();
            end = System.currentTimeMillis();
            return proceed;
        } catch (Exception e) {
            result = false;
            errorMsg = e.getMessage();
            throw e;
        } finally {
            LOGGER.info("serviceUniqueName:" + serviceUniqueName + ";methodName:" + methodName + ";result:" + result + ";args:" + args + ";cost:" + (end - start) + ";errorMsg:" + errorMsg);
        }
    }
}

然后配置切面相关的日志配置:

然后我启动服务之后调用controller测试一下:

兄弟们,看到了吧,我调用了controller里面的两个方法,一个成功调用,一个失败调用,都记录到了切面的日志文件中,这样后面如果需要配置http请求告警监控的话直接读取我们的http-aspect.log是不是就可以了

下面再补充一个知识点:

细心的朋友已经发现了我切面打印日志是用的获取Logger实例的方式打印的,原因是我切面类只有一个,所以我只需要在切面类获取一次Logger就行,那么如果不想用这种方式的话使用@Slf4j能不能实现呢?当然可以,下面就说下使用注解方式怎么做:

由于我们是只有切面里面的日志打印到http-aspect.log中,所以有两种方法:

1、配置扫描路径的方式

配置完扫描路径就可以直接使用@Slf4j打印了

2、通过在@Slf4j注解上使用topic指定logger-name即可

我的logger name是http-aspect

然后使用的时候在注解上通过topic字段指定该logger name

测试一下也是ok的

最后附加上logback-spring.xml相关的配置:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- include引入打印格式配置 -->
    <include resource="org/springframework/boot/logging/logback/defaults.xml" />

    <!-- 定义应用名称,区分应用 -->
    <property name="APP_NAME" value="myTradeProd"/>
    <!-- 定义日志文件的输出路径 -->
    <property name="LOG_PATH" value="${user.home}/logs/${APP_NAME}"/>
    <!-- 定义日志文件名称和路径 -->
    <property name="LOG_FILE" value="${LOG_PATH}/application.log"/>
    <!-- 定义错误级别日志文件名称和路径 -->
    <property name="ERROR_LOG_FILE" value="${LOG_PATH}/error.log"/>
    <!-- 定义指定目录service日志文件名称和路径 -->
    <property name="SERVICE_LOG_FILE" value="${LOG_PATH}/service.log"/>
    <!-- 配置out-service.log日志文件名称和路径 -->
    <property name="OUT_SERVICE_LOG_FILE" value="${LOG_PATH}/out-service.log"/>
    <!-- 定义指定切面日志文件名称和路径 -->
    <property name="HTTP_ASPECT_LOG_FILE" value="${LOG_PATH}/http-aspect.log"/>

    <!-- 将日志滚动输出到application.log文件中 -->
    <appender name="APPLICATION"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 输出文件目的地 -->
        <file>${LOG_FILE}</file>
        <encoder>
            <!-- 使用默认的输出格式打印 -->
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
        <!-- 设置 RollingPolicy 属性,用于配置文件大小限制,保留天数、文件名格式 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 文件命名格式 -->
            <fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 文件保留最大天数 -->
            <maxHistory>7</maxHistory>
            <!-- 文件大小限制 -->
            <maxFileSize>50MB</maxFileSize>
            <!-- 文件总大小 -->
            <totalSizeCap>500MB</totalSizeCap>
        </rollingPolicy>
    </appender>

    <!-- 配置控制台输出 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!-- 配置日志打印格式 -->
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
    </appender>

    <!-- 过滤ERROR日志输出到error.log中 -->
    <appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${ERROR_LOG_FILE}</file>
        <encoder>
            <!-- 使用默认的输出格式 -->
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
        <!-- 设置 RollingPolicy 属性,用于配置文件大小限制,保留天数、文件名格式 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 备份文件命名格式 -->
            <fileNamePattern>${LOG_PATH}/error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 文件保留最大天数 -->
            <maxHistory>7</maxHistory>
            <!-- 文件大小限制 -->
            <maxFileSize>50MB</maxFileSize>
            <!-- 文件总大小 -->
            <totalSizeCap>500MB</totalSizeCap>
        </rollingPolicy>
        <!-- 日志过滤器,将ERROR相关日志过滤出来 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
    </appender>

    <!-- 定义指定目录service的appender -->
    <appender name="SERVICE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${SERVICE_LOG_FILE}</file>
        <encoder>
            <!-- 使用默认的输出格式打印 -->
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
        <!-- 设置 RollingPolicy 属性,用于配置文件大小限制,保留天数、文件名格式 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 备份文件命名格式 -->
            <fileNamePattern>${LOG_PATH}/service.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 文件保留最大天数 -->
            <maxHistory>7</maxHistory>
            <!-- 文件大小限制 -->
            <maxFileSize>50MB</maxFileSize>
            <!-- 文件总大小 -->
            <totalSizeCap>500MB</totalSizeCap>
        </rollingPolicy>
    </appender>
    <!-- 配置扫描包路径,路径下所有service中的打印日志保存到service.log -->
    <!--若是additivity设为true,则子Logger不止会在自己的appender里输出,还会在root的logger的appender里输出-->
    <logger name="com.example.mybatisplus.service" level="INFO" additivity="false">
        <appender-ref ref="SERVICE"/>
    </logger>

    <!-- 定义指定目录service的appender -->
    <appender name="OUT-SERVICE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${OUT_SERVICE_LOG_FILE}</file>
        <encoder>
            <!-- 使用默认的输出格式打印 -->
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
        <!-- 设置 RollingPolicy 属性,用于配置文件大小限制,保留天数、文件名格式 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 备份文件命名格式 -->
            <fileNamePattern>${LOG_PATH}/out-service.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 文件保留最大天数 -->
            <maxHistory>7</maxHistory>
            <!-- 文件大小限制 -->
            <maxFileSize>50MB</maxFileSize>
            <!-- 文件总大小 -->
            <totalSizeCap>500MB</totalSizeCap>
        </rollingPolicy>
    </appender>
    <logger name="OUT-SERVICE" level="INFO" additivity="false">
        <appender-ref ref="OUT-SERVICE"/>
    </logger>

    <!-- 定义指定类topic的appender -->
    <appender name="HTTP-ASPECT" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${HTTP_ASPECT_LOG_FILE}</file>
        <encoder>
            <!-- 使用默认的输出格式打印 -->
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
        <!-- 设置 RollingPolicy 属性,用于配置文件大小限制,保留天数、文件名格式 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 文件命名格式 -->
            <fileNamePattern>${LOG_PATH}/http-aspect.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 文件保留最大天数 -->
            <maxHistory>7</maxHistory>
            <!-- 文件大小限制 -->
            <maxFileSize>50MB</maxFileSize>
            <!-- 文件总大小 -->
            <totalSizeCap>500MB</totalSizeCap>
        </rollingPolicy>
    </appender>

    <!-- 追加日志到HTTP-ASPECT的appender中 -->
    <!--若是additivity设为true,则子Logger不止会在自己的appender里输出,还会在root的logger的appender里输出-->
    <logger name="http-aspect" level="INFO" additivity="false">
        <appender-ref ref="HTTP-ASPECT"/>
    </logger>

    <!-- 配置日志级别 -->
    <root level="INFO">
        <appender-ref ref="CONSOLE"/>
        <!-- 加入APPLICATION输出 -->
        <appender-ref ref="APPLICATION"/>
        <!-- 加入ERROR日志输出 -->
        <appender-ref ref="ERROR"/>
    </root>
</configuration>

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

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

相关文章

高收录高权重的采集站源码——码山侠

前端预览&#xff1a;i5i.net——码山侠点击看看 采集非常简单&#xff0c;不伪原创&#xff0c;也不处理种种外链&#xff0c;也不需要什么配图&#xff0c;而且结构也不复杂。 后台管理&#xff1a; 文章发布手动发布及编辑管理后台 采集以及伪原创类工具后台&#xff1a; …

计算机毕业设计PyHive+Hadoop深圳共享单车预测系统 共享单车数据分析可视化大屏 共享单车爬虫 共享单车数据仓库 机器学习 深度学习 PySpark

毕业设计题目基于 Hadoop 的共享单车布局规划 二、毕业设计背景 公共交通工具的“最后一公里”是城市居民出行采用公共交通出行的主要障碍&#xff0c;也是建设绿色城市、低碳城市过程中面临的主要挑战。 共享单车&#xff08;自行车&#xff09;企业通过在校园、地铁站点、公…

光储充微电网能量管理系统控制策略研究及并网分析

引言 近年来&#xff0c;我国日益重视分布式能源和微电网的发展&#xff0c;特别是光伏系统和储能技术的应用&#xff0c;这些已成为确保电力供应可靠性、促进新能源利用和减少污染的关键措施。我国新能源领域的专家对光伏储能控制系统进行了深入研究&#xff0c;强调了其应用…

【Qt】 QComboBox | QSpinBox

文章目录 QComboBox —— 下拉框QComboBox 属性核心方法核心信号QComboBox 使用 QSpinBox —— 微调框QSpinBox 属性核心信号QSpinBox 使用 QComboBox —— 下拉框 QComboBox 属性 QComboBox —— 表示下拉框 currentText ——当前选中的文本 currentindex ——当前选中的条…

STM32 ADC采样详解

Content 0x00 前言0x01 ADC配置0x02 滤波处理 0x00 前言 在单片机开发过程中&#xff0c;常常涉及到ADC的使用&#xff0c;市面上大部分便宜的传感器都是采用的ADC来获取其数据&#xff0c;如MQ-2 烟雾传感器、光敏传感器等等。 此类传感器工作原理为根据所采集到的数据变化…

Axure健康助理小程序原型图70+页,医疗类高保真高交互模板

作品概况 页面数量&#xff1a;共 70 页 源文件格式&#xff1a;限 Axure RP 9/10&#xff0c;非app软件无源码 适用领域&#xff1a;医疗健康、健康助理 作品特色 本作品为健康助理小程序的Axure原型设计图&#xff0c;属于医疗健康项目&#xff0c;设计规范内容清晰&#…

坐牢第三十三天(手搓string)

一.mystring类 #include <iostream> #include <cstring> // 引入cstring以使用memcpy using namespace std; class myString {char *str; // 记录c风格的字符串int size; // 记录字符串的实际长度int my_capacity; // 记录最大容量 public:// 无参构…

LACP链路聚合

链路聚合包含两种模式&#xff1a;手动负载均衡模式和LACP&#xff08;Link AggregationControl Protocol&#xff09;模式。 手工负载分担模式&#xff1a;Eth-Trunk的建立、成员接口的加入由手工配置&#xff0c;没有链路聚合控制协议的参与。该模式下所有活动链路都参与数…

嵌入式软件--51单片机 DAY 2

一、数码管 1.数码管概况 2.设计 &#xff08;1&#xff09;硬件设计 我们可以通过阴极控制显示的位置&#xff0c;通过阳极控制显示的内容。两个数码管共有8个阴极引脚和16和阳极引脚&#xff0c;如果所有引脚都直接接入MCU&#xff0c;会造成MCU引脚的极大浪费。 为了节省…

Java编程基础-类加载机制

文章目录 基本概念类加载器的层次结构类的加载过程双亲委派模型自定义类加载器注意事项 Java 类加载器&#xff08;Class Loader&#xff09;是 Java 运行时环境的一部分&#xff0c;它负责在应用程序运行时加载类和接口的字节码。类加载器对于 Java 的动态特性和安全性有着至关…

Microsoft DirectML 现在支持 Copilot+ PC 和 WebNN

DirectML 是一个底层应用程序接口&#xff0c;使开发人员能够在任何兼容 DirectX 12 的 AMD、英特尔和英伟达&#xff08;NVIDIA&#xff09;GPU 上运行机器学习工作负载 。它首次出现在Windows 10 的 1903 版本中。最近&#xff0c;微软 开始在 DirectML 中支持现代 SoC 中的N…

新能源汽车超级电容和电池能量管理系统的simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 电池模型 4.2 电池荷电状态&#xff08;SOC&#xff09;估算 4.3 超级电容器模型 4.4 能量管理 5.完整工程文件 1.课题概述 新能源汽车的能量管理系统&#xff08;Energy Management System, EMS…

Conda离线部署django

要在没有网络连接的环境中使用conda部署Django&#xff0c;你需要预先在有网络连接的机器上创建一个包含所有必要包的环境&#xff0c;并导出该环境的配置文件。然后&#xff0c;你可以将这个配置文件和必要的包传输到目标机器上进行安装。 下面是详细的步骤&#xff1a; 1. …

mysql优化案例分享

一、mysql介绍 1、InnoDB引擎 mysql5.5.8版本开始后。InnoDB引擎就是默认存储引擎&#xff0c;本文介绍知识点也都是围绕该引擎展开。 知识点1聚集存储 InnoDB引擎采用聚集存储&#xff0c;即每张表的存储都是主键的顺序进行存放&#xff0c;也就是每行存储的物理顺序和主键…

基于SparkGraphX实现带权重的PageRank算法

基于SparkGraphX实现带权重的PageRank算法 文章目录 基于SparkGraphX实现带权重的PageRank算法一、什么是PageRank算法二、PageRank算法的实现三、PagRank算法实现步骤四、大数据量的PageRank算法实现总结 一、什么是PageRank算法 网页排序算法之PageRank 二、PageRank算法的…

【AI视频】Runway注册、基本设置、主界面详解

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AI视频 | Runway 文章目录 &#x1f4af;前言&#x1f4af;Runway的正确启动方式推荐使用Google Chrome打开Chrome翻译 &#x1f4af;Runway的注册&#x1f4af;My Account&#xff08;我的账户&#xff09;General&#xff08;常…

HTTPie CLI:重塑命令行HTTP交互的现代工具

更多内容前往个人网站&#xff1a;孔乙己大叔 在快速发展的数字时代&#xff0c;API&#xff08;应用程序编程接口&#xff09;已成为连接不同服务和应用的桥梁。无论是开发者还是系统管理员&#xff0c;与HTTP服务进行有效且高效的交互都是日常工作的核心部分。然而&#xff0…

idea中git提交或push到远程后回退到之前的某次提交简单有效的解决方案

场景&#xff1a; 1、先模拟出团队多人开发多分支&#xff0c;在各个分支分别提交代码&#xff0c;然后都合并到master分支 2、模拟如下两个分支dev、dev-0902合并到master&#xff0c;并且合并master后push到远程了 3、假如更新版本计划有变&#xff0c;只上dev-0902分支&…

stm32之I2C通信外设

系列文章目录 1. stm32之I2C通信协议 2. stm32之软件I2C读写MPU6050陀螺仪、加速度传感器应用案例 3. stm32之硬件I2C读写MPU6050陀螺仪、加速度传感器应用案例 文章目录 系列文章目录前言一、I2C通信外设1.1 I2C外设简介1.2 软件模拟和硬件外设对比 二、I2C外设电路结构2.1 I…

【数据结构-二维前缀异或和】【分区算法优化】力扣1738. 找出第 K 大的异或坐标值

给你一个二维矩阵 matrix 和一个整数 k &#xff0c;矩阵大小为 m x n 由非负整数组成。 矩阵中坐标 (a, b) 的 目标值 可以通过对所有元素 matrix[i][j] 执行异或运算得到&#xff0c;其中 i 和 j 满足 0 < i < a < m 且 0 < j < b < n&#xff08;下标从 …