springboot日志使用 SLF4J+Logback 实现(springboot默认的日志实现),日志打印到控制台及日志输出到指定文件

还是直接上代码

@Slf4j 这玩意 默认支持 不用引入

yml 配置文件

# 日志配置  如果配置了xml 这个就不生效了 xml优先级最高
#logging:
#  file:
#    path: /home/logs  # 日志目录地址
#    name:  /home/logs/skeleton.log
#    max-size: 1KB  # 设置日志大小的最大大小 1KB 用于演示 单位包括 KB、MB、GB
#    max-history: 3  # 默认存储最近7
#    total-size-cap: 3KB  #日志文档的总大小:当日志文档总大小超过该阈值会删除备份
#  level:
#    root: info  #全局的日志等级 哪些日志输出

下面分享 xml 方式
在 资源目录下创建 logback-spring.xml 粘贴走 即可 重启 看控制台变化 还有磁盘 有没有写入

坑 :
我在创建的时候 发现 xml 没有生效 排查了半天 发现 在创建 logback-spring.xml 这个文件的时候
我不是手打的 是复制的 文件名 前面多了个空格 导致不生效
所以如果有小伙伴 和我一样 复制的文件名 一定要小心
文件名两边不要复制多了 空格

<?xml version="1.0" encoding="UTF-8"?>
<configuration  scan="true" scanPeriod="10 seconds"><!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 --><!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true --><!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 --><!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 --><contextName>logback</contextName><!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 --><!--    日志输出位置--><property name="log.path" value="/home/logs/xx-skeleton" />
<!--    按照日期一个文件夹--><timestamp key="datetime" datePattern="yyyy-MM-dd"/><!-- 彩色日志 --><!-- 配置格式变量:CONSOLE_LOG_PATTERN 彩色日志格式 --><!-- magenta:洋红 --><!-- boldMagenta:粗红--><!-- cyan:青色 --><!-- white:白色 --><!-- magenta:洋红 --><property name="CONSOLE_LOG_PATTERN"value="%yellow(%date{yyyy-MM-dd HH:mm:ss}) |%highlight(%-5level) |%blue(%thread) |%blue(%file:%line) |%green(%logger) |%cyan(%msg%n)"/><!--输出到控制台--><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息--><!-- 例如:如果此处配置了INFO级别,则后面其他位置即使配置了DEBUG级别的日志,也不会被输出 --><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><level>INFO</level></filter><encoder><Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!-- 设置字符集 --><charset>UTF-8</charset></encoder></appender><!--输出到文件--><!-- 时间滚动输出 level为 INFO 日志 --><appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 正在记录的日志文件的路径及文件名 --><file>${log.path}/${datetime}/log_info.log</file><!--日志文件输出格式--><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern><charset>UTF-8</charset></encoder><!-- 日志记录器的滚动策略,按日期,按大小记录 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!-- 每天日志归档路径以及格式 --><fileNamePattern>${log.path}/${datetime}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>100MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><!--日志文件保留天数--><maxHistory>7</maxHistory></rollingPolicy><!-- 此日志文件只记录info级别的 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>INFO</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!-- 时间滚动输出 level为 WARN 日志 --><appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 正在记录的日志文件的路径及文件名 --><file>${log.path}/${datetime}/log_warn.log</file><!--日志文件输出格式--><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern><charset>UTF-8</charset> <!-- 此处设置字符集 --></encoder><!-- 日志记录器的滚动策略,按日期,按大小记录 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${log.path}/${datetime}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>100MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><!--日志文件保留天数--><maxHistory>7</maxHistory></rollingPolicy><!-- 此日志文件只记录warn级别的 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>warn</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!-- 时间滚动输出 level为 ERROR 日志 --><appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 正在记录的日志文件的路径及文件名 --><file>${log.path}/${datetime}/log_error.log</file><!--日志文件输出格式--><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern><charset>UTF-8</charset> <!-- 此处设置字符集 --></encoder><!-- 日志记录器的滚动策略,按日期,按大小记录 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${log.path}/${datetime}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>100MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><!--日志文件保留天数--><maxHistory>7</maxHistory></rollingPolicy><!-- 此日志文件只记录ERROR级别的 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>ERROR</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!--<logger>用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender>。<logger>仅有一个name属性,一个可选的level和一个可选的addtivity属性。name:用来指定受此logger约束的某一个包或者具体的某一个类。level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,如果未设置此属性,那么当前logger将会继承上级的级别。--><!--使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作:第一种把<root level="INFO">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息第二种就是单独给mapper下目录配置DEBUG模式,代码如下,这样配置sql语句会打印,其他还是正常DEBUG级别:--><!--开发环境:打印控制台--><springProfile name="dev"><!--可以输出项目中的debug日志,包括mybatis的sql日志--><logger name="com.xx" level="INFO" /><!--root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,默认是DEBUG可以包含零个或多个appender元素。--><root level="INFO"><appender-ref ref="CONSOLE" /><appender-ref ref="INFO_FILE" /><appender-ref ref="WARN_FILE" /><appender-ref ref="ERROR_FILE" /></root></springProfile><!--生产环境:输出到文件--><springProfile name="prd"><root level="INFO"><appender-ref ref="CONSOLE" /><appender-ref ref="DEBUG_FILE" /><appender-ref ref="INFO_FILE" /><appender-ref ref="ERROR_FILE" /><appender-ref ref="WARN_FILE" /></root></springProfile></configuration>

