前言
最近遇到个很尴尬的问题,就是服务器上的程序留下日志文件记得太多,而且也没有清除,居然把硬盘塞满了,然后程序就死了。真的尴尬呀,手动清除了一下过期没用的日志,重新启动就ok了。问题虽然是解决了,但真的是太尴尬了,日志只记不管,迟早还是会被塞满,程序还会在不知道什么时候又会死。所以呢,不如写一个小程序,设定一下保存多少天的日志,定期清除不需要的日志。正好最近在学习研究spring boot ,据说这spring boot 号称开箱即用,简化复杂配置,那就试一下吧。
目录结构
这是我的spring boot 目录结构:
配置文件
#要清除的根目录,多个目录用‘|’隔开
com.sundyn.gaox.cleanRoot=d:/logs|D:/repository
#清除10天以前的文件
com.sundyn.gaox.cleanDay=10
#程序日志记录生成路径
logging.file=d:/logs/cleanFile/cleanFile.log
name=gaoxing
banner.txt是什么呢?spring boot 启动的时候会出如下图的启动标志
再来看看我的启动标志
Text to ASCII Art Generator (TAAG),把生成的字符放在resources目录下的banner.txt里项目启动的时候就能看到了。
实现方式
定期清除过期的日志,主要就是用到spring的定时调度,很简单。spring boot启用调度就更简单了,首先你要在启动类的上面加一个注解@EnableScheduling,然后在你的调度执行方法上,加上注解@Scheduled(fixedDelay=1000*24*60*60),来注明调度执行的条件,这里fixedDelay=1000*24*60*60就表示这个方法每隔24小时就会执行一次,当然还有其他的方法,这里因为只是定期清除一下失效日志,对时间的要求并没有那么严格,所以越简单越好了,当然如果你的需求要求控制执行的时间非常精确,可以用复杂一点表达式,或者用更专业的一些框架等其他方法,总之做什么东西满足需求的情况下,越简单越好,没必要整的很复杂。
主要的类如下:
1、启动类CleanFileApplication.java:
@SpringBootApplication
@EnableScheduling
public class CleanFileApplication {
public static void main(String[] args) {
SpringApplication.run(CleanFileApplication.class, args);
}
}
2、封装实体类FileResult.java:
public class FileResult {
private File file;
private String name;
private Date lastTime;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getLastTime() {
return lastTime;
}
public void setLastTime(Date lastTime) {
this.lastTime = lastTime;
}
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
}
3、文件工具类FileUtil.java,主要用来获取目录下的所有文件和文件的创建时间:
public class FileUtil {
private static Set<File> set=new HashSet<File>();
/**
* 获取根目录包括根目录下所有子目录下的所有文件
* @param file
* @return
*/
public static Set<File> queryRoot(File file){
if(file.isDirectory()){
File[]files=file.listFiles();
for (File file2 : files) {
if(file2.isDirectory()){
queryRoot(file2);
}else{
set.add(file2);
}
}
}else{
set.add(file);
}
return set;
}
public static void clear(){
FileUtil.set.clear();
}
}
4、任务类CleanTask.java:
@Component
public class CleanTask {
@Value("${com.sundyn.gaox.cleanRoot}")
private String rootStr;
@Value("${com.sundyn.gaox.cleanDay}")
private int cleanDay;
private Logger log=Logger.getLogger(CleanTask.class);
@Scheduled(fixedDelay=24*60*60*1000)
public void clean(){
Integer seconds=cleanDay*24*60*60*1000;
// Integer seconds=1000*10;
String[] roots=rootStr.split("\\|");
for (String root : roots) {
Set<FileResult> list=this.getFileResults(root);
Date date=new Date(new Date().getTime()-seconds);
log.info("************"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date));
for (FileResult fileResult : list) {
if(fileResult.getLastTime().getTime()<date.getTime()){
File file=fileResult.getFile();
if(file.exists()){
file.delete();
log.info("delete+"+fileResult.getFile().getPath()+">>>[lastEditTime:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(fileResult.getLastTime())+"]");
}
}
}
}
FileUtil.clear();
}
public Set<FileResult> getFileResults(String root){
Set<FileResult> set=new HashSet<FileResult>();
Set<File> fileList=FileUtil.queryRoot(new File(root));
for (File file : fileList) {
FileResult fileResult=new FileResult();
fileResult.setFile(file);
fileResult.setLastTime(new Date(file.lastModified()));
fileResult.setName(file.getName());
set.add(fileResult);
}
return set;
}
}
小试了一把,不得不说,还真是开箱即用,配置简单。最近公司要由svn改用git了,码云开通很久了,一直没用过,正好,传到码云上练练手,对git 和spring boot有兴趣的小伙们可以去码云上https://gitee.com/gaoxing27/cleanFile.git下载源码参考一下。