mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-07-07 05:14:27 +00:00
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:
@@ -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,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]
|
||||
|
||||
Reference in New Issue
Block a user