添加系统日志统计

This commit is contained in:
2026-07-26 12:07:16 +08:00
parent 7a5fcb0853
commit 0b66f3d38d
13 changed files with 394 additions and 6 deletions
@@ -0,0 +1,25 @@
package xtools.app.sys.controller;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import xtools.app.sys.service.SysLogTotalService;
/**
* <p>Title : SysLogTotalController</p>
* <p>Description : 系统日志统计表 Controller</p>
* <p>Company : org.xujun</p>
*
* @author : xujun
* @version : 1.0.0
* @date : 2026-07-26 11:14:47
*/
@RequiredArgsConstructor
@Tag(name = "系统日志统计表")
@RestController
@RequestMapping("/sys/log-total")
public class SysLogTotalController {
private final SysLogTotalService sysLogTotalService;
}
@@ -0,0 +1,17 @@
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 {
}
@@ -0,0 +1,69 @@
package xtools.app.sys.job;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import xtools.app.common.job.base.BaseJob;
import xtools.app.common.log.bus.service.LogBusService;
import xtools.app.common.task.enums.TaskType;
import xtools.boot.log.LogBus;
import xtools.boot.log.enums.LogBusBaseType;
import xtools.boot.task.TaskBus;
import xtools.boot.task.enums.TaskStatus;
import xtools.core.UuidUtils;
import xtools.core.enums.LogLevel;
import java.util.Objects;
/**
* <p>Title : SysLogTotalJob</p>
* <p>Description : SysLogTotalJob</p>
* <p>DevelopTools : Idea_x64_v2026.1</p>
* <p>DevelopSystem : macOS Sequoia 15.7.5</p>
* <p>Company : org.xujun</p>
*
* @author : XuJun
* @version : 1.0.0
* @date : 2026/3/17 21:24
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class SysLogTotalJob extends BaseJob {
private final LogBusService logBusService;
/**
* 运行作业
*/
@Override
public void runJob() {
// 任务日志code
String code = UuidUtils.get();
// 任务类型
TaskType taskType = TaskType.TOTAL_SYS_LOG;
// 任务信息
String info = "开始统计昨天的日志信息,请稍候...";
// 保存任务
TaskBus.init(code, taskType, TaskStatus.ING).info(info).save();
// 异常
Exception ex = null;
try {
// 记录任务日志
info = logBusService.total();
} catch (Exception e) {
ex = e;
info = "执行失败";
throw e;
} finally {
// 保存任务
TaskStatus status = Objects.isNull(ex) ? TaskStatus.SUCCESS : TaskStatus.ERROR;
TaskBus.init(code, taskType, status).info(info).save();
if (Objects.nonNull(ex)) {
// 保存异常日志
LogBus.init(LogLevel.ERROR, LogBusBaseType.TASK).error(ex).save();
}
}
}
}
@@ -0,0 +1,19 @@
package xtools.app.sys.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import xtools.app.sys.model.entity.SysLogTotal;
/**
* <p>Title : SysLogTotalMapper</p>
* <p>Description : 系统日志统计表 Mapper 接口</p>
* <p>Company : org.xujun</p>
*
* @author : xujun
* @version : 1.0.0
* @date : 2026-07-26 11:14:47
*/
@Mapper
public interface SysLogTotalMapper extends BaseMapper<SysLogTotal> {
}
@@ -24,19 +24,27 @@ import java.time.Instant;
@AllArgsConstructor
public class SysTaskStatsResp implements Serializable {
/** 当天(Instant,当天 0 点) */
/**
* 当天(Instant,当天 0 点)
*/
@Schema(description = "当天(Instant,当天 0 点)")
private Instant day;
/** 成功数 */
/**
* 成功数
*/
@Schema(description = "成功数")
private Long successCount;
/** 失败数 */
/**
* 失败数
*/
@Schema(description = "失败数")
private Long failCount;
/** 进行中数 */
/**
* 进行中数
*/
@Schema(description = "进行中数")
private Long ingCount;
@@ -0,0 +1,72 @@
package xtools.app.sys.model.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.Instant;
/**
* <p>Title : SysLogTotal</p>
* <p>Description : 系统日志统计表实体对象</p>
* <p>Company : org.xujun</p>
*
* @author : xujun
* @version : 1.0.0
* @date : 2026-07-26 11:14:47
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("sys_log_total")
public class SysLogTotal implements Serializable {
/**
* 主键 ID
*/
@Schema(description = "主键 ID")
@TableId(value = "id", type = IdType.ASSIGN_ID)
private Long id;
/**
* 日志级别
*/
@Schema(description = "日志级别")
@TableField(value = "level")
private Integer level;
/**
* 统计数值
*/
@Schema(description = "统计数值")
@TableField(value = "count")
private Long count;
/**
* 数据时间(天)
*/
@Schema(description = "数据时间(天)")
@TableField(value = "data_time")
private Instant dataTime;
/**
* 备注
*/
@Schema(description = "备注")
@TableField(value = "memo")
private String memo;
/**
* 创建时间
*/
@Schema(description = "创建时间", example = "2026-01-05 10:32:00")
@TableField(value = "gmt_create")
private Instant gmtCreate;
}
@@ -0,0 +1,14 @@
package xtools.app.sys.service;
/**
* <p>Title : SysLogTotalService</p>
* <p>Description : 系统日志统计表 Service</p>
* <p>Company : org.xujun</p>
*
* @author : xujun
* @version : 1.0.0
* @date : 2026-07-26 11:14:47
*/
public interface SysLogTotalService {
}
@@ -0,0 +1,20 @@
package xtools.app.sys.service.base;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Component;
import xtools.app.sys.mapper.SysLogTotalMapper;
import xtools.app.sys.model.entity.SysLogTotal;
/**
* <p>Title : SysLogTotalBaseService</p>
* <p>Description : 系统日志统计表 BaseService</p>
* <p>Company : org.xujun</p>
*
* @author : xujun
* @version : 1.0.0
* @date : 2026-07-26 11:14:47
*/
@Component
public class SysLogTotalBaseService extends ServiceImpl<SysLogTotalMapper, SysLogTotal> {
}
@@ -2,22 +2,37 @@ package xtools.app.sys.service.impl;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import xtools.app.common.cache.enums.AppCache;
import xtools.app.common.log.bus.service.LogBusService;
import xtools.app.sys.model.entity.SysLog;
import xtools.app.sys.model.entity.SysLogTotal;
import xtools.app.sys.service.SysLogService;
import xtools.app.sys.service.SysOptLogService;
import xtools.app.sys.service.base.SysLogTotalBaseService;
import xtools.base.config.BaseParams;
import xtools.boot.api.model.dto.log.LogTrack;
import xtools.boot.cache.redis.base.RedisService;
import xtools.boot.log.enums.LogBusBaseType;
import xtools.boot.log.model.dto.LogBody;
import xtools.boot.log.model.dto.RunInfo;
import xtools.core.CollectionUtils;
import xtools.core.StringUtils;
import xtools.core.enums.LogLevel;
import xtools.core.enums.TimePattern;
import xtools.core.time.CalendarUtils;
import xtools.core.time.InstantUtils;
import xtools.extend.JsonUtils;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
@@ -35,12 +50,22 @@ import java.util.Objects;
@Primary
@Service
@RequiredArgsConstructor
public class LogBusServiceImpl implements LogBusService {
public class LogBusServiceImpl implements LogBusService, BaseParams {
/**
* 缓存参数
*/
private final static AppCache CACHE_PARAM = AppCache.COUNT_SYS_LOG;
private final SysLogService sysLogService;
private final SysOptLogService sysOptLogService;
private final SysLogTotalBaseService sysLogTotalBaseService;
@Resource
private RedisService redisService;
/**
* 保存日志
*
@@ -62,6 +87,13 @@ public class LogBusServiceImpl implements LogBusService {
return;
}
// 统计日志
try {
statLog(logBody.getLevel(), logTrack.time());
} catch (Exception e) {
log.error("统计日志异常", e);
}
RunInfo runInfo = logBody.getRunInfo();
JSONArray stackTrace = logBody.getStackTrace();
@@ -117,4 +149,76 @@ public class LogBusServiceImpl implements LogBusService {
}
return false;
}
/**
* 统计日志
*
* @param level 日志级别
* @param time 日志时间
*/
private void statLog(LogLevel level, Long time) {
if (Objects.isNull(level) || Objects.isNull(time)) {
return;
}
// 当天日期
String date = InstantUtils.format(InstantUtils.from(time), TimePattern.YMD);
redisService.incr(CACHE_PARAM.key(date, level.code()));
}
/**
* 日志统计
*
* @return 保存结果
*/
@Override
public String total() {
// 前一天时间
Instant yesterday = CalendarUtils.yesterday();
// 获取前一天的统计数据
Map<Integer, Long> totalMap = getTotalByDay(yesterday);
if (CollectionUtils.isEmpty(totalMap)) {
return "执行完成,前一天日志统计数据为空";
}
List<SysLogTotal> list = new ArrayList<>(totalMap.size());
for (Map.Entry<Integer, Long> entry : totalMap.entrySet()) {
Long count = entry.getValue();
if (count <= CP_NUM0) {
continue;
}
SysLogTotal total = new SysLogTotal();
total.setLevel(entry.getKey());
total.setCount(count);
total.setDataTime(yesterday);
list.add(total);
}
if (list.isEmpty()) {
return "执行完成,前一天日志统计数据无需保存";
}
// 保存统计
sysLogTotalBaseService.saveBatch(list);
return "执行完成,保存日志统计成功";
}
/**
* 获取指定日期的日志统计数据
*
* @param time 时间
* @return 统计数据
*/
public Map<Integer, Long> getTotalByDay(Instant time) {
Map<Integer, Long> result = new HashMap<>();
if (Objects.isNull(time)) {
return result;
}
// 日期
String date = InstantUtils.format(time, TimePattern.YMD);
for (LogLevel level : LogLevel.values()) {
// 缓存key
String key = CACHE_PARAM.key(date, level.code());
// 获取数量
Long count = redisService.get(key, Long.class);
result.put(level.code(), Objects.nonNull(count) ? count : 0L);
}
return result;
}
}
@@ -0,0 +1,28 @@
package xtools.app.sys.service.impl;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import xtools.app.sys.convert.SysLogTotalConvert;
import xtools.app.sys.service.SysLogTotalService;
import xtools.app.sys.service.base.SysLogTotalBaseService;
/**
* <p>Title : SysLogTotalServiceImpl</p>
* <p>Description : 系统日志统计表 ServiceImpl</p>
* <p>Company : org.xujun</p>
*
* @author : xujun
* @version : 1.0.0
* @date : 2026-07-26 11:14:47
*/
@Primary
@Service
@RequiredArgsConstructor
public class SysLogTotalServiceImpl implements SysLogTotalService {
private final SysLogTotalBaseService sysLogTotalBaseService;
private final SysLogTotalConvert sysLogTotalConvert;
}