AopLog是基于Spring Aop 和ThreadLocal实现的一个专门对请求方法内容日志的拦截与处理的日志工具包。

场景 :

  1. 我想知道一些重要的请求方法的请求参数,响应参数,请求头,以及耗时,方法是成功还是失败等等信息。
  2. 普通的log.info或warn信息没有所属请求的上下关系,我不知道执行到哪一步发生了异常,并不方便查看和分析。
  3. 正式环境中,我并不想打印太多无意义的info日志(有些只是为了排查问题打印的日志),只希望在发生异常时记录日志。
  4. 日志的收集,我希望将这些请求的日志记录下来,记录方式我自己决定,比如正常的日志打印,常见的日志写入数据库,日志写入到文件,日志入队列等等。
  5. 整个日志的记录完全不干扰正常请求方法的流程,日志的收集处理异步化,不影响正常请求方法的性能与响应。
  6. 不想日后每个项目工程都写一份这样的Aop拦截处理日志的代码。

快速开始

项目通过maven的pom.xml引入


<dependency>
<groupId>com.github.ealenxie</groupId>
<artifactId>aop-log</artifactId>
<version>2.1</version>
</dependency>

或者通过gradle引入

compile group: 'com.github.ealenxie', name: 'aop-log', version: '2.1'

@AopLog注解使用,进行日志记录

直接在类(作用类的所有方法)或类方法(作用于方法)上加上注解@AopLog,进行日志记录

例如 :

import com.github.AopLog;
import name.ealen.infra.base.resp.RespBody;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; /**
* @author EalenXie create on 2020/6/22 14:28
*/
@AopLog(type = "测试",stackTraceOnErr = true)
@RestController
public class AppController { @GetMapping("/app/sayHello")
public RespBody<String> sayHello() {
return RespBody.ok("hello EalenXie");
} }

自定义全局的日志收集器实现收集 LogCollector

