|
@@ -4,6 +4,7 @@ import (
|
|
|
"regexp"
|
|
"regexp"
|
|
|
"runtime"
|
|
"runtime"
|
|
|
"strings"
|
|
"strings"
|
|
|
|
|
+ "sync"
|
|
|
|
|
|
|
|
"github.com/mhsanaei/3x-ui/v3/internal/logger"
|
|
"github.com/mhsanaei/3x-ui/v3/internal/logger"
|
|
|
)
|
|
)
|
|
@@ -22,9 +23,25 @@ func NewLogWriter() *LogWriter {
|
|
|
|
|
|
|
|
// LogWriter processes and filters log output from the Xray process, handling crash detection and message filtering.
|
|
// LogWriter processes and filters log output from the Xray process, handling crash detection and message filtering.
|
|
|
type LogWriter struct {
|
|
type LogWriter struct {
|
|
|
|
|
+ mu sync.RWMutex
|
|
|
lastLine string
|
|
lastLine string
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// LastLine returns the most recently processed Xray log line. It is safe for
|
|
|
|
|
+// concurrent use: Process.GetResult reads it from a different goroutine than the
|
|
|
|
|
+// one Xray drives Write from.
|
|
|
|
|
+func (lw *LogWriter) LastLine() string {
|
|
|
|
|
+ lw.mu.RLock()
|
|
|
|
|
+ defer lw.mu.RUnlock()
|
|
|
|
|
+ return lw.lastLine
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (lw *LogWriter) setLastLine(line string) {
|
|
|
|
|
+ lw.mu.Lock()
|
|
|
|
|
+ lw.lastLine = line
|
|
|
|
|
+ lw.mu.Unlock()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// Write processes and filters log output from the Xray process, handling crash detection and message filtering.
|
|
// 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) {
|
|
func (lw *LogWriter) Write(m []byte) (n int, err error) {
|
|
|
// Convert the data to a string
|
|
// Convert the data to a string
|
|
@@ -39,7 +56,7 @@ func (lw *LogWriter) Write(m []byte) (n int, err error) {
|
|
|
// Check if the message contains a crash
|
|
// Check if the message contains a crash
|
|
|
if crashRegex.MatchString(message) {
|
|
if crashRegex.MatchString(message) {
|
|
|
logger.Debug("Core crash detected:\n", message)
|
|
logger.Debug("Core crash detected:\n", message)
|
|
|
- lw.lastLine = message
|
|
|
|
|
|
|
+ lw.setLastLine(message)
|
|
|
err1 := writeCrashReport(m)
|
|
err1 := writeCrashReport(m)
|
|
|
if err1 != nil {
|
|
if err1 != nil {
|
|
|
logger.Error("Unable to write crash report:", err1)
|
|
logger.Error("Unable to write crash report:", err1)
|
|
@@ -60,7 +77,7 @@ func (lw *LogWriter) Write(m []byte) (n int, err error) {
|
|
|
if strings.Contains(msgBodyLower, "tls handshake error") ||
|
|
if strings.Contains(msgBodyLower, "tls handshake error") ||
|
|
|
strings.Contains(msgBodyLower, "connection ends") {
|
|
strings.Contains(msgBodyLower, "connection ends") {
|
|
|
logger.Debug("XRAY: " + msgBody)
|
|
logger.Debug("XRAY: " + msgBody)
|
|
|
- lw.lastLine = ""
|
|
|
|
|
|
|
+ lw.setLastLine("")
|
|
|
continue
|
|
continue
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -80,14 +97,14 @@ func (lw *LogWriter) Write(m []byte) (n int, err error) {
|
|
|
logger.Debug("XRAY: " + msg)
|
|
logger.Debug("XRAY: " + msg)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- lw.lastLine = ""
|
|
|
|
|
|
|
+ lw.setLastLine("")
|
|
|
} else if msg != "" {
|
|
} else if msg != "" {
|
|
|
msgLower := strings.ToLower(msg)
|
|
msgLower := strings.ToLower(msg)
|
|
|
|
|
|
|
|
if strings.Contains(msgLower, "tls handshake error") ||
|
|
if strings.Contains(msgLower, "tls handshake error") ||
|
|
|
strings.Contains(msgLower, "connection ends") {
|
|
strings.Contains(msgLower, "connection ends") {
|
|
|
logger.Debug("XRAY: " + msg)
|
|
logger.Debug("XRAY: " + msg)
|
|
|
- lw.lastLine = msg
|
|
|
|
|
|
|
+ lw.setLastLine(msg)
|
|
|
continue
|
|
continue
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -96,7 +113,7 @@ func (lw *LogWriter) Write(m []byte) (n int, err error) {
|
|
|
} else {
|
|
} else {
|
|
|
logger.Debug("XRAY: " + msg)
|
|
logger.Debug("XRAY: " + msg)
|
|
|
}
|
|
}
|
|
|
- lw.lastLine = msg
|
|
|
|
|
|
|
+ lw.setLastLine(msg)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|