package com.system.batch;
public class LogGenerator {
private static final String ROOT_PATH = "./test-logs";
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
public static void main(String[] args) throws IOException {
File dir = new File(ROOT_PATH);
if (!dir.exists()) {
dir.mkdirs();
}
// 파일 이름에 날짜를 포함하여 생성 (예: access_2025-01-01.log)
createLogFile(dir, "access", 2); // 2일 전
createLogFile(dir, "access", 0); // 오늘
createLogFile(dir, "service", 50); // 50일 전
createLogFile(dir, "service", 100); // 100일 전
// 날짜 형식이 없는 예외 파일도 하나 추가 (삭제되면 안 됨)
createLogFile(dir, "system_config.conf", -1);
System.out.println("테스트용 로그 파일 생성 완료! 경로 확인: " + ROOT_PATH);
}
private static void createLogFile(File dir, String prefix, int daysAgo) throws IOException {
String filename;
if (daysAgo == -1) {
// 날짜 패턴이 없는 일반 파일
filename = prefix;
} else {
// 날짜 패턴 적용: prefix_yyyy-MM-dd.log
LocalDate targetDate = LocalDate.now().minusDays(daysAgo);
String dateStr = targetDate.format(DATE_FORMATTER);
filename = prefix + "_" + dateStr + ".log";
}
File file = new File(dir, filename);
if (file.createNewFile()) {
System.out.println("파일 생성됨: " + filename);
} else {
System.out.println("이미 존재함: " + filename);
}
}
> Task :com.system.batch.LogGenerator.main()
파일 생성됨: access_2026-01-26.log
파일 생성됨: access_2026-01-28.log
파일 생성됨: service_2025-12-09.log
파일 생성됨: service_2025-10-20.log
파일 생성됨: system_config.conf
테스트용 로그 파일 생성 완료! 경로 확인: ./test-logs
샘플 파일 생성 확인
✅ 2. Tasklet방식으로 배치 작성하기
FileCleanupTasklet.java
package com.system.batch;
@Slf4j
public class FileCleanupTasklet implements Tasklet {
private final String rootPath;
private final int retentionDays;
public FileCleanupTasklet(String rootPath, int retentionDays){
this.rootPath = rootPath;
this.retentionDays = retentionDays;
}
@Override
public @Nullable RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) {
LocalDate cutoffDate = LocalDate.now().minusDays(retentionDays);
File folder = new File(rootPath);
File[] files = folder.listFiles();
if (files == null) return RepeatStatus.FINISHED;
for (File file : files) {
String name = file.getName();
// 1. 로그 파일 형식인지 간단히 체크 (예: .log 포함 여부)
if (name.endsWith(".log") && name.length() >= 10) {
// 2. 파일명에서 날짜 부분만 추출
// access_2026-01-26.log -> "2026-01-26" 부분 추출
try {
String dateStr = name.substring(name.lastIndexOf("_") + 1, name.lastIndexOf("."));
LocalDate fileDate = LocalDate.parse(dateStr); // 기본 ISO_LOCAL_DATE(yyyy-MM-dd) 사용
if (fileDate.isBefore(cutoffDate)) {
file.delete();
log.info("삭제된 로그: {}", name);
}
} catch (Exception e) {
// 날짜 형식이 아니거나 파싱 불가능한 파일(system_config.conf 등)은 자연스럽게 스킵
continue;
}
}
}
return RepeatStatus.FINISHED;
}
}
✅ 3. 작성한 배치 Step과 Job으로 등록하기
FileCleanupConfig.java
package com.system.batch;
@Slf4j
@Configuration
@RequiredArgsConstructor
public class FileCleanupConfig {
private final JobRepository jobRepository;
private final PlatformTransactionManager transactionManager;
@Bean
public Tasklet fileCleanupTasklet(){
return new FileCleanupTasklet("./test-logs", 30);
}
@Bean
public Step fileCleanupStep(){
return new StepBuilder("fileCleanupStep", jobRepository)
.tasklet(fileCleanupTasklet(), transactionManager)
.build();
}
@Bean
public Job fileCleanupJob(){
return new JobBuilder("fileCleanupJob", jobRepository)
.start(fileCleanupStep())
.build();
}
}
✅ 4. 배치 실행 확인하기
# 각 운영체제에 맞는 명령문으로 배치 실행
./gradlew bootRun --args='--spring.batch.job.name=fileCleanupJob'