diff --git a/box.go b/box.go index 0a66c88c..b8a0fad1 100644 --- a/box.go +++ b/box.go @@ -41,6 +41,7 @@ type Options struct { option.Options Context context.Context PlatformInterface platform.Interface + PlatformLogWriter log.PlatformWriter } func New(options Options) (*Box, error) { @@ -71,7 +72,7 @@ func New(options Options) (*Box, error) { Observable: needClashAPI, DefaultWriter: defaultLogWriter, BaseTime: createdAt, - PlatformWriter: options.PlatformInterface, + PlatformWriter: options.PlatformLogWriter, }) if err != nil { return nil, E.Cause(err, "create log factory") diff --git a/experimental/libbox/platform/interface.go b/experimental/libbox/platform/interface.go index 77afa17b..8c471971 100644 --- a/experimental/libbox/platform/interface.go +++ b/experimental/libbox/platform/interface.go @@ -2,7 +2,6 @@ package platform import ( "context" - "io" "net/netip" "github.com/sagernet/sing-box/adapter" @@ -25,7 +24,6 @@ type Interface interface { UnderNetworkExtension() bool ClearDNSCache() process.Searcher - io.Writer } type NetworkInterface struct { diff --git a/experimental/libbox/service.go b/experimental/libbox/service.go index c8fef13e..67b57d7d 100644 --- a/experimental/libbox/service.go +++ b/experimental/libbox/service.go @@ -3,6 +3,7 @@ package libbox import ( "context" "net/netip" + "runtime" runtimeDebug "runtime/debug" "syscall" @@ -12,6 +13,7 @@ import ( "github.com/sagernet/sing-box/common/urltest" "github.com/sagernet/sing-box/experimental/libbox/internal/procfs" "github.com/sagernet/sing-box/experimental/libbox/platform" + "github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/option" "github.com/sagernet/sing-tun" "github.com/sagernet/sing/common" @@ -44,10 +46,12 @@ func NewService(configContent string, platformInterface PlatformInterface) (*Box ctx = service.ContextWithPtr(ctx, urlTestHistoryStorage) pauseManager := pause.NewDefaultManager(ctx) ctx = pause.ContextWithManager(ctx, pauseManager) + platformWrapper := &platformInterfaceWrapper{iif: platformInterface, useProcFS: platformInterface.UseProcFS()} instance, err := box.New(box.Options{ Context: ctx, Options: options, - PlatformInterface: &platformInterfaceWrapper{iif: platformInterface, useProcFS: platformInterface.UseProcFS()}, + PlatformInterface: platformWrapper, + PlatformLogWriter: platformWrapper, }) if err != nil { cancel() @@ -83,7 +87,10 @@ func (s *BoxService) Wake() { _ = s.instance.Router().ResetNetwork() } -var _ platform.Interface = (*platformInterfaceWrapper)(nil) +var ( + _ platform.Interface = (*platformInterfaceWrapper)(nil) + _ log.PlatformWriter = (*platformInterfaceWrapper)(nil) +) type platformInterfaceWrapper struct { iif PlatformInterface @@ -131,11 +138,6 @@ func (w *platformInterfaceWrapper) OpenTun(options *tun.Options, platformOptions return tun.New(*options) } -func (w *platformInterfaceWrapper) Write(p []byte) (n int, err error) { - w.iif.WriteLog(string(p)) - return len(p), nil -} - func (w *platformInterfaceWrapper) FindProcessInfo(ctx context.Context, network string, source netip.AddrPort, destination netip.AddrPort) (*process.Info, error) { var uid int32 if w.useProcFS { @@ -203,3 +205,11 @@ func (w *platformInterfaceWrapper) UnderNetworkExtension() bool { func (w *platformInterfaceWrapper) ClearDNSCache() { w.iif.ClearDNSCache() } + +func (w *platformInterfaceWrapper) DisableColors() bool { + return runtime.GOOS != "android" +} + +func (w *platformInterfaceWrapper) WriteMessage(level log.Level, message string) { + w.iif.WriteLog(message) +} diff --git a/log/default.go b/log/default.go index e3554647..c2e1c745 100644 --- a/log/default.go +++ b/log/default.go @@ -16,11 +16,11 @@ type simpleFactory struct { formatter Formatter platformFormatter Formatter writer io.Writer - platformWriter io.Writer + platformWriter PlatformWriter level Level } -func NewFactory(formatter Formatter, writer io.Writer, platformWriter io.Writer) Factory { +func NewFactory(formatter Formatter, writer io.Writer, platformWriter PlatformWriter) Factory { return &simpleFactory{ formatter: formatter, platformFormatter: Formatter{ @@ -76,7 +76,7 @@ func (l *simpleLogger) Log(ctx context.Context, level Level, args []any) { os.Exit(1) } if l.platformWriter != nil { - l.platformWriter.Write([]byte(l.platformFormatter.Format(ctx, level, l.tag, F.ToString(args...), nowTime))) + l.platformWriter.WriteMessage(level, l.platformFormatter.Format(ctx, level, l.tag, F.ToString(args...), nowTime)) } } diff --git a/log/log.go b/log/log.go index b6b0805c..19dbbbd9 100644 --- a/log/log.go +++ b/log/log.go @@ -42,7 +42,7 @@ type Options struct { Observable bool DefaultWriter io.Writer BaseTime time.Time - PlatformWriter io.Writer + PlatformWriter PlatformWriter } func New(options Options) (Factory, error) { diff --git a/log/observable.go b/log/observable.go index 83d9cf9c..c12cbbbe 100644 --- a/log/observable.go +++ b/log/observable.go @@ -6,7 +6,6 @@ import ( "os" "time" - C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing/common" F "github.com/sagernet/sing/common/format" "github.com/sagernet/sing/common/observable" @@ -18,18 +17,17 @@ type observableFactory struct { formatter Formatter platformFormatter Formatter writer io.Writer - platformWriter io.Writer + platformWriter PlatformWriter level Level subscriber *observable.Subscriber[Entry] observer *observable.Observer[Entry] } -func NewObservableFactory(formatter Formatter, writer io.Writer, platformWriter io.Writer) ObservableFactory { +func NewObservableFactory(formatter Formatter, writer io.Writer, platformWriter PlatformWriter) ObservableFactory { factory := &observableFactory{ formatter: formatter, platformFormatter: Formatter{ BaseTime: formatter.BaseTime, - DisableColors: C.IsDarwin || C.IsIos, DisableLineBreak: true, }, writer: writer, @@ -37,6 +35,9 @@ func NewObservableFactory(formatter Formatter, writer io.Writer, platformWriter level: LevelTrace, subscriber: observable.NewSubscriber[Entry](128), } + if platformWriter != nil { + factory.platformFormatter.DisableColors = platformWriter.DisableColors() + } factory.observer = observable.NewObserver[Entry](factory.subscriber, 64) return factory } @@ -94,7 +95,7 @@ func (l *observableLogger) Log(ctx context.Context, level Level, args []any) { } l.subscriber.Emit(Entry{level, messageSimple}) if l.platformWriter != nil { - l.platformWriter.Write([]byte(l.platformFormatter.Format(ctx, level, l.tag, F.ToString(args...), nowTime))) + l.platformWriter.WriteMessage(level, l.platformFormatter.Format(ctx, level, l.tag, F.ToString(args...), nowTime)) } } diff --git a/log/platform.go b/log/platform.go new file mode 100644 index 00000000..c6a9e525 --- /dev/null +++ b/log/platform.go @@ -0,0 +1,6 @@ +package log + +type PlatformWriter interface { + DisableColors() bool + WriteMessage(level Level, message string) +}