还是直接上代码
@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 这个文件的时候
我不是手打的 是复制的 文件名 前面多了个空格 导致不生效
所以如果有小伙伴 和我一样 复制的文件名 一定要小心 文件名两边不要复制多了 空格
<configuration scan="true" scanPeriod="10 seconds">
<contextName>logbackcontextName>
<property name="log.path" value="/home/logs/xx-skeleton" />
<timestamp key="datetime" datePattern="yyyy-MM-dd"/>
<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">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFOlevel>
filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}Pattern>
<charset>UTF-8charset>
encoder>
appender>
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/${datetime}/log_info.logfile>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern>
<charset>UTF-8charset>
encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${datetime}/info/log-info-%d{yyyy-MM-dd}.%i.logfileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MBmaxFileSize>
timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>7maxHistory>
rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFOlevel>
<onMatch>ACCEPTonMatch>
<onMismatch>DENYonMismatch>
filter>
appender>
<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/${datetime}/log_warn.logfile>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern>
<charset>UTF-8charset>
encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${datetime}/warn/log-warn-%d{yyyy-MM-dd}.%i.logfileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MBmaxFileSize>
timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>7maxHistory>
rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>warnlevel>
<onMatch>ACCEPTonMatch>
<onMismatch>DENYonMismatch>
filter>
appender>
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/${datetime}/log_error.logfile>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern>
<charset>UTF-8charset>
encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${datetime}/error/log-error-%d{yyyy-MM-dd}.%i.logfileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MBmaxFileSize>
timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>7maxHistory>
rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERRORlevel>
<onMatch>ACCEPTonMatch>
<onMismatch>DENYonMismatch>
filter>
appender>
<springProfile name="dev">
<logger name="com.xx" level="INFO" />
<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 = "日志测试")
@PassToken
public 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 directories
log.error("获取过期文件夹报错:" + e.getMessage());
}
});
} catch (Exception e) {
e.printStackTrace();
}
return oldFolders;
}
//删除过期文件夹 linux 注意 jar是否有 删除文件夹的权限 未测 linux
private 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());
}
});
}
}