15 changed files with 675 additions and 0 deletions
-
93tp-admin/src/main/java/com/inscloudtech/web/controller/system/SysExceptionReportController.java
-
61tp-common/src/main/java/com/inscloudtech/common/core/domain/event/ExceptionReportEvent.java
-
55tp-common/src/main/java/com/inscloudtech/common/core/domain/event/RequestLogEvent.java
-
83tp-common/src/main/java/com/inscloudtech/common/filter/RequestLoggingFilter.java
-
4tp-common/src/main/java/com/inscloudtech/common/utils/ServletUtils.java
-
11tp-framework/src/main/java/com/inscloudtech/framework/config/FilterConfig.java
-
11tp-framework/src/main/java/com/inscloudtech/framework/web/exception/GlobalExceptionHandler.java
-
80tp-system/src/main/java/com/inscloudtech/system/domain/SysExceptionReport.java
-
77tp-system/src/main/java/com/inscloudtech/system/domain/SysRequestLog.java
-
21tp-system/src/main/java/com/inscloudtech/system/mapper/SysExceptionReportMapper.java
-
23tp-system/src/main/java/com/inscloudtech/system/mapper/SysRequestLogMapper.java
-
17tp-system/src/main/java/com/inscloudtech/system/service/ISysExceptionReportService.java
-
29tp-system/src/main/java/com/inscloudtech/system/service/SysRequestLogService.java
-
24tp-system/src/main/java/com/inscloudtech/system/service/impl/SysExceptionReportServiceImpl.java
-
86tp-system/src/main/java/com/inscloudtech/system/service/impl/SysRequestLogServiceImpl.java
@ -0,0 +1,93 @@ |
|||
package com.inscloudtech.web.controller.system; |
|||
|
|||
/***/ |
|||
|
|||
|
|||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
|||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
|||
import com.inscloudtech.common.annotation.Log; |
|||
import com.inscloudtech.common.annotation.RepeatSubmit; |
|||
import com.inscloudtech.common.core.domain.PageQuery; |
|||
import com.inscloudtech.common.core.domain.R; |
|||
import com.inscloudtech.common.core.page.TableDataInfo; |
|||
import com.inscloudtech.common.enums.BusinessType; |
|||
import com.inscloudtech.system.domain.SysExceptionReport; |
|||
import com.inscloudtech.system.domain.SysRequestLog; |
|||
import com.inscloudtech.system.service.ISysExceptionReportService; |
|||
import com.inscloudtech.system.service.SysRequestLogService; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.web.bind.annotation.*; |
|||
|
|||
/** |
|||
* 异常情况报告 |
|||
* |
|||
* @author zfcf |
|||
* @date 2024-08-28 |
|||
*/ |
|||
@RestController |
|||
@RequiredArgsConstructor |
|||
@RequestMapping("/functional/exceptionReport") |
|||
public class SysExceptionReportController { |
|||
|
|||
private final ISysExceptionReportService iSysExceptionReportService; |
|||
|
|||
private final SysRequestLogService sysRequestLogService; |
|||
|
|||
|
|||
|
|||
/** |
|||
* 分页查询 |
|||
* @param |
|||
* @param |
|||
* @return |
|||
*/ |
|||
@GetMapping("/page" ) |
|||
public TableDataInfo<SysExceptionReport> page(PageQuery pageQuery, SysExceptionReport sysExceptionReport) { |
|||
Page page = new Page(); |
|||
page.setSize(pageQuery.getPageSize()); |
|||
page.setCurrent(pageQuery.getPageNum()); |
|||
Page result = iSysExceptionReportService.page(page, Wrappers.query(sysExceptionReport)); |
|||
TableDataInfo dataInfo = new TableDataInfo(); |
|||
dataInfo.setTotal(result.getTotal()); |
|||
dataInfo.setRows(result.getRecords()); |
|||
return dataInfo; |
|||
} |
|||
|
|||
|
|||
|
|||
/** |
|||
* 修改异常情况报告已读 |
|||
* @param |
|||
* @return R |
|||
*/ |
|||
@Log(title = "异常情况报告", businessType = BusinessType.UPDATE) |
|||
@RepeatSubmit() |
|||
@PutMapping |
|||
public R updateById(@RequestBody SysExceptionReport report) { |
|||
return R.ok(iSysExceptionReportService.updateById(report)); |
|||
} |
|||
|
|||
/** |
|||
* 修改异常情况报告阈值 |
|||
* @param |
|||
* @return R |
|||
*/ |
|||
@Log(title = "异常情况报告", businessType = BusinessType.UPDATE) |
|||
@RepeatSubmit() |
|||
@PutMapping |
|||
public R updateYz(@RequestBody SysRequestLog sysRequestLog) { |
|||
sysRequestLogService.updateYz(sysRequestLog); |
|||
return R.ok(); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 获取异常情况报告阈值 |
|||
* |
|||
*/ |
|||
@GetMapping("/getYzInfo") |
|||
public R getInfo() { |
|||
return R.ok(sysRequestLogService.getYzInfo()); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,61 @@ |
|||
package com.inscloudtech.common.core.domain.event; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.Date; |
|||
|
|||
/** |
|||
* 操作日志事件 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
|
|||
@Data |
|||
public class ExceptionReportEvent implements Serializable { |
|||
|
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
/** |
|||
* 日志主键 |
|||
*/ |
|||
private Long operId; |
|||
|
|||
/** |
|||
* 请求方法 |
|||
*/ |
|||
private String method; |
|||
|
|||
/** |
|||
* 请求方式 |
|||
*/ |
|||
private String requestMethod; |
|||
|
|||
|
|||
/** |
|||
* 操作人员 |
|||
*/ |
|||
private String operName; |
|||
|
|||
/** |
|||
* 请求url |
|||
*/ |
|||
private String operUrl; |
|||
|
|||
/** |
|||
* 操作地址 |
|||
*/ |
|||
private String operIp; |
|||
|
|||
/** |
|||
* 操作地点 |
|||
*/ |
|||
private String operLocation; |
|||
|
|||
/** |
|||
* 请求参数 |
|||
*/ |
|||
private String msg; |
|||
|
|||
|
|||
} |
@ -0,0 +1,55 @@ |
|||
package com.inscloudtech.common.core.domain.event; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.Date; |
|||
|
|||
/** |
|||
* 操作日志事件 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
|
|||
@Data |
|||
public class RequestLogEvent implements Serializable { |
|||
|
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
/** |
|||
* 日志主键 |
|||
*/ |
|||
private Long operId; |
|||
|
|||
/** |
|||
* 请求方式 |
|||
*/ |
|||
private String requestMethod; |
|||
|
|||
|
|||
/** |
|||
* 操作人员 |
|||
*/ |
|||
private String operName; |
|||
|
|||
/** |
|||
* 请求url |
|||
*/ |
|||
private String operUrl; |
|||
|
|||
/** |
|||
* 操作地址 |
|||
*/ |
|||
private String operIp; |
|||
|
|||
/** |
|||
* 操作地点 |
|||
*/ |
|||
private String operLocation; |
|||
|
|||
/** |
|||
* 请求参数 |
|||
*/ |
|||
private String operParam; |
|||
|
|||
} |
@ -0,0 +1,83 @@ |
|||
package com.inscloudtech.common.filter; |
|||
|
|||
|
|||
import cn.hutool.core.map.MapUtil; |
|||
import cn.hutool.core.util.ObjectUtil; |
|||
import cn.hutool.core.util.StrUtil; |
|||
import com.inscloudtech.common.core.domain.event.RequestLogEvent; |
|||
import com.inscloudtech.common.core.domain.model.LoginUser; |
|||
import com.inscloudtech.common.helper.LoginHelper; |
|||
import com.inscloudtech.common.utils.JsonUtils; |
|||
import com.inscloudtech.common.utils.ServletUtils; |
|||
import com.inscloudtech.common.utils.StringUtils; |
|||
import com.inscloudtech.common.utils.spring.SpringUtils; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.http.MediaType; |
|||
|
|||
import javax.servlet.*; |
|||
import javax.servlet.http.HttpServletRequest; |
|||
import java.io.IOException; |
|||
import java.util.Map; |
|||
|
|||
@Slf4j |
|||
public class RequestLoggingFilter implements Filter { |
|||
|
|||
@Override |
|||
public void init(FilterConfig filterConfig) throws ServletException { |
|||
|
|||
} |
|||
|
|||
@Override |
|||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) |
|||
throws IOException, ServletException { |
|||
|
|||
ServletRequest requestWrapper = null; |
|||
if (request instanceof HttpServletRequest |
|||
&& StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) { |
|||
requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response); |
|||
} |
|||
|
|||
handleLog(request); |
|||
|
|||
// 记录请求信息 |
|||
chain.doFilter(ObjectUtil.defaultIfNull(requestWrapper, request), response); |
|||
} |
|||
|
|||
@Override |
|||
public void destroy() { |
|||
|
|||
} |
|||
|
|||
protected void handleLog(ServletRequest request) { |
|||
try { |
|||
HttpServletRequest servletRequest = (HttpServletRequest) request; |
|||
String requestURI = servletRequest.getRequestURI(); |
|||
String method = servletRequest.getMethod(); |
|||
Map<String, String> paramMap = ServletUtils.getParamMap(servletRequest); |
|||
String operParam = ""; |
|||
if(MapUtil.isNotEmpty(paramMap)){ |
|||
operParam = StringUtils.substring(JsonUtils.toJsonString(paramMap), 0, 2000); |
|||
} |
|||
String ip = ServletUtils.getClientIPByRequest(servletRequest); |
|||
|
|||
RequestLogEvent requestLog = new RequestLogEvent(); |
|||
requestLog.setOperIp(ip); |
|||
requestLog.setOperUrl(StringUtils.substring(requestURI, 0, 255)); |
|||
requestLog.setRequestMethod(method); |
|||
requestLog.setOperParam(operParam); |
|||
|
|||
String authorization = servletRequest.getHeader("authorization"); |
|||
if(StrUtil.isNotEmpty(authorization)){ |
|||
authorization = authorization.replace("Bearer","").trim(); |
|||
LoginUser user = LoginHelper.getLoginUser(authorization); |
|||
requestLog.setOperName(user.getUsername()); |
|||
} |
|||
|
|||
SpringUtils.context().publishEvent(requestLog); |
|||
} catch (Exception exp) { |
|||
// 记录本地异常日志 |
|||
log.error("异常信息:{}", exp.getMessage()); |
|||
exp.printStackTrace(); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,80 @@ |
|||
package com.inscloudtech.system.domain; |
|||
|
|||
|
|||
import com.baomidou.mybatisplus.annotation.SqlCondition; |
|||
import com.baomidou.mybatisplus.annotation.TableField; |
|||
import com.baomidou.mybatisplus.annotation.TableId; |
|||
import com.baomidou.mybatisplus.annotation.TableName; |
|||
import lombok.Data; |
|||
|
|||
import java.util.Date; |
|||
|
|||
/** |
|||
* 异常情况报告对象 sys_exception_report |
|||
* |
|||
* @author inscloudtech |
|||
* @date 2024-09-06 |
|||
*/ |
|||
@Data |
|||
@TableName("sys_exception_report") |
|||
public class SysExceptionReport{ |
|||
|
|||
private static final long serialVersionUID=1L; |
|||
|
|||
/** |
|||
* 日志主键 |
|||
*/ |
|||
@TableId(value = "oper_id") |
|||
private Long operId; |
|||
/** |
|||
* 方法名称 |
|||
*/ |
|||
private String method; |
|||
/** |
|||
* 请求方式 |
|||
*/ |
|||
private String requestMethod; |
|||
/** |
|||
* 操作人员 |
|||
*/ |
|||
private String operName; |
|||
|
|||
/** |
|||
* 请求URL |
|||
*/ |
|||
@TableField(condition = SqlCondition.LIKE) |
|||
private String operUrl; |
|||
/** |
|||
* 主机地址 |
|||
*/ |
|||
private String operIp; |
|||
/** |
|||
* 操作地点 |
|||
*/ |
|||
private String operLocation; |
|||
/** |
|||
* 请求参数 |
|||
*/ |
|||
private String operParam; |
|||
/** |
|||
* 返回参数 |
|||
*/ |
|||
private String jsonResult; |
|||
/** |
|||
* 大量访问请求/异常数据输入 |
|||
*/ |
|||
private String type; |
|||
/** |
|||
* 错误消息 |
|||
*/ |
|||
private String msg; |
|||
/** |
|||
* 操作时间 |
|||
*/ |
|||
private Date operTime; |
|||
|
|||
/** |
|||
* 单位时间请求次数 |
|||
*/ |
|||
private Integer requestCount; |
|||
} |
@ -0,0 +1,77 @@ |
|||
package com.inscloudtech.system.domain; |
|||
|
|||
|
|||
import com.baomidou.mybatisplus.annotation.*; |
|||
import lombok.Data; |
|||
|
|||
import java.util.Date; |
|||
|
|||
/** |
|||
* 访问日志记录对象 sys_request_log |
|||
* |
|||
* @author inscloudtech |
|||
* @date 2024-09-06 |
|||
*/ |
|||
@Data |
|||
@TableName("sys_request_log") |
|||
public class SysRequestLog { |
|||
|
|||
private static final long serialVersionUID=1L; |
|||
|
|||
/** |
|||
* 日志主键 |
|||
*/ |
|||
@TableId(value = "oper_id") |
|||
private Long operId; |
|||
/** |
|||
* 方法名称 |
|||
*/ |
|||
private String method; |
|||
/** |
|||
* 请求方式 |
|||
*/ |
|||
private String requestMethod; |
|||
/** |
|||
* 操作人员 |
|||
*/ |
|||
private String operName; |
|||
/** |
|||
* 请求URL |
|||
*/ |
|||
private String operUrl; |
|||
/** |
|||
* 主机地址 |
|||
*/ |
|||
private String operIp; |
|||
/** |
|||
* 操作地点 |
|||
*/ |
|||
private String operLocation; |
|||
/** |
|||
* 请求参数 |
|||
*/ |
|||
private String operParam; |
|||
|
|||
/** |
|||
* 操作时间 |
|||
*/ |
|||
private Date operTime; |
|||
|
|||
/** |
|||
* 预警时间阈值(分钟) |
|||
*/ |
|||
@TableField(exist = false) |
|||
private Integer alterTime; |
|||
|
|||
/** |
|||
* 预警请求次数阈值 |
|||
*/ |
|||
@TableField(exist = false) |
|||
private Integer requestCount; |
|||
|
|||
/** |
|||
* 单位时间请求次数 |
|||
*/ |
|||
@TableField(exist = false) |
|||
private Integer count; |
|||
} |
@ -0,0 +1,21 @@ |
|||
package com.inscloudtech.system.mapper; |
|||
|
|||
|
|||
import com.inscloudtech.common.core.mapper.BaseMapperPlus; |
|||
import com.inscloudtech.system.domain.SysExceptionReport; |
|||
import com.inscloudtech.system.domain.SysRequestLog; |
|||
import org.apache.ibatis.annotations.Param; |
|||
import org.apache.ibatis.annotations.Select; |
|||
|
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 测试包管理Mapper接口 |
|||
* |
|||
* @author inscloudtech |
|||
* @date 2024-08-08 |
|||
*/ |
|||
public interface SysExceptionReportMapper extends BaseMapperPlus<SysExceptionReportMapper, SysExceptionReport, SysExceptionReport> { |
|||
|
|||
} |
|||
|
@ -0,0 +1,23 @@ |
|||
package com.inscloudtech.system.mapper; |
|||
|
|||
|
|||
import com.inscloudtech.common.core.mapper.BaseMapperPlus; |
|||
import com.inscloudtech.system.domain.SysRequestLog; |
|||
import org.apache.ibatis.annotations.Param; |
|||
import org.apache.ibatis.annotations.Select; |
|||
|
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 测试包管理Mapper接口 |
|||
* |
|||
* @author inscloudtech |
|||
* @date 2024-08-08 |
|||
*/ |
|||
public interface SysRequestLogMapper extends BaseMapperPlus<SysRequestLogMapper, SysRequestLog, SysRequestLog> { |
|||
|
|||
@Select("select oper_url operUrl,count(*) count from sys_request_log WHERE oper_time BETWEEN NOW() - INTERVAL > #{alterTime} MINUTE AND NOW()" + |
|||
" GROUP BY oper_url HAVING count > #{requestCount}") |
|||
List<SysRequestLog> getAlertURl(@Param("alterTime") int alterTime, @Param("requestCount") int requestCount); |
|||
} |
|||
|
@ -0,0 +1,17 @@ |
|||
package com.inscloudtech.system.service; |
|||
|
|||
|
|||
import com.baomidou.mybatisplus.extension.service.IService; |
|||
import com.inscloudtech.system.domain.SysExceptionReport; |
|||
import com.inscloudtech.system.domain.SysRequestLog; |
|||
|
|||
/** |
|||
* |
|||
* |
|||
* @author inscloudtech |
|||
* @date 2024-08-08 |
|||
*/ |
|||
public interface ISysExceptionReportService extends IService<SysExceptionReport> { |
|||
|
|||
} |
|||
|
@ -0,0 +1,29 @@ |
|||
package com.inscloudtech.system.service; |
|||
|
|||
|
|||
import com.baomidou.mybatisplus.extension.service.IService; |
|||
import com.inscloudtech.common.core.domain.PageQuery; |
|||
import com.inscloudtech.common.core.page.TableDataInfo; |
|||
import com.inscloudtech.system.domain.SysRequestLog; |
|||
import com.inscloudtech.system.domain.ToolManage; |
|||
import com.inscloudtech.system.domain.vo.DownloadToolRequest; |
|||
import com.inscloudtech.system.domain.vo.ToolManageVo; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
|
|||
import javax.servlet.http.HttpServletResponse; |
|||
import java.util.Collection; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* |
|||
* |
|||
* @author inscloudtech |
|||
* @date 2024-08-08 |
|||
*/ |
|||
public interface SysRequestLogService extends IService<SysRequestLog> { |
|||
|
|||
void updateYz(SysRequestLog sysRequestLog); |
|||
|
|||
SysRequestLog getYzInfo(); |
|||
} |
|||
|
@ -0,0 +1,24 @@ |
|||
package com.inscloudtech.system.service.impl; |
|||
|
|||
import cn.hutool.core.bean.BeanUtil; |
|||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
|||
import com.inscloudtech.common.core.domain.event.ExceptionReportEvent; |
|||
import com.inscloudtech.system.domain.SysExceptionReport; |
|||
import com.inscloudtech.system.mapper.SysExceptionReportMapper; |
|||
import com.inscloudtech.system.service.ISysExceptionReportService; |
|||
import org.springframework.context.event.EventListener; |
|||
import org.springframework.scheduling.annotation.Async; |
|||
|
|||
import java.util.Date; |
|||
|
|||
public class SysExceptionReportServiceImpl extends ServiceImpl<SysExceptionReportMapper, SysExceptionReport> implements ISysExceptionReportService { |
|||
|
|||
@Async |
|||
@EventListener |
|||
public void recordOper(ExceptionReportEvent reportEvent) { |
|||
SysExceptionReport report = BeanUtil.toBean(reportEvent, SysExceptionReport.class); |
|||
report.setType("异常数据输入"); |
|||
report.setOperTime(new Date()); |
|||
baseMapper.insert(report); |
|||
} |
|||
} |
@ -0,0 +1,86 @@ |
|||
package com.inscloudtech.system.service.impl; |
|||
|
|||
|
|||
import cn.hutool.core.bean.BeanUtil; |
|||
import cn.hutool.core.collection.CollectionUtil; |
|||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
|||
import com.inscloudtech.common.core.domain.event.RequestLogEvent; |
|||
import com.inscloudtech.common.utils.ip.AddressUtils; |
|||
import com.inscloudtech.system.domain.SysExceptionReport; |
|||
import com.inscloudtech.system.domain.SysRequestLog; |
|||
import com.inscloudtech.system.mapper.SysRequestLogMapper; |
|||
import com.inscloudtech.system.service.ISysExceptionReportService; |
|||
import com.inscloudtech.system.service.SysRequestLogService; |
|||
import lombok.AllArgsConstructor; |
|||
import org.springframework.context.event.EventListener; |
|||
import org.springframework.scheduling.annotation.Async; |
|||
import org.springframework.stereotype.Service; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.Date; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* |
|||
* @author zfcf |
|||
* @date 2024-08-28 |
|||
*/ |
|||
@Service |
|||
@AllArgsConstructor |
|||
public class SysRequestLogServiceImpl extends ServiceImpl<SysRequestLogMapper, SysRequestLog> implements SysRequestLogService { |
|||
|
|||
private final ISysExceptionReportService exceptionReportService; |
|||
|
|||
/** |
|||
* 预警时间阈值(分钟) |
|||
*/ |
|||
private Integer alterTime = 1; |
|||
|
|||
/** |
|||
* 预警请求次数阈值 |
|||
*/ |
|||
private Integer requestCount = 10; |
|||
|
|||
@Async |
|||
@EventListener |
|||
public void recordOper(RequestLogEvent requestLogEvent) { |
|||
|
|||
SysRequestLog requestLog = BeanUtil.toBean(requestLogEvent, SysRequestLog.class); |
|||
requestLog.setOperLocation(AddressUtils.getRealAddressByIP(requestLog.getOperIp())); |
|||
requestLog.setOperTime(new Date()); |
|||
baseMapper.insert(requestLog); |
|||
|
|||
List<SysRequestLog> alertURlList = baseMapper.getAlertURl(alterTime,requestCount); |
|||
if(CollectionUtil.isNotEmpty(alertURlList)){ |
|||
List<SysExceptionReport> addList = new ArrayList<>(); |
|||
for (SysRequestLog sysRequestLog : alertURlList) { |
|||
SysExceptionReport report = new SysExceptionReport(); |
|||
report.setOperUrl(sysRequestLog.getOperUrl()); |
|||
report.setRequestCount(sysRequestLog.getRequestCount()); |
|||
report.setType("大量访问请求"); |
|||
addList.add(report); |
|||
} |
|||
exceptionReportService.saveBatch(addList); |
|||
} |
|||
|
|||
} |
|||
|
|||
@Override |
|||
public void updateYz(SysRequestLog sysRequestLog) { |
|||
if(sysRequestLog.getAlterTime() != null){ |
|||
alterTime = sysRequestLog.getAlterTime(); |
|||
} |
|||
|
|||
if(sysRequestLog.getRequestCount() != null){ |
|||
requestCount = sysRequestLog.getRequestCount(); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public SysRequestLog getYzInfo() { |
|||
SysRequestLog sysRequestLog = new SysRequestLog(); |
|||
sysRequestLog.setAlterTime(alterTime); |
|||
sysRequestLog.setRequestCount(requestCount); |
|||
return sysRequestLog; |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue