Java自动记录日志并对根据日期对日志表自动创建或删除

自动创建和管理日志表:

每月自动生成新的日志表,并删除六个月前的旧日志表

日志记录:

通过切面记录方法执行前、执行后和异常时的日志,并将日志信息插入到当前月份的日志表中。

日志查询:

提供按日期范围查询日志的功能,支持跨月查询并汇总结果。

// 自动生成和管理日志表
@Service
public class LogTableManager {

    private final DataSource dataSource;

    public LogTableManager(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Scheduled(cron = "0 0 0 1 * ?") // 每月1号0点执行
    public void createMonthlyLogTable() {
        String month = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy_MM"));
        String tableName = "logs_" + month;
        String createTableSQL = String.format(
            "CREATE TABLE IF NOT EXISTS %s (" +
            "id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
            "timestamp TIMESTAMP NOT NULL, " +
            "log_message TEXT, " +
            "user_id BIGINT, " +
            "details JSON)", tableName
        );

        executeUpdate(createTableSQL);
    }

    @Scheduled(cron = "0 0 0 1 * ?") // 每月1号0点执行(根据需要调整)
    public void deleteOldLogTables() {
        LocalDate sixMonthsAgo = LocalDate.now().minusMonths(6);
        String pattern = "yyyy_MM";
        String oldTableNamePrefix = "logs_";

        for (LocalDate date = sixMonthsAgo.withDayOfMonth(1); date.isBefore(LocalDate.now()); date = date.plusMonths(1)) {
            String month = date.format(DateTimeFormatter.ofPattern(pattern));
            String tableName = oldTableNamePrefix + month;
            String dropTableSQL = "DROP TABLE IF EXISTS " + tableName;
            executeUpdate(dropTableSQL);
        }
    }

    private void executeUpdate(String sql) {
        CompletableFuture.runAsync(() -> {
            try (Connection conn = dataSource.getConnection(); Statement stmt = conn.createStatement()) {
                stmt.executeUpdate(sql);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }
}

// 日志服务
@Service
public class LogService {

    private final DataSource dataSource;

    public LogService(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public List<LogEntry> getLogsByDateRange(LocalDate startDate, LocalDate endDate) {
        List<LogEntry> logs = new ArrayList<>();
        String startMonth = startDate.format(DateTimeFormatter.ofPattern("yyyy_MM"));
        String endMonth = endDate.format(DateTimeFormatter.ofPattern("yyyy_MM"));

        LocalDate date = startDate;
        while (date.isBefore(endDate)) {
            String tableName = "logs_" + date.format(DateTimeFormatter.ofPattern("yyyy_MM"));
            String sql = String.format("SELECT * FROM %s WHERE timestamp BETWEEN ? AND ?", tableName);

            try (Connection conn = dataSource.getConnection();
                 PreparedStatement stmt = conn.prepareStatement(sql)) {

                stmt.setTimestamp(1, java.sql.Timestamp.valueOf(startDate.atStartOfDay()));
                stmt.setTimestamp(2, java.sql.Timestamp.valueOf(endDate.atStartOfDay()));

                try (ResultSet rs = stmt.executeQuery()) {
                    while (rs.next()) {
                        LogEntry entry = new LogEntry();
                        entry.setId(rs.getLong("id"));
                        entry.setTimestamp(rs.getTimestamp("timestamp").toLocalDateTime());
                        entry.setLogMessage(rs.getString("log_message"));
                        entry.setUserId(rs.getLong("user_id"));
                        entry.setDetails(rs.getString("details"));
                        logs.add(entry);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            date = date.plusMonths(1);
        }

        return logs;
    }
}

// 日志记录切面
@Aspect
@Component
public class LoggingAspect {

    @Autowired
    private DataSource dataSource;

    @Before("execution(* com.example..*(..))") // 指定需要记录日志的切点
    public void logBefore(JoinPoint joinPoint) {
        log("Before method: " + joinPoint.getSignature().toShortString());
    }

    @AfterReturning(pointcut = "execution(* com.example..*(..))", returning = "result")
    public void logAfterReturning(JoinPoint joinPoint, Object result) {
        log("After method: " + joinPoint.getSignature().toShortString() + " with result: " + result);
    }

    @AfterThrowing(pointcut = "execution(* com.example..*(..))", throwing = "exception")
    public void logAfterThrowing(JoinPoint joinPoint, Throwable exception) {
        log("Method: " + joinPoint.getSignature().toShortString() + " threw exception: " + exception);
    }

    private void log(String message) {
        String tableName = "logs_" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy_MM"));
        String sql = String.format(
            "INSERT INTO %s (timestamp, log_message) VALUES (?, ?)", tableName
        );

        CompletableFuture.runAsync(() -> {
            try (Connection conn = dataSource.getConnection();
                 PreparedStatement stmt = conn.prepareStatement(sql)) {

                stmt.setTimestamp(1, java.sql.Timestamp.valueOf(LocalDateTime.now()));
                stmt.setString(2, message);
                stmt.executeUpdate();
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }
}

// 日志条目数据结构
public class LogEntry {
    private Long id;
    private LocalDateTime timestamp;
    private String logMessage;
    private Long userId;
    private String details;

    // Getters and Setters
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值