fix(upms): aggregate log statistics in database (#7568)

This commit is contained in:
PIGCLOUD committed 2026-08-01 11:59:35 +08:00
1 parent 0a15577761
commit d3afca673e
4 files changed
+98 -24

No files matched your search

@@ -22,6 +22,11 @@ package com.pig4cloud.pigx.admin.mapper;
import com.pig4cloud.pigx.admin.api.entity.SysLog;
import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
/**
* <p>
@@ -34,4 +39,11 @@ import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface SysLogMapper extends PigxBaseMapper<SysLog> {
/**
* 按日期和日志类型聚合日志数量
* @param startTime 开始时间
* @return 聚合结果
*/
List<Map<String, Object>> selectLogSum(@Param("startTime") LocalDateTime startTime);
}
@@ -19,8 +19,6 @@
package com.pig4cloud.pigx.admin.service.impl;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -40,10 +38,11 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.TreeMap;
/**
* <p>
@@ -124,27 +123,20 @@ public class SysLogServiceImpl extends ServiceImpl<SysLogMapper, SysLog> impleme
*/
@Override
public List<Map<String, Object>> getLogSum() {
// 查询createTime最近30天的数据
List<SysLog> sysLogList = baseMapper
.selectList(Wrappers.<SysLog>lambdaQuery().ge(SysLog::getCreateTime, LocalDateTime.now().minusDays(30)));
List<Map<String, Object>> logSumList = baseMapper.selectLogSum(LocalDateTime.now().minusDays(30));
Map<String, Map<String, Object>> resultMap = new TreeMap<>();
return sysLogList.stream()
// 按照日期进行分组
.collect(Collectors.groupingBy(log -> DateUtil.format(log.getCreateTime(), DatePattern.NORM_DATE_PATTERN)))
.entrySet()
.stream()
// 将每个日期对应的日志按日志类型分组,并计算每种类型的日志数量
.map(entry -> {
Map<String, Object> map = entry.getValue()
.stream()
.collect(Collectors.groupingBy(SysLog::getLogType,
Collectors.collectingAndThen(Collectors.counting(), Long::intValue)));
map.put(SysLog.Fields.createTime, entry.getKey());
return map;
})
// 按createTime升序排序
.sorted(Comparator.comparing(map -> map.get(SysLog.Fields.createTime).toString()))
.toList();
for (Map<String, Object> row : logSumList) {
String createTime = row.get(SysLog.Fields.createTime).toString();
Map<String, Object> logSum = resultMap.computeIfAbsent(createTime, key -> {
Map<String, Object> item = new LinkedHashMap<>();
item.put(SysLog.Fields.createTime, key);
return item;
});
logSum.put(row.get(SysLog.Fields.logType).toString(), ((Number) row.get("logCount")).intValue());
}
return new ArrayList<>(resultMap.values());
}
}
@@ -21,4 +21,14 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pig4cloud.pigx.admin.mapper.SysLogMapper">
<select id="selectLogSum" resultType="java.util.Map">
SELECT DATE(create_time) AS "createTime",
log_type AS "logType",
COUNT(*) AS "logCount"
FROM sys_log
WHERE create_time >= #{startTime}
GROUP BY DATE(create_time), log_type
ORDER BY DATE(create_time), log_type
</select>
</mapper>
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.admin.service.impl;
import com.pig4cloud.pigx.admin.mapper.SysLogMapper;
import org.junit.jupiter.api.Test;
import org.springframework.test.util.ReflectionTestUtils;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
class SysLogServiceImplTests {
@Test
void getLogSumUsesDatabaseAggregationAndKeepsResponseShape() {
SysLogMapper sysLogMapper = mock(SysLogMapper.class);
SysLogServiceImpl service = new SysLogServiceImpl();
ReflectionTestUtils.setField(service, "baseMapper", sysLogMapper);
when(sysLogMapper.selectLogSum(any()))
.thenReturn(List.of(row("2026-07-13", "0", 12L), row("2026-07-13", "9", 3L), row("2026-07-14", "0", 8L)));
when(sysLogMapper.selectList(any())).thenThrow(new AssertionError("不应加载日志实体进行内存聚合"));
List<Map<String, Object>> result = service.getLogSum();
assertThat(result).containsExactly(Map.of("createTime", "2026-07-13", "0", 12, "9", 3),
Map.of("createTime", "2026-07-14", "0", 8));
verify(sysLogMapper).selectLogSum(any());
}
private Map<String, Object> row(String createTime, String logType, long logCount) {
Map<String, Object> row = new LinkedHashMap<>();
row.put("createTime", createTime);
row.put("logType", logType);
row.put("logCount", logCount);
return row;
}
}