# OpenLinkLog
**Repository Path**: wangSky0634/OSSRH-71430
## Basic Information
- **Project Name**: OpenLinkLog
- **Description**: linkLog通过拦截主流框架请求,添加traceId的进行系统间传导,然后通过slf4j的MDC功能打印到日志中,从而达到日志链路跟踪的效果
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 18
- **Created**: 2024-11-05
- **Last Updated**: 2024-11-05
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
## LinkLog简介
### linkLog内容

### linkLog使用教程
[日志体系最佳实践](doc/linklog.md)
### linkLog链路跟踪功能描述
linkLog通过拦截主流框架请求,添加traceId的进行系统间传导,然后通过slf4j的MDC功能打印到日志中,从而达到日志链路跟踪的效果
链路跟踪主要有traceId和spanId两个组成,traceId为单次请求的全局唯一ID,spanId为所在请求的节点ID(为树结构)。
如图:

### linkLog支持的框架
+ 支持Disconf,Apollo等配置中心动态修改日志级别
说明:修改/添加 linklog.properties 文件
```
### k=v 键值对 k=logger的名称 v=日志级别
### k:LoggerFactory.getLogger(LinkLog.class)获取logger的时候 k为LinkLog全路径类名
### v: 日志级别包含 OFF>FATAL>ERROR>WARN>INFO>DEBUG>TRACE>ALL
cn.ry.LinkLog=DEBUG
```
+ 支持的日志框架:logback,log4j,log4j2
+ 自动适配的框架:SpringBoot,SpringMVC,Fegin,Spring GateWay,Dubbo
+ HttpClient接入方式:
```
//添加LinkLogHttpRequestInterceptor拦截器
CloseableHttpClient httpClient = HttpClientBuilder.create()
.addInterceptorFirst(new LinkLogHttpRequestInterceptor())
.build();
```
+ RestTempate接入方式:
```
//添加LinkLogRestTemplateFilter拦截器
RestTemplate restTemplate = new RestTemplate();
restTemplate.setInterceptors(Collections.singletonList(new LinkLogRestTemplateFilter()));
```
+ OkHttp接入方式
```
//添加LinkLogOkHttpInterceptor拦截器
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new LinkLogOkHttpInterceptor())
.build();
```
+ Jersey接入方式
```
ClientBuilder clientBuilder = ClientBuilder.newBuilder();
Client client=clientBuilder.withConfig(new ClientConfig(LinkLogJerseyFilter.class)).build();
```
### linkLog特点
+ 一键接入,系统零添加
+ 轻量,不会依赖三方jar
+ 自动适配,根据系统jar自动适配拦截器
### linkLog使用
##### 添加依赖 pom.xml
```
io.gitee.reywong
ry-linklog
1.0.1-releases
```
##### 展示traceId log配置文件中添加
> pattern中添加 ```%X{linkLog}```
如:
```
[%X{linkLog}] [%date{yyyy-MM-dd HH:mm:ss.SSS}] [%thread] [%-5level] [%logger:%line] %msg%n
UTF-8
```
##### 展示效果
> A系统 调用 B系统
#### A系统代码
```
public String linklog(HttpServletRequest request, HttpServletResponse response) {
StringBuilder stringBuilder = new StringBuilder();
logger.info("1.请求参数{}", "reywong");
List sayList = demoServer.sayHello("reywong");
if (sayList != null) {
for (String say : sayList) {
stringBuilder.append(say);
}
}
String result = stringBuilder.toString();
logger.info(result);
logger.info("2.请求参数{}", "reywong");
demoServer.sayHello("reywong");
logger.info("3.httpclient 请求接口");
httpClient();
return result;
}
public String httpClient() {
String msg = "";
// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
CloseableHttpClient httpClient = HttpClientBuilder
.create()
.addInterceptorFirst(new LinkLogHttpRequestInterceptor())
.build();
// 创建Get请求
HttpGet httpGet = new HttpGet("http://localhost:8082/springMvc");
// 响应模型
CloseableHttpResponse response = null;
try {
Thread.sleep(1000);
// 由客户端执行(发送)Get请求
logger.info("request springMVC");
response = httpClient.execute(httpGet);
// 从响应模型中获取响应实体
HttpEntity responseEntity = response.getEntity();
msg = responseEntity.toString();
if (responseEntity != null) {
logger.info("reponse get springMVC");
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
try {
// 释放资源
if (httpClient != null) {
httpClient.close();
}
if (response != null) {
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return msg;
}
}
```
#### A系统日志

#### B系统代码
```
@RequestMapping("/springMvc")
public String springMvc(HttpServletRequest request, HttpServletResponse response) {
logger.info("linkLog-Server springMvc");
return "springMvc";
}
```
#### B系统日志

##### 测试方案
项目中提供了测试项目,可以直接运行
LinkLog-example/link-example-dubbo 提供了springMvc和dubbo的测试用例。
步骤如下:
1. 启动linklog-example-dubbo-server
2. 启用linklog-example-dubbo-client
3. 执行dubbo.http中的请求(idea支持http请求类似postman)
#### 备注
1. 项目目前通过SPI的方式加载,支持tomcat spi,springboot spi,dubbo spi
2. 如果springmvc无法拦截,可以在配置一个拦截器``` ```
3. java8以后开启空指针堆栈,jvm启动参数添加``` -XX:-OmitStackTraceInFastThrow ```
## 最佳实践
[日志体系最佳实践](doc/linklog.md)
#### 其它开源项目
[Meteor-基于Arthas的线上故障诊断神器](https://gitee.com/reywong/meteor?_from=gitee_search)