From d2215bb7f766aa26417c3851e17e03ee3c55ba1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Sun, 28 Jun 2026 11:10:20 +0800 Subject: [PATCH] Write logs to oom report --- daemon/started_service.go | 6 ++++ experimental/libbox/command_server.go | 5 ++- experimental/libbox/config.go | 6 ---- experimental/libbox/oom_report.go | 45 ++++++++++++++++++++++++--- service/oomkiller/service_darwin.go | 4 +-- 5 files changed, 51 insertions(+), 15 deletions(-) diff --git a/daemon/started_service.go b/daemon/started_service.go index d6187dbec..5dbc9a7de 100644 --- a/daemon/started_service.go +++ b/daemon/started_service.go @@ -1487,6 +1487,12 @@ func (s *StartedService) WriteMessage(level log.Level, message string) { } } +func (s *StartedService) SavedLog() []*log.Entry { + s.logAccess.RLock() + defer s.logAccess.RUnlock() + return s.logLines.Array() +} + func (s *StartedService) Instance() *Instance { s.serviceAccess.RLock() defer s.serviceAccess.RUnlock() diff --git a/experimental/libbox/command_server.go b/experimental/libbox/command_server.go index d25f81b94..dc09fa31e 100644 --- a/experimental/libbox/command_server.go +++ b/experimental/libbox/command_server.go @@ -14,6 +14,7 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/daemon" "github.com/sagernet/sing-box/log" + "github.com/sagernet/sing-box/service/oomkiller" "github.com/sagernet/sing/common" E "github.com/sagernet/sing/common/exceptions" "github.com/sagernet/sing/service" @@ -74,10 +75,12 @@ func NewCommandServer(handler CommandServerHandler, platformInterface PlatformIn // GroupID: sGroupID, // SystemProxyEnabled: false, }) + reporter := &oomReporter{startedService: server.StartedService} + service.MustRegister[oomkiller.OOMReporter](ctx, reporter) server.managedService = daemon.NewManagedService(daemon.ManagedServiceOptions{ Handler: (*platformHandler)(server), Debug: sDebug, - OOMReporter: sOOMReporter, + OOMReporter: reporter, }) return server, nil } diff --git a/experimental/libbox/config.go b/experimental/libbox/config.go index 08b9d6556..d9c52db0d 100644 --- a/experimental/libbox/config.go +++ b/experimental/libbox/config.go @@ -13,7 +13,6 @@ import ( "github.com/sagernet/sing-box/include" "github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/option" - "github.com/sagernet/sing-box/service/oomkiller" tun "github.com/sagernet/sing-tun" "github.com/sagernet/sing/common/control" E "github.com/sagernet/sing/common/exceptions" @@ -24,8 +23,6 @@ import ( "github.com/sagernet/sing/service/filemanager" ) -var sOOMReporter oomkiller.OOMReporter - func baseContext(platformInterface PlatformInterface) context.Context { dnsRegistry := include.DNSTransportRegistry() if platformInterface != nil { @@ -37,9 +34,6 @@ func baseContext(platformInterface PlatformInterface) context.Context { } ctx := context.Background() ctx = filemanager.WithDefault(ctx, sWorkingPath, sTempPath, sUserID, sGroupID) - if sOOMReporter != nil { - ctx = service.ContextWith[oomkiller.OOMReporter](ctx, sOOMReporter) - } return box.Context(ctx, include.InboundRegistry(), include.OutboundRegistry(), include.EndpointRegistry(), dnsRegistry, include.ServiceRegistry(), include.CertificateProviderRegistry()) } diff --git a/experimental/libbox/oom_report.go b/experimental/libbox/oom_report.go index 64afc4b52..c9570995b 100644 --- a/experimental/libbox/oom_report.go +++ b/experimental/libbox/oom_report.go @@ -3,22 +3,21 @@ package libbox import ( + "bytes" "os" "path/filepath" "runtime" "strings" "time" + "github.com/sagernet/sing-box/daemon" "github.com/sagernet/sing-box/experimental/libbox/internal/oomprofile" + "github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/service/oomkiller" "github.com/sagernet/sing/common/byteformats" "github.com/sagernet/sing/common/memory" ) -func init() { - sOOMReporter = &oomReporter{} -} - var oomReportProfiles = []string{ "allocs", "block", @@ -59,7 +58,9 @@ type oomReportMetadata struct { LastGC string `json:"lastGC,omitempty"` } -type oomReporter struct{} +type oomReporter struct { + startedService *daemon.StartedService +} var _ oomkiller.OOMReporter = (*oomReporter)(nil) @@ -172,10 +173,44 @@ func (r *oomReporter) writeSnapshot(destPath string, memoryUsage uint64) error { } writeReportMetadata(destPath, metadata) copyConfigSnapshot(destPath) + writeOOMLog(destPath, r.startedService.SavedLog()) return nil } +func writeOOMLog(destPath string, entries []*log.Entry) { + if len(entries) == 0 { + return + } + var buffer bytes.Buffer + for _, entry := range entries { + writeWithoutColors(&buffer, entry.Message) + buffer.WriteByte('\n') + } + writeReportFile(destPath, "go.log", buffer.Bytes()) +} + +func writeWithoutColors(buffer *bytes.Buffer, message string) { + start := 0 + for index := 0; index < len(message); { + if message[index] != '\x1b' || index+1 >= len(message) || message[index+1] != '[' { + index++ + continue + } + end := index + 2 + for end < len(message) && message[end] != 'm' { + end++ + } + if end >= len(message) { + break + } + buffer.WriteString(message[start:index]) + index = end + 1 + start = index + } + buffer.WriteString(message[start:]) +} + func writeOOMProfile(destPath string, name string) { filePath, err := oomprofile.WriteFile(destPath, name) if err != nil { diff --git a/service/oomkiller/service_darwin.go b/service/oomkiller/service_darwin.go index 64504ac46..0efdb7ab0 100644 --- a/service/oomkiller/service_darwin.go +++ b/service/oomkiller/service_darwin.go @@ -117,9 +117,7 @@ func (s *Service) writeOOMDraft(memoryUsage uint64) { if time.Duration(now-lastDraft) < oomDraftMinInterval { return } - if !s.lastDraftTime.CompareAndSwap(lastDraft, now) { - return - } + s.lastDraftTime.Store(now) reporter := service.FromContext[OOMReporter](s.ctx) if reporter == nil { return