Junjie
7 小时以前 8bfe1168a42d4e3750a15b0c0fb0a7629d6cf91c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
package com.zy.system.service.impl;
 
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.core.exception.CoolException;
import com.zy.system.entity.Config;
import com.zy.system.mapper.LogCleanupMapper;
import com.zy.system.model.LogCleanupExecutionResult;
import com.zy.system.service.ConfigService;
import com.zy.system.service.LogCleanupService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
 
@Slf4j
@Service("logCleanupService")
public class LogCleanupServiceImpl implements LogCleanupService {
 
    private static final String CONFIG_CODE_EXPIRE_DAYS = "logCleanupExpireDays";
    private static final int DEFAULT_EXPIRE_DAYS = 180;
    private static final int DELETE_BATCH_LIMIT = 50000;
    private static final String MODE_ALL = "all";
    private static final String MODE_SELECTED = "selected";
    private static final Map<String, String> SUPPORTED_TABLES = new LinkedHashMap<>();
    private static final Map<String, String> TIME_COLUMNS = new LinkedHashMap<>();
 
    static {
        register("asr_bas_crnp_opt", "堆垛机操作日志", "update_time");
        register("asr_bas_dual_crnp_opt", "双工位堆垛机操作日志", "update_time");
        register("asr_bas_rgv_err_log", "RGV故障日志", "create_time");
        register("asr_wrk_mast_log", "工作档日志", "modi_time");
        register("asr_bas_dual_crnp_err_log", "双工位堆垛机故障日志", "create_time");
        register("asr_bas_station_err_log", "站点故障日志", "create_time");
        register("asr_bas_station_opt", "站点操作日志", "update_time");
        register("asr_wrk_analysis", "任务执行分析", "finish_time");
        register("sys_http_request_log", "HTTP请求日志", "create_time");
        register("sys_operate_log", "操作日志", "create_time");
    }
 
    @Autowired
    private ConfigService configService;
    @Autowired
    private LogCleanupMapper logCleanupMapper;
 
    @Override
    public Integer getExpireDays() {
        Config config = configService.getOne(new QueryWrapper<Config>().eq("code", CONFIG_CODE_EXPIRE_DAYS));
        if (config == null || config.getValue() == null || config.getValue().trim().isEmpty()) {
            return DEFAULT_EXPIRE_DAYS;
        }
        try {
            int value = Integer.parseInt(config.getValue().trim());
            return value > 0 ? value : DEFAULT_EXPIRE_DAYS;
        } catch (NumberFormatException ignore) {
            return DEFAULT_EXPIRE_DAYS;
        }
    }
 
    @Override
    public void saveExpireDays(Integer expireDays) {
        int normalized = normalizeExpireDays(expireDays);
        Config config = configService.getOne(new QueryWrapper<Config>().eq("code", CONFIG_CODE_EXPIRE_DAYS));
        if (config == null) {
            config = new Config();
            config.setName("日志流水清理保留天数");
            config.setCode(CONFIG_CODE_EXPIRE_DAYS);
            config.setValue(String.valueOf(normalized));
            config.setType((short) 1);
            config.setStatus((short) 1);
            config.setSelectType("develop");
            configService.save(config);
            return;
        }
        config.setValue(String.valueOf(normalized));
        configService.updateById(config);
    }
 
    @Override
    public LogCleanupExecutionResult cleanupAll(Integer expireDays) {
        return executeCleanup(MODE_ALL, expireDays, new ArrayList<>(SUPPORTED_TABLES.keySet()));
    }
 
    @Override
    public LogCleanupExecutionResult cleanupSelected(Integer expireDays, List<String> tables) {
        if (tables == null || tables.isEmpty()) {
            throw new CoolException("请选择至少一张日志表");
        }
        LinkedHashSet<String> normalized = new LinkedHashSet<>();
        for (String table : tables) {
            if (table == null || table.trim().isEmpty()) {
                continue;
            }
            String tableName = table.trim();
            if (!SUPPORTED_TABLES.containsKey(tableName)) {
                throw new CoolException("存在不支持清理的日志表: " + tableName);
            }
            normalized.add(tableName);
        }
        if (normalized.isEmpty()) {
            throw new CoolException("请选择至少一张日志表");
        }
        return executeCleanup(MODE_SELECTED, expireDays, new ArrayList<>(normalized));
    }
 
    @Override
    public LogCleanupExecutionResult cleanupScheduled() {
        try {
            return cleanupAll(getExpireDays());
        } catch (Exception ex) {
            log.error("日志流水定时清理失败", ex);
            throw ex;
        }
    }
 
    @Override
    public Map<String, String> getSupportedTables() {
        return new LinkedHashMap<>(SUPPORTED_TABLES);
    }
 
    private LogCleanupExecutionResult executeCleanup(String mode, Integer expireDays, List<String> tables) {
        int normalized = normalizeExpireDays(expireDays);
        LogCleanupExecutionResult result = new LogCleanupExecutionResult();
        result.setMode(mode);
        result.setExpireDays(normalized);
        result.setExecuteTime(System.currentTimeMillis());
        long totalDeleted = 0L;
        for (String table : tables) {
            long tableDeleted = deleteTable(table, TIME_COLUMNS.get(table), normalized);
            result.getDetail().put(table, tableDeleted);
            totalDeleted += tableDeleted;
        }
        result.setTotalDeleted(totalDeleted);
        return result;
    }
 
    private long deleteTable(String table, String timeColumn, int expireDays) {
        long deleted = 0L;
        while (true) {
            int affected = logCleanupMapper.deleteExpiredBatch(table, timeColumn, expireDays, DELETE_BATCH_LIMIT);
            if (affected <= 0) {
                break;
            }
            deleted += affected;
            if (affected < DELETE_BATCH_LIMIT) {
                break;
            }
        }
        return deleted;
    }
 
    private int normalizeExpireDays(Integer expireDays) {
        if (expireDays == null || expireDays <= 0) {
            throw new CoolException("日志保留天数必须大于0");
        }
        return expireDays;
    }
 
    private static void register(String table, String label, String timeColumn) {
        SUPPORTED_TABLES.put(table, label);
        TIME_COLUMNS.put(table, timeColumn);
    }
}