Bläddra i källkod

perf(xray): compile log/traffic regexps once at package scope (#5362)

GetTraffic recompiled two stats regexps on every traffic tick, and LogWriter.Write
recompiled two more on every log line. Hoist all four to package-level vars so they
compile once at load instead of per call on hot paths.

Co-authored-by: Sanaei <[email protected]>
n0ctal 1 dag sedan
förälder
incheckning
26cc4838ed
2 ändrade filer med 15 tillägg och 7 borttagningar
  1. 7 3
      internal/xray/api.go
  2. 8 4
      internal/xray/log_writer.go

+ 7 - 3
internal/xray/api.go

@@ -38,6 +38,13 @@ import (
 	"google.golang.org/grpc/status"
 )
 
+// Compiled once at package load: GetTraffic runs on every traffic-stats tick,
+// so recompiling these per call is wasted work.
+var (
+	trafficRegex       = regexp.MustCompile(`(inbound|outbound)>>>([^>]+)>>>traffic>>>(downlink|uplink)`)
+	clientTrafficRegex = regexp.MustCompile(`user>>>([^>]+)>>>traffic>>>(downlink|uplink)`)
+)
+
 // XrayAPI is a gRPC client for managing Xray core configuration, inbounds, outbounds, and statistics.
 type XrayAPI struct {
 	HandlerServiceClient *command.HandlerServiceClient
@@ -537,9 +544,6 @@ func (x *XrayAPI) GetTraffic() ([]*Traffic, []*ClientTraffic, error) {
 		return nil, nil, common.NewError("xray api is not initialized")
 	}
 
-	trafficRegex := regexp.MustCompile(`(inbound|outbound)>>>([^>]+)>>>traffic>>>(downlink|uplink)`)
-	clientTrafficRegex := regexp.MustCompile(`user>>>([^>]+)>>>traffic>>>(downlink|uplink)`)
-
 	ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
 	defer cancel()
 

+ 8 - 4
internal/xray/log_writer.go

@@ -8,6 +8,13 @@ import (
 	"github.com/mhsanaei/3x-ui/v3/internal/logger"
 )
 
+// Compiled once at package load: Write runs on every line Xray emits, so
+// recompiling these per write is wasted work.
+var (
+	crashRegex   = regexp.MustCompile(`(?i)(panic|exception|stack trace|fatal error)`)
+	logLineRegex = regexp.MustCompile(`^(\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}\.\d{6}) \[([^\]]+)\] (.+)$`)
+)
+
 // NewLogWriter returns a new LogWriter for processing Xray log output.
 func NewLogWriter() *LogWriter {
 	return &LogWriter{}
@@ -20,8 +27,6 @@ type LogWriter struct {
 
 // Write processes and filters log output from the Xray process, handling crash detection and message filtering.
 func (lw *LogWriter) Write(m []byte) (n int, err error) {
-	crashRegex := regexp.MustCompile(`(?i)(panic|exception|stack trace|fatal error)`)
-
 	// Convert the data to a string
 	message := strings.TrimSpace(string(m))
 	msgLowerAll := strings.ToLower(message)
@@ -42,11 +47,10 @@ func (lw *LogWriter) Write(m []byte) (n int, err error) {
 		return len(m), nil
 	}
 
-	regex := regexp.MustCompile(`^(\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}\.\d{6}) \[([^\]]+)\] (.+)$`)
 	messages := strings.SplitSeq(message, "\n")
 
 	for msg := range messages {
-		matches := regex.FindStringSubmatch(msg)
+		matches := logLineRegex.FindStringSubmatch(msg)
 
 		if len(matches) > 3 {
 			level := matches[2]