system针对审计日志的微调

This commit is contained in:
2024-08-19 19:55:12 +08:00
parent f36b3f9ee9
commit c2af7e708c
5 changed files with 116 additions and 17 deletions

View File

@@ -343,6 +343,20 @@ public class RequestUtil {
return StrUtil.isBlank(loginName) ? LogInfo.UNKNOWN_USER : loginName; return StrUtil.isBlank(loginName) ? LogInfo.UNKNOWN_USER : loginName;
} }
/**
* ServerHttpRequest获取在网关中存储的用户昵称
*/
public static String getLoginNameByPayload(HttpServletRequest request) {
String loginName = LogInfo.UNKNOWN_USER;
JSONObject jwtPayload = getJwtPayload(request);
if (Objects.nonNull(jwtPayload)) {
String loginNameTemp = jwtPayload.getString(SecurityConstants.USER_NAME_KEY);
loginName = StrUtil.isBlank(loginNameTemp) ? LogInfo.UNKNOWN_USER : loginNameTemp;
}
return loginName;
}
/** /**
* ServerHttpRequest获取在网关中存储的用户昵称 * ServerHttpRequest获取在网关中存储的用户昵称
*/ */

View File

@@ -46,4 +46,16 @@ public class AuditParam {
@Range(min = 1,message = "条数必须大于0") @Range(min = 1,message = "条数必须大于0")
private Integer pageSize; private Integer pageSize;
@ApiModelProperty("排序")
private String orderBy;
@ApiModelProperty("排序字段")
private String sortBy;
@ApiModelProperty("排序字段中文名")
private String sortName;
@ApiModelProperty("是否导出")
private boolean export;
} }

View File

@@ -24,6 +24,7 @@ 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 javax.servlet.http.HttpServletRequest;
import java.text.ParseException; import java.text.ParseException;
import java.util.List; import java.util.List;
@@ -46,9 +47,10 @@ public class AuditController extends BaseController {
@PostMapping("/getAuditLog") @PostMapping("/getAuditLog")
@ApiOperation("审计日志列表") @ApiOperation("审计日志列表")
@ApiImplicitParam(name = "auditParam", value = "审计日志参数", required = true) @ApiImplicitParam(name = "auditParam", value = "审计日志参数", required = true)
public HttpResult<Page<AuditLogVO>> getAuditLog(@RequestBody @Validated AuditParam auditParam){ public HttpResult<Page<AuditLogVO>> getAuditLog(@RequestBody @Validated AuditParam auditParam, HttpServletRequest request){
String methodDescribe = getMethodDescribe("getAuditLog"); String methodDescribe = getMethodDescribe("getAuditLog");
Page<AuditLogVO> result = auditService.getAuditLog(auditParam); Page<AuditLogVO> result = auditService.getAuditLog(auditParam);
auditService.saveAuditLog(request,auditParam,methodDescribe);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS,result,methodDescribe); return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS,result,methodDescribe);
} }

View File