例如只是简单打印,或写入到库等等。


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.LogData;
import com.github.collector.LogCollector;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; /**
* @author EalenXie create on 2020/9/15 13:46
* 此为样例参考
* 配置一个简单的日志收集器 这里只是做了一个log.info打印一下,可以在这里写入到数据库中或者写入
*/
@Slf4j
@Component
public class AopLogCollector implements LogCollector {
private ObjectMapper objectMapper = new ObjectMapper();
@Override
public void collect(LogData logData) {
try {
log.info(objectMapper.writeValueAsString(logData));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}

配置@Component的全局日志收集器只能配置一个。

接口调用 /say/hello 测试即可看看到控制台打印出结果 :

2020-09-16 16:01:04.782  INFO 2012 --- [AsyncExecutor-2] name.ealen.infra.advice.AopLogCollector  : {"appName":"app-template","host":"127.0.0.1","port":8080,"clientIp":"192.168.110.1","reqUrl":"http://localhost:8080/app/sayHello","httpMethod":"GET","headers":{"User-Agent":"Apache-HttpClient/4.5.10 (Java/11.0.5)"},"type":"测试","content":"","method":"name.ealen.api.facade.AppController#sayHello","args":null,"respBody":{"code":"200","desc":"OK","message":"请求成功","dateTime":"2020-09-16 16:01:04","body":"hello EalenXie"},"logDate":1600243264780,"costTime":1,"threadName":"http-nio-8080-exec-3","threadId":33,"success":true}

记录的日志对象LogData属性说明

LogData 记录的内容

字段 类型 注释
appName String 应用名称
host String 主机
port int 端口号
clientIp String 请求客户端的Ip
reqUrl String 请求地址
headers Object 请求头部信息(可选择记录) 默认记录user-agent,content-type
type String 操作类型,默认值undefined
content String 方法步骤内容,默认是空,可使用LogData.step进行内容步骤记录
method String 请求的本地java方法
args Object 方法请求参数
respBody Object 方法响应参数
costTime long 整个方法耗时
logDate Date Log产生时间,LogData对象初始化的时间
threadName String 线程名称
threadId long 线程Id
success boolean 执行状态,成功(true)/异常(false)

AopLog 注解选项说明

选项 类型 说明 默认
logOnErr boolean 仅当发生异常时才记录收集 false
type String 操作类型 默认值"undefined"
headers String[] 记录的header信息 ,选择要记录哪些header信息 默认"User-Agent","content-type"
args boolean 是否记录请求参数 true
respBody boolean 是否记录响应参数 true
stackTraceOnErr boolean 当目标方法发生异常时,是否追加异常堆栈信息到LogData的content中 false
asyncMode boolean 异步方式收集 true
collector Class<? extends LogCollector> 指定日志收集器 默认不调整收集器,使用全局的日志收集器

LogData的step方法。

记录步骤。(如果某些重要步骤希望被记录下来)

例如 :

import com.github.AopLog;
import com.github.LogData;
import name.ealen.infra.base.resp.RespBody;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; /**
* @author EalenXie create on 2020/6/22 14:28
*/
@AopLog(type = "测试",stackTraceOnErr = true)
@RestController
public class AppController { @GetMapping("/app/sayHello")
public RespBody<String> sayHello() {
LogData.step("1. 第一步执行完成");
//......
LogData.step("2. 第二步执行完成");
//.....
LogData.step("3. service的方法执行完成");
//.....
return RespBody.ok("hello EalenXie");
} }

注意: 此方法如果不在被@AopLog注解的方法的整体调用链路中使用,则当前线程中的ThreadLocal中的LogData不会释放,需要手动调用LogData.removeCurrent();

此时再次接口调用 /say/hello 测试即可看看到控制台打印出结果,重点观察content字段 :

2020-09-16 17:26:20.285  INFO 3284 --- [AsyncExecutor-2] name.ealen.infra.advice.AopLogCollector  : {"appName":"app-template","host":"127.0.0.1","port":8080,"clientIp":"192.168.110.1","reqUrl":"http://localhost:8080/app/sayHello","httpMethod":"GET","headers":{"User-Agent":"Apache-HttpClient/4.5.10 (Java/11.0.5)"},"type":"测试","content":"1. 第一步执行完成\n2. 第二步执行完成\n3. service的方法执行完成\n","method":"name.ealen.api.facade.AppController#sayHello","args":null,"respBody":{"code":"200","desc":"OK","message":"请求成功","dateTime":"2020-09-16 17:26:20","body":"hello EalenXie"},"logDate":1600248380283,"costTime":1,"threadName":"http-nio-8080-exec-2","threadId":32,"success":true}

关于

开源Github地址 :

https://github.com/EalenXie/aop-log

感谢各位提出意见和支持。

老生常谈SpringAop日志收集与处理做的工具包的更多相关文章

  1. 微服务下,使用ELK做日志收集及分析

    一.使用背景 目前项目中,采用的是微服务框架,对于日志,采用的是logback的配置,每个微服务的日志,都是通过File的方式存储在部署的机器上,但是由于日志比较分散,想要检查各个微服务是否有报错信息 ...

  2. 【转】Flume日志收集

    from:http://www.cnblogs.com/oubo/archive/2012/05/25/2517751.html Flume日志收集   一.Flume介绍 Flume是一个分布式.可 ...

  3. [转载] 一共81个,开源大数据处理工具汇总(下),包括日志收集系统/集群管理/RPC等

    原文: http://www.36dsj.com/archives/25042 接上一部分:一共81个,开源大数据处理工具汇总(上),第二部分主要收集整理的内容主要有日志收集系统.消息系统.分布式服务 ...

  4. 用fabric部署维护kle日志收集系统

    最近搞了一个logstash kafka elasticsearch kibana 整合部署的日志收集系统.部署参考lagstash + elasticsearch + kibana 3 + kafk ...

  5. 基于Flume的美团日志收集系统(二)改进和优化

    在<基于Flume的美团日志收集系统(一)架构和设计>中,我们详述了基于Flume的美团日志收集系统的架构设计,以及为什么做这样的设计.在本节中,我们将会讲述在实际部署和使用过程中遇到的问 ...

  6. 基于Flume的美团日志收集系统(一)架构和设计

    美团的日志收集系统负责美团的所有业务日志的收集,并分别给Hadoop平台提供离线数据和Storm平台提供实时数据流.美团的日志收集系统基于Flume设计和搭建而成. <基于Flume的美团日志收 ...

  7. Flume-NG + HDFS + HIVE 日志收集分析

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  8. 基于Flume的美团日志收集系统(一)架构和设计【转】

    美团的日志收集系统负责美团的所有业务日志的收集,并分别给Hadoop平台提供离线数据和Storm平台提供实时数据流.美团的日志收集系统基于Flume设计和搭建而成. <基于Flume的美团日志收 ...

  9. 日志收集框架 Exceptionless

    日志收集框架 Exceptionless 前言 从去年就答应过Eric(Exceptionless的作者之一),在中国会帮助给 Exceptionless 做推广,但是由于各种原因一直没有做这件事情, ...

随机推荐

  1. Android Studio 代码回退

    1.VCS–Local History–Show History 或者 这个按钮 2.代码操作记录出现了,选定我们操作的一个历史阶段 3.点击左上角的按钮(revert),代码回退成功

  2. 关于haar特征的理解及使用(java实现)

    Haar特征原理综述Haar特征是一种反映图像的灰度变化的,像素分模块求差值的一种特征.它分为三类:边缘特征.线性特征.中心特征和对角线特征.如下所示: Haar-like矩形特征拓展  Lienha ...

  3. MacOS开发环境搭建

    1 Java 安装jdk 下载安装即可,没什么可说的,着重说一下配置mac下的环境变量 $ /usr/libexec/java_home -V #查看安装的jdk版本和路径 $ vim ~/.bash ...

  4. Apache Hudi 0.6.0版本重磅发布

    1. 下载信息 源码:Apache Hudi 0.6.0 Source Release (asc, sha512) 二进制Jar包:nexus 2. 迁移指南 如果您从0.5.3以前的版本迁移至0.6 ...

  5. smtplib文字邮件的发送

    今天跟大家讲解一下接口测试框架的知识准备阶段,首先是发送纯文字的电子邮件,会的同学可以忽略,不会的就多敲几遍,直到自己能敲出来为止~~ # coding: utf-8import smtplibfro ...

  6. jq cdn地址

    百度CDN支持版本2.0.3, 2.0.2, 2.0.1, 2.0.0,1.11.1, 1.10.2, 1.10.1, 1.10.0, 1.9.1, 1.9.0, 1.8.3, 1.8.2, 1.8. ...

  7. Android开发之http网络请求返回码问题集合。

    HTTP状态码(HTTP Status Code) 一些常见的状态码为: 200 - 服务器成功返回网页  404 - 请求的网页不存在  503 - 服务不可用  一.1xx(临时响应) 表示临时响 ...

  8. 在C++/CLI环境下,千万不要把普通全局函数当标准C/C++的函数指针传递给native的库使用

    先上一个简单代码: #include <cstdlib> #include <cstdio> // native apis extern "C" { typ ...

  9. Shader 语义

    在书写HLSL shader程序时,输入和输出变量需要拥有他们 含义来表明语义.这在HLSL shader中是一个标准的做法. Vertex shader 输入语义 主顶点着色器函数(被指令 #pra ...

  10. 开源基于lua gc管理c++对象的cocos2dx lua绑定方案

    cocos2dx目前lua对应的c++对象的生命周期管理,是基于c++析构函数的,也就是生命周期可能存在不一致,比如c++对象已经释放,而lua对象还存在,如果这时候再使用,会有宕机的风险,为此我开发 ...