【项目实用】SpringBoot整合日志功能插件

​分享不易,耗时耗力,麻烦给个不要钱的关注和赞吧

承接毕设指导,技术答疑,学习路上缺少导师的同学可以私信我

更多学习资料,公众号:墨轩学习网,B站:墨轩大楼

一、日志概述

日志记录了系统行为的时间、地点等很多细节的具体信息,在发生错误或者接近某种危险状态时能够及时提醒开发人员处理,往往在系统产生问题时承担问题定位与诊断和解决的重要角色。

开发阶段我们可以通过开发工具的控制台查看异常信息,但是一旦上线之后,很多问题只能通过进行日志分析才可以解决。所以日志功能在开发环节中是十分重要的。

1.1 常用的日志框架

常用的日志框架一般包括:Commons Logging、Slf4j、Log4j,Log4j2,Logback。

日志框架一般分为日志门面和对应的具体实现两部分,所谓日志门面就是门面模式的一个典型的应用,门面模式也称为外观模式,而日志门面框架就是一套提供了日志相关功能的接口而无具体实现的框架,日志记录是通过调用具体的实现框架来进行的。

典型的日志门面就是 Commons Logging、SLF4J,具体的实现就是Logback、Log4j 。比较常用的组合方式是 Slf4j 和 Logback 的组合使用,Commons Logging 与 Log4j 的组合使用,并且 Logback 必须得配合 Slf4j 使用。

1.2 Logback 简介

Logback 是由 log4j 的创始人编写的,但是性能上的话会比 log4j 更好一些,他主要分为有三个模块:

  • logback-core:核心代码模块。
  • logback-classic:log4j 的一个改良版本,同时实现了 slf4j 的接口。
  • logback-access:这是 logback 的访问模块,它与 Servlet 容器集成并且提供通过 Http 来访问日志的功能。

二、SpringBoot整合Logback框架

2.1 关于依赖

在spring boot项目中,我们不用再单独引入相关依赖,因为在spring boot项目的启动依赖中包含了该日志框架的相关依赖,spring-boot-starter 就已经包含了 spring-boot-starter-logging,而 spring-boot-starter-logging 中引用了 Logback 的依赖。

2.2.添加配置文件

在resources文件夹下面添加logback的配置文件来配置logback信息:

<?xml version="1.0" encoding="UTF-8"?>
<configuration><contextName>community</contextName><property name="LOG_PATH" value="./logs"/><property name="APPDIR" value="community"/><!-- 错误信息保存文件 file --><appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${LOG_PATH}/${APPDIR}/log_error.log</file><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${LOG_PATH}/${APPDIR}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>5MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><maxHistory>30</maxHistory></rollingPolicy><append>true</append><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><pattern>%d %level [%thread] %logger{10} [%file:%line] %msg%n</pattern><charset>utf-8</charset></encoder><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>error</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!-- 警告信息文件 file --><appender name="FILE_WARN" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${LOG_PATH}/${APPDIR}/log_warn.log</file><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${LOG_PATH}/${APPDIR}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>5MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><maxHistory>30</maxHistory></rollingPolicy><append>true</append><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><pattern>%d %level [%thread] %logger{10} [%file:%line] %msg%n</pattern><charset>utf-8</charset></encoder><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>warn</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!-- info file --><appender name="FILE_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${LOG_PATH}/${APPDIR}/log_info.log</file><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${LOG_PATH}/${APPDIR}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>5MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><maxHistory>30</maxHistory></rollingPolicy><append>true</append><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><pattern>%d %level [%thread] %logger{10} [%file:%line] %msg%n</pattern><charset>utf-8</charset></encoder><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>info</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!-- console --><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%d %level [%thread] %logger{10} [%file:%line] %msg%n</pattern><charset>utf-8</charset></encoder><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><level>debug</level></filter></appender><logger name="com.greate.community" level="debug"/><root level="info"><appender-ref ref="FILE_ERROR"/><appender-ref ref="FILE_WARN"/><appender-ref ref="FILE_INFO"/><appender-ref ref="STDOUT"/></root></configuration>

2.3.在springboot配置文件中添加日志配置文件路径

spring.profiles.active = develop# logback
logging.config=classpath:logback-spring-${spring.profiles.active}.xml

这里需要注意的是,我这里日志配置文件的名称为logback-spring-develop.xml ,上面的写法是为了方便在开发环境和生产环境之间切换。

三、SpringBoot项目使用AOP拦截请求日志信息

3.1 关于AOP

Aop的整体内容主要包含以下几点:

Pointcut:切点,主要是决定处理如权限校验、日志记录等在何处切入业务代码中(即织入切面)。切点分为 execution 方式和 annotation 方式。前者可以用路径表达式指定哪些类织入切面,后者可以指定被哪些注解修饰的代码织入切面。