@@ -9,6 +9,7 @@ import com.njcn.system.pojo.vo.AuditLogVO;
import com.njcn.system.pojo.vo.LogParamVO; import com.njcn.system.pojo.vo.LogParamVO;
import com.njcn.system.pojo.vo.OnlineUsersVO; import com.njcn.system.pojo.vo.OnlineUsersVO;
import javax.servlet.http.HttpServletRequest;
import java.text.ParseException; import java.text.ParseException;
import java.util.List; import java.util.List;
@@ -24,6 +25,11 @@ public interface AuditService extends IService<UserLog> {
*/ */
Page<AuditLogVO> getAuditLog(AuditParam auditParam); Page<AuditLogVO> getAuditLog(AuditParam auditParam);
/**
* 异步存储审计排序或到处日志
*/
void saveAuditLog(HttpServletRequest request, AuditParam auditParam, String methodDescribe);
/** /**
* 日志文件备份下载 * 日志文件备份下载
*/ */

View File

@@ -21,14 +21,21 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.tocrhz.mqtt.publisher.MqttPublisher;
import com.nimbusds.jose.JWSObject; import com.nimbusds.jose.JWSObject;
import com.njcn.common.config.GeneralInfo; import com.njcn.common.config.GeneralInfo;
import com.njcn.common.pojo.constant.LogInfo; import com.njcn.common.pojo.constant.LogInfo;
import com.njcn.common.pojo.constant.OperateType; import com.njcn.common.pojo.constant.OperateType;
import com.njcn.common.pojo.constant.SecurityConstants; import com.njcn.common.pojo.constant.SecurityConstants;
import com.njcn.common.pojo.dto.DeviceLogDTO;
import com.njcn.common.pojo.dto.LogInfoDTO;
import com.njcn.common.pojo.dto.UserTokenInfo; import com.njcn.common.pojo.dto.UserTokenInfo;
import com.njcn.common.pojo.enums.common.DataStateEnum; import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.enums.common.LogEnum;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException; import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.utils.PubUtils;
import com.njcn.common.utils.ReflectCommonUtil;
import com.njcn.oss.constant.OssPath; import com.njcn.oss.constant.OssPath;
import com.njcn.redis.utils.RedisUtil; import com.njcn.redis.utils.RedisUtil;
import com.njcn.system.enums.AuditLogEnum; import com.njcn.system.enums.AuditLogEnum;
@@ -43,17 +50,21 @@ import com.njcn.system.service.AuditService;
import com.njcn.system.service.IConfigService; import com.njcn.system.service.IConfigService;
import com.njcn.user.api.UserFeignClient; import com.njcn.user.api.UserFeignClient;
import com.njcn.user.pojo.po.User; import com.njcn.user.pojo.po.User;
import com.njcn.web.advice.DeviceLog;
import com.njcn.web.utils.RequestUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.commons.compress.utils.IOUtils; import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile; import org.springframework.web.multipart.commons.CommonsMultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.InputStream; import java.io.InputStream;
@@ -91,33 +102,42 @@ public class AuditServiceImpl extends ServiceImpl<UserLogMapper, UserLog> implem
private final IConfigService iConfigService; private final IConfigService iConfigService;
private final MqttPublisher publisher;
@Override @Override
public Page<AuditLogVO> getAuditLog(AuditParam auditParam) { public Page<AuditLogVO> getAuditLog(AuditParam auditParam) {
List<AuditLogVO> auditLogVOS = new ArrayList<>(); List<AuditLogVO> auditLogVOS = new ArrayList<>();
LambdaQueryWrapper<UserLog> lambdaQueryWrapper = new LambdaQueryWrapper<>(); QueryWrapper<UserLog> queryWrapper = new QueryWrapper<>();
lambdaQueryWrapper queryWrapper
.between(UserLog::getCreateTime, DateUtil.beginOfDay(DateUtil.parse(auditParam.getSearchBeginTime())), .between("sys_user_log.create_time", DateUtil.beginOfDay(DateUtil.parse(auditParam.getSearchBeginTime())),
DateUtil.endOfDay(DateUtil.parse(auditParam.getSearchEndTime()))) DateUtil.endOfDay(DateUtil.parse(auditParam.getSearchEndTime())))
.ne(UserLog::getLoginName,UNKNOWN_USER) .ne("sys_user_log.login_name", UNKNOWN_USER);
.orderByDesc(UserLog::getCreateTime);
if (StrUtil.isNotBlank(auditParam.getLoginName())) { if (StrUtil.isNotBlank(auditParam.getLoginName())) {
lambdaQueryWrapper.eq(UserLog::getLoginName, auditParam.getLoginName()); queryWrapper.eq("sys_user_log.login_name", auditParam.getLoginName());
} }
if (StrUtil.isNotBlank(auditParam.getOperateType())) { if (StrUtil.isNotBlank(auditParam.getOperateType())) {
lambdaQueryWrapper.eq(UserLog::getOperateType, auditParam.getOperateType()); queryWrapper.eq("sys_user_log.operate_type", auditParam.getOperateType());
} }
if (Objects.nonNull(auditParam.getType())) { if (Objects.nonNull(auditParam.getType())) {
lambdaQueryWrapper.eq(UserLog::getType, auditParam.getType()); queryWrapper.eq("sys_user_log.type", auditParam.getType());
} }
if (Objects.nonNull(auditParam.getResult())) { if (Objects.nonNull(auditParam.getResult())) {
lambdaQueryWrapper.eq(UserLog::getResult, auditParam.getResult()); queryWrapper.eq("sys_user_log.result", auditParam.getResult());
}
if (StrUtil.isNotBlank(auditParam.getSortBy()) && StrUtil.isNotBlank(auditParam.getOrderBy())) {
if (auditParam.getOrderBy().equalsIgnoreCase("desc")) {
queryWrapper.orderByDesc("sys_user_log." + auditParam.getSortBy());
} else {
queryWrapper.orderByAsc("sys_user_log." + auditParam.getSortBy());
}
} else {
queryWrapper.orderByDesc("sys_user_log.create_time");
} }
Page<UserLog> info = this.page(new Page<>(auditParam.getPageNum(), auditParam.getPageSize()), lambdaQueryWrapper); Page<UserLog> info = this.page(new Page<>(auditParam.getPageNum(), auditParam.getPageSize()), queryWrapper);
Page<AuditLogVO> page = BeanUtil.copyProperties(info, Page.class); Page<AuditLogVO> page = BeanUtil.copyProperties(info, Page.class);
if (CollUtil.isNotEmpty(info.getRecords())) { if (CollUtil.isNotEmpty(info.getRecords())) {
@@ -156,6 +176,37 @@ public class AuditServiceImpl extends ServiceImpl<UserLogMapper, UserLog> implem
return page; return page;
} }
@Override
@Async("asyncExecutor")
public void saveAuditLog(HttpServletRequest request, AuditParam auditParam, String methodDescribe) {
//处理审计日志
String loginName;
String userName;
String userIndex;
loginName = RequestUtil.getLoginNameByPayload(request);
userName = RequestUtil.getUserNickname(request);
userIndex = RequestUtil.getUserIndex(request);
String result = CommonResponseEnum.SUCCESS.getMessage();
String ip = RequestUtil.getRealIp(request);
String type = LogEnum.BUSINESS_COMMON.getOperateType();
String level = LogEnum.BUSINESS_COMMON.getOperateLevel();
String operateType = OperateType.QUERY;
Integer severity = levelStringToNumber(level);
if(auditParam.isExport()){
methodDescribe = "审计日志列表导出";
}else{
if (StrUtil.isNotBlank(auditParam.getSortBy()) && StrUtil.isNotBlank(auditParam.getOrderBy())) {
methodDescribe = methodDescribe.concat("并以")
.concat(auditParam.getSortName())
.concat("进行")
.concat(auditParam.getOrderBy().equalsIgnoreCase("desc")?"降序":"升序")
.concat("查询");
}
}
LogInfoDTO logInfoDTO = new LogInfoDTO(loginName, userName, ip, methodDescribe, operateType, result.equalsIgnoreCase("失败") ? 0 : 1, "", severity, type.equalsIgnoreCase("业务事件") ? 0 : 1, generalInfo.getMicroServiceName(), userIndex, LocalDateTime.now());
publisher.send("/userLog", PubUtils.obj2json(logInfoDTO), 2, false);
}
@Override @Override
public void logFileWriter() { public void logFileWriter() {
TimeInterval timeInterval = new TimeInterval(); TimeInterval timeInterval = new TimeInterval();
@@ -164,7 +215,7 @@ public class AuditServiceImpl extends ServiceImpl<UserLogMapper, UserLog> implem
if (StrUtil.isNotBlank(logFileWriter) || ObjectUtil.equals(logFileWriter, "1")) { if (StrUtil.isNotBlank(logFileWriter) || ObjectUtil.equals(logFileWriter, "1")) {
throw new BusinessException(AuditLogEnum.MULTIPLE_CLICKS_LOGFILEWRITER); throw new BusinessException(AuditLogEnum.MULTIPLE_CLICKS_LOGFILEWRITER);
} }
redisUtil.saveByKeyWithExpire("logFileWriter", "1",600L); redisUtil.saveByKeyWithExpire("logFileWriter", "1", 600L);
Config config = iConfigService.getOne(new LambdaQueryWrapper<Config>().eq(Config::getState, DataStateEnum.ENABLE.getCode())); Config config = iConfigService.getOne(new LambdaQueryWrapper<Config>().eq(Config::getState, DataStateEnum.ENABLE.getCode()));
@@ -230,7 +281,7 @@ public class AuditServiceImpl extends ServiceImpl<UserLogMapper, UserLog> implem
excelWriter.finish(); excelWriter.finish();
} }
redisUtil.delete("logFileWriter"); redisUtil.delete("logFileWriter");
System.out.println("日志备份结束,共花费时间"+timeInterval.intervalSecond()+"S"); System.out.println("日志备份结束,共花费时间" + timeInterval.intervalSecond() + "S");
} }
@@ -256,7 +307,7 @@ public class AuditServiceImpl extends ServiceImpl<UserLogMapper, UserLog> implem
if (StrUtil.isNotBlank(logFileWriter) || ObjectUtil.equals(logFileWriter, "1")) { if (StrUtil.isNotBlank(logFileWriter) || ObjectUtil.equals(logFileWriter, "1")) {
throw new BusinessException(AuditLogEnum.MULTIPLE_CLICKS_LOGFILEWRITER); throw new BusinessException(AuditLogEnum.MULTIPLE_CLICKS_LOGFILEWRITER);
} }
redisUtil.saveByKeyWithExpire("recoverLogFile", "1",600L); redisUtil.saveByKeyWithExpire("recoverLogFile", "1", 600L);
File newFile = getLastFile(); File newFile = getLastFile();
if (FileUtil.isEmpty(newFile)) { if (FileUtil.isEmpty(newFile)) {
throw new BusinessException(AuditLogEnum.NOT_FIND_FILE); throw new BusinessException(AuditLogEnum.NOT_FIND_FILE);
@@ -440,4 +491,18 @@ public class AuditServiceImpl extends ServiceImpl<UserLogMapper, UserLog> implem
return newFile; return newFile;
} }
/**
* 严重度 文字 转 数字
*/
private Integer levelStringToNumber(String level) {
switch (level) {
case "中等":
return 1;
case "严重":
return 2;
default:
return 0;
}
}
} }