|
|
@@ -0,0 +1,103 @@
|
|
|
+package cn.seecoder.seecoderlog.context;
|
|
|
+
|
|
|
+import lombok.AllArgsConstructor;
|
|
|
+import lombok.Data;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+
|
|
|
+import java.net.InetAddress;
|
|
|
+import java.net.UnknownHostException;
|
|
|
+
|
|
|
+@Data
|
|
|
+@AllArgsConstructor
|
|
|
+public class TraceInfo {
|
|
|
+ // 进程ID
|
|
|
+ private static final String PROCESS_ID = String.valueOf(ProcessHandle.current().pid() % 1000);
|
|
|
+
|
|
|
+ // 递增计数器
|
|
|
+ private static volatile int counter = 0;
|
|
|
+
|
|
|
+ private String traceId;
|
|
|
+ private String rpcId;
|
|
|
+
|
|
|
+ // 在现有字段中添加时间戳记录
|
|
|
+ private static volatile long lastTimestamp = 0;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据当前RPC ID生成子级RPC ID
|
|
|
+ */
|
|
|
+ public static String generateChildRpcId(String currentRpcId) {
|
|
|
+ if (StringUtils.isEmpty(currentRpcId)) {
|
|
|
+ return "1";
|
|
|
+ }
|
|
|
+ return currentRpcId + ".1";
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据当前RPC ID生成同级下一个RPC ID
|
|
|
+ */
|
|
|
+ public static String generateNextRpcId(String currentRpcId) {
|
|
|
+ return incurRpcId(currentRpcId);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void updateNextRpcId(){
|
|
|
+ rpcId = incurRpcId(rpcId);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成新的TraceId
|
|
|
+ */
|
|
|
+ public static String generateTraceId() {
|
|
|
+ try {
|
|
|
+ // 获取本机IP地址并转换为16进制
|
|
|
+ InetAddress inetAddress = InetAddress.getLocalHost();
|
|
|
+ byte[] ipBytes = inetAddress.getAddress();
|
|
|
+ StringBuilder ipHex = new StringBuilder();
|
|
|
+ for (byte b : ipBytes) {
|
|
|
+ ipHex.append(String.format("%02x", b & 0xFF));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 毫秒时间戳
|
|
|
+ long timestamp = System.currentTimeMillis();
|
|
|
+
|
|
|
+ // 4位递增数
|
|
|
+ int count = getNextCounter();
|
|
|
+
|
|
|
+ // 生成traceId: IP十六进制 + 时间戳 + 递增数 + 进程ID + 标识位(0)
|
|
|
+ return String.format("%s%013d%04d%s0", ipHex, timestamp, count, PROCESS_ID);
|
|
|
+ } catch (UnknownHostException e) {
|
|
|
+ // 如果无法获取IP,则使用随机数替代
|
|
|
+ long random = (long) (Math.random() * 100000000);
|
|
|
+ long timestamp = System.currentTimeMillis();
|
|
|
+ int count = getNextCounter();
|
|
|
+ return String.format("%08x%013d%04d%s0", random, timestamp, count, PROCESS_ID);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取下一个递增计数器值
|
|
|
+ * 修改为时间戳绑定的递增计数器
|
|
|
+ */
|
|
|
+ private static synchronized int getNextCounter() {
|
|
|
+ long currentTimestamp = System.currentTimeMillis();
|
|
|
+
|
|
|
+ // 如果时间戳变化,则重置计数器
|
|
|
+ if (currentTimestamp != lastTimestamp) {
|
|
|
+ counter = 0;
|
|
|
+ lastTimestamp = currentTimestamp;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 递增并返回计数器值,保持原有的取模逻辑
|
|
|
+ return ++counter % 10000;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String incurRpcId(String currentRpcId){
|
|
|
+ if (StringUtils.isEmpty(currentRpcId)){
|
|
|
+ return "1";
|
|
|
+ }
|
|
|
+ String[] parts = currentRpcId.split("\\.");
|
|
|
+ int lastPart = Integer.parseInt(parts[parts.length - 1]);
|
|
|
+ parts[parts.length - 1] = String.valueOf(lastPart + 1);
|
|
|
+
|
|
|
+ return String.join(".", parts);
|
|
|
+ }
|
|
|
+}
|