Skip to content

Commit e15a4fb

Browse files
authored
Merge pull request #83 from KUTEJiang/main_traceid_dev_mingcao
[feat](log)generate traceId for each http request(#36)
2 parents ed1f5b9 + 7e9cebd commit e15a4fb

File tree

9 files changed

+262
-3
lines changed

9 files changed

+262
-3
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.alipay.muagent.model.trace;
2+
3+
import lombok.Data;
4+
5+
/**
6+
* @author Joshua
7+
* @version TraceContext.java v1.0 2024-11-20 20:21
8+
**/
9+
@Data
10+
public class TraceContext {
11+
12+
private String traceId;
13+
14+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.alipay.muagent.model.trace;
2+
3+
import java.util.EmptyStackException;
4+
5+
/**
6+
* @author Joshua
7+
* @version TraceThreadLocalContext.java v1.0 2024-11-20 20:24
8+
**/
9+
public class TraceThreadLocalContext {
10+
11+
private final ThreadLocal<TraceContext> traceContextThreadLocal = new ThreadLocal<>();
12+
13+
public void push(TraceContext traceContext) {
14+
if (traceContext == null) {
15+
return;
16+
}
17+
traceContextThreadLocal.set(traceContext);
18+
}
19+
20+
public TraceContext pop() throws EmptyStackException {
21+
if (this.isEmpty()) {
22+
return null;
23+
}
24+
TraceContext traceContext = traceContextThreadLocal.get();
25+
this.clear();
26+
return traceContext;
27+
}
28+
29+
public TraceContext getCurrentTraceContext() throws EmptyStackException {
30+
if (this.isEmpty()) {
31+
return null;
32+
}
33+
return traceContextThreadLocal.get();
34+
}
35+
36+
public boolean isEmpty() {
37+
TraceContext traceContext = traceContextThreadLocal.get();
38+
return traceContext == null;
39+
}
40+
41+
public void clear() {
42+
traceContextThreadLocal.remove();
43+
}
44+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.alipay.muagent.model.trace;
2+
3+
/**
4+
* @author Joshua
5+
* @version TraceThreadLocalContextHolder.java v1.0 2024-11-20 20:28
6+
**/
7+
public class TraceThreadLocalContextHolder {
8+
9+
/**
10+
* singleton SofaTraceContext
11+
*/
12+
private static final TraceThreadLocalContext SINGLE_TRACE_CONTEXT = new TraceThreadLocalContext();
13+
14+
/**
15+
* Get threadlocal trace context
16+
*
17+
* @return TraceThreadLocalContext
18+
*/
19+
public static TraceThreadLocalContext getTraceThreadLocalContext() {
20+
return SINGLE_TRACE_CONTEXT;
21+
}
22+
23+
}

runtime/util/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@
1818
</properties>
1919

2020
<dependencies>
21+
<dependency>
22+
<groupId>com.alipay.muagent</groupId>
23+
<artifactId>model</artifactId>
24+
<version>0.0.1-SNAPSHOT</version>
25+
</dependency>
26+
2127
<dependency>
2228
<groupId>com.google.code.gson</groupId>
2329
<artifactId>gson</artifactId>

runtime/util/src/main/java/com/alipay/muagent/util/LoggerUtil.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
*/
55
package com.alipay.muagent.util;
66

7+
import com.alipay.muagent.model.trace.TraceThreadLocalContext;
8+
import com.alipay.muagent.model.trace.TraceThreadLocalContextHolder;
79
import org.slf4j.Logger;
810
import org.slf4j.helpers.MessageFormatter;
911

@@ -13,10 +15,16 @@
1315
*/
1416
public class LoggerUtil {
1517

18+
/**
19+
* 获取当前请求上下文的traceId
20+
* @return traceId
21+
*/
1622
private static String getTraceId() {
17-
// todo
18-
return "";
19-
23+
TraceThreadLocalContext traceThreadLocalContext = TraceThreadLocalContextHolder.getTraceThreadLocalContext();
24+
if (!traceThreadLocalContext.isEmpty()) {
25+
return traceThreadLocalContext.getCurrentTraceContext().getTraceId();
26+
}
27+
return null;
2028
}
2129

2230
/**
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package com.alipay.muagent.util;
2+
3+
import java.net.InetAddress;
4+
import java.util.concurrent.atomic.AtomicInteger;
5+
6+
/**
7+
* @author Joshua
8+
* @version TraceUtil.java v1.0 2024-11-20 20:34
9+
**/
10+
public class TraceUtil {
11+
12+
private static final String EMPTY_STRING = "";
13+
14+
private static final AtomicInteger COUNT = new AtomicInteger(1000);
15+
16+
private static String processId = null;
17+
18+
private static String hexIpAddress = "ffffffff";
19+
20+
static {
21+
try {
22+
String ipAddressStr = getInetAddress();
23+
if (null != ipAddressStr) {
24+
hexIpAddress = getHexAddress(ipAddressStr);
25+
}
26+
} catch (Exception e) {
27+
/*
28+
* empty catch
29+
*/
30+
}
31+
}
32+
33+
public static String generateTraceId() {
34+
return getTraceId(hexIpAddress, System.currentTimeMillis(), getNextId());
35+
}
36+
37+
private static String getTraceId(String ip, long timeStamp, int nextId) {
38+
return ip + timeStamp + nextId + getProcessId();
39+
}
40+
41+
private static String getProcessId() {
42+
if (StringUtils.isNotBlank(processId)) {
43+
return processId;
44+
}
45+
46+
String processName = java.lang.management.ManagementFactory.getRuntimeMXBean().getName();
47+
48+
if (StringUtils.isBlank(processName)) {
49+
return EMPTY_STRING;
50+
}
51+
52+
String[] processSplitName = processName.split("@");
53+
54+
if (processSplitName.length == 0) {
55+
return EMPTY_STRING;
56+
}
57+
58+
String pid = processSplitName[0];
59+
60+
if (StringUtils.isBlank(pid)) {
61+
return EMPTY_STRING;
62+
}
63+
64+
processId = pid;
65+
return pid;
66+
}
67+
68+
private static String getHexAddress(String ipAddressStr) {
69+
final String[] ips = ipAddressStr.split("\\.");
70+
StringBuilder stringBuilder = new StringBuilder();
71+
for (String partOfAddress : ips) {
72+
String hex = Integer.toHexString(Integer.parseInt(partOfAddress));
73+
if (hex.length() == 1) {
74+
stringBuilder.append('0').append(hex);
75+
} else {
76+
stringBuilder.append(hex);
77+
}
78+
}
79+
return stringBuilder.toString();
80+
}
81+
82+
private static String getInetAddress() {
83+
try {
84+
return InetAddress.getLocalHost().getHostAddress();
85+
} catch (Exception e) {
86+
return null;
87+
}
88+
}
89+
90+
private static int getNextId() {
91+
while (true) {
92+
int current = COUNT.get();
93+
int next = (current > 9000) ? 1000 : current + 1;
94+
if (COUNT.compareAndSet(current, next)) {
95+
return next;
96+
}
97+
}
98+
}
99+
100+
101+
}

runtime/web/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@
4040
<artifactId>model</artifactId>
4141
<version>0.0.1-SNAPSHOT</version>
4242
</dependency>
43+
44+
<dependency>
45+
<groupId>org.springframework.boot</groupId>
46+
<artifactId>spring-boot-starter-aop</artifactId>
47+
</dependency>
4348
</dependencies>
4449

4550
</project>
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package com.alipay.muagent.web.interceptor;
2+
3+
import com.alipay.muagent.model.trace.TraceContext;
4+
import com.alipay.muagent.model.trace.TraceThreadLocalContext;
5+
import com.alipay.muagent.model.trace.TraceThreadLocalContextHolder;
6+
import com.alipay.muagent.util.TraceUtil;
7+
import com.alipay.muagent.web.model.Result;
8+
import org.aspectj.lang.JoinPoint;
9+
import org.aspectj.lang.annotation.*;
10+
import org.springframework.stereotype.Component;
11+
12+
/**
13+
* @author Joshua
14+
* @version RequestInterceptorAspect.java v1.0 2024-11-20 20:52
15+
**/
16+
@Aspect
17+
@Component
18+
public class RequestInterceptorAspect {
19+
20+
@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping) || " +
21+
"@annotation(org.springframework.web.bind.annotation.GetMapping) || " +
22+
"@annotation(org.springframework.web.bind.annotation.PostMapping) || " +
23+
"@annotation(org.springframework.web.bind.annotation.PutMapping) || " +
24+
"@annotation(org.springframework.web.bind.annotation.DeleteMapping)")
25+
public void requestMappingMethods() {
26+
}
27+
28+
@Before("requestMappingMethods()")
29+
public void doBeforeRequestHandle() {
30+
TraceContext traceContext = new TraceContext();
31+
traceContext.setTraceId(TraceUtil.generateTraceId());
32+
TraceThreadLocalContext traceThreadLocalContext = TraceThreadLocalContextHolder.getTraceThreadLocalContext();
33+
traceThreadLocalContext.push(traceContext);
34+
}
35+
36+
@AfterReturning(pointcut = "requestMappingMethods()", returning = "result")
37+
public void handleAfterReturning(JoinPoint joinPoint, Object result) {
38+
try {
39+
TraceContext traceContext = TraceThreadLocalContextHolder.getTraceThreadLocalContext().getCurrentTraceContext();
40+
((Result<?>) result).setTraceId(traceContext.getTraceId());
41+
} catch (Exception e) {
42+
/*
43+
* empty catch
44+
*/
45+
} finally {
46+
TraceThreadLocalContextHolder.getTraceThreadLocalContext().clear();
47+
}
48+
}
49+
50+
@AfterThrowing(pointcut = "requestMappingMethods()", throwing = "error")
51+
public void handleAfterThrowing(JoinPoint joinPoint, Throwable error) {
52+
TraceThreadLocalContextHolder.getTraceThreadLocalContext().clear();
53+
}
54+
55+
56+
}

runtime/web/src/main/java/com/alipay/muagent/web/model/Result.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ public class Result<T> {
2727

2828
private String host = getLocalHost();
2929

30+
private String traceId;
31+
3032
/**
3133
* 创建一个方法执行成功的Result对象
3234
*

0 commit comments

Comments
 (0)