背景:需要定时将服务器下的日志文件上传到指定FTP服务器的目录下,并通知第三方平台文件已上传。
FTP服务器模拟工具:
application.yml配置:
spring:
logfilepath: /home/jboss/server/default/log
# ftp配置
ftp:
ip: 192.*****
port: 21
username: root
password: 123456
path: /FtpRoot/ZZDT12/
subsystem: CCTV/
# 智能运维平台配置
znyw:
# ftp文件上传后通知智能运维系统地址
filestatusurl: http://***:7000/imaster/log/upload
# 日志文件每天 23 点 58 分执行上传、通知智能运维平台一次
scan: "0 58 23 * * ?"
# 线路编码
lineid: 12
# 子系统编码
subsystemid: 10
servlet:
multipart:
enabled: true
# 根据实际需求作调整
max-file-size: -1
max-request-size: -1
定时任务:
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.vcom.nms.service.IFileUploadService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
/**
* 运维对接-日志文件上报接口
*/
@Configuration
public class LogFilePushTask extends BaseTask {
private static final Logger logger = LoggerFactory.getLogger(LogFilePushTask.class);
@Autowired
private IFileUploadService fileUploadService;
@Value("${spring.logfilepath}")
private String SYS_LOG_FILE_PATH;
/**
* 日志文件每天 23 点 58 分执行上传、通知智能运维平台一次
*/
@Scheduled(cron = "${spring.znyw.scan}")
private void fileUploadTask() {
logger.info("============come in fileUploadTask============");
List<MultipartFile> multipartFileList = new ArrayList<>();
try {
multipartFileList = getFilesAsMultipart(SYS_LOG_FILE_PATH);
} catch (IOException e) {
logger.error("io Exc:", e);
} catch (Exception e) {
logger.error("Exc:", e);
}
logger.info("此次上传文件共:" + multipartFileList.size());
multipartFileList.forEach(file -> {
String fileName = fileUploadService.uploadFileAndNotice(file);
if (StringUtils.isNotBlank(fileName)) {
logger.info("成功上传日志文件:" + fileName);
}
});
}
public static List<MultipartFile> getFilesAsMultipart(String directoryPath) throws IOException {
List<MultipartFile> multipartFiles = new ArrayList<>();
File directory = new File(directoryPath);
File[] files = directory.listFiles();
for (File file : files) {
multipartFiles.add(convertToMultipart(file));
}
return multipartFiles;
}
private static MultipartFile convertToMultipart(File file) throws IOException {
byte[] fileContent = Files.readAllBytes(file.toPath());
return new MockMultipartFile(file.getName(), file.getName(), "text/plain", fileContent);
}
}
接口类:
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
public interface IFileUploadService {
/**
* @Description: 上传文件到ftp服务器并通知智能运维平台
* @param file
* @return:
* @Author: hyh
* @Date: 2023/4/19 9:19
*/
String uploadFileAndNotice(MultipartFile file);
/**
* @Description: 通知智能运维平台文件上传
* @param fileName
* @return:
* @Author: hyh
* @Date: 2023/4/19 11:13
*/
void noticZnywFileStatus(String fileName);
/**
* @Description: 根据文件名称查看是否成功上传
* @param fileName
* @return:
* @Author: hyh
* @Date: 2023/4/19 13:28
*/
List getFileNameList(String fileName);
}
接口实现类:
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Service
public class FileUploadServiceImpl implements IFileUploadService {
private static final Logger logger = LoggerFactory.getLogger(FileUploadServiceImpl.class);
@Autowired
private final FtpUtil ftpUtil;
@Value("${spring.ftp.path}")
private String FTP_ROOT_DIR;
@Value("${spring.ftp.subsystem}")
private String SUBSYSTEM_NAME;
@Value("${spring.znyw.filestatusurl}")
private String ZNYW_FILE_STATUS_URL;
@Value("${spring.znyw.lineid}")
private int ZNYW_LINEID;
@Value("${spring.znyw.subsystemid}")
private int ZNYW_SUBSYSTEMID;
private FileUploadServiceImpl(FtpUtil ftpUtil) {
this.ftpUtil = ftpUtil;
}
@Override
public String uploadFileAndNotice(MultipartFile file) {
if (!ftpUtil.checkFileSize(file.getSize(), 100, "M")) {
logger.warn("文件{}大小超过100MB,不予上传!", file.getOriginalFilename());
return null;
}
String fileName = "";
try {
// 读取文件信息
String name = file.getOriginalFilename();
InputStream fileInputStream = file.getInputStream();
//年月日
LocalDate date = LocalDate.now();
DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyyMMdd");
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy_MM_dd");
fileName = date.format(formatter2) + "_" + name;
// 上传文件到 Ftp 服务
boolean flag = ftpUtil.upload(FTP_ROOT_DIR + SUBSYSTEM_NAME + date.format(formatter1), fileName, fileInputStream);
//通知智能运维平台
if (!(flag && syncMsgToZnywPlatform(fileName))) {
logger.error(flag + ":{}文件上传失败!", file.getOriginalFilename());
return null;
}
} catch (IOException e) {
logger.error("文件上传失败!", String.valueOf(e));
}
return fileName;
}
@Override
public void noticZnywFileStatus(String fileName) {
syncMsgToZnywPlatform(fileName);
}
@Override
public List getFileNameList(String fileName) {
Pattern pattern = Pattern.compile("\\d{4}_\\d{2}_\\d{2}");
Matcher matcher = pattern.matcher(fileName);
String directory = "";
if (matcher.find()) {
directory = matcher.group().replace("_", "");
} else {
throw new RuntimeException("文件名称格式不正确!");
}
String path = FTP_ROOT_DIR + SUBSYSTEM_NAME + directory;
return ftpUtil.getFileNameList(path);
}
//同步ftp文件上传信息到智能运维平台
public boolean syncMsgToZnywPlatform(String fileName) {
Response response = null;
long timestamp = System.currentTimeMillis();
try {
OkHttpClient client = new OkHttpClient().newBuilder()
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.build();
MediaType mediaType = MediaType.parse("text/plain");
RequestBody body = RequestBody.create(mediaType, "");
Request request = new Request.Builder()
.url(ZNYW_FILE_STATUS_URL + "?lineId=" + ZNYW_LINEID + "&systemId=" + ZNYW_SUBSYSTEMID + "&fileName=" + fileName)
.method("POST", body)
.addHeader("Content-Type", "application/json")
.build();
response = client.newCall(request).execute();
if (response.isSuccessful()) {
String res = response.body().string();
logger.info("操作:通知智能运维系统,请求客户端返回信息:{}", res);
return true;
}
} catch (Exception e) {
logger.error("IOException={}", e.getMessage());
return false;
} finally {
if (null != response) {
response.close();
}
logger.info("fileStatusUpload_time:" + (System.currentTimeMillis() - timestamp));
}
return false;
}
}