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. 数据结构-二叉树(6)哈夫曼树(Huffman树)/最优二叉树

    树的路径长度是从树根到每一个结点的路径长度(经过的边数)之和. n个结点的一般二叉树,为完全二叉树时取最小路径长度PL=0+1+1+2+2+2+2+… 带权路径长度=根结点到任意结点的路径长度*该结点 ...

  2. Win 10 蓝屏,出现DRIVER_POWER_STATE_FAILURE的解决方法

    笔者个人笔记本电脑,用的是华硕的飞行堡垒FZ系列,上个月装了个Ubuntu的系统,之后换回Windows后,电脑疯狂蓝屏,错误代码只有这个DRIVER_POWER_STATE_FAILURE.一开始我 ...

  3. Vue 开发技巧总结

    ​博客地址:https://ainyi.com/95 本人玩了 Vue 两年多,在此总结一下开发时的一些技巧和方法 自定义组件 v-model v-model 是 Vue 提供的一个语法糖,它本质上是 ...

  4. 什么是谷歌PageRank (简称PR值)

    http://www.wocaoseo.com/thread-213-1-1.html 谷歌pageRank是谷歌用来评测网页质量高低的一个工具,主要分为0到10共11个等级,目前有很多的工具或谷歌工 ...

  5. Netty源码分析之ByteBuf(一)—ByteBuf中API及类型概述

    ByteBuf是Netty中主要的数据容器与操作工具,也是Netty内存管理优化的具体实现,本章我们先从整体上对ByteBuf进行一个概述: AbstractByteBuf是整个ByteBuf的框架类 ...

  6. 初级知识六——C#事件通知系统实现(观察者模式运用)

    观察者模式,绝对是游戏中十分重要的一种模式,运用这种模式,可以让游戏模块间的通信变得简单,耦合度也会大大降低,下面讲解如何利用C#实现事件通知系统. 补充,首先说下这个系统的实现原理,不然一头扎进去就 ...

  7. Building(单调栈+凸包)

    Problem Description Once upon a time Matt went to a small town. The town was so small and narrow tha ...

  8. [BUUOJ记录] [BSidesCF 2020]Had a bad day

    主要考察文件包含以及php://filter伪协议的一个小trick.题目很简单,但是因为不知道这个trick卡了很久,记录一下 进入题目看到有两个按钮,没有其他信息: 点击按钮显示出来一张图片,然后 ...

  9. termux 进阶

    直接正题. 1.优化键位: mkdir $HOME/.termux echo "extra-keys = [['ESC','/','-','HOME','UP','END','PGUP'], ...

  10. libtorrent资料整理

    源码libtorrent源码地址:https://github.com/arvidn/libtorrent/releases libtorrent Java库地址:https://github.com ...