日志记录

This commit is contained in:
2024-04-29 09:59:48 +08:00
parent ecae487993
commit 5ac93618a6
120 changed files with 1180 additions and 738 deletions

View File

@@ -15,10 +15,7 @@
*/
package cn.ysk.cashier.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.*;
/**
* @author Zheng Jie
@@ -27,5 +24,10 @@ import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
/**
* ("登录授权: #authUser.username") :必填
* 实际会存为 登录授权:用户名
* @return
*/
String value() default "";
}

View File

@@ -1,123 +0,0 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.rest;
import cn.ysk.cashier.annotation.Log;
import cn.ysk.cashier.service.LogService;
import cn.ysk.cashier.service.dto.LogQueryCriteria;
import cn.ysk.cashier.service.dto.LogQueryCriteriaExt;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.utils.SecurityUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
/**
* @author Zheng Jie
* @date 2018-11-24
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/logs")
@Api(tags = "系统:日志管理")
public class LogController {
private final LogService logService;
@Log("导出数据")
@ApiOperation("导出数据")
@GetMapping(value = "/download")
@PreAuthorize("@el.check()")
public void exportLog(HttpServletResponse response, LogQueryCriteria criteria) throws IOException {
criteria.setLogType("INFO");
logService.download(logService.queryAll(criteria), response);
}
@Log("导出错误数据")
@ApiOperation("导出错误数据")
@GetMapping(value = "/error/download")
@PreAuthorize("@el.check()")
public void exportErrorLog(HttpServletResponse response, LogQueryCriteria criteria) throws IOException {
criteria.setLogType("ERROR");
logService.download(logService.queryAll(criteria), response);
}
@GetMapping
@ApiOperation("日志查询")
@PreAuthorize("@el.check()")
public ResponseEntity<Object> queryLog(LogQueryCriteria criteria, Pageable pageable){
criteria.setLogType("INFO");
return new ResponseEntity<>(logService.queryAll(criteria,pageable), HttpStatus.OK);
}
@GetMapping(value = "/user")
@ApiOperation("用户日志查询")
public ResponseEntity<Object> queryUserLog(LogQueryCriteria criteria, Pageable pageable){
criteria.setLogType("INFO");
criteria.setUsername(SecurityUtils.getCurrentUsername());
return new ResponseEntity<>(logService.queryAllByUser(criteria,pageable), HttpStatus.OK);
}
@GetMapping(value = "/error")
@ApiOperation("错误日志查询")
@PreAuthorize("@el.check()")
public ResponseEntity<Object> queryErrorLog(LogQueryCriteria criteria, Pageable pageable){
criteria.setLogType("ERROR");
return new ResponseEntity<>(logService.queryAll(criteria,pageable), HttpStatus.OK);
}
@GetMapping(value = "/error/{id}")
@ApiOperation("日志异常详情查询")
@PreAuthorize("@el.check()")
public ResponseEntity<Object> queryErrorLogDetail(@PathVariable Long id){
return new ResponseEntity<>(logService.findByErrDetail(id), HttpStatus.OK);
}
@DeleteMapping(value = "/del/error")
@Log("删除所有ERROR日志")
@ApiOperation("删除所有ERROR日志")
@PreAuthorize("@el.check()")
public ResponseEntity<Object> delAllErrorLog(){
logService.delAllByError();
return new ResponseEntity<>(HttpStatus.OK);
}
@DeleteMapping(value = "/del/info")
@Log("删除所有INFO日志")
@ApiOperation("删除所有INFO日志")
@PreAuthorize("@el.check()")
public ResponseEntity<Object> delAllInfoLog(){
logService.delAllByInfo();
return new ResponseEntity<>(HttpStatus.OK);
}
/**
*
* @param criteria
* @param pageable
* @return
*/
@GetMapping("/shopInfo")
public ResponseEntity<Object> queryShopInfoLog(LogQueryCriteriaExt criteria, Pageable pageable){
return new ResponseEntity<>(logService.shopInfoLog(criteria, pageable),HttpStatus.OK);
}
}

View File

