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 <ho3ein.sanaei@gmail.com>
This commit is contained in:
n0ctal
2026-06-20 16:26:40 +05:00
committed by GitHub
parent a5bc71a6f1
commit 26cc4838ed
2 changed files with 15 additions and 7 deletions
+7 -3
View File
@@ -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
View File
@@ -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]