SpringBoot使用Slf4j+Log4j2完成项目的日志记录

SpringBoot使用Slf4j+Log4j完成项目的日志记录


前言

本示例采用SpringBoot项目使用SpringAOP记录日志,Slf4j作为日志门面,Log4j2作为日志实现实,实现开发中的日志记录.


部分效果展示 :

日志文件 :在这里插入图片描述

日志信息 :在这里插入图片描述

代码具体实现如下 :

  1. 因为SpringBoot自动集成了Slf4j日志门面并且同样集成了logback等日志实现,Log4j2和Logback并不能共存,所以我们要先排除依赖,并添加Log4j2的依赖与SpringAOP的依赖。
    避坑 : 在网上有很多人说是在 spring-boot-starter-web 这个启动器里面进行依赖排除,但是经过我的测试这种方法有时候并不是有效的,所以复制上面的依赖就好。
	<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><exclusions><!-- 排除springboot自带的logback框架 --><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions></dependency><!-- 引入log4j2依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId></dependency><!-- SpringAOP启动器 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId><version>2.4.5</version></dependency>

二、编写log4j2-spring.xml : log4j2的配置文件

代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!--status = "warn" 日志框架本身的输入日志级别monitorInterval = "5" 自动加载配置文件的时间间隔不低于5s-->
<Configuration status="warn" monitorInterval="5"><!-- 日志级别以及优先级排序 :在log4j2中, 共有8个级别,按照从低到高为:ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF。All:最低等级的,用于打开所有日志记录.Trace:是追踪,就是程序推进一下.Debug:指出细粒度信息事件对调试应用程序是非常有帮助的.Info:消息在粗粒度级别上突出强调应用程序的运行过程.Warn:输出警告及warn以下级别的日志.Error:输出错误信息日志.Fatal:输出每个严重的错误事件将会导致应用程序的退出的日志.OFF:最高等级的,用于关闭所有日志记录.程序会打印高于或等于所设置级别的日志,设置的日志等级越高,打印出来的日志就越少。--><!--集中配置属性进行管理--><Properties><!--定义格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符%logger{36} 表示 Logger 名字最长36个字符--><property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight{%-5level}[%thread] %style{%logger{36}}{cyan} : %msg%n" /><!-- 定义日志存储的路径,绝对路径 --><property name="FILE_PATH" value="存储的绝对路径" /><property name="FILE_NAME" value="项目名称" /></Properties><!--日志处理--><Appenders><!--*********************控制台日志***********************--><!--target: SYSTEM_OUT 或 SYSTEM_ERR,一般只设置默认:SYSTEM_OUT.--><console name="Console" target="SYSTEM_OUT"><!--输出日志的格式和颜色--><PatternLayout pattern="${LOG_PATTERN}" disableAnsi="false" noConsoleNoAnsi="false"/><!--控制台只输出level及其以上级别的信息(onMatch)放行,其他的直接拒绝(onMismatch)--><ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/></console><!--*********************文件日志***********************--><!--按照一定规则查分日志文件的appender /logs/$${date:yyyy-MM-dd}/myrollog-%d{yyyy-MM-dd-HH-mm}-%i.log/logs:放在logs这个目录下,/$${date:yyyy-MM-dd}:以天为单位生成文件夹myrollog-%d{yyyy-MM-dd-HH-mm}-%d: 以分钟为单位到达了指定大小在进行拆分.gz 进行压缩归档--><!--error 运行时异常日志信息--><RollingFile name = "errorRollingFile" fileName = "${FILE_NAME}/error日志.log"filePattern = "${FILE_PATH}/$${date:yyyy-MM-dd}/error-%d{yyyy-MM-dd-HH-mm}-%i.log.gz"><!--日志级别过滤器,文件只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)--><ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/><!--日志的消息格式--><PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l %c{36} - %msg%n"/><!--在系统每次启动时,触发拆分规则,生产一个新的日志文件--><OnStartupTriggeringPolicy/><!--按照文件大小进行拆分--><SizeBasedTriggeringPolicy size = "10 MB"/><!--按照时间节点进行拆分--><TimeBasedTriggeringPolicy/><!--在同一个目录下,文件的个数限定为30个,超过按照实际进行覆盖--><DefaultRolloverStrategy max="30"/></RollingFile><!--fatal 正常运行时日志--><RollingFile name = "fatalRollingFile" fileName = "${FILE_NAME}/fatal日志.log"filePattern = "${FILE_PATH}/$${date:yyyy-MM-dd}/fatal-%d{yyyy-MM-dd-HH-mm}-%i.log.gz"><!--日志级别过滤器,文件只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)--><ThresholdFilter level="fatal" onMatch="ACCEPT" onMismatch="DENY"/><!--日志的消息格式--><PatternLayout pattern="${LOG_PATTERN}"/><!--在系统每次启动时,触发拆分规则,生产一个新的日志文件--><OnStartupTriggeringPolicy/><!--按照文件大小进行拆分--><SizeBasedTriggeringPolicy size = "10 MB"/><!--按照时间节点进行拆分--><TimeBasedTriggeringPolicy/><!--在同一个目录下,文件的个数限定为30个,超过按照实际进行覆盖--><DefaultRolloverStrategy max="30"/></RollingFile><!--info 操作日志--><RollingFile name = "infoRollingFile" fileName = "${FILE_NAME}/info日志.log"filePattern = "${FILE_PATH}/$${date:yyyy-MM-dd}/info-%d{yyyy-MM-dd-HH-mm}-%i.log.gz"><!--日志级别过滤器,文件只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)--><ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/><!--日志的消息格式--><PatternLayout pattern="${LOG_PATTERN}"/><!--在系统每次启动时,触发拆分规则,生产一个新的日志文件--><OnStartupTriggeringPolicy/><!--按照文件大小进行拆分--><SizeBasedTriggeringPolicy size = "10 MB"/><!--按照时间节点进行拆分--><TimeBasedTriggeringPolicy/><!--在同一个目录下,文件的个数限定为30个,超过按照实际进行覆盖--><DefaultRolloverStrategy max="30"/></RollingFile></Appenders><!--Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。--><!--然后定义loggers,只有定义了logger并引入的appender,appender才会生效--><loggers><!--过滤掉spring和mybatis的一些无用的信息--><logger name="org.mybatis" level="info" additivity="false"><AppenderRef ref="Console"/></logger><!--监控系统信息--><!--若是additivity设为false,则 子Logger 只会在自己的appender里输出,而不会在 父Logger 的appender里输出。--><Logger name="org.springframework" level="info" additivity="false"><AppenderRef ref="Console"/></Logger><root level="info"><!--控制台--><appender-ref ref="Console"/><!--用户操作文件--><appender-ref ref="infoRollingFile"/><!--调试错误文件--><appender-ref ref="errorRollingFile"/><!--正常运行文件--><appender-ref ref="fatalRollingFile"/></root></loggers></Configuration>

