github.com/sagernet/sing-box@v1.2.7/log/observable.go (about)

     1  package log
     2  
     3  import (
     4  	"context"
     5  	"io"
     6  	"os"
     7  	"time"
     8  
     9  	C "github.com/sagernet/sing-box/constant"
    10  	"github.com/sagernet/sing/common"
    11  	F "github.com/sagernet/sing/common/format"
    12  	"github.com/sagernet/sing/common/observable"
    13  )
    14  
    15  var _ Factory = (*observableFactory)(nil)
    16  
    17  type observableFactory struct {
    18  	formatter         Formatter
    19  	platformFormatter Formatter
    20  	writer            io.Writer
    21  	platformWriter    io.Writer
    22  	level             Level
    23  	subscriber        *observable.Subscriber[Entry]
    24  	observer          *observable.Observer[Entry]
    25  }
    26  
    27  func NewObservableFactory(formatter Formatter, writer io.Writer, platformWriter io.Writer) ObservableFactory {
    28  	factory := &observableFactory{
    29  		formatter: formatter,
    30  		platformFormatter: Formatter{
    31  			BaseTime:      formatter.BaseTime,
    32  			DisableColors: C.IsDarwin || C.IsIos,
    33  		},
    34  		writer:         writer,
    35  		platformWriter: platformWriter,
    36  		level:          LevelTrace,
    37  		subscriber:     observable.NewSubscriber[Entry](128),
    38  	}
    39  	factory.observer = observable.NewObserver[Entry](factory.subscriber, 64)
    40  	return factory
    41  }
    42  
    43  func (f *observableFactory) Level() Level {
    44  	return f.level
    45  }
    46  
    47  func (f *observableFactory) SetLevel(level Level) {
    48  	f.level = level
    49  }
    50  
    51  func (f *observableFactory) Logger() ContextLogger {
    52  	return f.NewLogger("")
    53  }
    54  
    55  func (f *observableFactory) NewLogger(tag string) ContextLogger {
    56  	return &observableLogger{f, tag}
    57  }
    58  
    59  func (f *observableFactory) Subscribe() (subscription observable.Subscription[Entry], done <-chan struct{}, err error) {
    60  	return f.observer.Subscribe()
    61  }
    62  
    63  func (f *observableFactory) UnSubscribe(sub observable.Subscription[Entry]) {
    64  	f.observer.UnSubscribe(sub)
    65  }
    66  
    67  func (f *observableFactory) Close() error {
    68  	return common.Close(
    69  		f.observer,
    70  	)
    71  }
    72  
    73  var _ ContextLogger = (*observableLogger)(nil)
    74  
    75  type observableLogger struct {
    76  	*observableFactory
    77  	tag string
    78  }
    79  
    80  func (l *observableLogger) Log(ctx context.Context, level Level, args []any) {
    81  	level = OverrideLevelFromContext(level, ctx)
    82  	if level > l.level {
    83  		return
    84  	}
    85  	nowTime := time.Now()
    86  	message, messageSimple := l.formatter.FormatWithSimple(ctx, level, l.tag, F.ToString(args...), nowTime)
    87  	if level == LevelPanic {
    88  		panic(message)
    89  	}
    90  	l.writer.Write([]byte(message))
    91  	if level == LevelFatal {
    92  		os.Exit(1)
    93  	}
    94  	l.subscriber.Emit(Entry{level, messageSimple})
    95  	if l.platformWriter != nil {
    96  		l.platformWriter.Write([]byte(l.platformFormatter.Format(ctx, level, l.tag, F.ToString(args...), nowTime)))
    97  	}
    98  }
    99  
   100  func (l *observableLogger) Trace(args ...any) {
   101  	l.TraceContext(context.Background(), args...)
   102  }
   103  
   104  func (l *observableLogger) Debug(args ...any) {
   105  	l.DebugContext(context.Background(), args...)
   106  }
   107  
   108  func (l *observableLogger) Info(args ...any) {
   109  	l.InfoContext(context.Background(), args...)
   110  }
   111  
   112  func (l *observableLogger) Warn(args ...any) {
   113  	l.WarnContext(context.Background(), args...)
   114  }
   115  
   116  func (l *observableLogger) Error(args ...any) {
   117  	l.ErrorContext(context.Background(), args...)
   118  }
   119  
   120  func (l *observableLogger) Fatal(args ...any) {
   121  	l.FatalContext(context.Background(), args...)
   122  }
   123  
   124  func (l *observableLogger) Panic(args ...any) {
   125  	l.PanicContext(context.Background(), args...)
   126  }
   127  
   128  func (l *observableLogger) TraceContext(ctx context.Context, args ...any) {
   129  	l.Log(ctx, LevelTrace, args)
   130  }
   131  
   132  func (l *observableLogger) DebugContext(ctx context.Context, args ...any) {
   133  	l.Log(ctx, LevelDebug, args)
   134  }
   135  
   136  func (l *observableLogger) InfoContext(ctx context.Context, args ...any) {
   137  	l.Log(ctx, LevelInfo, args)
   138  }
   139  
   140  func (l *observableLogger) WarnContext(ctx context.Context, args ...any) {
   141  	l.Log(ctx, LevelWarn, args)
   142  }
   143  
   144  func (l *observableLogger) ErrorContext(ctx context.Context, args ...any) {
   145  	l.Log(ctx, LevelError, args)
   146  }
   147  
   148  func (l *observableLogger) FatalContext(ctx context.Context, args ...any) {
   149  	l.Log(ctx, LevelFatal, args)
   150  }
   151  
   152  func (l *observableLogger) PanicContext(ctx context.Context, args ...any) {
   153  	l.Log(ctx, LevelPanic, args)
   154  }