springboot+log根据要求,动态生成不同的日志

项目需求描述

  1. 项目根据aop切面做日志,但有个别接口返回数据特别多,导致实时查看日志刷屏
  2. 个别接口返回数据日志也需要记录,打印到专门的文件中

项目使用springboot+logback

转自:https://www.iteye.com/blog/shift-alt-ctrl-2394366

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.core.rolling.RollingFileAppender;
import ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy;
import ch.qos.logback.core.util.FileSize;
import ch.qos.logback.core.util.OptionHelper;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;


@Component
public class LoggerBuilderUtils {
    private static String loggingPath;

    @Value("${logging.file.path}")
    public void setLoggingPath(String loggingPath) {
        LoggerBuilderUtils.loggingPath = loggingPath;
    }

    private static final Map container = new HashMap<>();

    public static Logger getLogger(String name) {
        Logger logger = container.get(name);
        if (logger != null) {
            return logger;
        }
        synchronized (LoggerBuilderUtils.class) {
            logger = container.get(name);
            if (logger != null) {
                return logger;
            }
            logger = build(name);
            container.put(name, logger);
        }
        return logger;
    }

    private static Logger build(String name) {
        LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
        Logger logger = context.getLogger("FILE-" + name);
        logger.setAdditive(false);
        RollingFileAppender appender = new RollingFileAppender();
        appender.setContext(context);
        appender.setName("FILE-" + name);
        appender.setFile(OptionHelper.substVars(loggingPath +"/"+  name + "_big_info" + ".log", context));
        appender.setAppend(true);
        appender.setPrudent(false);
        SizeAndTimeBasedRollingPolicy policy = new SizeAndTimeBasedRollingPolicy();
        String fp = OptionHelper.substVars(loggingPath +"/"+  name + "_big_info.log.%d{yyyy-MM-dd}.%i", context);

        policy.setMaxFileSize(FileSize.valueOf("500MB"));
        policy.setFileNamePattern(fp);
        policy.setMaxHistory(30);
        policy.setTotalSizeCap(FileSize.valueOf("32GB"));
        policy.setParent(appender);
        policy.setContext(context);
        policy.start();

        PatternLayoutEncoder encoder = new PatternLayoutEncoder();
        encoder.setContext(context);
        encoder.setPattern("%d{yyyy-MM-dd HH:mm:ss.SSS}|%X{localIp}|[%t] %-5level %logger{50} %line - %m%n");
        encoder.start();

        appender.setRollingPolicy(policy);
        appender.setEncoder(encoder);
        appender.start();
        logger.addAppender(appender);
        return logger;
    }
}

aop代码

import cn.hutool.json.JSONUtil;
import com.lowi.manylogs.config.Result;
import com.lowi.manylogs.utils.LoggerBuilderUtils;
import lombok.Getter;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.*;

@Aspect
@Component
@Getter
public class ControllerInterceptor {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 定义拦截规则:拦截com.lyx.oaserver.controller包下面的所有类中,有@RequestMapping注解的方法。
     */
    @Pointcut("execution(* com.lowi.manylogs.controller..*(..))")
    public void controllerMethodPointcut() {
    }

    private static Set setList = new HashSet<>();

    private static String inNewLogMethod;

    @Value("${inNewLogMethod}")
    public void setInNewLogMethod(String inNewLogMethod) {
        ControllerInterceptor.inNewLogMethod = inNewLogMethod;
        if (!inNewLogMethod.isEmpty()) {
            String[] split = inNewLogMethod.split(",");
            setList.addAll(Arrays.asList(split));
        }
    }

    private final static String serviceName = "lowi";

    /**
     * 拦截器具体实现
     *
     * @param pjp
     * @param requestMapping
     * @return Object 被拦截方法的执行结果
     */
    @Around("controllerMethodPointcut() && @annotation(requestMapping)") //指定拦截器规则;也可以直接把“execution(* .........)”写进这里
    public Object Interceptor(ProceedingJoinPoint pjp, RequestMapping requestMapping) {
        Result result = new Result();
        result.setCode(1);
        result.setMsg("fail");
        boolean inNewLog = false;
        String classPath = "";
        String methodPath = "";
        String requestPath = "";
        ch.qos.logback.classic.Logger newLogger = null;
        Map parameMap = new HashMap();
        try {
            //类的注解请求路径
            classPath = pjp.getTarget().getClass().getAnnotation(RequestMapping.class).value()[0];
            //方法的注解请求路径
            methodPath = requestMapping.value()[0];
            inNewLog = setList.contains(methodPath);
            requestPath = classPath + methodPath;
            //取出请求参数
            Object[] args = pjp.getArgs();
            if (args != null && args.length > 0 && args[0] instanceof Map) {
                parameMap = (Map) args[0];
            }
            //执行被拦截的方法
            Object res = pjp.proceed();
            if (res instanceof Result) {
                result = (Result) res;
            }
        } catch (Throwable e) {
            logger.error("[{}]接口请求处理异常: ", requestPath, e);
        }
        if (inNewLog) {
            newLogger = LoggerBuilderUtils.getLogger(serviceName);
            newLogger.info("请求路径:{}", requestPath);
            ;
            newLogger.info("请求参数:{}", JSONUtil.toJsonStr(parameMap));
            newLogger.info("[{}]接口请求处理结果:" + JSONUtil.toJsonStr(result), requestPath);
        } else {
            logger.info("请求路径:{}", requestPath);
            logger.info("请求参数:{}", JSONUtil.toJsonStr(parameMap));
            logger.info("[{}]接口请求处理结果:" + JSONUtil.toJsonStr(result), requestPath);
        }
        return result;
    }

}

配置文件中过滤  /bigDataMethod 此接口到新配置log的文件中

springboot+log根据要求,动态生成不同的日志_第1张图片

正常请求这2个接口springboot+log根据要求,动态生成不同的日志_第2张图片

springboot+log根据要求,动态生成不同的日志_第3张图片

日志已经分开打印,至少完成了需求 emmmm

你可能感兴趣的:(java)