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 }