# log-access
**Repository Path**: ck-jesse/log-access
## Basic Information
- **Project Name**: log-access
- **Description**: 将接口方法的访问日志(入参和出参)输出到access日志文件;
支持的方法类型:http请求方法、dubbo请求方法、普通方法。
- **Primary Language**: Java
- **License**: OSL-3.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 2
- **Forks**: 1
- **Created**: 2019-06-05
- **Last Updated**: 2022-05-20
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# log-access
## 介绍
将接口方法的访问日志(入参和出参)输出到access日志文件;
支持的方法类型:http请求方法、dubbo请求方法、普通方法。
# 一、log-access功能描述
1、支持 http请求、dubbo请求、普通方法 的访问日志(入参和出参)输出到日志文件;
2、支持 [字符串] 最大输出长度限制,如:字段长度为500,仅输出前256个字符,其他的省略;
3、支持 [集合] 最大输出元素限制,如:集合大小为10,仅输出集合中的前3个元素,其他的省略;
4、支持将敏感数据脱敏后再输出到日志文件(目前支持手机号和身份证号的脱敏);
5、支持跨服务链路追踪(基于trace_id实现)
# 二、使用log-access的配置步骤:
## 1、Maven包引入
````xml
com.tn.log
log-access
1.0-SNAPSHOT
````
注意:要特别注意log-access组件中依赖的spring和dubbo相关的包可能与组件使用方中的版本有冲突,所以需要解决冲突后才能使用。
方案一:将log-access组件中的spring或dubbo给排除掉(建议使用)
方案二:将组件使用方中的spring或dubbo给排除掉
````xml
com.tn.log
log-access
1.0-SNAPSHOT
spring-web
org.springframework
````
## 2、引入spring配置
### 方式一: 在组件使用方的spring配置文件中引入如下配置
````xml
````
### 方式二: 基于注解 @EnableLogAccess 的方式(结合SpringBoot使用)
````java
@EnableLogAccess
public class LogAccessConfig {
}
````
注:上面两种方式二选一即可
## 3、配置logback.xml配置(此处已logback为例)
````xml
INFO
${LOG_DIR}/${APP_NAME}-access.log
${LOG_DIR}/${APP_NAME}-access-%d{yyyy-MM-dd}.%i.log
500MB
%m%n
UTF-8
````
## 4、代码中的使用
注:在需要打印出入参数的类或者方法上标记@LogAccess注解
````java
// 方式一:@LogAccess标记在类上,对类的所有方法起作用
@LogAccess
public class MessageFacadeImpl implements MessageFacade {
@Override
public Result sendMessage(String msgTye, String msg) {
// xxxx
}
}
````
````java
// 方式二:@LogAccess标记在方法上,仅对该方法起作用
public class MessageFacadeImpl implements MessageFacade {
@LogAccess
@Override
public Result sendMessage(String msgTye, String msg) {
// xxxx
}
}
````
## 5、访问日志的格式
````json
【格式】
访问时间|执行耗时ms|执行结果|请求类型|模块名|接口名|本机IP|客户端IP|消息跟踪号|请求参数|响应参数|attachment|附件参数
【字段描述】
访问时间:开始的访问时间,
执行结果:用于区分该请求是否正常响应,N 对应normal,表示正常响应,E 对应error,表示出现异常,
请求类型:METHOD 表示普通方法、HTTP 表示http请求、DUBBO 表示dubbo请求,
执行耗时:业务方法的执行时间,单位毫秒(ms),
消息跟踪号:对应trace_id,用于日志链路追踪
请求参数:json格式串
响应参数:json格式串
attachment:用于标记后面的是附件参数
附件参数:以便灵活扩展(如cookie和header中的内容等)
注意:
1、对于入参和出参对象中的集合只输出指定数量的元素,如:集合大小为10,仅输出集合中的前3个元素,其他的省略
2、对于入参和出参对象中的字符串字段控制最大的输出长度,如:字段长度为500,仅输出前256个字符,其他的省略
````
## 6、访问日志样例
### 5.1 普通方法的访问日志样例
```json
2019-05-14 16:32:07.411|N|METHOD|43ms|com.xx.xx.XXService|xxMethod|10.1.1.48|10.1.1.48|3a1979e559e24c56b8b866731155c889|["1000008684","fast"]|{"status":200,"message":null,"data":{"code":"success","createTime":1557492448000,"updateTime":1557492979000},"error":false,"success":true}|attachtment|
```
### 5.2 http接口的访问日志样例
```json
2019-05-14 16:32:07.405|N|HTTP|104ms|xx-web|test/test|10.1.1.48|127.0.0.1|3a1979e559e24c56b8b866731155c889|fast|{"status":200,"message":null,"data":{"code":"success","createTime":1557492448000,"updateTime":1557492979000},"error":false,"success":true}|attachtment|
```
### 5.3 dubbo接口的访问日志样例
```json
2019-05-14 13:54:42.880|N|DUBBO|57ms|dubbo://127.0.0.1:20885/group/com.xx.xx.XXFacade|queryXX|10.1.1.48|10.1.1.48:50542|3a1979e559e24c56b8b866731155c889|["1000008684",3,"fast"]|{"status":200,"message":null,"data":{"code":"success","createTime":1557492448000,"updateTime":1557492979000},"error":false,"success":true}|attachtment|
```
## 7、跨服务链路追踪
### 7.1 rest服务间的链路追踪
> 原理:通过自定义ServletTraceInfoAttachmentFilter,从request的header中获取trace_id,实现本服务的日志链路追踪。
>
> 注:若需跨服务将trace_id传递到服务方,那么需要根据不同的调用方式来进行扩展。
>
> 1、若基于RestTemplate,则扩展ClientHttpRequestInterceptor将trace_id设置到header中传递到服务提供方。
>
> 2、若基于Feign,则扩展RequestInterceptor将trace_id设置到header中传递到服务提供方。
>
```java
@EnableLogAccess
public class LogAccessConfig {
/**
* 配置http请求日志跟踪信息拦截器,header中无trace_id则生成
*/
@Bean
public FilterRegistrationBean logFilterRegister() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new ServletTraceInfoAttachmentFilter());
registration.setName(ServletTraceInfoAttachmentFilter.class.getSimpleName());
registration.addUrlPatterns("/*");
// 从小到大的顺序来依次过滤
registration.setOrder(1);
return registration;
}
/**
* 基于RestTemplate的服务调用
*/
@Bean("restTemplate")
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setRequestFactory(httpRequestFactory());
// 将trace_id设置到header中传递到服务提供方
restTemplate.setInterceptors(Arrays.asList(new ClientHttpRequestInterceptor(){
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
String traceId = MDCLogTracerContextUtil.getTraceId();
if (traceId != null) {
request.getHeaders().add(TracingVariable.TRACE_ID, traceId);
}
return execution.execute(request, body);
}
}));
return restTemplate;
}
/**
* 基于Feign的服务调用
*/
@Bean
public RequestInterceptor requestInterceptor() {
RequestInterceptor requestInterceptor = template -> {
String traceId = MDCLogTracerContextUtil.getTraceId();
if (traceId != null) {
template.header(TracingVariable.TRACE_ID, traceId);
}
};
return requestInterceptor;
}
}
```
### 7.2 dubbo服务间的链路追踪
> 原理:dubbo提供了良好的spi扩展机制,通过扩展Filter,实现服务间的trace_id传递
> 1、通过自定义DubboTraceInfoDetachmentFilter,从RpcContext的attachment属性中获取trace_id
>
> 2、通过自定义DubboTraceInfoAttachmentFilter,将trace_id设置到RpcContext的attachment属性中,透传到服务提供方
>