日志告警

This commit is contained in:
weiweiw 2024-11-11 09:50:05 +08:00
parent 9f8c5303a9
commit e7012cb467
13 changed files with 135 additions and 29 deletions

View File

@ -90,6 +90,18 @@
<version>24.11.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.23</version>
<scope>compile</scope>
</dependency>
</dependencies>

View File

@ -266,7 +266,7 @@ public class PasswordValidatorService {
String nowIp = IpUtils.getIpAddr();
String hisIp = redisService.getCacheObject("IP:" + user.getUserId());
if (!nowIp.equals(hisIp)) {
recordLogService.saveErrorLogs(username, System.currentTimeMillis(), user.getUserId().toString());
recordLogService.saveErrorLogs(username, System.currentTimeMillis(), user.getUserId().toString(),"用户连续两次在不同IP登录");
}
redisService.setCacheObject("IP:" + user.getUserId(), nowIp, 5L, TimeUnit.MINUTES);
} catch (Exception e) {

View File

@ -72,7 +72,7 @@ public class SysPasswordService {
if (retryCount >= times) {
long time = redisService.getExpire(getCacheKey(username));
String errMsg = String.format("密码输入错误%s次帐户锁定,请%s分钟后重试", maxRetryCount, time / 60 + 1);
recordLogService.saveLogs(username, startTime, "用户账号锁定", "用户账号已锁定,请" + times + "后重试", null, null);
recordLogService.saveErrorLogs( user.getUserName(), startTime,"", "连续登录失败,锁定账号" );
throw new ServiceException(errMsg);
}
if (!matches(user, password)) {

View File

@ -107,7 +107,7 @@ public class SysRecordLogService
* @param
* @return
*/
public void saveErrorLogs(String username, long startTime,String userId) {
public void saveErrorLogs(String username, long startTime,String userId, String errMessage) {
long endTime = System.currentTimeMillis();
SysLogsVo sysLogsVo = new SysLogsVo();
sysLogsVo.setGrade("");
@ -130,10 +130,12 @@ public class SysRecordLogService
sysLogsVo.setIp(IpUtils.getIpAddr());
sysLogsVo.setParams("{\"username\":\""+username+"\"}");
sysLogsVo.setOperateDetail("用户登录系统");
sysLogsVo.setErrType("IP异常");
sysLogsVo.setErrType(errMessage);
try{
long times=endTime-startTime;
sysLogsVo.setTimes(times+"");
if(startTime != 0) {
long times = endTime - startTime;
sysLogsVo.setTimes(times + "");
}
remoteLogService.addLogs(sysLogsVo, SecurityConstants.INNER);
}catch (Exception e){
log.error(e.toString(),e);

View File

@ -2,6 +2,7 @@ package com.bonus.gateway.filter;
import com.bonus.common.core.constant.CacheConstants;
import com.bonus.common.redis.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
@ -27,6 +28,10 @@ import java.util.Map;
public class IpFilter implements GlobalFilter, Ordered {
@Resource
private RedisService redisService;
// @Resource
// private RemoteLogService remoteLogService;
// public RemoteLogService remoteLogService = SpringUtils.getBean(RemoteLogService.class);
/**
* Process the Web request and (optionally) delegate to the next {@code GatewayFilter}
* through the given {@link GatewayFilterChain}.
@ -53,6 +58,7 @@ public class IpFilter implements GlobalFilter, Ordered {
boolean currentTimeInRange = isCurrentTimeInRange(accessStartTime, accessEndTime);
if (!currentTimeInRange){
// 完成响应
// handleLog();
exchange.getResponse().setStatusCode(org.springframework.http.HttpStatus.FORBIDDEN);
return exchange.getResponse().setComplete();
}else {
@ -69,6 +75,7 @@ public class IpFilter implements GlobalFilter, Ordered {
boolean currentTimeInRange = isCurrentTimeInRange(accessStartTime, accessEndTime);
if (!currentTimeInRange){
// 完成响应
// handleLog();
exchange.getResponse().setStatusCode(org.springframework.http.HttpStatus.FORBIDDEN);
return exchange.getResponse().setComplete();
}else {
@ -83,6 +90,23 @@ public class IpFilter implements GlobalFilter, Ordered {
exchange.getResponse().setStatusCode(org.springframework.http.HttpStatus.FORBIDDEN);
return exchange.getResponse().setComplete();
}
// private void handleLog()
// {
// SysLogsVo sysLogsVo = new SysLogsVo();
// String uuid= UUID.randomUUID().toString().replace("-","").toUpperCase();
// sysLogsVo.setLogId(uuid);
// sysLogsVo.setOperaUserName("");
// sysLogsVo.setIp(IpUtils.getIpAddr());
// sysLogsVo.setOperTime(DateUtils.getTime());
// sysLogsVo.setLogType(0);
// sysLogsVo.setOperType("IP地址异常");
// sysLogsVo.setWarningStatus("0");
// try {
// remoteLogService.addLogs(sysLogsVo, SecurityConstants.INNER);
// } catch (Exception e) {
// throw new RuntimeException(e);
// }
// }
/**
* 检查给定的IP地址是否在指定的网段区间内
*

View File

@ -23,6 +23,7 @@ import com.bonus.system.domain.UserPasswordHistory;
import com.bonus.system.service.*;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@ -66,6 +67,9 @@ public class SysUserController extends BaseController {
private RedisService redisService;
@Autowired
private ISysLogService sysLogService;
/**
* 获取用户列表
*/
@ -225,6 +229,10 @@ public class SysUserController extends BaseController {
ajax.put("user", user);
ajax.put("roles", roles);
ajax.put("permissions", permissions);
//在系统管理员和审计管理员登录时处理警告日志
if(roles.contains("admin") || roles.contains("audit") || roles.contains("systemAdmin")){
sysLogService.handleWarningLog();
}
return ajax;
} catch (Exception e) {
logger.error(e.toString(), e);

View File

@ -119,4 +119,18 @@ public interface SysLogMapper {
* @return
*/
List<SysLogsVo> getLogsLists(@Param("logType") String logType);
/**
* 查询未处理告警日志
* @return
*/
List<SysLogsVo> getNotHandleWarningLog();
/**
* 修改指定日志为已处理状态
* @param logId 日志id
* @return
*/
void updateLogsWithHandledStatus(String logId);
}

View File

@ -3,6 +3,7 @@ package com.bonus.system.service;
import com.bonus.common.core.domain.R;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.system.api.domain.SysLogsVo;
import org.springframework.scheduling.annotation.Async;
import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
@ -67,4 +68,14 @@ public interface ISysLogService {
* @return
*/
void saveLogs(SysLogsVo sysLog, HttpServletRequest request);
/**
* 获取未处理的告警日志
* @return
*/
@Async
public void handleWarningLog();
@Async
public void updateLogsWithHandledStatus(String logId);
}

View File

@ -17,8 +17,10 @@ import com.bonus.system.api.domain.SysLogsVo;
import com.bonus.system.api.model.LoginUser;
import com.bonus.system.mapper.SysLogMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.scripting.xmltags.ForEachSqlNode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
@ -61,8 +63,13 @@ public class SysLogServiceImpl implements ISysLogService {
}
}
}
if (sysLog.getLogType() == 2) {
sysLog.setWarningStatus("0");
}
mapper.saveLogs(sysLog);
eventPublisher.publishEvent(new WaringLogEvent(new SysWarning(sysLog.getLogId(),"测试系统日志告警","",sysLog.getIp(),sysLog.getGrade(),sysLog.getOperaUserName())));
if (sysLog.getLogType() == 2) {
eventPublisher.publishEvent(new WaringLogEvent(new SysWarning(sysLog.getLogId(),sysLog.getErrType() ,sysLog.getIp(),sysLog.getOperaUserName(),sysLog.getOperTime())));
}
} catch (Exception e) {
log.error("保存系统日志");
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
@ -73,7 +80,6 @@ public class SysLogServiceImpl implements ISysLogService {
@Override
public void saveLogs(SysLogsVo sysLog, HttpServletRequest request) {
try{
// sysLog.setFruit("失败");
String loginUuid = IdUtils.fastUUID();
String ip = IpUtils.getIpAddr(request);
sysLog.setLogId(loginUuid);
@ -97,9 +103,14 @@ public class SysLogServiceImpl implements ISysLogService {
if(StringUtils.isEmpty(module)){
sysLog.setModel(modules);
}
mapper.saveLogs(sysLog);
}
eventPublisher.publishEvent(new WaringLogEvent(new SysWarning(loginUuid,"越权访问","",ip,"",user.getUsername())));
if (sysLog.getLogType() == 2) {
sysLog.setWarningStatus("0");
}
mapper.saveLogs(sysLog);
if (sysLog.getLogType() == 2) {
eventPublisher.publishEvent(new WaringLogEvent(new SysWarning(loginUuid, "越权访问", ip, user.getUsername(), DateUtils.getTime())));
}
}catch (Exception e){
log.error(e.toString(),e);
}
@ -284,6 +295,21 @@ public class SysLogServiceImpl implements ISysLogService {
}
@Override
@Async
public void handleWarningLog(){
List<SysLogsVo> list = mapper.getNotHandleWarningLog();
// 使用for-each循环遍历List
for (SysLogsVo item : list) {
eventPublisher.publishEvent(new WaringLogEvent(new SysWarning(item.getLogId(),item.getErrType(), item.getIp(),item.getOperaUserName(),item.getOperTime())));
log.info("*****系统管理员和审计管理员处理异常日志*******");
}
}
@Override
@Async
public void updateLogsWithHandledStatus(String logId){
mapper.updateLogsWithHandledStatus(logId);
}
}

View File

@ -2,6 +2,7 @@ package com.bonus.system.service.impl;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.shaded.com.google.common.collect.Maps;
@ -101,7 +102,10 @@ public class SysOperLogServiceImpl implements ISysOperLogService
*/
@Override
public int addLogs(SysLogsVo sysLogsVo) {
eventPublisher.publishEvent(new WaringLogEvent(new SysWarning(sysLogsVo.getLogId(),"测试系统日志告警","",sysLogsVo.getIp(),sysLogsVo.getGrade(),sysLogsVo.getOperaUserName())));
if (sysLogsVo.getLogType() == 2) {
sysLogsVo.setWarningStatus("0");
eventPublisher.publishEvent(new WaringLogEvent(new SysWarning(sysLogsVo.getLogId(), sysLogsVo.getOperType(), sysLogsVo.getIp(), sysLogsVo.getOperaUserName(), sysLogsVo.getOperTime())));
}
return operLogMapper.addLogs(sysLogsVo);
}

View File

@ -7,27 +7,22 @@ import java.util.Date;
@Data
public class SysWarning {
public SysWarning(String warningId,String warningEvent, String warningContent,String warningIp,String warningGrade, String operaUserName ){
public SysWarning(String warningId,String warningEvent,String warningIp,String operaUserName,String operaTime ){
this.warningId = warningId;
this.warningEvent = warningEvent;
this.warningContent = warningContent;
this.warningIp = warningIp;
this.warningGrade = warningGrade;
this.operaUserName = operaUserName;
this.operaTime = operaTime;
}
private String warningId;
private String warningEvent = "";
private String warningContent = "";
private String warningIp = "";
private String warningGrade = "";
private String operaUserName = "";
private Date warningTime;
private String operaTime;
private String warningStatus = "0";
@ -35,11 +30,9 @@ public class SysWarning {
return "SysWarning{" +
"warningId='" + warningId + '\'' +
", warningEvent='" + warningEvent + '\'' +
", warningContent='" + warningContent + '\'' +
", warningIp='" + warningIp + '\'' +
", warningGrade='" + warningGrade + '\'' +
", operaUserName='" + operaUserName + '\'' +
", warningTime=" + warningTime +
", warningTime=" + operaTime +
", warningStatus='" + warningStatus + '\'' +
'}';
}

View File

@ -2,6 +2,7 @@ package com.bonus.system.warning;
import com.alibaba.fastjson.JSON;
import com.bonus.system.service.ISysLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
@ -17,13 +18,14 @@ import javax.annotation.Resource;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArrayList;
@Slf4j
@Component
public class WebSocketHandler extends TextWebSocketHandler {
private static final Logger logger = LoggerFactory.getLogger(WebSocketHandler.class);
private static final CopyOnWriteArrayList<WebSocketSession> sessions = new CopyOnWriteArrayList<>();
@Resource(name = "ISysLogService")
private ISysLogService service;
private ISysLogService logService;
public static void closeSession(WebSocketSession session) throws IOException {
session.close();
@ -83,12 +85,7 @@ public class WebSocketHandler extends TextWebSocketHandler {
String payload = message.getPayload();
logger.info("接收到消息: " + payload);
// 处理接收到的消息例如广播给所有客户端
for (WebSocketSession wsSession : sessions) {
if (wsSession.isOpen()) {
wsSession.sendMessage(new TextMessage("服务端回应: " + payload));
}
}
logService.updateLogsWithHandledStatus(payload);
}
@Override

View File

@ -265,4 +265,19 @@
where log_type=#{logType}
</select>
<select id="getNotHandleWarningLog" resultType="com.bonus.system.api.domain.SysLogsVo">
SELECT
log_id logId, opera_user_name operaUserName,ip,
user_id userId, oper_time operTime,
oper_type operType
FROM sys_logs
where warning_status=0
</select>
<update id="updateLogsWithHandledStatus">
update sys_logs set warning_status=1 where log_id=#{logId}
</update>
</mapper>