老生常谈SpringAop日志收集与处理做的工具包
AopLog是基于Spring Aop 和ThreadLocal实现的一个专门对请求方法内容日志的拦截与处理的日志工具包。
场景 :
- 我想知道一些重要的请求方法的请求参数,响应参数,请求头,以及耗时,方法是成功还是失败等等信息。
- 普通的log.info或warn信息没有所属请求的上下关系,我不知道执行到哪一步发生了异常,并不方便查看和分析。
- 正式环境中,我并不想打印太多无意义的info日志(有些只是为了排查问题打印的日志),只希望在发生异常时记录日志。
- 日志的收集,我希望将这些请求的日志记录下来,记录方式我自己决定,比如正常的日志打印,常见的日志写入数据库,日志写入到文件,日志入队列等等。
- 整个日志的记录完全不干扰正常请求方法的流程,日志的收集处理异步化,不影响正常请求方法的性能与响应。
- 不想日后每个项目工程都写一份这样的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日志收集与处理做的工具包的更多相关文章
- 微服务下,使用ELK做日志收集及分析
一.使用背景 目前项目中,采用的是微服务框架,对于日志,采用的是logback的配置,每个微服务的日志,都是通过File的方式存储在部署的机器上,但是由于日志比较分散,想要检查各个微服务是否有报错信息 ...
- 【转】Flume日志收集
from:http://www.cnblogs.com/oubo/archive/2012/05/25/2517751.html Flume日志收集 一.Flume介绍 Flume是一个分布式.可 ...
- [转载] 一共81个,开源大数据处理工具汇总(下),包括日志收集系统/集群管理/RPC等
原文: http://www.36dsj.com/archives/25042 接上一部分:一共81个,开源大数据处理工具汇总(上),第二部分主要收集整理的内容主要有日志收集系统.消息系统.分布式服务 ...
- 用fabric部署维护kle日志收集系统
最近搞了一个logstash kafka elasticsearch kibana 整合部署的日志收集系统.部署参考lagstash + elasticsearch + kibana 3 + kafk ...
- 基于Flume的美团日志收集系统(二)改进和优化
在<基于Flume的美团日志收集系统(一)架构和设计>中,我们详述了基于Flume的美团日志收集系统的架构设计,以及为什么做这样的设计.在本节中,我们将会讲述在实际部署和使用过程中遇到的问 ...
- 基于Flume的美团日志收集系统(一)架构和设计
美团的日志收集系统负责美团的所有业务日志的收集,并分别给Hadoop平台提供离线数据和Storm平台提供实时数据流.美团的日志收集系统基于Flume设计和搭建而成. <基于Flume的美团日志收 ...
- Flume-NG + HDFS + HIVE 日志收集分析
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...
- 基于Flume的美团日志收集系统(一)架构和设计【转】
美团的日志收集系统负责美团的所有业务日志的收集,并分别给Hadoop平台提供离线数据和Storm平台提供实时数据流.美团的日志收集系统基于Flume设计和搭建而成. <基于Flume的美团日志收 ...
- 日志收集框架 Exceptionless
日志收集框架 Exceptionless 前言 从去年就答应过Eric(Exceptionless的作者之一),在中国会帮助给 Exceptionless 做推广,但是由于各种原因一直没有做这件事情, ...
随机推荐
- Android Studio 代码回退
1.VCS–Local History–Show History 或者 这个按钮 2.代码操作记录出现了,选定我们操作的一个历史阶段 3.点击左上角的按钮(revert),代码回退成功
- 关于haar特征的理解及使用(java实现)
Haar特征原理综述Haar特征是一种反映图像的灰度变化的,像素分模块求差值的一种特征.它分为三类:边缘特征.线性特征.中心特征和对角线特征.如下所示: Haar-like矩形特征拓展 Lienha ...
- MacOS开发环境搭建
1 Java 安装jdk 下载安装即可,没什么可说的,着重说一下配置mac下的环境变量 $ /usr/libexec/java_home -V #查看安装的jdk版本和路径 $ vim ~/.bash ...
- Apache Hudi 0.6.0版本重磅发布
1. 下载信息 源码:Apache Hudi 0.6.0 Source Release (asc, sha512) 二进制Jar包:nexus 2. 迁移指南 如果您从0.5.3以前的版本迁移至0.6 ...
- smtplib文字邮件的发送
今天跟大家讲解一下接口测试框架的知识准备阶段,首先是发送纯文字的电子邮件,会的同学可以忽略,不会的就多敲几遍,直到自己能敲出来为止~~ # coding: utf-8import smtplibfro ...
- 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. ...
- Android开发之http网络请求返回码问题集合。
HTTP状态码(HTTP Status Code) 一些常见的状态码为: 200 - 服务器成功返回网页 404 - 请求的网页不存在 503 - 服务不可用 一.1xx(临时响应) 表示临时响 ...
- 在C++/CLI环境下,千万不要把普通全局函数当标准C/C++的函数指针传递给native的库使用
先上一个简单代码: #include <cstdlib> #include <cstdio> // native apis extern "C" { typ ...
- Shader 语义
在书写HLSL shader程序时,输入和输出变量需要拥有他们 含义来表明语义.这在HLSL shader中是一个标准的做法. Vertex shader 输入语义 主顶点着色器函数(被指令 #pra ...
- 开源基于lua gc管理c++对象的cocos2dx lua绑定方案
cocos2dx目前lua对应的c++对象的生命周期管理,是基于c++析构函数的,也就是生命周期可能存在不一致,比如c++对象已经释放,而lua对象还存在,如果这时候再使用,会有宕机的风险,为此我开发 ...