This is an automated email from the ASF dual-hosted git repository.

dingtao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozhera.git


The following commit(s) were added to refs/heads/master by this push:
     new 9afee4fb optimize TraceUtil (#601)
9afee4fb is described below

commit 9afee4fb8b3045def0157d2b1da57aa5e44d6244
Author: shanwb <[email protected]>
AuthorDate: Mon Aug 18 19:40:07 2025 +0800

    optimize TraceUtil (#601)
---
 .../ozhera/log/agent/common/trace/TraceUtil.java   | 156 ++++++++++++++++++---
 1 file changed, 140 insertions(+), 16 deletions(-)

diff --git 
a/ozhera-log/log-agent/src/main/java/org/apache/ozhera/log/agent/common/trace/TraceUtil.java
 
b/ozhera-log/log-agent/src/main/java/org/apache/ozhera/log/agent/common/trace/TraceUtil.java
index 518b118c..b16fb314 100644
--- 
a/ozhera-log/log-agent/src/main/java/org/apache/ozhera/log/agent/common/trace/TraceUtil.java
+++ 
b/ozhera-log/log-agent/src/main/java/org/apache/ozhera/log/agent/common/trace/TraceUtil.java
@@ -48,7 +48,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicReference;
-import java.util.regex.Pattern;
 
 @Slf4j
 public class TraceUtil {
@@ -61,7 +60,6 @@ public class TraceUtil {
     private static final String TAG_KEY_HOST = "host.name";
     private static final Set<String> SPECIAL_TAG_KEYS = 
Sets.newHashSet(TAG_KEY_SPAN_KIND,
             TAG_KEY_SERVICE_NAME, TAG_KEY_IP, TAG_KEY_HOST);
-    private static Pattern EMPTY_PATTERN = Pattern.compile("\\r\\n");
 
     public static byte[] toBytes(String spanStr) {
         try {
@@ -91,15 +89,15 @@ public class TraceUtil {
     }
 
     public static TSpanData toTSpanData(String spanStr) {
-        String message;
-        spanStr = EMPTY_PATTERN.matcher(spanStr).replaceAll("");
-        if (spanStr.contains(" ||| ")) {
-            String[] messages = spanStr.split(" \\|\\|\\| ");
-            message = messages[1];
-        } else {
-            message = spanStr.split(" \\| ")[1];
-        }
-        String[] messageArray = message.split(MessageUtil.SPLIT);
+        // 步骤1优化:使用简单字符串替换代替正则表达式
+        String cleanSpanStr = spanStr.replace("\r\n", "");
+        
+        // 步骤2优化:使用 indexOf 代替 split 减少数组创建
+        String message = extractMessage(cleanSpanStr);
+        
+        // 步骤3优化:使用预分配大小的分割逻辑
+        String[] messageArray = splitMessage(message);
+        
         // Bit check
         if (messageArray.length != MessageUtil.COUNT) {
             log.error("message count illegal : " + spanStr);
@@ -109,6 +107,51 @@ public class TraceUtil {
         return toTSpanData(messageArray);
     }
 
+    /**
+     * 优化的消息提取方法 - 避免创建不必要的数组
+     */
+    private static String extractMessage(String spanStr) {
+        int tripleIndex = spanStr.indexOf(" ||| ");
+        if (tripleIndex != -1) {
+            // 找到三重管道符,取后面的部分
+            return spanStr.substring(tripleIndex + 5);
+        }
+        
+        int singleIndex = spanStr.indexOf(" | ");
+        if (singleIndex != -1) {
+            // 找到单管道符,取后面的部分
+            return spanStr.substring(singleIndex + 3);
+        }
+        
+        // 兜底:如果都没找到,返回原字符串
+        return spanStr;
+    }
+
+    /**
+     * 优化的消息分割方法 - 预分配容量减少扩容
+     */
+    private static String[] splitMessage(String message) {
+        String delimiter = MessageUtil.SPLIT;
+        int delimiterLength = delimiter.length();
+        
+        // 预估分段数量,减少数组扩容
+        List<String> parts = new ArrayList<>(MessageUtil.COUNT);
+        int start = 0;
+        int end;
+        
+        while ((end = message.indexOf(delimiter, start)) != -1) {
+            parts.add(message.substring(start, end));
+            start = end + delimiterLength;
+        }
+        
+        // 添加最后一段
+        if (start < message.length()) {
+            parts.add(message.substring(start));
+        }
+        
+        return parts.toArray(new String[0]);
+    }
+
     private static TSpanData toTSpanData(String[] array) {
         TSpanData span = new TSpanData();
         span.setTraceId(array[MessageUtil.TRACE_ID]);
@@ -138,13 +181,94 @@ public class TraceUtil {
         return span;
     }
 
+    /**
+     * 优化的字符串解码方法 - 避免多次字符串替换和正则表达式
+     */
     private static String decodeLineBreak(String value) {
-        if (StringUtils.isNotEmpty(value)) {
-            return value.replaceAll("\\\\","\\\\\\\\").replaceAll("##r'", 
"\\\\\"")
-                    .replaceAll("##n", "\\\\n").replaceAll("##r", 
"\\\\r").replaceAll("##t", "\\\\t")
-                    .replaceAll("##tat", "\\\\tat").replaceAll("##'", 
"\\\\\"");
+        if (StringUtils.isEmpty(value)) {
+            return value;
+        }
+        
+        // 如果不包含需要替换的字符,直接返回,避免不必要的处理
+        if (!containsDecodeChars(value)) {
+            return value;
+        }
+        
+        // 使用 StringBuilder 进行一次性替换,避免多次字符串创建
+        return performOptimizedDecode(value);
+    }
+    
+    /**
+     * 快速检查是否包含需要解码的字符序列
+     */
+    private static boolean containsDecodeChars(String value) {
+        return value.indexOf('\\') != -1 || value.indexOf('#') != -1;
+    }
+    
+    /**
+     * 执行优化的解码操作 - 使用字符级别的处理避免正则表达式
+     */
+    private static String performOptimizedDecode(String value) {
+        StringBuilder result = new StringBuilder(value.length() + 20);
+        char[] chars = value.toCharArray();
+        
+        for (int i = 0; i < chars.length; i++) {
+            if (chars[i] == '\\' && i + 1 < chars.length && chars[i + 1] == 
'\\') {
+                // 处理 \\ -> \\\\
+                result.append("\\\\\\\\");
+                i++; // 跳过下一个字符
+            } else if (chars[i] == '#' && i + 2 < chars.length && chars[i + 1] 
== '#') {
+                // 处理 ## 开头的序列
+                String replacement = getReplacementForSequence(chars, i);
+                if (replacement != null) {
+                    result.append(replacement);
+                    i += getSequenceLength(chars, i) - 1; // 跳过已处理的字符
+                } else {
+                    result.append(chars[i]);
+                }
+            } else {
+                result.append(chars[i]);
+            }
+        }
+        
+        return result.toString();
+    }
+    
+    /**
+     * 获取字符序列的替换内容
+     */
+    private static String getReplacementForSequence(char[] chars, int start) {
+        if (start + 3 < chars.length) {
+            String sequence = new String(chars, start, Math.min(6, 
chars.length - start));
+            
+            // 精确匹配,避免正则表达式
+            if (sequence.startsWith("##r'")) return "\\\\\"";
+            if (sequence.startsWith("##n")) return "\\\\n";
+            if (sequence.startsWith("##r")) return "\\\\r";
+            if (sequence.startsWith("##t")) return "\\\\t";
+            if (sequence.startsWith("##tat")) return "\\\\tat";
+            if (sequence.startsWith("##'")) return "\\\\\"";
+        }
+        
+        return null;
+    }
+    
+    /**
+     * 获取匹配序列的长度
+     */
+    private static int getSequenceLength(char[] chars, int start) {
+        if (start + 3 < chars.length) {
+            String sequence = new String(chars, start, Math.min(6, 
chars.length - start));
+            
+            if (sequence.startsWith("##tat")) return 5;
+            if (sequence.startsWith("##r'")) return 4;
+            if (sequence.startsWith("##n")) return 3;
+            if (sequence.startsWith("##r")) return 3;
+            if (sequence.startsWith("##t")) return 3;
+            if (sequence.startsWith("##'")) return 3;
         }
-        return value;
+        
+        return 1;
     }
 
     /**


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to