测试

@RestController
@RequestMapping("/test-cg")
@Slf4j
public class TestCgController extends BaseController {@GetMapping("index14")@ApiOperation(value = "日志测试")@PassTokenpublic R index14(){log.trace("我是trace");log.debug("我是 debug");log.info("我是info");log.warn("我是warn");log.error("我是error");return R.success();}
}

最后再送 一个 定时任务 删除过期 日志文件 防止删除失败

定时任务 用的 xxl-job 不太清除这个定时任务插件 可百度

package com.xxx.init.job;import com.xxx.api.out.R;
import com.xxx.init.aop.XxlJobTask;
import com.xxx.init.utils.BaseDataUtil;import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;import java.nio.file.*;import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;import java.util.List;/*** User:Json* Date: 2024/4/18**/
@Slf4j
@Component
public class RuntimeFileClearJob {@Value("${spring.application.name}")private String serviceName;private static final String LOG_DIRECTORY_WINDOWS = "home\\logs"; // Windows系统的日志目录private static final String LOG_DIRECTORY_LINUX = "/home/logs/"; // Linux系统的日志目录//jobHandler 必须唯一  每天凌晨3点13分0秒触发 0 13 3 * * ?@XxlJob("planRuntimeFileClearJava")@XxlJobTask(jobDesc = "日志文件的清空-Java", cron = "0 13 3 * * ?", jobHandler = "planRuntimeFileClearJava", routeStrategy = "ROUND")//自定义注解public R planRuntimeFileClearJava() {Integer clearCacheDay = BaseDataUtil.getSystemConfigNacos().getClearCacheDay();log.info("===========清空缓存日志文件开始执行==========");if (clearCacheDay == null) {//从nacos里读,读不到就设置为7天。clearCacheDay = 7;}cleanupLogs(clearCacheDay);log.info("===========清空缓存日志文件结束执行==========");return R.success();}public void cleanupLogs(Integer clearCacheDay) {String logDirectory = getLogDirectory();if (logDirectory == null) {log.error("日志文件 目录不能为空!");return;}List<String> oldFolders = getOldFolders(logDirectory, clearCacheDay);if (!CollectionUtils.isEmpty(oldFolders)) {deleteOldFolders(oldFolders);}}//获取日志根目录private String getLogDirectory() {// 根据运行环境确定日志目录String osName = System.getProperty("os.name").toLowerCase();if (osName.contains("windows")) {String drive = Paths.get("").toAbsolutePath().getRoot().toString();return drive + "\\" + LOG_DIRECTORY_WINDOWS + "\\" + serviceName;} else {return LOG_DIRECTORY_LINUX + "/" + serviceName;}}//获取过期文件夹 不会递归着找 只会找当前目录下的  文件夹格式是 : 2024-04-18 会根据文件夹检索private List<String> getOldFolders(String logDirectory, Integer clearCacheDay) {List<String> oldFolders = new ArrayList<>();LocalDate today = LocalDate.now();DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");try {Files.list(Paths.get(logDirectory)).filter(Files::isDirectory).forEach(dir -> {String dirName = dir.getFileName().toString();try {LocalDate folderDate = LocalDate.parse(dirName, formatter);if (folderDate.isBefore(today.minusDays(clearCacheDay))) {oldFolders.add(dir.toString());}} catch (Exception e) {// Ignore non-date directorieslog.error("获取过期文件夹报错:" + e.getMessage());}});} catch (Exception e) {e.printStackTrace();}return oldFolders;}//删除过期文件夹  linux 注意 jar是否有 删除文件夹的权限 未测 linuxprivate void deleteOldFolders(List<String> oldFolders) {oldFolders.forEach(folder -> {try {Files.walk(Paths.get(folder)).sorted((path1, path2) -> -path1.compareTo(path2)).forEach(path -> {try {Files.deleteIfExists(path);} catch (Exception e) {e.printStackTrace();}});} catch (Exception e) {e.printStackTrace();log.error("删除过期文件夹报错:" + e.getMessage());}});}
}

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

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

