请求日志打印包

最近借到一个需求,是真的难搞!要造一个工具包,自动收集请求日志,然后做分析.

卧槽,如果只是在项目中的logback.xml中配置分分钟根据类分个配置早搞定了,但是为了以后的方便,要集成到一个随时拔插的jar包里!

经过几番尝试,踩了不少坑,总算搞出来了!

一些依赖

<dependency>
  <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

然后是aop+日志配置类

/**
 * @author linnine
 * @since 2022-03-28,v1.0.0
 */
@Aspect
@Component
//有配置才会启用
@ConditionalOnProperty(name = "req-log.file")
public class LogAspect {
    private final Logger log= new RootLogger(Level.INFO);

    //读取日志输出路径
    @Value("${req-log.file}")
    private String reqLogFile;

    @Value("spring.application.name")
    private String appName;

    @PostConstruct
    public void setLoggerFactory() throws IOException {
        //从resources文件夹中读取配置文件
        Resource resource = new ClassPathResource("log4j-aop.properties");
        //创建配置类
        PropertyConfigurator pc = new PropertyConfigurator();
        Properties p = new Properties();
        //解析配置文件
        p.load(resource.getInputStream());
        //添加日志输出路径
        p.setProperty("log4j.appender.API_LOG.File", reqLogFile);
        //开启控制台日志
    String enableStdout = SpringContextUtil.getEnvironmentProperty("thread0.req-log.stdout");
    if (StringUtils.equalsAny(enableStdout,"true","enabled")){
       // ### 输出到控制台 ###
        p.setProperty("log4j.rootLogger","INFO,stdout,API_LOG");
    }
        LoggerRepository lr1 = new Hierarchy(log);
        //设置log
        pc.doConfigure(p, lr1);
    }


    @Pointcut("execution(public * com.thread0..*.controller..*.*(..))")
    public void controllerLog() {
        //切点
    }
    @Before("controllerLog()")
    public void doBefore(JoinPoint joinPoint) {
        // 接收到请求,记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        assert attributes != null;
        HttpServletRequest request = attributes.getRequest();
        // 记录下请求内容
        log.info(JsonUtil.toJsonStrSerializeNulls(new ReqLog(request, joinPoint,appName)));
    }
}

最后是日志配置文件,要放在这个包里的resources目录下,文件名要叫 log4j-aop.properties

log4j.rootLogger = INFO,API_LOG

### 输出到日志文件 ###
log4j.appender.API_LOG = org.apache.log4j.DailyRollingFileAppender
#log4j.appender.API_LOG.File = /Users/linnine/home/log/api/req-aop.log
log4j.appender.API_LOG.Append = true
log4j.appender.API_LOG.Threshold = INFO ## 输出INFO级别以上的日志
log4j.appender.API_LOG.layout = org.apache.log4j.PatternLayout
#只输出纯日志+换行 上面已经转成对象了,输出来就是一个json格式的日志
log4j.appender.API_LOG.layout.ConversionPattern = %m%n
### 输出到控制台 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{ABSOLUTE} %5p %c{1}:%L - %m%n

补充一下日志对象

@Data
@Accessors(chain = true)
public class ReqLog {
    //标签
    private String tag;
    //应用名
    private String appName;
    //请求时间
    private String time;
    //访问地址
    private String url;
    //请求方法
    private String reqMethod;
    private String sessionId;
    private String ip;
    //private String classMethod;
    private Object[] allArgs;

    public ReqLog(HttpServletRequest request, JoinPoint joinPoint,String appName) {
        this.tag = "reqLog";
        this.time = DateUtil.getNow(DateUtil.ALL_TIME_EN);
        this.url = request.getRequestURL().toString();
        this.reqMethod = request.getMethod();
        this.sessionId=request.getRequestedSessionId();
        this.ip = IpUtil.getIpFromRequest(request);
        //与url功能类似 大可不必
        //this.classMethod = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
        this.allArgs = joinPoint.getArgs();
        this.appName=appName;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值