共有 13 个文件被更改,包括 382 次插入 和 14 次删除
@ -0,0 +1,19 @@ |
|||||
|
package com.aiprose.mbp.annotation; |
||||
|
import java.lang.annotation.Documented; |
||||
|
import java.lang.annotation.ElementType; |
||||
|
import java.lang.annotation.Retention; |
||||
|
import java.lang.annotation.RetentionPolicy; |
||||
|
import java.lang.annotation.Target; |
||||
|
|
||||
|
/** |
||||
|
* 自定义操作日志注解 |
||||
|
* @author nelson |
||||
|
*/ |
||||
|
@Target(ElementType.METHOD) //注解放置的目标位置,METHOD是可注解在方法级别上
|
||||
|
@Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行
|
||||
|
@Documented |
||||
|
public @interface OperLog { |
||||
|
String operModul() default ""; // 操作模块
|
||||
|
String operType() default ""; // 操作类型
|
||||
|
String operDesc() default ""; // 操作说明
|
||||
|
} |
@ -0,0 +1,186 @@ |
|||||
|
package com.aiprose.mbp.aop; |
||||
|
|
||||
|
import com.aiprose.mbp.annotation.OperLog; |
||||
|
import com.aiprose.mbp.entity.ExceptionLog; |
||||
|
import com.aiprose.mbp.entity.SysLog; |
||||
|
import com.aiprose.mbp.service.ExceptionLogService; |
||||
|
import com.aiprose.mbp.service.SysLogService; |
||||
|
import com.aiprose.mbp.util.IPUtil; |
||||
|
import com.alibaba.fastjson.JSON; |
||||
|
import org.aspectj.lang.JoinPoint; |
||||
|
import org.aspectj.lang.annotation.AfterReturning; |
||||
|
import org.aspectj.lang.annotation.AfterThrowing; |
||||
|
import org.aspectj.lang.annotation.Aspect; |
||||
|
import org.aspectj.lang.annotation.Pointcut; |
||||
|
import org.aspectj.lang.reflect.MethodSignature; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.beans.factory.annotation.Value; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
import org.springframework.web.context.request.RequestAttributes; |
||||
|
import org.springframework.web.context.request.RequestContextHolder; |
||||
|
|
||||
|
import javax.servlet.http.HttpServletRequest; |
||||
|
import java.lang.reflect.Method; |
||||
|
import java.util.HashMap; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
@Aspect |
||||
|
@Component |
||||
|
public class OperLogAspect { |
||||
|
|
||||
|
@Value("${version}") |
||||
|
private String operVer; |
||||
|
|
||||
|
@Autowired |
||||
|
private SysLogService sysLogService; |
||||
|
|
||||
|
@Autowired |
||||
|
private ExceptionLogService excService; |
||||
|
|
||||
|
/** |
||||
|
* 设置操作日志切入点 记录操作日志 在注解的位置切入代码 |
||||
|
*/ |
||||
|
@Pointcut("@annotation(com.aiprose.mbp.annotation.OperLog)") |
||||
|
public void syslogPoinCut() { |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 设置操作异常切入点记录异常日志 扫描所有controller包下操作 |
||||
|
*/ |
||||
|
@Pointcut("execution(* com.aiprose.mbp.controller..*.*(..))") |
||||
|
public void operExceptionLogPoinCut() { |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 正常返回通知,拦截用户操作日志,连接点正常执行完成后执行, 如果连接点抛出异常,则不会执行 |
||||
|
* @param joinPoint 切入点 |
||||
|
* @param keys 返回结果 |
||||
|
*/ |
||||
|
@AfterReturning(value = "syslogPoinCut()", returning = "keys") |
||||
|
public void savesyslog(JoinPoint joinPoint, Object keys) { |
||||
|
// 获取RequestAttributes
|
||||
|
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); |
||||
|
// 从获取RequestAttributes中获取HttpServletRequest的信息
|
||||
|
HttpServletRequest request = (HttpServletRequest) requestAttributes |
||||
|
.resolveReference(RequestAttributes.REFERENCE_REQUEST); |
||||
|
|
||||
|
SysLog syslog = new SysLog(); |
||||
|
try { |
||||
|
|
||||
|
// 从切面织入点处通过反射机制获取织入点处的方法
|
||||
|
MethodSignature signature = (MethodSignature) joinPoint.getSignature(); |
||||
|
// 获取切入点所在的方法
|
||||
|
Method method = signature.getMethod(); |
||||
|
// 获取操作
|
||||
|
OperLog opLog = method.getAnnotation(OperLog.class); |
||||
|
if (opLog != null) { |
||||
|
String operModul = opLog.operModul(); |
||||
|
String operType = opLog.operType(); |
||||
|
String operDesc = opLog.operDesc(); |
||||
|
syslog.setOperModul(operModul); // 操作模块
|
||||
|
syslog.setOperType(operType); // 操作类型
|
||||
|
syslog.setOperDesc(operDesc); // 操作描述
|
||||
|
} |
||||
|
// 获取请求的类名
|
||||
|
String className = joinPoint.getTarget().getClass().getName(); |
||||
|
// 获取请求的方法名
|
||||
|
String methodName = method.getName(); |
||||
|
methodName = className + "." + methodName; |
||||
|
|
||||
|
syslog.setOperMethod(methodName); // 请求方法
|
||||
|
|
||||
|
// 请求的参数
|
||||
|
Map<String, String> rtnMap = converMap(request.getParameterMap()); |
||||
|
// 将参数所在的数组转换成json
|
||||
|
String params = JSON.toJSONString(rtnMap); |
||||
|
|
||||
|
syslog.setOperRequParam(params); // 请求参数
|
||||
|
syslog.setOperRespParam(JSON.toJSONString(keys)); // 返回结果
|
||||
|
syslog.setOperUserId(1l); // 请求用户ID
|
||||
|
syslog.setOperUserName("nelson"); // 请求用户名称
|
||||
|
syslog.setOperIp(IPUtil.getIpAddr(request)); // 请求IP
|
||||
|
syslog.setOperUri(request.getRequestURI()); // 请求URI
|
||||
|
syslog.setOperVersion(operVer); // 操作版本
|
||||
|
sysLogService.save(syslog); |
||||
|
} catch (Exception e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 异常返回通知,用于拦截异常日志信息 连接点抛出异常后执行 |
||||
|
* |
||||
|
* @param joinPoint 切入点 |
||||
|
* @param e 异常信息 |
||||
|
*/ |
||||
|
@AfterThrowing(pointcut = "operExceptionLogPoinCut()", throwing = "e") |
||||
|
public void saveExceptionLog(JoinPoint joinPoint, Throwable e) { |
||||
|
// 获取RequestAttributes
|
||||
|
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); |
||||
|
// 从获取RequestAttributes中获取HttpServletRequest的信息
|
||||
|
HttpServletRequest request = (HttpServletRequest) requestAttributes |
||||
|
.resolveReference(RequestAttributes.REFERENCE_REQUEST); |
||||
|
|
||||
|
ExceptionLog excepLog = new ExceptionLog(); |
||||
|
try { |
||||
|
// 从切面织入点处通过反射机制获取织入点处的方法
|
||||
|
MethodSignature signature = (MethodSignature) joinPoint.getSignature(); |
||||
|
// 获取切入点所在的方法
|
||||
|
Method method = signature.getMethod(); |
||||
|
// 获取请求的类名
|
||||
|
String className = joinPoint.getTarget().getClass().getName(); |
||||
|
// 获取请求的方法名
|
||||
|
String methodName = method.getName(); |
||||
|
methodName = className + "." + methodName; |
||||
|
// 请求的参数
|
||||
|
Map<String, String> rtnMap = converMap(request.getParameterMap()); |
||||
|
// 将参数所在的数组转换成json
|
||||
|
String params = JSON.toJSONString(rtnMap); |
||||
|
excepLog.setExcRequParam(params); // 请求参数
|
||||
|
excepLog.setOperMethod(methodName); // 请求方法名
|
||||
|
excepLog.setExcName(e.getClass().getName()); // 异常名称
|
||||
|
excepLog.setExcMsg(stackTraceToString(e.getClass().getName(), e.getMessage(), e.getStackTrace())); // 异常信息
|
||||
|
excepLog.setOperUserId(1l); // 请求用户ID
|
||||
|
excepLog.setOperUserName("nelson"); // 请求用户名称
|
||||
|
excepLog.setOperUri(request.getRequestURI()); // 操作URI
|
||||
|
excepLog.setOperIp(IPUtil.getIpAddr(request)); // 操作员IP
|
||||
|
excepLog.setOperVersion(operVer); // 操作版本号
|
||||
|
|
||||
|
excService.save(excepLog); |
||||
|
|
||||
|
} catch (Exception e2) { |
||||
|
e2.printStackTrace(); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 转换request 请求参数 |
||||
|
* |
||||
|
* @param paramMap request获取的参数数组 |
||||
|
*/ |
||||
|
public Map<String, String> converMap(Map<String, String[]> paramMap) { |
||||
|
Map<String, String> rtnMap = new HashMap<String, String>(); |
||||
|
for (String key : paramMap.keySet()) { |
||||
|
rtnMap.put(key, paramMap.get(key)[0]); |
||||
|
} |
||||
|
return rtnMap; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 转换异常信息为字符串 |
||||
|
* |
||||
|
* @param exceptionName 异常名称 |
||||
|
* @param exceptionMessage 异常信息 |
||||
|
* @param elements 堆栈信息 |
||||
|
*/ |
||||
|
public String stackTraceToString(String exceptionName, String exceptionMessage, StackTraceElement[] elements) { |
||||
|
StringBuffer strbuff = new StringBuffer(); |
||||
|
for (StackTraceElement stet : elements) { |
||||
|
strbuff.append(stet + "\n"); |
||||
|
} |
||||
|
String message = exceptionName + ":" + exceptionMessage + "\n\t" + strbuff.toString(); |
||||
|
return message; |
||||
|
} |
||||
|
} |
@ -0,0 +1,39 @@ |
|||||
|
package com.aiprose.mbp.entity; |
||||
|
import com.baomidou.mybatisplus.annotation.TableName; |
||||
|
import com.gitee.sunchenbin.mybatis.actable.annotation.Column; |
||||
|
import com.gitee.sunchenbin.mybatis.actable.annotation.Table; |
||||
|
import com.gitee.sunchenbin.mybatis.actable.constants.MySqlTypeConstant; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
@Data |
||||
|
@Table(name="mbp_exception_log") |
||||
|
@TableName("mbp_exception_log") |
||||
|
public class ExceptionLog extends SuperEntity{ |
||||
|
|
||||
|
@Column(name = "oper_user_id",comment = "操作用户id") |
||||
|
private Long operUserId; |
||||
|
|
||||
|
@Column(name = "oper_user_name",comment = "操作用户名") |
||||
|
private String operUserName; |
||||
|
|
||||
|
@Column(name = "exc_requ_param",comment = "请求参数",type = MySqlTypeConstant.TEXT) |
||||
|
private String excRequParam; |
||||
|
|
||||
|
@Column(name = "oper_method",comment = "操作方法") |
||||
|
private String operMethod; |
||||
|
|
||||
|
@Column(name = "oper_uri",comment = "请求uri") |
||||
|
private String operUri; |
||||
|
|
||||
|
@Column(name = "oper_ip",comment = "请求ip") |
||||
|
private String operIp; |
||||
|
|
||||
|
@Column(name = "oper_version",comment = "版本号") |
||||
|
private String operVersion; |
||||
|
|
||||
|
@Column(name = "exc_name",comment = "异常名称") |
||||
|
private String excName; |
||||
|
|
||||
|
@Column(name = "exc_msg",comment = "异常信息",type = MySqlTypeConstant.TEXT) |
||||
|
private String excMsg; |
||||
|
} |
@ -0,0 +1,45 @@ |
|||||
|
package com.aiprose.mbp.entity; |
||||
|
import com.baomidou.mybatisplus.annotation.TableName; |
||||
|
import com.gitee.sunchenbin.mybatis.actable.annotation.Column; |
||||
|
import com.gitee.sunchenbin.mybatis.actable.annotation.Table; |
||||
|
import com.gitee.sunchenbin.mybatis.actable.constants.MySqlTypeConstant; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
@Data |
||||
|
@Table(name="mbp_syslog") |
||||
|
@TableName("mbp_syslog") |
||||
|
public class SysLog extends SuperEntity{ |
||||
|
|
||||
|
@Column(name = "oper_user_id",comment = "操作用户id") |
||||
|
private Long operUserId; |
||||
|
|
||||
|
@Column(name = "oper_user_name",comment = "操作用户名") |
||||
|
private String operUserName; |
||||
|
|
||||
|
@Column(name = "oper_modul",comment = "功能模块") |
||||
|
private String operModul; |
||||
|
|
||||
|
@Column(name = "oper_type",comment = "操作类型") |
||||
|
private String operType; |
||||
|
|
||||
|
@Column(name = "oper_desc",comment = "操作描述") |
||||
|
private String operDesc; |
||||
|
|
||||
|
@Column(name = "oper_requ_param",comment = "请求参数",type = MySqlTypeConstant.TEXT) |
||||
|
private String operRequParam; |
||||
|
|
||||
|
@Column(name = "oper_resp_param",comment = "返回参数",type = MySqlTypeConstant.TEXT) |
||||
|
private String operRespParam; |
||||
|
|
||||
|
@Column(name = "oper_method",comment = "操作方法") |
||||
|
private String operMethod; |
||||
|
|
||||
|
@Column(name = "oper_uri",comment = "请求uri") |
||||
|
private String operUri; |
||||
|
|
||||
|
@Column(name = "oper_ip",comment = "请求ip") |
||||
|
private String operIp; |
||||
|
|
||||
|
@Column(name = "oper_version",comment = "版本号") |
||||
|
private String operVersion; |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
package com.aiprose.mbp.mapper; |
||||
|
|
||||
|
import com.aiprose.mbp.entity.ExceptionLog; |
||||
|
import com.aiprose.mbp.entity.SysLog; |
||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||
|
import org.apache.ibatis.annotations.Mapper; |
||||
|
|
||||
|
@Mapper |
||||
|
public interface ExceptionLogMapper extends BaseMapper<ExceptionLog> { |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
package com.aiprose.mbp.mapper; |
||||
|
|
||||
|
import com.aiprose.mbp.entity.SysLog; |
||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||
|
import org.apache.ibatis.annotations.Mapper; |
||||
|
|
||||
|
@Mapper |
||||
|
public interface SysLogMapper extends BaseMapper<SysLog> { |
||||
|
} |
@ -0,0 +1,13 @@ |
|||||
|
package com.aiprose.mbp.service; |
||||
|
|
||||
|
import com.aiprose.mbp.entity.ExceptionLog; |
||||
|
import com.aiprose.mbp.entity.SysLog; |
||||
|
import com.aiprose.mbp.mapper.ExceptionLogMapper; |
||||
|
import com.aiprose.mbp.mapper.SysLogMapper; |
||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
@Service |
||||
|
public class ExceptionLogService extends ServiceImpl<ExceptionLogMapper, ExceptionLog> { |
||||
|
|
||||
|
} |
@ -0,0 +1,18 @@ |
|||||
|
package com.aiprose.mbp.service; |
||||
|
|
||||
|
import com.aiprose.mbp.entity.SysLog; |
||||
|
import com.aiprose.mbp.entity.User; |
||||
|
import com.aiprose.mbp.mapper.SysLogMapper; |
||||
|
import com.aiprose.mbp.mapper.UserMapper; |
||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
@Service |
||||
|
public class SysLogService extends ServiceImpl<SysLogMapper, SysLog> { |
||||
|
|
||||
|
} |
@ -0,0 +1,26 @@ |
|||||
|
package com.aiprose.mbp.util; |
||||
|
|
||||
|
import javax.servlet.http.HttpServletRequest; |
||||
|
|
||||
|
public class IPUtil { |
||||
|
/** |
||||
|
* 获取IP地址 |
||||
|
* |
||||
|
* 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址 |
||||
|
* 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址 |
||||
|
*/ |
||||
|
public static String getIpAddr(HttpServletRequest request) { |
||||
|
|
||||
|
String ip = request.getHeader("x-forwarded-for"); |
||||
|
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
||||
|
ip = request.getHeader("Proxy-Client-IP"); |
||||
|
} |
||||
|
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
||||
|
ip = request.getHeader("WL-Proxy-Client-IP"); |
||||
|
} |
||||
|
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
||||
|
ip = request.getRemoteAddr(); |
||||
|
} |
||||
|
return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip; |
||||
|
} |
||||
|
} |
正在加载...
在新工单中引用