fix(gateway): include tail logs on abnormal exit

When the managed gateway process exits with an error, append the last buffered stdout/stderr lines to the exit log to make root causes visible.

Closes #2513
This commit is contained in:
王国栋0668001083 2026-04-20 17:22:04 +08:00
parent e556a816e4
commit 735187c86c
2 changed files with 38 additions and 1 deletions

View file

@ -762,7 +762,12 @@ func (h *Handler) startGatewayLocked(initialStatus string, existingPid int) (int
// Wait for exit in background and clean up // Wait for exit in background and clean up
go func() { go func() {
if err := cmd.Wait(); err != nil { if err := cmd.Wait(); err != nil {
logger.ErrorC("gateway", fmt.Sprintf("Gateway process exited: %v", err)) tail := gateway.logs.Tail(50)
if len(tail) > 0 {
logger.ErrorC("gateway", fmt.Sprintf("Gateway process exited: %v\nLast gateway logs:\n%s", err, strings.Join(tail, "\n")))
} else {
logger.ErrorC("gateway", fmt.Sprintf("Gateway process exited: %v", err))
}
} else { } else {
logger.InfoC("gateway", "Gateway process exited normally") logger.InfoC("gateway", "Gateway process exited normally")
} }

View file

@ -95,3 +95,35 @@ func (b *LogBuffer) RunID() int {
return b.runID return b.runID
} }
// Tail returns up to the last n buffered lines (newest last).
// If n <= 0, it returns nil.
func (b *LogBuffer) Tail(n int) []string {
if n <= 0 {
return nil
}
b.mu.RLock()
defer b.mu.RUnlock()
if b.total == 0 || len(b.lines) == 0 {
return nil
}
if n > len(b.lines) {
n = len(b.lines)
}
result := make([]string, n)
if b.total <= b.cap {
copy(result, b.lines[len(b.lines)-n:])
return result
}
start := (b.total - n) % b.cap
for i := 0; i < n; i++ {
result[i] = b.lines[(start+i)%b.cap]
}
return result
}