springboot项目日志切面与保存日志记录笔记

所需额外依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.62</version>
</dependency>        

切面类

package com.zy.admin.aspect;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.zy.admin.domain.ExceptionLog;
import com.zy.admin.domain.Syslog;
import com.zy.admin.mapper.ILogMapper;
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.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Date;

/**
 * 日志切面类
 */
@Aspect
@Component
public class LogAspect {

    private Date visitTime; //访问时间
    private String username;    //操作者用户名
    private String url; //访问ip
    private String ip;  //访问资源url
    private String classMethod; //访问方法
    private String args;  //访问参数


    @Autowired
    private HttpServletRequest request;

    @Autowired
    private ILogMapper logMapper;

    /**
     * 引入日志输出对象
     */
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 两个切点,对应前端展示和管理后台的controller位置,使用时可以使用或关系进行共同使用
     */
    @Pointcut("execution(* com.zy.admin.web.*.*(..))")
    public void log(){}
    @Pointcut("execution(* com.zy.admin.web.admin.*.*(..))")
    public void log1(){}

    /**
     * 前置通知,得到访问url、访问者ip、处理访问的控制器方法、传入的参数、操作用户
     * @param joinPoint
     */
    @Before("log() || log1()")
    public void doBefore(JoinPoint joinPoint){
        visitTime = new Date();
        url = request.getRequestURL().toString();   //获取url

        //获取ip
        ip = "";
        String ip1 = request.getHeader("X-Forwarded-For");
        if(ip1 != null && !"unKnown".equals(ip1)){
            int index = ip1.indexOf(",");
            if(index != -1){
                ip = ip1.substring(0,index);
            }else{
                ip = ip1;
            }
        }else{
            ip1 = request.getHeader("X-Real-IP");
            if(ip1 != null && !"unKnown".equals(ip1)){
                ip = ip1;
            }else{
                ip = request.getRemoteAddr();
            }
        }

        //获取执行方法
        classMethod = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();

        //获取传入参数
        Object[] argsValue = joinPoint.getArgs();
        args = Arrays.toString(argsValue);

        //获取当前操作的用户
        SecurityContext context = SecurityContextHolder.getContext();  //从上下文中获取当前登录的用户
        Object principal = context.getAuthentication().getPrincipal();
        if("anonymousUser".equals(principal)){
            username = null;
        }else{
            User user = (User) principal;
            username = user.getUsername();
        }

        logger.info("--------------------------------BeforeStart-----------------------------------------");
        logger.info("url : {}", url);
        logger.info("ip : {}", ip);
        logger.info("classMethod : {}", classMethod);
        logger.info("args : {}", args);
        logger.info("username : {}", username);
        logger.info("visitTime : {}", visitTime);
        logger.info("--------------------------------BeforeEnd-----------------------------------------");
    }

    /**
     * 后置通知,得到控制器返回参数、执行时长
     * @param resultValue
     */
    @AfterReturning(returning = "resultValue",pointcut = "log() || log1()")
    public void doAfterReturn(Object resultValue) throws Exception {
        //获取返回值
        String result = JSON.toJSONString(resultValue, SerializerFeature.DisableCircularReferenceDetect,SerializerFeature.WriteMapNullValue);
        //获取执行时间
        Long executionTime = new Date().getTime() - visitTime.getTime();

        logger.info("--------------------------------doAfterReturnStart-----------------------------------------");
        logger.info("Result : {}", resultValue);
        logger.info("executionTime : {}", executionTime);
        logger.info("--------------------------------doAfterReturnEnd-----------------------------------------");

        //构建日志类
        Syslog syslog = new Syslog(null, visitTime, username, url, ip, executionTime, classMethod, args, result);
        //存入数据库
//        logMapper.saveSyslog(syslog);
    }

