需求:应用端把审计日志按照特定的格式(txt)写入到文件,每个文件保证包含完整的日志信息, 每个文件控制在10000条及以内,由应用侧把文件通过SFTP/FTP协议传输到审计系统指定的文件服务器目录下。
1.本地生成日志文件
1.1新建一个日志对象
1.2对象赋值
1.3对象转成JSON
AuditLogEntity au = new AuditLogEntity();
au.setLOG_ID(UUID.randomUUID().toString());
String content = JSON.toJSONString(au);
1.4在本地路径生成日志文件
1.4.1获取写入文件
获取目录下目录下最新一个文件为写入文件,判断条件为最后修改时间
/**
* 获取最后一个文件名称
* @path 文件目录地址
* @return 最后一个文件名称, 按修改时间倒排序
*/
public String getLastFileName(String path) {
File filePath = new File(path);
File[] files = filePath.listFiles();
if (files.length > 0) {
if (files.length > 1) {
Arrays.sort(files, new Comparator<File>() {
@Override
public int compare(File file1, File file2) {
return (int) (file2.lastModified() - file1.lastModified());
}
});
}
return files[0].getName();
} else {
return null;
}
}
1.4.2获取文件和内容
根据文件名称获取文件和封装后的内容
- 封装内容为每条日志为一行,需在开头增加换行
- 每个日志不件不超过10000行
- 日志名称格式为20210601_001.txt
- 超过行数重新按规格生成一个新的文件,20210601_002.txt,以此类推
/**
* 根据文件名组装路径获取文件
* @return path
*/
public Map getFilePath(String content, String lastFileName) {
String prefix = "d:/ftpTest/";
String filepath;
String uploadName = new SimpleDateFormat("yyyyMMdd").format(new Date());
if (null != lastFileName && lastFileName.startsWith(uploadName)) {
filepath = prefix + lastFileName;
} else {
filepath = prefix + new SimpleDateFormat("yyyyMMdd").format(new Date()) + "_001.txt";
}
File file = new File(filepath);
//获取现有文件行数
long lineNumber = getLineNumber(file);
logger.info("文件现有行数为--》" + lineNumber);
//如果大于规定行数
if (lineNumber > 0) {
//超过规定行数新生成文件
if (lineNumber > 10000) {
int num = Integer.parseInt(lastFileName.substring(10, 12));
num++;
String suffix = String.format("_%03d", num) + ".txt";
String fileName = new SimpleDateFormat("yyyyMMdd").format(new Date());
filepath = prefix + fileName + suffix;
} else {
//换行
content = "\n" + content;
}
}
Map map = new HashMap(2);
map.put("filepath", filepath);
map.put("content", content);
return map;
}
/**
* 获取文件行数
*
* @param file 文件
* @return 行数
*/
public long getLineNumber(File file) {
if (file.exists()) {
try {
FileReader fileReader = new FileReader(file);
LineNumberReader lineNumberReader = new LineNumberReader(fileReader);
lineNumberReader.skip(Long.MAX_VALUE);
long lines = lineNumberReader.getLineNumber() + 1;
fileReader.close();
lineNumberReader.close();
return lines;
} catch (IOException e) {
logger.error("读取文件行数异常!!");
e.printStackTrace();
}
}
return 0;
}
1.4.3写入文件
try {
String lastFileName = getLastFileName("D:/ftpTest/");
//根据文件名称获取文件和封装后的内容
Map m = getFilePath(content, lastFileName);
File file = new File(m.get("filepath").toString());
FileWriter fw = new FileWriter(file.getAbsoluteFile(), true);
BufferedWriter bw = new BufferedWriter(fw);
bw.write(m.get("content").toString());
bw.close();
fw.close();
logger.info("日志写入成功!");
} catch (Exception e) {
logger.error("日志写入失败!!");
e.printStackTrace();
}
2.上传文件
2.1连接FTP服务器
2.2获取路径下所的文件
2.3定时任务只上传前一天的日志文件
public void uploadFile() {
FTPClient ftp = new FTPClient();
try {
String prefix = "d:/ftpTest/";
File filePath = new File(prefix);
File[] files = filePath.listFiles();
if (files.length < 0) {
logger.error("没有找到指定文件,无法上传!!!");
} else {
int reply;
// 连接FTP服务器
ftp.connect("192.168.1.211", 21);
// 登录
ftp.login("test", "test");
reply = ftp.getReplyCode();
logger.error("reply----》" + reply);
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
}
//设置为被动模式
ftp.enterLocalPassiveMode();
//设置编码格式为utf-8
ftp.setControlEncoding("UTF-8");
//设置上传文件的类型为二进制类型
ftp.setFileType(FTP.BINARY_FILE_TYPE);
//设置存储的文件夹
ftp.changeWorkingDirectory("/home/test/data");
for (int i = 0; i < files.length; i++) {
String fileName = files[i].getName();
String uploadName = new SimpleDateFormat("yyyyMMdd").format(new Date().getTime() - 24 * 60 * 60 * 1000);
//只上传前一天的日志
if (fileName.startsWith(uploadName)) {
String path = prefix + fileName;
FileInputStream localFile = new FileInputStream(path);
//上传文件
boolean b = ftp.storeFile(fileName, localFile);
logger.info("{}上传结果----》{}", fileName, b);
localFile.close();
}
}
ftp.logout();
}
} catch (IOException e) {
logger.info("FTP上传失败!");
e.printStackTrace();
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
}
3.配置文件
#ftp服务器的地址
ftp.host=192.168.1.211
#ftp服务器的端口号(连接端口号)
ftp.port=21
#ftp的用户名
ftp.username=test
#ftp的密码
ftp.password=test
#ftp上传的根目录
ftp.remotePath=/home/test/data
#日志生成目录
ftp.localFilepath=d:/ftpTest/