操作日志和访问日志记录追踪ID,方便排查问题

This commit is contained in:
b2baccline
2020-05-28 01:27:57 +08:00
parent f79cf065d4
commit c6ab664c01
19 changed files with 293 additions and 107 deletions

View File

@@ -3,10 +3,12 @@ package com.hccake.ballcat.admin.modules.conf.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hccake.ballcat.commom.log.operation.annotation.CreateOperationLogging;
import com.hccake.ballcat.commom.log.operation.annotation.DeleteOperationLogging;
import com.hccake.ballcat.commom.log.operation.annotation.UpdateOperationLogging;
import com.hccake.ballcat.common.core.result.R;
import com.hccake.ballcat.common.modules.config.model.entity.BaseConfig;
import com.hccake.ballcat.common.modules.config.service.BaseConfigService;
import com.hccake.ballcat.commom.log.operation.annotation.OperationLogging;
import com.hccake.ballcat.common.core.result.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
@@ -62,7 +64,7 @@ public class BaseConfigController {
* @return R
*/
@ApiOperation(value = "新增系统配置表", notes = "新增系统配置表")
@OperationLogging("新增系统配置表")
@CreateOperationLogging(msg = "新增系统配置表")
@PostMapping
@PreAuthorize("@per.hasPermission('config:baseconfig:add')")
public R save(@RequestBody BaseConfig baseConfig) {
@@ -76,7 +78,7 @@ public class BaseConfigController {
* @return R
*/
@ApiOperation(value = "修改系统配置表", notes = "修改系统配置表")
@OperationLogging("修改系统配置表")
@UpdateOperationLogging(msg = "修改系统配置表")
@PutMapping
@PreAuthorize("@per.hasPermission('config:baseconfig:edit')")
public R updateById(@RequestBody BaseConfig baseConfig) {
@@ -90,7 +92,7 @@ public class BaseConfigController {
* @return R
*/
@ApiOperation(value = "通过id删除系统配置表", notes = "通过id删除系统配置表")
@OperationLogging("通过id删除系统配置表")
@DeleteOperationLogging(msg = "通过id删除系统配置表")
@DeleteMapping("/{id}")
@PreAuthorize("@per.hasPermission('config:baseconfig:del')")
public R removeById(@PathVariable Integer id) {

View File

@@ -7,10 +7,12 @@ import com.hccake.ballcat.admin.modules.log.thread.AccessLogAdminSaveThread;
import com.hccake.ballcat.admin.oauth.SysUserDetails;
import com.hccake.ballcat.admin.oauth.util.SecurityUtils;
import com.hccake.ballcat.commom.log.access.handler.AccessLogHandler;
import com.hccake.ballcat.commom.log.constant.LogConstant;
import com.hccake.ballcat.commom.log.util.LogUtils;
import com.hccake.ballcat.common.core.util.IPUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.HandlerMapping;
@@ -44,6 +46,7 @@ public class AdminAccessLogHandler implements AccessLogHandler<AdminAccessLog> {
public AdminAccessLog prodLog(HttpServletRequest request, HttpServletResponse response, Long time, Throwable myThrowable) {
AdminAccessLog adminAccessLog = new AdminAccessLog()
.setTraceId(MDC.get(LogConstant.TRACE_ID))
.setCreateTime(LocalDateTime.now())
.setTime(time)
.setIp(IPUtil.getIpAddr(request))

View File

@@ -31,6 +31,11 @@ public class AdminAccessLog extends Model<AdminAccessLog> {
@TableId
@ApiModelProperty(value = "编号")
private Long id;
/**
* 追踪ID
*/
@ApiModelProperty(value="追踪ID")
private String traceId;
/**
* 用户ID
*/

View File

@@ -29,6 +29,11 @@ private static final long serialVersionUID = 1L;
@TableId
@ApiModelProperty(value="编号")
private Long id;
/**
* 追踪ID
*/
@ApiModelProperty(value="追踪ID")
private String traceId;
/**
* 日志消息
*/
@@ -50,9 +55,9 @@ private static final long serialVersionUID = 1L;
@ApiModelProperty(value="请求URI")
private String uri;
/**
* 操作方式
* 请求方法
*/
@ApiModelProperty(value="操作方式")
@ApiModelProperty(value="请求方法")
private String method;
/**
* 操作提交的数据
@@ -64,6 +69,11 @@ private static final long serialVersionUID = 1L;
*/
@ApiModelProperty(value="操作状态")
private Integer status;
/**
* 操作类型
*/
@ApiModelProperty(value="操作类型")
private Integer type;
/**
* 执行时长
*/

View File

@@ -7,7 +7,9 @@ import com.hccake.ballcat.admin.modules.sys.model.entity.SysDict;
import com.hccake.ballcat.admin.modules.sys.model.entity.SysDictItem;
import com.hccake.ballcat.admin.modules.sys.model.qo.SysDictQO;
import com.hccake.ballcat.admin.modules.sys.model.vo.DictDataAndHashVO;
import com.hccake.ballcat.commom.log.operation.annotation.OperationLogging;
import com.hccake.ballcat.commom.log.operation.annotation.CreateOperationLogging;
import com.hccake.ballcat.commom.log.operation.annotation.DeleteOperationLogging;
import com.hccake.ballcat.commom.log.operation.annotation.UpdateOperationLogging;
import com.hccake.ballcat.common.core.result.BaseResultCode;
import com.hccake.ballcat.common.core.result.R;
import io.swagger.annotations.Api;
@@ -83,7 +85,7 @@ public class SysDictController {
* @return R
*/
@ApiOperation(value = "新增字典表", notes = "新增字典表")
@OperationLogging("新增字典表")
@CreateOperationLogging(msg = "新增字典表")
@PostMapping
@PreAuthorize("@per.hasPermission('sys:dict:add')")
public R save(@RequestBody SysDict sysDict) {
@@ -98,7 +100,7 @@ public class SysDictController {
* @return R
*/
@ApiOperation(value = "修改字典表", notes = "修改字典表")
@OperationLogging("修改字典表")
@UpdateOperationLogging(msg = "修改字典表")
@PutMapping
@PreAuthorize("@per.hasPermission('sys:dict:edit')")
public R updateById(@RequestBody SysDict sysDict) {
@@ -113,7 +115,7 @@ public class SysDictController {
* @return R
*/
@ApiOperation(value = "通过id删除字典表", notes = "通过id删除字典表")
@OperationLogging("通过id删除字典表")
@DeleteOperationLogging(msg = "通过id删除字典表")
@DeleteMapping("/{id}")
@PreAuthorize("@per.hasPermission('sys:dict:del')")
public R removeById(@PathVariable Integer id) {
@@ -144,7 +146,7 @@ public class SysDictController {
* @return R
*/
@ApiOperation(value = "新增字典项", notes = "新增字典项")
@OperationLogging("新增字典项")
@CreateOperationLogging(msg = "新增字典项")
@PostMapping("item")
@PreAuthorize("@per.hasPermission('sys:dict:add')")
public R saveItem(@RequestBody SysDictItem sysDictItem) {
@@ -159,7 +161,7 @@ public class SysDictController {
* @return R
*/
@ApiOperation(value = "修改字典项", notes = "修改字典项")
@OperationLogging("修改字典项")
@UpdateOperationLogging(msg = "修改字典项")
@PutMapping("item")
@PreAuthorize("@per.hasPermission('sys:dict:edit')")
public R updateItemById(@RequestBody SysDictItem sysDictItem) {
@@ -174,7 +176,7 @@ public class SysDictController {
* @return R
*/
@ApiOperation(value = "通过id删除字典项", notes = "通过id删除字典项")
@OperationLogging("通过id删除字典项")
@DeleteOperationLogging(msg = "通过id删除字典项")
@DeleteMapping("/item/{id}")
@PreAuthorize("@per.hasPermission('sys:dict:del')")
public R removeItemById(@PathVariable Integer id) {

View File

@@ -10,7 +10,9 @@ import com.hccake.ballcat.admin.modules.sys.model.vo.Router;
import com.hccake.ballcat.admin.modules.sys.service.SysPermissionService;
import com.hccake.ballcat.admin.oauth.SysUserDetails;
import com.hccake.ballcat.admin.oauth.util.SecurityUtils;
import com.hccake.ballcat.commom.log.operation.annotation.OperationLogging;
import com.hccake.ballcat.commom.log.operation.annotation.CreateOperationLogging;
import com.hccake.ballcat.commom.log.operation.annotation.DeleteOperationLogging;
import com.hccake.ballcat.commom.log.operation.annotation.UpdateOperationLogging;
import com.hccake.ballcat.common.core.result.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -93,7 +95,7 @@ public class SysPermissionController {
@ApiOperation(value = "新增权限", notes = "新增权限" )
@OperationLogging("新增权限" )
@CreateOperationLogging(msg = "新增权限" )
@PostMapping
@PreAuthorize("@per.hasPermission('sys:syspermission:add')")
public R save(@Valid @RequestBody SysPermission sysMenu) {
@@ -108,7 +110,7 @@ public class SysPermissionController {
* @return R
*/
@ApiOperation(value = "修改权限", notes = "修改权限" )
@OperationLogging("修改权限" )
@UpdateOperationLogging(msg = "修改权限" )
@PutMapping
@PreAuthorize("@per.hasPermission('sys:syspermission:edit')" )
public R update(@Valid @RequestBody SysPermission sysPermission) {
@@ -117,7 +119,7 @@ public class SysPermissionController {
@ApiOperation(value = "通过id删除权限", notes = "通过id删除权限" )
@OperationLogging("通过id删除权限" )
@DeleteOperationLogging(msg = "通过id删除权限" )
@DeleteMapping("/{id}" )
@PreAuthorize("@per.hasPermission('sys:syspermission:del')" )
public R removeById(@PathVariable Integer id) {

View File

@@ -9,7 +9,9 @@ import com.hccake.ballcat.admin.modules.sys.model.vo.PermissionVO;
import com.hccake.ballcat.admin.modules.sys.service.SysPermissionService;
import com.hccake.ballcat.admin.modules.sys.service.SysRolePermissionService;
import com.hccake.ballcat.admin.modules.sys.service.SysRoleService;
import com.hccake.ballcat.commom.log.operation.annotation.OperationLogging;
import com.hccake.ballcat.commom.log.operation.annotation.CreateOperationLogging;
import com.hccake.ballcat.commom.log.operation.annotation.DeleteOperationLogging;
import com.hccake.ballcat.commom.log.operation.annotation.UpdateOperationLogging;
import com.hccake.ballcat.common.core.result.R;
import com.hccake.ballcat.common.core.vo.SelectData;
import io.swagger.annotations.Api;
@@ -65,7 +67,7 @@ public class SysRoleController {
* @return R
*/
@ApiOperation(value = "新增系统角色", notes = "新增系统角色")
@OperationLogging("新增系统角色")
@CreateOperationLogging(msg = "新增系统角色")
@PostMapping
@PreAuthorize("@per.hasPermission('sys:sysrole:add')")
public R save(@Valid @RequestBody SysRole sysRole) {
@@ -79,7 +81,7 @@ public class SysRoleController {
* @return success/false
*/
@ApiOperation(value = "修改系统角色", notes = "修改系统角色")
@OperationLogging("修改系统角色")
@UpdateOperationLogging(msg = "修改系统角色")
@PutMapping
@PreAuthorize("@per.hasPermission('sys:sysrole:edit')")
public R update(@Valid @RequestBody SysRole role) {
@@ -94,7 +96,7 @@ public class SysRoleController {
*/
@DeleteMapping("/{id}")
@ApiOperation(value = "通过id删除系统角色", notes = "通过id删除系统角色")
@OperationLogging("通过id删除系统角色")
@DeleteOperationLogging(msg = "通过id删除系统角色")
@PreAuthorize("@per.hasPermission('sys:sysrole:del')")
public R removeById(@PathVariable Integer id) {
return R.ok(sysRoleService.removeRoleById(id));
@@ -120,7 +122,7 @@ public class SysRoleController {
*/
@PutMapping("/permission/ids/{roleId}")
@ApiOperation(value = "更新角色权限", notes = "更新角色权限")
@OperationLogging("更新角色权限")
@UpdateOperationLogging(msg = "更新角色权限")
@PreAuthorize("@per.hasPermission('sys:sysrole:grant')")
public R savePermissionIds(@PathVariable Integer roleId, @RequestBody Integer[] permissionIds) {
return R.ok(sysRolePermissionService.saveRolePermissions(roleId, permissionIds));

View File

@@ -12,7 +12,9 @@ import com.hccake.ballcat.admin.modules.sys.model.entity.SysUser;
import com.hccake.ballcat.admin.modules.sys.model.qo.SysUserQO;
import com.hccake.ballcat.admin.modules.sys.service.SysUserRoleService;
import com.hccake.ballcat.admin.modules.sys.service.SysUserService;
import com.hccake.ballcat.commom.log.operation.annotation.OperationLogging;
import com.hccake.ballcat.commom.log.operation.annotation.CreateOperationLogging;
import com.hccake.ballcat.commom.log.operation.annotation.DeleteOperationLogging;
import com.hccake.ballcat.commom.log.operation.annotation.UpdateOperationLogging;
import com.hccake.ballcat.common.core.result.BaseResultCode;
import com.hccake.ballcat.common.core.result.R;
import com.hccake.ballcat.common.core.result.SystemResultCode;
@@ -90,7 +92,7 @@ public class SysUserController {
*/
@PostMapping
@ApiOperation(value = "新增系统用户", notes = "新增系统用户")
@OperationLogging("新增系统用户")
@CreateOperationLogging(msg = "新增系统用户")
@PreAuthorize("@per.hasPermission('sys:sysuser:add')")
public R addSysUser(@Valid @RequestBody SysUserDTO sysUserDto) {
@@ -111,7 +113,7 @@ public class SysUserController {
*/
@PutMapping
@ApiOperation(value = "修改系统用户", notes = "修改系统用户")
@OperationLogging("修改系统用户")
@UpdateOperationLogging(msg = "修改系统用户")
@PreAuthorize("@per.hasPermission('sys:sysuser:edit')")
public R updateUserInfo(@Valid @RequestBody SysUserDTO sysUserDto) {
return sysUserService.updateSysUser(sysUserDto) ?
@@ -127,7 +129,7 @@ public class SysUserController {
*/
@DeleteMapping("/{userId}")
@ApiOperation(value = "通过id删除系统用户", notes = "通过id删除系统用户")
@OperationLogging("通过id删除系统用户")
@DeleteOperationLogging(msg = "通过id删除系统用户")
@PreAuthorize("@per.hasPermission('sys:sysuser:del')")
public R deleteByUserId(@PathVariable Integer userId) {
return sysUserService.deleteByUserId(userId) ?
@@ -170,7 +172,7 @@ public class SysUserController {
*/
@PutMapping("/scope/{userId}")
@ApiOperation(value = "系统用户授权", notes = "系统用户授权")
@OperationLogging("系统用户授权")
@UpdateOperationLogging(msg = "系统用户授权")
@PreAuthorize("@per.hasPermission('sys:sysuser:grant')")
public R updateUserScope(@PathVariable Integer userId, @RequestBody SysUserScope sysUserScope) {
return sysUserService.updateUserScope(userId, sysUserScope) ?
@@ -188,7 +190,7 @@ public class SysUserController {
*/
@PutMapping("/pass/{userId}")
@ApiOperation(value = "修改系统用户密码", notes = "修改系统用户密码")
@OperationLogging("修改系统用户密码")
@UpdateOperationLogging(msg = "修改系统用户密码")
@PreAuthorize("@per.hasPermission('sys:sysuser:pass')")
public R updateUserPass(@PathVariable Integer userId, String pass, String confirm) {
if (StrUtil.isBlank(pass) || StrUtil.isBlank(confirm) || !pass.equals(confirm)) {
@@ -208,7 +210,7 @@ public class SysUserController {
*/
@PutMapping("/status")
@ApiOperation(value = "批量修改用户状态", notes = "批量修改用户状态")
@OperationLogging("批量修改用户状态")
@UpdateOperationLogging(msg = "批量修改用户状态")
@PreAuthorize("@per.hasPermission('sys:sysuser:edit')")
public R updateUserStatus(@NotEmpty(message = "用户ID不能为空") @RequestBody List<Integer> userIds,
@NotNull(message = "用户状态不能为空") @RequestParam Integer status) {
@@ -222,7 +224,7 @@ public class SysUserController {
@ApiOperation(value = "修改系统用户头像", notes = "修改系统用户头像")
@OperationLogging("修改系统用户头像")
@UpdateOperationLogging(msg = "修改系统用户头像")
@PreAuthorize("@per.hasPermission('sys:sysuser:edit')")
@PostMapping("/avatar")
public R<String> updateAvatar(@RequestParam("file") MultipartFile file, @RequestParam("userId") Integer userId) {

View File

@@ -17,8 +17,8 @@ public interface OperationLogConverter {
/**
* 转换OperationLog 为 OperationLogAdmin
* @param operationLogDTO
* @return
* @param operationLogDTO 操作日志DTO
* @return AdminOperationLog
*/
AdminOperationLog dtoToPo(OperationLogDTO operationLogDTO);

View File

@@ -63,7 +63,7 @@ public class ${className}Controller {
* @return R
*/
@ApiOperation(value = "新增${comments}", notes = "新增${comments}")
@OperationLogging("新增${comments}" )
@CreateOperationLogging(msg = "新增${comments}" )
@PostMapping
@PreAuthorize("@per.hasPermission('${moduleName}:${pathName}:add')" )
public R save(@RequestBody ${className} ${classname}) {
@@ -77,7 +77,7 @@ public class ${className}Controller {
* @return R
*/
@ApiOperation(value = "修改${comments}", notes = "修改${comments}")
@OperationLogging("修改${comments}" )
@UpdateOperationLogging(msg = "修改${comments}" )
@PutMapping
@PreAuthorize("@per.hasPermission('${moduleName}:${pathName}:edit')" )
public R updateById(@RequestBody ${className} ${classname}) {
@@ -91,7 +91,7 @@ public class ${className}Controller {
* @return R
*/
@ApiOperation(value = "通过id删除${comments}", notes = "通过id删除${comments}")
@OperationLogging("通过id删除${comments}" )
@DeleteOperationLogging(msg = "通过id删除${comments}" )
@DeleteMapping("/{${pk.lowerAttrName}}" )
@PreAuthorize("@per.hasPermission('${moduleName}:${pathName}:del')" )
public R removeById(@PathVariable ${pk.attrType} ${pk.lowerAttrName}) {

View File

@@ -0,0 +1,26 @@
package com.hccake.ballcat.commom.log.operation.annotation;
import com.hccake.ballcat.commom.log.operation.enums.OperationTypeEnum;
import org.springframework.core.annotation.AliasFor;
import java.lang.annotation.*;
/**
* @author Hccake
* @version 1.0
* @date 2019/10/15 18:09
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@OperationLogging(type = OperationTypeEnum.CREATE)
public @interface CreateOperationLogging {
/**
* 日志信息
* @return 日志描述信息
*/
@AliasFor(annotation = OperationLogging.class)
String msg();
}

View File

@@ -0,0 +1,25 @@
package com.hccake.ballcat.commom.log.operation.annotation;
import com.hccake.ballcat.commom.log.operation.enums.OperationTypeEnum;
import org.springframework.core.annotation.AliasFor;
import java.lang.annotation.*;
/**
* @author Hccake
* @version 1.0
* @date 2019/10/15 18:09
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@OperationLogging(type = OperationTypeEnum.DELETE)
public @interface DeleteOperationLogging {
/**
* 日志信息
* @return 日志描述信息
*/
@AliasFor(annotation = OperationLogging.class)
String msg();
}

View File

@@ -1,5 +1,7 @@
package com.hccake.ballcat.commom.log.operation.annotation;
import com.hccake.ballcat.commom.log.operation.enums.OperationTypeEnum;
import java.lang.annotation.*;
/**
@@ -7,14 +9,20 @@ import java.lang.annotation.*;
* @version 1.0
* @date 2019/10/15 18:09
*/
@Target(ElementType.METHOD)
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperationLogging {
/**
* 日志信息
* @return
* @return 日志描述信息
*/
String value();
String msg() default "";
/**
* 日志操作类型
* @return 日志操作类型枚举
*/
OperationTypeEnum type();
}

View File

@@ -0,0 +1,25 @@
package com.hccake.ballcat.commom.log.operation.annotation;
import com.hccake.ballcat.commom.log.operation.enums.OperationTypeEnum;
import org.springframework.core.annotation.AliasFor;
import java.lang.annotation.*;
/**
* @author Hccake
* @version 1.0
* @date 2019/10/15 18:09
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@OperationLogging(type = OperationTypeEnum.UPDATE)
public @interface UpdateOperationLogging {
/**
* 日志信息
* @return 日志描述信息
*/
@AliasFor(annotation = OperationLogging.class)
String msg();
}

View File

@@ -1,36 +1,35 @@
package com.hccake.ballcat.commom.log.operation.aspect;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.json.JSONUtil;
import com.hccake.ballcat.commom.log.constant.LogConstant;
import com.hccake.ballcat.commom.log.operation.annotation.OperationLogging;
import com.hccake.ballcat.commom.log.operation.enums.LogStatus;
import com.hccake.ballcat.commom.log.operation.enums.LogStatusEnum;
import com.hccake.ballcat.commom.log.operation.event.OperationLogEvent;
import com.hccake.ballcat.commom.log.operation.model.OperationLogDTO;
import com.hccake.ballcat.commom.log.util.LogUtils;
import com.hccake.ballcat.common.core.util.IPUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.Order;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.util.Assert;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* @author Hccake
* @version 1.0
* @date 2019/10/15 18:16
* 操作日志切面类
*/
@Slf4j
@Aspect
@@ -40,77 +39,58 @@ public class OperationLogAspect {
@Autowired
private ApplicationEventPublisher publisher;
@Around("@annotation(operationLogging)")
public Object around(ProceedingJoinPoint joinPoint, OperationLogging operationLogging) throws Throwable {
Signature signature = joinPoint.getSignature();
String strClassName = joinPoint.getTarget().getClass().getName();
String strMethodName = signature.getName();
log.debug("[类名]:{},[方法]:{}", strClassName, strMethodName);
// 获取日志
OperationLogDTO operationLogDTO = prodOperationLog();
operationLogDTO.setMsg(operationLogging.value());
// 记录参数
MethodSignature methodSignature = (MethodSignature) signature;
operationLogDTO.setParams(getParams(joinPoint, methodSignature));
@Around("execution(@(@com.hccake.ballcat.commom.log.operation.annotation.OperationLogging *) * *(..)) " +
"|| @annotation(com.hccake.ballcat.commom.log.operation.annotation.OperationLogging)")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
// 开始时间
Long startTime = System.currentTimeMillis();
Object result;
long startTime = System.currentTimeMillis();
//获取目标方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
// 获取操作日志注解 备注: AnnotationUtils.findAnnotation 方法无法获取继承的属性
OperationLogging operationLogging = AnnotatedElementUtils.findMergedAnnotation(method, OperationLogging.class);
// 获取操作日志 DTO
Assert.notNull(operationLogging, "operationLogging annotation must not be null!");
OperationLogDTO operationLogDTO = this.initOperationLog(operationLogging, joinPoint);
try {
result = joinPoint.proceed();
return joinPoint.proceed();
} catch (Throwable throwable) {
operationLogDTO.setStatus(LogStatus.FAIL.getValue());
operationLogDTO.setStatus(LogStatusEnum.FAIL.getValue());
throw throwable;
}
} finally {
// 结束时间
Long endTime = System.currentTimeMillis();
operationLogDTO.setTime(endTime - startTime);
operationLogDTO.setTime(System.currentTimeMillis() - startTime);
// 发布事件
publisher.publishEvent(new OperationLogEvent(operationLogDTO));
return result;
}
/**
* 获取方法参数
* @param joinPoint
* @param methodSignature
* @return
*/
private String getParams(ProceedingJoinPoint joinPoint, MethodSignature methodSignature) {
String[] parameterNames = methodSignature.getParameterNames();
Object[] args = joinPoint.getArgs();
if(ArrayUtil.isEmpty(parameterNames)){
return null;
}
Map<String, Object> paramsMap = new HashMap<>();
for (int i = 0; i < parameterNames.length; i++) {
paramsMap.put(parameterNames[i], args[i]);
}
return JSONUtil.toJsonStr(paramsMap);
}
/**
* 根据请求生成操作日志
* @return
*
* @param operationLogging 操作日志注解
* @param joinPoint 切点
* @return 初始化一个操作日志DTO
*/
private OperationLogDTO prodOperationLog() {
HttpServletRequest request = ((ServletRequestAttributes) Objects
.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
private OperationLogDTO initOperationLog(OperationLogging operationLogging, ProceedingJoinPoint joinPoint) {
// 获取 Request
HttpServletRequest request = LogUtils.getHttpServletRequest();
return new OperationLogDTO()
.setCreateTime(LocalDateTime.now())
.setIp(IPUtil.getIpAddr(request))
.setMethod(request.getMethod())
.setOperator(Objects.requireNonNull(LogUtils.getUsername()))
.setStatus(LogStatus.SUCCESS.getValue())
.setStatus(LogStatusEnum.SUCCESS.getValue())
.setUserAgent(request.getHeader("user-agent"))
.setUri(URLUtil.getPath(request.getRequestURI()));
.setUri(URLUtil.getPath(request.getRequestURI()))
.setType(operationLogging.type().getValue())
.setMsg(operationLogging.msg())
.setParams(LogUtils.getParams(joinPoint))
.setTraceId(MDC.get(LogConstant.TRACE_ID));
}
}

View File

@@ -11,7 +11,7 @@ import lombok.Getter;
*/
@Getter
@AllArgsConstructor
public enum LogStatus {
public enum LogStatusEnum {
/**
* 成功
*/

View File

@@ -0,0 +1,37 @@
package com.hccake.ballcat.commom.log.operation.enums;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
/**
* @author Hccake
* @version 1.0
* @date 2020/5/27 17:56
* 操作类型
*/
@Getter
@RequiredArgsConstructor
public enum OperationTypeEnum {
/**
* 登陆操作
*/
LOGIN(1),
/**
* 新建操作
*/
CREATE(2),
/**
* 修改操作
*/
UPDATE(3),
/**
* 删除操作
*/
DELETE(4);
private final Integer value;
}

View File

@@ -18,6 +18,16 @@ public class OperationLogDTO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 跟踪ID
*/
@ApiModelProperty(value = "跟踪ID")
private String traceId ;
/**
* 操作类型
*/
@ApiModelProperty(value = "操作类型")
private Integer type ;
/**
* 日志消息
*/
@@ -62,7 +72,7 @@ public class OperationLogDTO implements Serializable {
* 操作人
*/
@ApiModelProperty(value = "操作人")
private String operator ;
private String operator;
/**
* 创建时间
*/

View File

@@ -1,13 +1,23 @@
package com.hccake.ballcat.commom.log.util;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.json.JSONUtil;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.http.HttpMethod;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
@@ -56,10 +66,10 @@ public class LogUtils {
/**
* 判断是否是multipart/form-data请求
*
* @param request
* @return
* @param request 请求信息
* @return 是否是multipart/form-data请求
*/
public static boolean isMultipartContent(HttpServletRequest request) {
public boolean isMultipartContent(HttpServletRequest request) {
if (!HttpMethod.POST.name().equals(request.getMethod().toUpperCase())) {
return false;
}
@@ -68,4 +78,41 @@ public class LogUtils {
return (contentType != null) && (contentType.toLowerCase().startsWith("multipart/"));
}
/**
* 获取当前请求的request
* @return HttpServletRequest
*/
public HttpServletRequest getHttpServletRequest() {
return ((ServletRequestAttributes) Objects
.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
}
/**
* 获取方法参数
* @param joinPoint 切点
* @return 当前方法入参的Json Str
*/
public String getParams(ProceedingJoinPoint joinPoint) {
// 获取方法签名
Signature signature = joinPoint.getSignature();
String strClassName = joinPoint.getTarget().getClass().getName();
String strMethodName = signature.getName();
MethodSignature methodSignature = (MethodSignature) signature;
log.debug("[initOperationLog],获取方法签名[类名]:{},[方法]:{}", strClassName, strMethodName);
String[] parameterNames = methodSignature.getParameterNames();
Object[] args = joinPoint.getArgs();
if(ArrayUtil.isEmpty(parameterNames)){
return null;
}
Map<String, Object> paramsMap = new HashMap<>();
for (int i = 0; i < parameterNames.length; i++) {
paramsMap.put(parameterNames[i], args[i]);
}
return JSONUtil.toJsonStr(paramsMap);
}
}