github.com/inazumav/sing-box@v0.0.0-20230926072359-ab51429a14f1/log/observable.go (about)

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