Advice:处理(通知),包括处理时机和处理内容。处理内容就是要做什么事,比如校验权限和记录日志。处理时机就是在什么时机执行处理内容,分为前置处理(即业务代码执行前)、后置处理(业务代码执行后)等。这也回答了我们之前提到的什么时候切入,切入过后应该要做哪些事情。

Aspect:切面,即 Pointcut 和 Advice,在代码中就是我们定义的这个切面的类,选择在什么地方织入。

Joint point:连接点,是程序执行的一个点。例如,一个方法的执行或者一个异常的处理。在 AOP 中,一个连接点总是代表着一个方法执行。

Weaving:织入,就是通过动态代理的方式在目标对象方法中执行处理内容的过程。

3.2 添加Aop依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>

3.3 添加AOP配置

package com.softeem.car.aspect;import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;/**
* 统一日志记录
*/
@Component
@Aspect
public class ServiceLogAspect {private static final String START_TIME = "request-start";private static final Logger logger = LoggerFactory.getLogger(ServiceLogAspect.class);/*** 将service业务层中所有的方法作为切入点*/@Pointcut("execution(* com.softeem.car.service.*.*(..))")public void pointcut() {}/*** 前置操作* @param joinPoint*/@Before("pointcut()")public void before(JoinPoint joinPoint) {// 用户[IP 地址], 在某个时间访问了 [com.softeem.car.service.xxx]ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();if (attributes == null) {return ;}HttpServletRequest request = attributes.getRequest();String ip = request.getRemoteHost();String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());String target = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();logger.info(String.format("用户[%s], 在[%s], 访问了[%s].", ip, time, target));}}

接下来编写控制器,调用service中的任意方法,都会触发记录日志:

同时也会在对应的目录中自动生成日志文件:

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安装WMware和Ubuntu并使用xShell连接

0、我的电脑配置 设备名称 hello 处理器 Intel(R) Core(TM) i7-10700K CPU 3.80GHz 3.79 GHz 机带 RAM 16.0 GB (15.9 GB 可用) 设备 ID 541EC230-9910-418C-9043-5FBBF8ED320C 产品 ID 00330-80000-00000-AA846 系统类型 64 位操作系统, 基于 x64 的处理器 笔和触控 没有可…

网络服务器及IO模型

网络服务器 单循环服务器&#xff1a;服务器在同一时刻只能响应一个客户端的请求 并发服务器模型&#xff1a;服务器在同一时刻可以响应多个客户端的请求 实现TCP并发服务器 1.多进程 2.多线程 3.IO多路复用&#xff1a; 为了解决进程或线程阻塞到某个 I/O 系统调用而出现的…

计算机视觉编程 3(图片处理)

目录 图像差分 高斯差分 形态学-物体计数 ​编辑 图片降噪 图像差分 # -*- coding: utf-8 -*- from PIL import Image from pylab import * from scipy.ndimage import filters import numpy# 添加中文字体支持 from matplotlib.font_manager import FontProperties font…

算法学习:一维数组的排序算法

【排序算法】八种排序算法可视化过程_哔哩哔哩_bilibili 1&#xff0c;冒泡排序&#xff1a; 冒泡排序(Bubble Sort): 冒泡排序是一种简单的排序算法,它通过重复地交换相邻的元素,直到整个序列有序。算法思路是:从第一个元素开始,依次比较相邻的两个元素,如果前者大于后者,就交…

51单片机最快能生成多高频率的方波?

前言 在嵌入式系统开发中&#xff0c;51 单片机作为一种非常非常非常经典&#xff0c;贯穿上下几十年的微控制器&#xff0c;被广泛应用于各种电子项目中。其中&#xff0c;生成特定频率的方波信号是一项常见的需求。 那么&#xff0c;51 单片机究竟能以多快的速度生成方波呢&…

c++类的继承

1.直接继承父类的方法 #include <iostream> #include <string>using namespace std; class Person{ public:void eat(){cout<<"在吃饭"<<endl;} }; class Student : public Person{ private:int age; public:string name;Student() {cout &…

Spring security 密码加密使用

一、密码加密 2011年12月21日&#xff0c;有人在网络上公开了一个包含600万个CSDN 用户资料的数据库&#xff0c;数据全部为明文储存&#xff0c;包含用户名、密码以及注册邮箱。事件发生后CSDN 在微博、官方网站等渠道发出了声明、解释说此数据库系2009 年备份所用&#xff0c…

外包干了2年,女朋友跑了...

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 简单的说下&#xff0c;我大学的一个同学&#xff0c;毕业后我自己去了自研的公司&#xff0c;他去了外包&#xff0c;快两年了我薪资、技术各个方面都有了很大的…

Salesforce篇——如何在lightning页面添加ListviewButton使用lwc组件

1.创建lwc组件&#xff0c;用于展示listview已选数据&#xff1a; html&#xff1a; <template><lightning-card title"Selected Records"><p>Selected Record IDs: {selectedIds}</p><lightning-button label"返回" onclick…

Spring中Bean的生命周期管理

Spring框架中的Bean生命周期是指从创建到销毁的整个过程。在这个过程中&#xff0c;Spring容器会负责管理Bean的状态和行为。以下是Spring中Bean生命周期的详细解释&#xff1a; 实例化&#xff1a;Spring容器根据Bean的定义信息&#xff0c;通过反射机制创建Bean对象。 设置属…

“阉割版”ADS还能遥遥领先吗?

文/王俣祺 导语&#xff1a;随着特斯拉FSD一次又一次的“入华无门”&#xff0c; 让国内车企智能驾驶的“内卷”之争迎来了喘息的余地&#xff0c;而“端到端”也成为现如今市场上的首要研发目标。早在今年4月份&#xff0c;华为就宣布其研发的HUAWEI ADS 3.0已经采用了最新的端…

Java-数据结构-包装类和认识泛型 !!!∑(゚Д゚ノ)ノ

目录&#xff1a; 一、包装类&#xff1a; 1、基本数据类型所对应的包装类&#xff1a; 2、装箱和拆箱&#xff1a; 二、 泛型&#xff1a; 1、什么是泛型&#xff1a; 2、语法&#xff1a; 三、泛型类的使用&#xff1a; 四、裸类型&#xff1a; 五、泛型的擦除机制&…

[oeasy]python031_[趣味拓展]unix起源_Ken_Tompson_Ritchie_multics

[趣味拓展]unix起源_Ken_Tompson_Ritchie_multics &#x1f94b; 回忆上次内容 上次 动态设置了 断点 断点 可以把代码 切成一段一段的可以 更快地调试 调试的目的 是 去除 bug 别害怕 bug 一步步 总能找到 bug这 就是 程序员基本功 调试 debug 在bug出现的时候 甚至…

Python 变量类型

Python 变量类型 变量赋值 多个变量赋值 标准数据类型 Python 数字 Python字符串 Python列表 Python 元组 Python 字典 Python数据类型转换 Python 变量类型 变量是存储在内存中的值&#xff0c;这就意味着在创建变量时会在内存中开辟一个空间。 基于变量的数据类型…

【视频讲解】主成分分析原理与水果成熟数据实例:Python中PCA-LDA 与卷积神经网络CNN...

全文链接&#xff1a;https://tecdat.cn/?p37450 分析师&#xff1a;Shixian Ding 主成分分析&#xff08;PCA&#xff09;作为数据科学中用于可视化和降维的重要工具&#xff0c;在处理具有大量特征的数据集时非常有用。就像我们难以找到时间阅读一本 1000 页的书&#xff0…

实现流程化办公,可专注于开源可视化报表设计器!

近日&#xff0c;有很多粉丝和朋友们会问我们关于低代码技术平台、开源可视化报表设计器的相关内容和问题。其实&#xff0c;在流程化办公新时代&#xff0c;愿意启用新软件平台的客户朋友会收获市场红利&#xff0c;也会站在前沿之地上斩获更多市场份额。今天我们就一起来了解…

随机森林与线性回归

集成学习方法之随机森林 集成学习&#xff08;Ensemble Learning&#xff09;是一种通过组合多个分类器来提高预测性能的方法。主要分为三种类型:Bagging、Boosting和Stacking。以下是集成学习的基本步骤和概念&#xff1a; 1数据采样&#xff1a;从训练集中有放回地随机抽取…

【渗透测试】ATTCK靶场一,phpmyadmin,域渗透,内网横向移动攻略

前言 博客主页&#xff1a;h0ack1r丶羽~ 从0到1~ VulnStack&#xff0c;作为红日安全团队匠心打造的知识平台&#xff0c;其独特优势在于全面模拟了国内企业的实际业务场景&#xff0c;涵盖了CMS、漏洞管理及域管理等核心要素。这一设计理念源于红日安全团队对ATT&CK红队评…

斯坦福大学cs231n (图像分类)

1.介绍 当作图像分类时&#xff0c;分类系统接收一些分类图像&#xff0c;比如猫咪。并且系统清楚了一些已经确定了分类或者标签的集合。那么&#xff0c;计算机的工作就是根据图片&#xff0c;给他分配一些固定的分类或者标签。 对于一个计算机来说&#xff0c;这是一个非常…

springsecurity 在web中如何获取用户信息(后端/前端)

一、SecurityContextHolder 是什么 SecurityContextHolder用来获取登录之后用户信息。Spring Security 会将登录用户数据保存在Session中。但是&#xff0c;为了使用方便,Spring Security在此基础上还做了一些改进&#xff0c;其中最主要的一个变化就是线程绑定。当用户登录成功…