    /**
     * 异常通知,得到异常信息、发生时间、ip、url、执行时长、执行方法、传入参数
     * @param e
     */
    @AfterThrowing(throwing = "e",pointcut = "log() || log1()")
    public void doAfterThrowing(Throwable e) throws Exception {
        //获取异常出现时间
        Date happenTime = new Date();
        //获取异常详细信息
        String exceptionJson = JSON.toJSONString(e, SerializerFeature.DisableCircularReferenceDetect,SerializerFeature.WriteMapNullValue);
        //获取异常简单信息
        String exceptionMessage = e.getMessage();
        //获取执行时间
        Long executionTime = new Date().getTime() - visitTime.getTime();

        logger.info("--------------------------------doAfterThrowingStart-----------------------------------------");
        logger.info("exceptionJson : {}", exceptionJson);
        logger.info("exceptionMessage : {}", exceptionMessage);
        logger.info("happenTime : {}", happenTime);
        logger.info("executionTime : {}", executionTime);
        logger.info("--------------------------------doAfterThrowingEnd-----------------------------------------");

        //构建错误日志类
        ExceptionLog exceptionLog = new ExceptionLog(null, exceptionMessage, happenTime,url,executionTime,classMethod,args);
        //存入数据库
//        logMapper.saveExceptionLog(exceptionLog);
    }

    /**
     * 最终通知,输出日志则表示本次访问处理完毕
     */
    @After("log() || log1()")
    public void After(){
        logger.info("--------------------------------doAfter----------------------------------------");
    }


}

日志类

package com.zy.admin.domain;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

/**
 * 日志信息
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Syslog {

    private Long id;
    private Date visitTime; //访问时间
    private String username;    //操作者用户名
    private String url; //访问ip
    private String ip;  //访问资源url
    private Long executionTime;  //执行时长
    private String classMethod; //访问方法
    private String args;  //访问参数
    private String result;  //返回数据
}
package com.zy.admin.domain;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

/**
 * 错误日志信息
 */
@AllArgsConstructor
@NoArgsConstructor
@Data
public class ExceptionLog {

    private Long id;
    private String exceptionMessage;    //异常简单信息
    private Date happenTime;    //异常发生时间
    private String url;  //访问资源url
    private Long executionTime;  //执行时长
    private String classMethod; //访问方法
    private String args;  //访问参数
}

Mapper

package com.zy.admin.mapper;

import com.zy.admin.domain.ExceptionLog;
import com.zy.admin.domain.Syslog;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface ILogMapper {

    /**
     * 保存日志信息
     * @param syslog
     * @throws Exception
     */
    void saveSyslog(Syslog syslog) throws Exception;

    /**
     * 保存错误日志信息
     * @param exceptionLog
     * @throws Exception
     */
    void saveExceptionLog(ExceptionLog exceptionLog) throws Exception;
}

sql

<?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.zy.admin.mapper.ILogMapper">

    <insert id="saveSyslog">
        insert into syslog (id,visit_time,username,ip,url,execution_time,class_method,args,result) values
        (UUID_SHORT(),#{visitTime},#{username},#{ip},#{url},#{executionTime},#{classMethod},#{args},#{result})
    </insert>

    <insert id="saveExceptionLog">
        insert into exception_log (id,happen_time,exceptionMessage,url,execution_time,class_method,args) values
        (UUID_SHORT(),#{happenTime},#{exceptionMessage},#{url},#{executionTime},#{classMethod},#{args})
    </insert>
</mapper>

数据库表

-- 日志表
create table syslog(
	id bigint not null primary key,
	visit_time timestamp,  -- 访问时间
	username varchar(50),  -- 操作者用户名
	ip varchar(30),  -- 访问ip
	url varchar(50),  -- 访问资源url
	execution_time bigint,  -- 执行时长
	class_method varchar(200),  -- 访问方法
	args text,  -- 传入参数
	result text  -- 返回数据
);

-- 错误日志表
create table exception_log(
	id bigint not null primary key,
	happen_time timestamp,  -- 异常发生时间
	exceptionMessage varchar(100),  -- 异常简单信息
	url varchar(100),  -- 访问资源url
	execution_time bigint,  -- 执行时长
	class_method varchar(200),  -- 访问方法
	args text  -- 传入参数
);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@zhouyu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值