三、添加全局异步日志 : log4j2.component.properties

Log4j2的最大优点就是它的异步Logger,主要就是性能更好,这个这里不做过多解释。

#全局异步日志开启,提高日志性能
Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector

四、声明log4j2的配置文件路径 :

在application.properties的SpringBoot主配置文件中添加如下配置 :

我这里是给配置文件添加了个config的包目录,你要改成你自己的路径。

五、自定义注解类 :

自定义注解 : 主要是作用就是为了自定义方法操作,用于向AOP中添加方法操作的日志信息,既然已经到项目日志阶段那么我相信你也已经不是一个小白了,注解就是一个标注这里也不做过多解释。

//作用在方法上
@Target(ElementType.METHOD)
//运行时
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogAnnotationMethod {//模块名称String module() default "";//操作名称String operator() default "";//扩展属性String value() default "";
}

六、创建HttpContextUtil工具类用于在IP工具类中获取IP使用 :

public class HttpContextUtil {public static HttpServletRequest getHttpServletRequest(){return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();}}

七、创建IP获取工具类 :

用于获取访问的用户IP,并记录到日志中。

@Slf4j
public class IpUtils {/*** 获取IP地址* <p>* 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址* 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址*/public static String getIpAddr(HttpServletRequest request) {String ip = null, unknown = "unknown", seperator = ",";int maxLength = 15;try {ip = request.getHeader("x-forwarded-for");if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) {ip = request.getHeader("Proxy-Client-IP");}if (StringUtils.isEmpty(ip) || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {ip = request.getHeader("WL-Proxy-Client-IP");}if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) {ip = request.getHeader("HTTP_CLIENT_IP");}if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) {ip = request.getHeader("HTTP_X_FORWARDED_FOR");}if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) {ip = request.getRemoteAddr();}} catch (Exception e) {log.error("IpUtils ERROR ", e);}// 使用代理,则获取第一个IP地址if (StringUtils.isEmpty(ip) && ip.length() > maxLength) {int idx = ip.indexOf(seperator);if (idx > 0) {ip = ip.substring(0, idx);}}return ip;}/*** 获取ip地址** @return*/public static String getIpAddr() {HttpServletRequest request = HttpContextUtil.getHttpServletRequest();return getIpAddr(request);}
}