相关文章

DevOps转型的意义:加速创新、提高效率

DevOps作为一种文化和方法论&#xff0c;正在成为现代软件开发和运维的核心。本文将探讨DevOps转型的意义&#xff0c;以及它对组织的影响&#xff0c;如何加速创新、提高效率&#xff0c;并为企业赋予竞争优势。 --- 在当今数字化时代&#xff0c;软件开发和运维已经成为企业竞…

ELB 后端主机异常

场景&#xff1a;运维同事发现某个业务访问不正常&#xff0c;用户访问页面得不到响应。查看elb(共享ELB)后端主机组发现&#xff0c;后端主机组显示异常。开始以为是共享负载均衡的问题&#xff0c;修改监控检查协议为tcp,之前是http协议。发现后端主机组显示正常。但是业务不…

Ubuntu22.04.4 - SSH - 笔记

SSH在Ubuntu22.04.4环境下的笔记 在服务器安装的时候勾选了ssh选项&#xff0c;后面都是默认配置信息 一、允许 root ssh 登录 这里遇到了 使用xshell 连接虚拟机&#xff0c;出现拒绝密码的提示 cp /etc/ssh/sshd_config /etc/ssh/sshd_config.ori 备份 vi /etc/ssh/sshd_con…

Linux 操作系统gdb、makefile

今天是对前面两天的补充和完善。 1、gdb 1.1 gdb 作用 调试程序 1.2 调试bug的步骤 测试&#xff1a;发现问题 固化&#xff1a;让bug重现 定位&#xff1a;找到bug的位置 修改&#xff1a;修改bug 验证 1.3 gdb调试工具的使用 1->想要使用gdb调试工具&#xff0c;在编…

【网站项目】自习室预约系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

汽车充电桩充电效率的四大决定因素

随着电动汽车的快速普及&#xff0c;交流充电桩作为电动汽车的充电基础设施&#xff0c;其充电效率受到了广泛的关注。接下来&#xff0c;我们将深入探讨交流充电桩的充电效率&#xff0c;包括充电效率的定义、影响因素以及提升方法。 充电效率的定义 交流充电桩的充电效率指的…

在CentOs7中设置tomcat应用systemd启动服务

目的&#xff1a; 解决安装tomcat服务后无法后台启动问题 一&#xff1a;配置Tomcat应用的service服务 具体文件内容如下&#xff1a; tomcat.service [Unit] DescriptionApache Tomcat Web Application Container Aftersyslog.target network.target [Service] Typeforkin…

【微信小程序从入门到精通(项目实战)】——微电影小程序

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

2024华中杯C题完整解题思路及代码

C 题 基于光纤传感器的平面曲线重建算法建模 光纤传感技术是伴随着光纤及光通信技术发展起来的一种新型传感器技 术。它是以光波为传感信号、光纤为传输载体来感知外界环境中的信号&#xff0c;其 基本原理是当外界环境参数发生变化时&#xff0c;会引起光纤传感器中光波参量&…

零基础机器学习|线性回归

一、数据收集和预处理 1、读取可视化 使用pandas库导入csv&#xff08;逗号相隔开的文件&#xff09;pd.read_csv() import pandas as pd df_ads pd.read_csv("本地文件地址D:\…\双斜线表示“&#xff09; 使用head()读出数据表格的前5行 df_ads.head() 2、相关分析 …

