Write logs to oom report
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user