八、 编写AOP日志切面类

此类用于保存和执行具体的日志信息。

/*** @author 码不多* @version 1.0* @description: 此类采用SpringAOP,用于记录日志*///声明AOP类
@Aspect
//声明组件
@Component
//使用Slf4j日志门面
@Slf4j
public class AopLogUtil {//定义切入点方法 标注这个自定义注解@Pointcut("@annotation(com.shouzhong.epidemicprevention.annotation.LogAnnotationMethod)")public void pt(){}/*** 功能描述: 执行通知日志的方法* @author 码不多* @date 2021/8/16* @param point* @return java.lang.Object*///拦截所有的Controller或者RestController或者自定义注解标识的方法@Around("@within(org.springframework.stereotype.Controller) ||"+"@within(org.springframework.web.bind.annotation.RestController) ||"+"pt()")private Object runAndSaveLog(ProceedingJoinPoint point){//获取获取当前时间long beginTime = System.currentTimeMillis();//执行原始方法Object result = null;try {result = point.proceed();} catch (Throwable throwable) {//出现异常打印error日志log.error("Aop中方法出现异常",throwable);}//获取方法执行时间long runtime = System.currentTimeMillis() - beginTime;//调用保存日志的方法recordLog(point,runtime);//将结果返回return  result;}/*** 功能描述: 保存日志的方法* @author 码不多* @date 2021/8/16* @param joinPoint time* @return void*/private void recordLog(ProceedingJoinPoint joinPoint,long time){//获取类名Object target = joinPoint.getTarget();String canonicalName = target.getClass().getCanonicalName();//获取模块名MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();Method method = methodSignature.getMethod();//获取方法名Signature signature = joinPoint.getSignature();String methodName = signature.getName();//获取请求参数Object[] args = joinPoint.getArgs();String params = JSON.toJSONString(args[0]);//获取request,设置ip地址HttpServletRequest request = HttpContextUtil.getHttpServletRequest();//获取IP地址String ipAddr = IpUtils.getIpAddr(request);//获取注解对象LogAnnotationMethod logAnnotation = method.getAnnotation(LogAnnotationMethod.class);//添加类名到日志,采用占位符赋值log.info("类名: {}",canonicalName);//添加模块日志信息,采用占位符赋值,通过注解对象获取注解中的值log.info("模块名: {}",logAnnotation.module());//添加方法名到日志,采用占位符赋值log.info("方法名: {}",methodName);//添加操作到日志,采用占位符赋值,通过注解对象获取注解中的值log.info("操作: {}",logAnnotation.operator());//添加请求参数信息到日志,采用占位符赋值log.info("请求参数: {}:",params);//添加ip地址到日志,采用占位符赋值log.info("ip地址: {}",ipAddr);//添加执行时间到日志,采用占位符赋值log.info("执行时间: {} ms",time);//日志结束log.info("#####################log End####################");补充001 ://不使用IPUtils获取ip和一些其他请求头日志信息的方法: logger.info不在这里定义。还是在上面的代码中/*     // 接收请求,记录请求中的内容ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getRequest();// 记录下请求内容//请求的urllogger.info("URL : " + request.getRequestURL().toString());//请求的方法类型 : GET、POST...logger.info("HTTP_METHOD : " + request.getMethod());//IP地址logger.info("IP : " + request.getRemoteAddr());//类方法logger.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());//参数数组logger.info("ARGS : " + Arrays.toString(joinPoint.getArgs()));//获取所有参数方法 ://获取请求参数们Enumeration<String> enu=request.getParameterNames();//遍历while(enu.hasMoreElements()){//取出请求参数名String paraName=(String)enu.nextElement();//请求的具体参数值System.out.println(paraName+": "+request.getParameter(paraName));}}*/补充002:/*//如果有文件上传的参数MultipartFile类型,为了避免冲突可以给它们添加进集合展示// 接收请求,记录请求中的内容ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getRequest();//创建集合存储请求参数ArrayList paramsList = new ArrayList();//获取所有参数方法 :Enumeration<String> enu=request.getParameterNames();while(enu.hasMoreElements()){String paraName=(String)enu.nextElement();//将参数添加到集合paramsList.add(paraName+": "+request.getParameter(paraName));}log.info("请求参数 :{}",paramsList)*/}
}

九、控制器日志添加