@@ -0,0 +1,52 @@
package cn.ysk.cashier.service;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import java.lang.reflect.Method;
public class SpelUtil {
/**
* 用于SpEL表达式解析.
*/
private static final SpelExpressionParser parser = new SpelExpressionParser();
/**
* 用于获取方法参数定义名字.
*/
private static final DefaultParameterNameDiscoverer nameDiscoverer = new DefaultParameterNameDiscoverer();
/**
* 解析SpEL表达式
*
* @param spELStr
* @param joinPoint
* @return
*/
public static String generateKeyBySpEL(String spELStr, ProceedingJoinPoint joinPoint) {
// 通过joinPoint获取被注解方法
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod();
// 使用Spring的DefaultParameterNameDiscoverer获取方法形参名数组
String[] paramNames = nameDiscoverer.getParameterNames(method);
// 解析过后的Spring表达式对象
Expression expression = parser.parseExpression(spELStr);
// Spring的表达式上下文对象
EvaluationContext context = new StandardEvaluationContext();
// 通过joinPoint获取被注解方法的形参
Object[] args = joinPoint.getArgs();
// 给上下文赋值
for (int i = 0; i < args.length; i++) {
context.setVariable(paramNames[i], args[i]);
}
if(expression.getValue(context)==null){
return "";
}
return expression.getValue(context).toString();
}
}

View File

@@ -23,6 +23,7 @@ import cn.ysk.cashier.domain.Log;
import cn.ysk.cashier.domain.LogVO;
import cn.ysk.cashier.repository.LogRepository;
import cn.ysk.cashier.service.LogService;
import cn.ysk.cashier.service.SpelUtil;
import cn.ysk.cashier.service.dto.LogQueryCriteria;
import cn.ysk.cashier.service.dto.LogQueryCriteriaExt;
import cn.ysk.cashier.service.mapstruct.LogErrorMapper;
@@ -80,7 +81,7 @@ public class LogServiceImpl implements LogService {
@Override
@Transactional(rollbackFor = Exception.class)
public void save(String username, String browser, String ip, ProceedingJoinPoint joinPoint, Log log,Integer shopId) {
public void save(String username, String browser, String ip, ProceedingJoinPoint joinPoint, Log log, Integer shopId) {
if (log == null) {
throw new IllegalArgumentException("Log 不能为 null!");
}
@@ -90,17 +91,21 @@ public class LogServiceImpl implements LogService {
// 方法路径
String methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()";
// 描述
log.setDescription(aopLog.value());
String[] split = aopLog.value().split(":");
if (split.length == 2) {
String value = SpelUtil.generateKeyBySpEL(split[1], joinPoint);
// 描述
log.setDescription(split[0] + ":" + value);
}else {
log.setDescription(split[0]);
}
log.setRequestIp(ip);
log.setAddress(StringUtils.getCityInfo(log.getRequestIp()));
log.setMethod(methodName);
log.setUsername(username);
log.setParams(getParameter(method, joinPoint.getArgs()));
// 记录登录用户,隐藏密码信息
if(signature.getName().equals("login") && StringUtils.isNotEmpty(log.getParams())){
if (signature.getName().equals("login") && StringUtils.isNotEmpty(log.getParams())) {
JSONObject obj = JSONUtil.parseObj(log.getParams());
log.setUsername(obj.getStr("username", ""));
log.setParams(JSONUtil.toJsonStr(Dict.create().set("username", log.getUsername())));
@@ -182,7 +187,7 @@ public class LogServiceImpl implements LogService {
public Map<String, Object> shopInfoLog(LogQueryCriteriaExt criteria, Pageable pageable) {
Page<Log> page = logRepository.findAll(((root, criteriaQuery, cb) -> QueryHelp.getPredicate(root, criteria, cb)), pageable);
List<LogVO> logVOList = new ArrayList<>();
for (Log log :page.getContent()) {
for (Log log : page.getContent()) {
LogVO logVO = new LogVO();
logVO.setDescription(log.getDescription());
logVO.setCreateTime(log.getCreateTime());
@@ -190,9 +195,9 @@ public class LogServiceImpl implements LogService {
logVO.setRequestIp(log.getRequestIp());
logVOList.add(logVO);
}
Map<String,Object> map = new LinkedHashMap<>(2);
map.put("content",logVOList);
map.put("totalElements",page.getTotalElements());
Map<String, Object> map = new LinkedHashMap<>(2);
map.put("content", logVOList);
map.put("totalElements", page.getTotalElements());
return map;
}