Vue前端框架如何调用天聚数行API?

Vue是一个业内优秀的前端解决方案&#xff0c;采用了最新流行的MVVM框架模式&#xff0c;深受web前端开发者的喜爱&#xff0c;在相关开发者社区也一直都是热门交流话题。那么&#xff0c;如何通过Vue调用天行数据的API接口呢&#xff0c;下面就具体给大家示例。 vue采用的是数…

数字零售力航母-看微软如何重塑媒体

数字零售力航母-看微软如何重塑媒体 - 从2024全美广播协会展会看微软如何整合营销媒体AI技术和AI平台公司 2024年&#xff0c;微软公司联合英伟达总司&#xff0c;赞助全美广播协会展会。本次展会微软通过搭建一个由全面的合作伙伴生态系统支持的可信和安全的平台&#xff0c;…

TCP和UDP协议的区别

1、定义 TCP协议的全称是Transmission Control Protocol&#xff08;传输控制协议&#xff09;&#xff0c;是一种面向连接的点对点的传输层协议。 UDP协议的全称是User Datagram Protocal&#xff08;用户数据报协议&#xff09;&#xff0c;为应用程序提供一种无需建立连接…

手机从0基础到精通拍摄,拍摄手法0基础教学,快速入门

课程下载&#xff1a;https://download.csdn.net/download/m0_66047725/89064797 更多资源下载&#xff1a;关注我。 课程内容&#xff1a; 1 为什么学拍摄剪辑.mp4 2 如何选择手机.mp4 3 补光灯的作用.mp4 !三角支架的作用.mp4 5 麦克风的作用.mp4 6 帧率清晰度参数.m…

Hive进阶

目录 一、MapReduce的计算过程 二、Yarn的资源调度 yarn的资源调度策略 三、Hive的语法树 四、Hive配置优化 五、数据开发 六、数据仓库 七、数据仓库开发流程 八、数仓分层 九、ETL和ELT 一、MapReduce的计算过程 分布式计算框架 需要编写代码执行&#xff0c;执行时…

Edge的使用心得与深度探索:优化浏览体验的技巧与建议

随着互联网的快速发展&#xff0c;浏览器已经成为我们日常生活中不可或缺的工具之一。在众多浏览器中&#xff0c;微软Edge凭借其稳定性、安全性和功能丰富性备受用户青睐。本文将深入探讨Edge浏览器的各种功能与技巧&#xff0c;帮助用户优化其浏览体验。 文章目录 Edge翻译插…

【无标题】axios的ts封装,记录一下(Vue3项目)

request.ts: // 参考&#xff1a;https://www.jb51.net/article/282238.htm import axios from axiosconst instance axios.create({baseURL: https://api.apiopen.top/api })// 添加请求拦截器 instance.interceptors.request.use(function (config) {// 在发送请求之前做些…

iOS 全平台矢量动画库:体积小巧、功能丰富 | 开源日报 No.227

airbnb/lottie-ios Stars: 24k License: NOASSERTION lottie-ios 是一个用于在 iOS 平台上本地渲染 After Effects 矢量动画的库。 该项目主要功能、关键特性、核心优势包括&#xff1a; 跨平台支持&#xff1a;可在 iOS, macOS, tvOS, visionOS, Android 和 Web 上使用实时渲…

ASP.NET医院手麻信息系统源码 .NET6.0+VUE

目录 麻醉记录单 复苏记录单 麻醉文书 手术麻醉信息 1、 体征监控记录 2、 麻醉用药信息 3、 手术事件登记 4、 手术状态变更 5、 麻醉医师交接 6、 其他辅助操作 手麻信息系统是以服务围术期临床业务工作的开展为核心&#xff0c;通过与床边监护设备以及医院H…

【数据库】MySQL之union联合查询

联合查询&#xff1a; 关键字union,作用就是将多条查询语句的结果合并成一个结果集。 案例&#xff1a;&#xff08;查询部门编号大于100或名字中含有a字符的员工信息&#xff09; select * from employees where department_id>100 or last_name like %a%; 用联合查询演…