在你需要记录操作日志的Controller层的请求映射的方法上添加你的自定义注解,并将你的方法日志信息添加到你自定义的属性值中。

    //自定义注解,声明方法日志@LogAnnotationMethod(module = "获得信息列表",operator = "分页查询或多条件查询信息需求列表")@RequestMapping("/InforDS")public Pagination<InforDemandSide> inforDemandSide(Pagination pagination){xxxxxxxxxxxxxxxxx;}

十、开启控制台Mybatis的sql输出 :

在application.properties的主配置文件中添加如下配置


简单总结一下 :

整体日志记录就是采用面向切面编程,你可以在配置文件中配置你的Appender或者修改你的日志级别。

如果你想在方法中使用日志记录具体的操作,你可以在你需要记录的类上添加@Slf4j这个注解,在你需要记录日志的地方直接使用 log.xxx() 直接记录你的日志即可。

如果这篇文章对你有帮助请为我点个小赞支持一下!

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

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

相关文章

鸿蒙构架谁提供的,科普丨关于“鸿蒙”,不知道这些你都不好意思跟别人打招呼!...

鸿蒙的英文名是Harmony OS华为消费者业务CEO余承东8月9日正式发布鸿蒙系统&#xff0c;英文名是Harmony OS 。国家知识产权局商标局网站显示&#xff0c;华为已经申请注册“华为鸿蒙”商标&#xff0c;申请日期是2018年8月24日&#xff0c;注册公告日期是2019年5月14日。鸿蒙是…

springBoot Logging 日志详解

文章目录日志格式控制台输出彩色编码输出文件输出文件级别自定义日志配置Logback 扩展profile 指定 配置文件Environment 属性springBoot 日志使用Commons Logging作为抽象层&#xff0c;并将具体实现开放&#xff0c;支持Java Util Logging、Log4j2和Logback。loggers 默认配置…

计算机应用电子技术课程,中专计算机应用有什么课程

中专计算机应用有什么课程2020-10-29 16:40:11文/董玉莹计算机应用学习研究计算机应用于各个领域的理论、方法、技术和系统等&#xff0c;是计算机学科与其他学科相结合的边缘学科&#xff0c;是计算机学科的组成部分。计算机应用是对在社会活动中的如何参与和实施给予方针指导…

Spring Boot 配置日志输出等级

Spring boot 默认使用 logback作进行日志输出。 有两种方式一个是通过application.properties 配置文件的方式来配置。 另一种是通过logback.xml配置文件的方式进行配置。 首先要说的是:application.properties 和logback.xml这两个配置文件都是放在 src/main/resources 目录…

springboot如何使用log4j记录日志

文章目录导入依赖1、去掉slf4j的依赖2、引入log4j的依赖创建log4j.properties导入依赖 因为springboot的启动依赖会引入SLF4J的日志依赖&#xff0c;因此想要用log4j&#xff0c;就要先把slf4j的依赖去掉&#xff0c;然后再引入log4j的启动依赖。 1、去掉slf4j的依赖 网上有…

在SpringBoot中使用slf4j与logbak

本次开发环境为&#xff1a; 系统&#xff1a;Windows 10 JDK&#xff1a;1.8 开发工具&#xff1a;IntelliJ IDEA springboot框架&#xff1a;2.X.X 日志设置参考官方文档https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boo…

站酷用HTML5播放视频,站酷:动效展示实践的问题及解决

前两天设计一款主页&#xff0c;想给它加上一些操作演示&#xff0c;于是便自己琢磨如何实现。先上效果图&#xff1a;首先&#xff0c;是界面设计的部分&#xff1a;需求是针对现有的网站做移动端的展示。针对门户网站的性质&#xff0c;以及对象的行业特性&#xff0c;将首页…

SpringBoot ——Spring Boot日志配置

Spring Boot 采用了 slf4jlogback 的组合形式&#xff0c;Spring Boot也提供对JUL、log4j2、Logback提供了默认配置 1、默认日志配置 修改日志默认级别 2、修改日志默认配置 修改日志文件生成路径 ​ ​ 修改日志输出格式 ​ 3、日志底层实现 在web项目中&#xff0c…

手机计算机数字显示在桌面上,手机桌面上的应用如何取消显示的数字角标

手机桌面上的应用如何取消显示的数字角标很多小伙伴都还不知道&#xff0c;下面IEfans小编为大家整理了取消显示的数字角标的流程一览&#xff0c;怎么取消显示的数字角标&#xff0c;一起来看看吧!方法/步骤分享&#xff1a;1、首先&#xff0c;点击手机桌面上的【设置】&…

SpringBoot日志配置

