添加系统日志状态接口

This commit is contained in:
2026-07-26 16:30:47 +08:00
parent 0b66f3d38d
commit b1064475e2
10 changed files with 234 additions and 20 deletions
@@ -2,6 +2,9 @@ package xtools.app.common.log.bus.service;
import xtools.boot.log.model.dto.LogBody; import xtools.boot.log.model.dto.LogBody;
import java.time.Instant;
import java.util.Map;
/** /**
* <p>Title : LogBusService</p> * <p>Title : LogBusService</p>
* <p>Description : LogBusService</p> * <p>Description : LogBusService</p>
@@ -29,4 +32,12 @@ public interface LogBusService {
*/ */
String total(); String total();
/**
* 获取指定日期的日志统计数据(按级别,从Redis读取)
*
* @param time 时间
* @return 日志级别编码 -> 数量
*/
Map<Integer, Long> getTotalByDay(Instant time);
} }
@@ -1,10 +1,19 @@
package xtools.app.sys.controller; package xtools.app.sys.controller;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import xtools.app.sys.model.dto.req.SysLogTotalStatsReq;
import xtools.app.sys.model.dto.resp.SysLogTotalStatsResp;
import xtools.app.sys.service.SysLogTotalService; import xtools.app.sys.service.SysLogTotalService;
import xtools.boot.api.model.dto.Result;
import java.util.List;
/** /**
* <p>Title : SysLogTotalController</p> * <p>Title : SysLogTotalController</p>
@@ -22,4 +31,16 @@ import xtools.app.sys.service.SysLogTotalService;
public class SysLogTotalController { public class SysLogTotalController {
private final SysLogTotalService sysLogTotalService; private final SysLogTotalService sysLogTotalService;
/**
* 获取统计信息
*
* @param req 统计请求(时间范围)
* @return 统计信息
*/
@Operation(summary = "获取统计信息")
@PostMapping("stats")
public Result<List<SysLogTotalStatsResp>> getStats(@RequestBody @Valid SysLogTotalStatsReq req) {
return sysLogTotalService.getStats(req);
}
} }
@@ -1,17 +0,0 @@
package xtools.app.sys.convert;
import org.mapstruct.Mapper;
/**
* <p>Title : SysLogTotalConvert</p>
* <p>Description : 系统日志统计表 Convert</p>
* <p>Company : org.xujun</p>
*
* @author : xujun
* @version : 1.0.0
* @date : 2026-07-26 11:14:47
*/
@Mapper(componentModel = "spring")
public interface SysLogTotalConvert {
}
@@ -2,8 +2,13 @@ package xtools.app.sys.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import xtools.app.sys.model.dto.resp.SysLogTotalStatsResp;
import xtools.app.sys.model.entity.SysLogTotal; import xtools.app.sys.model.entity.SysLogTotal;
import java.time.Instant;
import java.util.List;
/** /**
* <p>Title : SysLogTotalMapper</p> * <p>Title : SysLogTotalMapper</p>
* <p>Description : 系统日志统计表 Mapper 接口</p> * <p>Description : 系统日志统计表 Mapper 接口</p>
@@ -16,4 +21,16 @@ import xtools.app.sys.model.entity.SysLogTotal;
@Mapper @Mapper
public interface SysLogTotalMapper extends BaseMapper<SysLogTotal> { public interface SysLogTotalMapper extends BaseMapper<SysLogTotal> {
/**
* 按天统计日志数量(按级别)
*
* @param startTime 开始时间(包含)
* @param endTime 结束时间(包含)
* @return 每日统计列表
*/
List<SysLogTotalStatsResp> selectStats(
@Param("startTime") Instant startTime,
@Param("endTime") Instant endTime
);
} }
@@ -0,0 +1,35 @@
package xtools.app.sys.model.dto.req;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.Instant;
/**
* <p>Title : SysLogTotalStatsReq</p>
* <p>Description : 系统日志统计请求对象</p>
* <p>Company : org.xujun</p>
*
* @author : xujun
* @version : 1.0.0
* @date : 2026-07-26
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SysLogTotalStatsReq implements Serializable {
/**
* 数据时间范围[开始时间(包含),结束时间(包含)],不能为空且需同时包含开,结束时间
*/
@NotNull(message = "时间范围不能为空")
@Size(min = 2, message = "时间范围需要包含开始和结束时间")
@Schema(description = "数据时间范围(包含两端)", example = "['2026-07-17 00:00:00', '2026-07-24 23:59:59']")
private Instant[] dataTimeRange;
}
@@ -0,0 +1,57 @@
package xtools.app.sys.model.dto.resp;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.Instant;
/**
* <p>Title : SysLogTotalStatsResp</p>
* <p>Description : 系统日志每日统计响应对象(按级别)</p>
* <p>Company : org.xujun</p>
*
* @author : xujun
* @version : 1.0.0
* @date : 2026-07-26
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SysLogTotalStatsResp implements Serializable {
/**
* 当天(Instant,当天 0 点)
*/
@Schema(description = "当天(Instant,当天 0 点)")
private Instant day;
/**
* DEBUG 数量
*/
@Schema(description = "DEBUG 数量")
private Long debugCount;
/**
* INFO 数量
*/
@Schema(description = "INFO 数量")
private Long infoCount;
/**
* WARN 数量
*/
@Schema(description = "WARN 数量")
private Long warnCount;
/**
* ERROR 数量
*/
@Schema(description = "ERROR 数量")
private Long errorCount;
}
@@ -1,5 +1,11 @@
package xtools.app.sys.service; package xtools.app.sys.service;
import xtools.app.sys.model.dto.req.SysLogTotalStatsReq;
import xtools.app.sys.model.dto.resp.SysLogTotalStatsResp;
import xtools.boot.api.model.dto.Result;
import java.util.List;
/** /**
* <p>Title : SysLogTotalService</p> * <p>Title : SysLogTotalService</p>
* <p>Description : 系统日志统计表 Service</p> * <p>Description : 系统日志统计表 Service</p>
@@ -11,4 +17,12 @@ package xtools.app.sys.service;
*/ */
public interface SysLogTotalService { public interface SysLogTotalService {
/**
* 获取统计信息
*
* @param req 统计请求(时间范围)
* @return 统计信息
*/
Result<List<SysLogTotalStatsResp>> getStats(SysLogTotalStatsReq req);
} }
@@ -205,6 +205,7 @@ public class LogBusServiceImpl implements LogBusService, BaseParams {
* @param time 时间 * @param time 时间
* @return 统计数据 * @return 统计数据
*/ */
@Override
public Map<Integer, Long> getTotalByDay(Instant time) { public Map<Integer, Long> getTotalByDay(Instant time) {
Map<Integer, Long> result = new HashMap<>(); Map<Integer, Long> result = new HashMap<>();
if (Objects.isNull(time)) { if (Objects.isNull(time)) {
@@ -3,9 +3,24 @@ package xtools.app.sys.service.impl;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import xtools.app.sys.convert.SysLogTotalConvert; import xtools.app.common.log.bus.service.LogBusService;
import xtools.app.sys.model.dto.req.SysLogTotalStatsReq;
import xtools.app.sys.model.dto.resp.SysLogTotalStatsResp;
import xtools.app.sys.service.SysLogTotalService; import xtools.app.sys.service.SysLogTotalService;
import xtools.app.sys.service.base.SysLogTotalBaseService; import xtools.app.sys.service.base.SysLogTotalBaseService;
import xtools.base.config.BaseParams;
import xtools.boot.api.exection.BizWarning;
import xtools.boot.api.model.dto.Result;
import xtools.core.CollectionUtils;
import xtools.core.enums.LogLevel;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/** /**
* <p>Title : SysLogTotalServiceImpl</p> * <p>Title : SysLogTotalServiceImpl</p>
@@ -19,10 +34,52 @@ import xtools.app.sys.service.base.SysLogTotalBaseService;
@Primary @Primary
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
public class SysLogTotalServiceImpl implements SysLogTotalService { public class SysLogTotalServiceImpl implements SysLogTotalService, BaseParams {
private final SysLogTotalBaseService sysLogTotalBaseService; private final SysLogTotalBaseService sysLogTotalBaseService;
private final SysLogTotalConvert sysLogTotalConvert; private final LogBusService logBusService;
/**
* 获取统计信息
* <p>小于今天的数据从数据库获取;包含今天的数据从Redis获取(今天尚未落库)</p>
*
* @param req 统计请求(时间范围)
* @return 统计信息
*/
@Override
public Result<List<SysLogTotalStatsResp>> getStats(SysLogTotalStatsReq req) {
Instant[] range = req.getDataTimeRange();
if (Objects.isNull(range) || range.length != CP_NUM2) {
throw new BizWarning("时间范围不能为空且需要包含开始和结束时间");
}
// 判断开始时间不能大于结束时间
Instant startTime = range[CP_NUM0];
Instant endTime = range[CP_NUM1];
if (startTime.isAfter(endTime)) {
throw new BizWarning("开始时间不能大于结束时间");
}
List<SysLogTotalStatsResp> dbList = sysLogTotalBaseService.getBaseMapper().selectStats(startTime, endTime);
List<SysLogTotalStatsResp> list = new ArrayList<>(dbList.size() + CP_NUM1);
if (CollectionUtils.isNotEmpty(dbList)) {
list.addAll(dbList);
}
// 判断是否包含今天的数据
long now = System.currentTimeMillis();
if (now >= startTime.toEpochMilli() && now <= endTime.toEpochMilli()) {
Instant day = LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant();
Map<Integer, Long> totalMap = logBusService.getTotalByDay(day);
Long defCount = 0L;
// 今天的数据追加到末尾
list.add(SysLogTotalStatsResp.builder()
.day(day)
.debugCount(totalMap.getOrDefault(LogLevel.DEBUG.code(), defCount))
.infoCount(totalMap.getOrDefault(LogLevel.INFO.code(), defCount))
.warnCount(totalMap.getOrDefault(LogLevel.WARN.code(), defCount))
.errorCount(totalMap.getOrDefault(LogLevel.ERROR.code(), defCount))
.build());
}
return Result.ok(list);
}
} }
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="xtools.app.sys.mapper.SysLogTotalMapper">
<!-- 按天统计日志数量(按级别) -->
<select id="selectStats" resultType="xtools.app.sys.model.dto.resp.SysLogTotalStatsResp">
SELECT DATE(data_time) AS day,
COALESCE(SUM(CASE WHEN level = 0 THEN `count` END), 0) AS debugCount,
COALESCE(SUM(CASE WHEN level = 1 THEN `count` END), 0) AS infoCount,
COALESCE(SUM(CASE WHEN level = 2 THEN `count` END), 0) AS warnCount,
COALESCE(SUM(CASE WHEN level = 3 THEN `count` END), 0) AS errorCount
FROM sys_log_total
WHERE data_time BETWEEN #{startTime} AND #{endTime}
GROUP BY DATE(data_time)
ORDER BY day
</select>
</mapper>