mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-11-07 13:45:01 +03:00
fix(xray): capture whole core crash reports instead of the first pipe chunk
LogWriter inspected each pipe chunk on its own. The Go runtime writes "panic: " with a separate write before the message and traceback, so the crash report was written from that first chunk alone and the panel left 7-byte core_crash_*.log files holding only "panic: ". Any ordinary log line mentioning panic/exception/stack trace was also treated as a crash and dropped from the panel log. The writer now splits output into lines, starts a crash only on a line beginning with the Go runtime's "panic: " / "fatal error: " header, keeps everything after it, and writes one report from Flush, which waitForCommand calls after cmd.Wait has delivered all output. The header line becomes LastLine so GetResult shows the cause. The report filename format "_000000000" is not a Go fractional-seconds layout and always produced literal zeros, so reports from the same second overwrote each other; os.CreateTemp now gives every report a unique name.
This commit is contained in:
@@ -734,6 +734,7 @@ func (p *process) waitForCommand(cmd *exec.Cmd, done chan struct{}) {
|
||||
defer close(done)
|
||||
|
||||
err := cmd.Wait()
|
||||
p.logWriter.Flush()
|
||||
if err == nil || p.intentionalStop.Load() {
|
||||
return
|
||||
}
|
||||
@@ -830,17 +831,27 @@ const (
|
||||
maxCrashReports = 10
|
||||
)
|
||||
|
||||
// writeCrashReport persists a captured xray crash chunk to the log folder
|
||||
// with nanosecond-precision filename so restart-loop bursts don't overwrite
|
||||
// each other, and prunes old reports to keep the folder bounded.
|
||||
// writeCrashReport persists a captured xray crash to the log folder; CreateTemp's
|
||||
// random suffix keeps restart-loop bursts within one second from overwriting each other.
|
||||
func writeCrashReport(m []byte) error {
|
||||
dir := config.GetLogFolder()
|
||||
if err := os.MkdirAll(dir, 0o770); err != nil {
|
||||
return err
|
||||
}
|
||||
pruneOldCrashReports(dir, maxCrashReports-1)
|
||||
name := crashReportPrefix + time.Now().Format("20060102_150405_000000000") + crashReportSuffix
|
||||
return os.WriteFile(filepath.Join(dir, name), m, 0o640)
|
||||
pattern := crashReportPrefix + time.Now().Format("20060102_150405") + "_*" + crashReportSuffix
|
||||
f, err := os.CreateTemp(dir, pattern)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = f.Write(m)
|
||||
if cerr := f.Close(); err == nil {
|
||||
err = cerr
|
||||
}
|
||||
if err == nil {
|
||||
err = os.Chmod(f.Name(), 0o640)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func pruneOldCrashReports(dir string, keep int) {
|
||||
|
||||
Reference in New Issue
Block a user