参考文章:
https://blog.youkuaiyun.com/nan961136007/article/details/86554522
https://blog.youkuaiyun.com/bobozai86/article/details/79229455
https://blog.youkuaiyun.com/weixin_34050005/article/details/91876491
第一步:先创建数据据库和日志类
create table logaspect(
id int unsigned primary key not null auto_increment,
logtype varchar(50) default null,
logerrorcode varchar(20) default null,
logcontent varchar(255) default null,
logdate timestamp default current_timestamp,
useridlogaspect int unsigned default null,
constraint logaspect1 foreign key(userid) references useraccount(id)
)default character set utf8mb4;
package com.gkk.ssm.po;
import java.sql.Timestamp;
/**
* @ClassName: SystemLogAspect
* @Description: TODO
* @author: gxf
* @date: 2019年11月8日 下午7:25:12
*/
public class SystemLogAspectPo {
private Integer id;
private String logType;
private String logErrorCode;
private String logContent;
private Integer userid;
private Timestamp logDate;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUserid() {
return userid;
}
public void setUserid(Integer userid) {
this.userid = userid;
}
/**
* @return the logType
*/
public String getLogType() {
return logType;
}
/**
* @param logType the logType to set
*/
public void setLogType(String logType) {
this.logType = logType;
}
/**
* @return the logErrorCode
*/
public String getLogErrorCode() {
return logErrorCode;
}
/**
* @param logErrorCode the logErrorCode to set
*/
public void setLogErrorCode(String logErrorCode) {
this.logErrorCode = logErrorCode;
}
/**
* @return the logContent
*/
public String getLogContent() {
return logContent;
}
/**
* @param logContent the logContent to set
*/
public void setLogContent(String logContent) {
this.logContent = logContent;
}
/**
* @return the logDate
*/
public Timestamp getLogDate() {
return logDate;
}
/**
* @param logDate the logDate to set
*/
public void setLogDate(Timestamp logDate) {
this.logDate = logDate;
}
}
第二部:创建日志类的Mapper.xml和接口,Service层
package com.gkk.ssm.mapper;
import java.util.List;
import com.gkk.ssm.po.SystemLogAspectPo;
public interface SystemLogAspectMapper{
public List<SystemLogAspectPo> findAll()throws Exception;
public Integer insertLogAspect(SystemLogAspectPo systemLogAspectPo)throws Exception;
public Integer deleteInformation(Integer id)throws Exception;
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.gkk.ssm.mapper.SystemLogAspectMapper" >
<select id="findAll" resultType="com.gkk.ssm.po.SystemLogAspectPo">
SELECT * FROM logaspect
</select>
<insert id="insertLogAspect" parameterType="com.gkk.ssm.po.SystemLogAspectPo">
INSERT INTO logaspect
(logtype,logerrorcode,logcontent,userid)
VALUES(#{logType},#{logErrorCode},#{logContent},#{userid})
</insert>
<delete id="deleteInformation" parameterType="int">
delete from logaspect where id=#{id}
</delete>
</mapper>
/**
* Copyright © 2019 eSunny Info. Tech Ltd. All rights reserved.
*
* @Package: com.gkk.ssm.service.impl
* @author: gxf
* @instroduction:
* @date: 2019年11月9日 上午9:42:24
*/
package com.gkk.ssm.service.impl;
import java.util.List;
import com.gkk.ssm.po.SystemLogAspectPo;
/**
* @ClassName: SystemLogAspectService
* @Description: TODO
* @author: gxf
* @date: 2019年11月9日 上午9:42:24
*/
public interface SystemLogAspectService {
public List<SystemLogAspectPo> findAll()throws Exception;
public Integer insertLogAspect(SystemLogAspectPo systemLogAspectPo)throws Exception;
public Integer deleteInformation(Integer id)throws Exception;
}
/**
* Copyright © 2019 eSunny Info. Tech Ltd. All rights reserved.
*
* @Package: com.gkk.ssm.service.impl
* @author: gxf
* @instroduction:
* @date: 2019年11月9日 上午9:43:51
*/
package com.gkk.ssm.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import com.gkk.ssm.mapper.SystemLogAspectMapper;
import com.gkk.ssm.po.SystemLogAspectPo;
/**
* @ClassName: SystemLogAspectServiceImpl
* @Description: TODO
* @author: gxf
* @date: 2019年11月9日 上午9:43:51
*/
public class SystemLogAspectServiceImpl implements SystemLogAspectService {
@Autowired
private SystemLogAspectMapper systemLogAspectMapper;
@Override
public List<SystemLogAspectPo> findAll() throws Exception {
// TODO Auto-generated method stub
return systemLogAspectMapper.findAll();
}
@Override
public Integer insertLogAspect(SystemLogAspectPo systemLogAspectPo) throws Exception {
// TODO Auto-generated method stub
return systemLogAspectMapper.insertLogAspect(systemLogAspectPo);
}
@Override
public Integer deleteInformation(Integer id) throws Exception {
// TODO Auto-generated method stub
return systemLogAspectMapper.deleteInformation(id);
}
/**
* @return the systemLogAspectMapper
*/
public SystemLogAspectMapper getSystemLogAspectMapper() {
return systemLogAspectMapper;
}
/**
* @param systemLogAspectMapper the systemLogAspectMapper to set
*/
public void setSystemLogAspectMapper(SystemLogAspectMapper systemLogAspectMapper) {
this.systemLogAspectMapper = systemLogAspectMapper;
}
}
第三步:创建注解类和日志切面类
/**
* Copyright © 2019 eSunny Info. Tech Ltd. All rights reserved.
*
* @Package: com.gkk.ssm.annotation
* @author: gxf
* @instroduction:
* @date: 2019年11月9日 下午2:01:11
*/
package com.gkk.ssm.annotation;
import java.lang.annotation.*;
/**
* @ClassName: SystemControllerLog
* @Description: TODO
* @author: gxf
* @date: 2019年11月9日 下午2:01:11
*/
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemControllerLog {
String description() default "";
String actionType() default "";
}
package com.gkk.ssm.aspect;
import java.lang.reflect.Method;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import com.gkk.ssm.annotation.SystemControllerLog;
import com.gkk.ssm.po.SystemLogAspectPo;
import com.gkk.ssm.po.UserAccount;
import com.gkk.ssm.service.impl.SystemLogAspectService;
/**
* @ClassName: SystemLogAspect
* @Description: TODO
* @author: gxf
* @date: 2019年11月8日 下午5:52:47
*/
@Aspect
@Component
public class SystemLogAspect {
@Autowired
private SystemLogAspectService systemLogAspectService;
private static final Logger logger = LoggerFactory.getLogger(SystemLogAspect.class);
@Pointcut("execution (* com.gkk.ssm.controller..*.*(..))")
public void controllerAspect() {
}
@Before("controllerAspect()")
public void doBefore(JoinPoint joinPoint) {
if (logger.isInfoEnabled()) {
logger.info("before " + joinPoint);
}
}
@After("controllerAspect()")
public void after(JoinPoint joinPoint) {
UserAccount userAccount = new UserAccount();
userAccount.setId(1);
try {
String targetName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] arguments = joinPoint.getArgs();
Class targetClass = Class.forName(targetName);
Method[] methods = targetClass.getMethods();
String logType = "";
String logContent = "";
for (Method method : methods) {
if (method.getName().equals(methodName)) {
Class[] clazzs = method.getParameterTypes();
if (clazzs.length == arguments.length) {
logType = method.getAnnotation(SystemControllerLog.class).actionType();
logContent = method.getAnnotation(SystemControllerLog.class).description();
break;
}
}
}
//*========控制台输出=========*//
System.out.println("请求方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));
System.out.println("方法描述:" + logContent);
System.out.println("请求人:" + userAccount.getUsername());
//*========数据库日志=========*//
SystemLogAspectPo log = new SystemLogAspectPo();
log.setUserid(userAccount.getId());
log.setLogType(logType);
log.setLogContent(logContent);
log.setLogErrorCode(HttpStatus.OK.toString());
//保存数据库
systemLogAspectService.insertLogAspect(log);
} catch (Exception e) {
//记录本地异常日志
logger.error("异常信息:{}", e.getMessage());
}
}
//配置后置返回通知,使用在方法aspect()上注册的切入点
@AfterReturning("controllerAspect()")
public void afterReturn(JoinPoint joinPoint) {
if (logger.isInfoEnabled()) {
logger.info("afterReturn " + joinPoint);
}
}
@AfterThrowing(pointcut = "controllerAspect()", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Throwable e) {
UserAccount userAccount = new UserAccount();
userAccount.setId(1);
String logResult = "";
try {
String targetName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] arguments = joinPoint.getArgs();
Class targetClass = Class.forName(targetName);
Method[] methods = targetClass.getMethods();
String logType = "";
String logContent = "";
for (Method method : methods) {
if (method.getName().equals(methodName)) {
Class[] clazzs = method.getParameterTypes();
if (clazzs.length == arguments.length) {
logType = method.getAnnotation(SystemControllerLog.class).actionType();
logContent = method.getAnnotation(SystemControllerLog.class).description();
break;
}
}
}
/*========控制台输出=========*/
System.out.println("异常代码:" + e.getClass().getName());
System.out.println("异常信息:" + e.getMessage());
System.out.println("异常方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));
System.out.println("方法描述:" + logContent);
System.out.println("请求人:" + userAccount.getUsername());
/*==========数据库日志=========*/
SystemLogAspectPo log = new SystemLogAspectPo();
log.setUserid(userAccount.getId());
log.setLogType(logType);
log.setLogContent(logContent);
log.setLogErrorCode(e.getMessage());
//保存数据库
systemLogAspectService.insertLogAspect(log);
} catch (Exception ex) {
//记录本地异常日志
logger.error("异常信息:{}", ex.getMessage());
}
/*==========记录本地异常日志==========*/
logger.error("异常方法:{}异常代码:{}异常信息:{}参数:{}", joinPoint.getTarget().getClass().getName() + joinPoint.getSignature().getName(), e.getClass().getName(), e.getMessage());
}
/**
* @return the systemLogAspectService
*/
public SystemLogAspectService getSystemLogAspectService() {
return systemLogAspectService;
}
/**
* @param systemLogAspectService the systemLogAspectService to set
*/
public void setSystemLogAspectService(SystemLogAspectService systemLogAspectService) {
this.systemLogAspectService = systemLogAspectService;
}
}
第四步:修改配置文件
在springmvc.xml中添加
<!--开启aopproxy-target-class="true"默认是false,更改为true时使用的是cglib动态代理,这样只能实现对Controller层的日志记录-->
<aop:aspectj-autoproxy proxy-target-class="true"/>
<!--扫描日志记录切面-->
<context:component-scan base-package="package com.gkk.ssm.aspect" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/>
</context:component-scan>
效果:
总结:
日志模块大致是完成了,但还有不少地方需要完善,比如日志表中插入的用户id是直接指定为1的,这是因为,我还没把登陆的用户id收集进项目中,后续开发了登录拦截再添加进去。