SpringBoot日志配置 1.Spring Boot默认日志框架 Spring Boot默认使用LogBack日志系统&#xff0c;如果不需要更改为其他日志系统如Log4j2等&#xff0c;则无需多余的配置&#xff0c;LogBack默认将日志打印到控制台上。如果要使用LogBack&#xff0c;原则上是需要添加depende…

上证50基金有哪些_定投基金(易方达上证50指数A)

今天小编想要推荐的基金是定投基金(易方达上证50指数A)(数据信息来源&#xff1a;天天基金网)一、基金的概况二、投资范围本基金的股票投资部分主要投资于标的指数的成分股票,包括上证50指数的成分股和预期将要被选入上证50指数的股票,还可适当投资一级市场申购的股票(包括新股…

Spring Boot 日志配置(超详细)

Spring Boot-日志配置(超详细) 更新日志&#xff1a; 20170810 更新通过 application.yml传递参数到 logback 中。 简书不支持目录&#xff0c;截图一张。 默认日志 Logback&#xff1a; 默认情况下&#xff0c;Spring Boot会用Logback来记录日志&#xff0c;并用INFO级别…

网络中的计算机如果加入家庭组,win10系统加入其他计算机家庭组的操作方法

很多小伙伴都遇到过对win10系统加入其他计算机家庭组进行设置的困惑吧&#xff0c;一些朋友看过网上对win10系统加入其他计算机家庭组设置的零散处理方法&#xff0c;并没有完完全全明白win10系统加入其他计算机家庭组的操作方法非常简单&#xff0c;只需要1、打开“此电脑”&a…

jmstemplate 获取队列id_学习Linux(38)消息队列

消息队列、共享内存 和 信号量 被统称为 system-V IPC&#xff0c;V 是罗马数字 5&#xff0c;是 Unix 的AT&T 分支的其中一个版本&#xff0c;一般习惯称呼他们为 IPC 对象&#xff0c;这些对象的操作接口都比较类似&#xff0c;在系统中他们都使用一种叫做 key 的键值来唯…

ad软件one pin错误是啥意思_Unity3D 4.5 软件安装教程

Unity3D 4.5 软件安装教程01Unity3D 4.5软件介绍【软件名称】&#xff1a;Unity3D 4.5【安装环境】&#xff1a;WindowsUnity3D 4.5是unity系列软件的版本&#xff0c;也是一款跨平台的计算机游戏开发环境&#xff0c;能够允许用户创建在20多种不同操作系统上运行的应用程序&am…

项目构建之springboot集成lomback.xml,和log4j基于properties方式的日志配置记录

文章目录springboot集成lomback.xml 描述在yml中定义的一些配置信息创建logback-spring.xml文件logback-spring.xml配置如下&#xff1a;**log4j入门配置****详细介绍配置信息的&#xff1a;****自动清理导出的日志文件**springboot集成lomback.xml 描述 首先在resouces目录下…

计算机里什么文件无法删除,电脑上的文件删不掉怎么办

电脑上的文件删不掉怎么办如果你遇到删不掉的文件,会有“无发删除&#xff0c;磁盘未写保护或者程序正被另一个人使用中”提示。这时候该怎么办呢&#xff1f;文件出现正常方法删不走的文件&#xff0c;有几种原因。1)文件受损&#xff0c;出现异常2)文件被使用中。例如该文件打…

php编写六十甲子纳音表_六十甲子纳音表详细说明,看看你属于什么命,属于那个颜色...

六十甲子纳音表详细说明 &#xff0c;六十甲子与五行十二生肖的对应关系。1、甲子乙丑海中金&#xff0c;白&#xff0c;此年生人&#xff0c;是海中金命&#xff0c;属相是白鼠和白牛  2、丙寅丁卯炉中火&#xff0c;红&#xff0c;此年生人&#xff0c;是炉中火命&#xff…

hcl启动设备失败_英林储罐清洗设备清洗公司2021收费

英林储罐清洗设备清洗公司2021收费泉州市骏泰机电工程有限公司是拥有资质的工业清洗企业&#xff0c;从事工业机械设备清洗、空调清洗清洁、换热器清洗清洁、冷凝器清洗清洁、设备清洗、化学清洗、锅炉清洗、燃气锅炉清洗、电锅炉清洗、锅炉碱洗、锅炉酸洗、锅炉预膜、工业清洗…

SpringBoot与日志配置

前言&#xff1a; 前文我们介绍了配置文件的原理还有如果切换配置文件的环境,个人觉得归纳为一手册&#xff0c;要用的时候查一下就好了。不然记那么多挺麻烦的。。 1.日志 1、日志框架 老生常谈&#xff0c;什么是日志&#xff1b;我们平时用System.out.println(“xxxxxx”…