| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 | 
							- package log
 
- import (
 
- 	"context"
 
- 	"io"
 
- 	"os"
 
- 	"time"
 
- 	"github.com/sagernet/sing/common"
 
- 	F "github.com/sagernet/sing/common/format"
 
- 	"github.com/sagernet/sing/common/observable"
 
- 	"github.com/sagernet/sing/service/filemanager"
 
- )
 
- var _ Factory = (*defaultFactory)(nil)
 
- type defaultFactory struct {
 
- 	ctx               context.Context
 
- 	formatter         Formatter
 
- 	platformFormatter Formatter
 
- 	writer            io.Writer
 
- 	file              *os.File
 
- 	filePath          string
 
- 	platformWriter    PlatformWriter
 
- 	needObservable    bool
 
- 	level             Level
 
- 	subscriber        *observable.Subscriber[Entry]
 
- 	observer          *observable.Observer[Entry]
 
- }
 
- func NewDefaultFactory(
 
- 	ctx context.Context,
 
- 	formatter Formatter,
 
- 	writer io.Writer,
 
- 	filePath string,
 
- 	platformWriter PlatformWriter,
 
- 	needObservable bool,
 
- ) ObservableFactory {
 
- 	factory := &defaultFactory{
 
- 		ctx:       ctx,
 
- 		formatter: formatter,
 
- 		platformFormatter: Formatter{
 
- 			BaseTime:         formatter.BaseTime,
 
- 			DisableLineBreak: true,
 
- 		},
 
- 		writer:         writer,
 
- 		filePath:       filePath,
 
- 		platformWriter: platformWriter,
 
- 		needObservable: needObservable,
 
- 		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
 
- }
 
- func (f *defaultFactory) Start() error {
 
- 	if f.filePath != "" {
 
- 		logFile, err := filemanager.OpenFile(f.ctx, f.filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
 
- 		if err != nil {
 
- 			return err
 
- 		}
 
- 		f.writer = logFile
 
- 		f.file = logFile
 
- 	}
 
- 	return nil
 
- }
 
- func (f *defaultFactory) Close() error {
 
- 	return common.Close(
 
- 		common.PtrOrNil(f.file),
 
- 		f.observer,
 
- 	)
 
- }
 
- func (f *defaultFactory) Level() Level {
 
- 	return f.level
 
- }
 
- func (f *defaultFactory) SetLevel(level Level) {
 
- 	f.level = level
 
- }
 
- func (f *defaultFactory) Logger() ContextLogger {
 
- 	return f.NewLogger("")
 
- }
 
- func (f *defaultFactory) NewLogger(tag string) ContextLogger {
 
- 	return &observableLogger{f, tag}
 
- }
 
- func (f *defaultFactory) Subscribe() (subscription observable.Subscription[Entry], done <-chan struct{}, err error) {
 
- 	return f.observer.Subscribe()
 
- }
 
- func (f *defaultFactory) UnSubscribe(sub observable.Subscription[Entry]) {
 
- 	f.observer.UnSubscribe(sub)
 
- }
 
- var _ ContextLogger = (*observableLogger)(nil)
 
- type observableLogger struct {
 
- 	*defaultFactory
 
- 	tag string
 
- }
 
- func (l *observableLogger) Log(ctx context.Context, level Level, args []any) {
 
- 	level = OverrideLevelFromContext(level, ctx)
 
- 	if level > l.level {
 
- 		return
 
- 	}
 
- 	nowTime := time.Now()
 
- 	if l.needObservable {
 
- 		message, messageSimple := l.formatter.FormatWithSimple(ctx, level, l.tag, F.ToString(args...), nowTime)
 
- 		if level == LevelPanic {
 
- 			panic(message)
 
- 		}
 
- 		l.writer.Write([]byte(message))
 
- 		if level == LevelFatal {
 
- 			os.Exit(1)
 
- 		}
 
- 		l.subscriber.Emit(Entry{level, messageSimple})
 
- 	} else {
 
- 		message := l.formatter.Format(ctx, level, l.tag, F.ToString(args...), nowTime)
 
- 		if level == LevelPanic {
 
- 			panic(message)
 
- 		}
 
- 		l.writer.Write([]byte(message))
 
- 		if level == LevelFatal {
 
- 			os.Exit(1)
 
- 		}
 
- 	}
 
- 	if l.platformWriter != nil {
 
- 		l.platformWriter.WriteMessage(level, l.platformFormatter.Format(ctx, level, l.tag, F.ToString(args...), nowTime))
 
- 	}
 
- }
 
- func (l *observableLogger) Trace(args ...any) {
 
- 	l.TraceContext(context.Background(), args...)
 
- }
 
- func (l *observableLogger) Debug(args ...any) {
 
- 	l.DebugContext(context.Background(), args...)
 
- }
 
- func (l *observableLogger) Info(args ...any) {
 
- 	l.InfoContext(context.Background(), args...)
 
- }
 
- func (l *observableLogger) Warn(args ...any) {
 
- 	l.WarnContext(context.Background(), args...)
 
- }
 
- func (l *observableLogger) Error(args ...any) {
 
- 	l.ErrorContext(context.Background(), args...)
 
- }
 
- func (l *observableLogger) Fatal(args ...any) {
 
- 	l.FatalContext(context.Background(), args...)
 
- }
 
- func (l *observableLogger) Panic(args ...any) {
 
- 	l.PanicContext(context.Background(), args...)
 
- }
 
- func (l *observableLogger) TraceContext(ctx context.Context, args ...any) {
 
- 	l.Log(ctx, LevelTrace, args)
 
- }
 
- func (l *observableLogger) DebugContext(ctx context.Context, args ...any) {
 
- 	l.Log(ctx, LevelDebug, args)
 
- }
 
- func (l *observableLogger) InfoContext(ctx context.Context, args ...any) {
 
- 	l.Log(ctx, LevelInfo, args)
 
- }
 
- func (l *observableLogger) WarnContext(ctx context.Context, args ...any) {
 
- 	l.Log(ctx, LevelWarn, args)
 
- }
 
- func (l *observableLogger) ErrorContext(ctx context.Context, args ...any) {
 
- 	l.Log(ctx, LevelError, args)
 
- }
 
- func (l *observableLogger) FatalContext(ctx context.Context, args ...any) {
 
- 	l.Log(ctx, LevelFatal, args)
 
- }
 
- func (l *observableLogger) PanicContext(ctx context.Context, args ...any) {
 
- 	l.Log(ctx, LevelPanic, args)
 
- }
 
 
  |