自动生成日志、自动上传FTP日志服务器

807 阅读3分钟

需求:应用端把审计日志按照特定的格式(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/