操作日志记录(包括输出至自定义日志文件)

1.日志部分

1.1日志依赖


<dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-core</artifactId>
      <version>1.2.3</version>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.2.3</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.30</version>
</dependency>

1.2logback.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<!-- configuration file for LogBack (slf4J implementation)
See here for more details: http://gordondickens.com/wordpress/2013/03/27/sawing-through-the-java-loggers/ -->
<!--code generator-->
<!--author Steven-->
<!--version 1.0.0-->
<configuration scan="true" scanPeriod="30 seconds">

    <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
        <resetJUL>true</resetJUL>
    </contextListener>

    <!-- To enable JMX Management -->
    <jmxConfigurator/>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logs/log.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- Daily rollover with compression -->
            <fileNamePattern>logs/log-%d{yyyy-MM-dd}.gz</fileNamePattern>
            <!-- keep 30 days worth of history -->
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%date{yyyy-MM-dd HH:mm:ss} ${PID}: %-5level %logger{0} - %msg%n</pattern>
        </encoder>
    </appender>
    <appender name="errorAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logs/error.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>logs/error-%d{yyyy-MM-dd}.log</fileNamePattern>
        </rollingPolicy>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} %thread %X{invokeNo} %logger{40} %msg%n</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 只打印错误日志 -->
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%date{yyyy-MM-dd HH:mm:ss} ${PID}: %-5level %logger{0} - %msg%n</pattern>
        </encoder>
    </appender>

    <!--不同业务逻辑的日志打印到不同文件-->
    <appender name="operationLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>logs/operation.log</File>
        <append>true</append>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>logs/operation-%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder charset="UTF-8">
            <pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %level [%thread] %file:%line - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- 不同的业务逻辑日志打印到指定文件夹-->
    <logger name="operation" additivity="false" level="INFO">
        <appender-ref ref="operationLog"/>
    </logger>

    <!-- Specify logging levels -->
    <logger name="org.springframework" level="info"/>
    <logger name="org.hibernate" level="info"/>
    <logger name="com.jpxx.admin" level="debug"/>
    <logger name="com.jpxx.base" level="info"/>
    <!--<logger name="org.springframework.transaction" level="DEBUG" />-->
    <!--<logger name="org.springframework.jdbc.datasource" level="DEBUG" />-->
    <!--<logger name="org.springframework.orm.jpa" level="DEBUG" />-->

    <root level="info">
        <appender-ref ref="console"/>
        <appender-ref ref="FILE"/>
        <appender-ref ref="errorAppender"/>
    </root>
</configuration>

2.自定义注解配合aop实现拦截记录用户操作

2.1aop依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

2.2开启aop配置

spring:
  #切面启用
  aop:
    proxy-target-class: true
    auto: true

2.3自定义注解

@Target({ElementType.PARAMETER, ElementType.METHOD})//作用在参数和方法上
@Retention(RetentionPolicy.RUNTIME)//运行时注解
@Documented//表明这个注解应该被 javadoc工具记录
public @interface OperationLog  {
    String description() default "";
}

2.4切面类


import com.alibaba.fastjson.JSON;
import com.jpxx.admin.common.util.LoggerUtils;
import com.jpxx.admin.system.service.api.SysUserService;

import com.jpxx.base.utils.jwt.JwtSubject;
import com.jpxx.base.utils.jwt.JwtUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.util.Enumeration;

/**
 * @ClassName SystemLogAspect
 * @Description
 * @Author Administrator
 * @Date 2020/10/15 0015 16:49
 * @Version 1.0
 */
@Aspect
@Component
@SuppressWarnings("all")
public class SystemLogAspect {


    //本地日志记录对象
    private static final Logger logger = LoggerUtils.Logger("operation");


    //api切点
    @Pointcut("@annotation(com.jpxx.admin.system.web.annotation.OperationLog)")
    public void operationAspect() {
    }

    /**
     * @Description 前置通知 
     */
    @Before("operationAspect()")
    public void doBefore(JoinPoint joinPoint) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        Enumeration<String> headerNames = request.getHeaderNames();
        //读取用户信息
        String token = request.getHeader("token");
        JwtSubject decode = JwtUtils.decode(token);
        Long usId = decode.getUsId();
        String ip = request.getRemoteHost();
        try {
            //*========控制台输出=========*//
            System.out.println("==============前置通知开始==============");
            System.out.println("请求方法" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName()));
            System.out.println("方法描述:" + getControllerMethodDescription(joinPoint));
            System.out.println("请求人id:" + usId);
            System.out.println("请求ip:" + ip);

            //日志记录
            logger.info("请求方法" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName()));
            logger.info("方法描述:" + getControllerMethodDescription(joinPoint));
            logger.info("请求人id:" + usId);
            logger.info("请求ip:" + ip);
        } catch (Exception e) {
            //记录本地异常日志
            logger.error("==前置通知异常==");
            logger.error("异常信息:{}", e.getMessage());
        }
    }

   

    /**
     * @Description 获取方法描述
     */
    public static String getServiceMethodDescription(JoinPoint joinPoint) throws Exception {
        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 description = "";
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                Class[] clazzs = method.getParameterTypes();
                if (clazzs.length == arguments.length) {
                    description = method.getAnnotation(SystemServiceLog.class).description();
                    break;
                }
            }
        }
        return description;
    }

}

2.5测试添加注解的接口

运行后:

控制台:

 日志:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值