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

     1  package log
     2  
     3  import (
     4  	"io"
     5  	"os"
     6  	"time"
     7  
     8  	C "github.com/sagernet/sing-box/constant"
     9  	"github.com/sagernet/sing-box/option"
    10  	"github.com/sagernet/sing/common"
    11  	E "github.com/sagernet/sing/common/exceptions"
    12  )
    13  
    14  type factoryWithFile struct {
    15  	Factory
    16  	file *os.File
    17  }
    18  
    19  func (f *factoryWithFile) Close() error {
    20  	return common.Close(
    21  		f.Factory,
    22  		common.PtrOrNil(f.file),
    23  	)
    24  }
    25  
    26  type observableFactoryWithFile struct {
    27  	ObservableFactory
    28  	file *os.File
    29  }
    30  
    31  func (f *observableFactoryWithFile) Close() error {
    32  	return common.Close(
    33  		f.ObservableFactory,
    34  		common.PtrOrNil(f.file),
    35  	)
    36  }
    37  
    38  type Options struct {
    39  	Options        option.LogOptions
    40  	Observable     bool
    41  	DefaultWriter  io.Writer
    42  	BaseTime       time.Time
    43  	PlatformWriter io.Writer
    44  }
    45  
    46  func New(options Options) (Factory, error) {
    47  	logOptions := options.Options
    48  
    49  	if logOptions.Disabled {
    50  		return NewNOPFactory(), nil
    51  	}
    52  
    53  	var logFile *os.File
    54  	var logWriter io.Writer
    55  
    56  	switch logOptions.Output {
    57  	case "":
    58  		logWriter = options.DefaultWriter
    59  		if logWriter == nil {
    60  			logWriter = os.Stderr
    61  		}
    62  	case "stderr":
    63  		logWriter = os.Stderr
    64  	case "stdout":
    65  		logWriter = os.Stdout
    66  	default:
    67  		var err error
    68  		logFile, err = os.OpenFile(C.BasePath(logOptions.Output), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
    69  		if err != nil {
    70  			return nil, err
    71  		}
    72  		logWriter = logFile
    73  	}
    74  	logFormatter := Formatter{
    75  		BaseTime:         options.BaseTime,
    76  		DisableColors:    logOptions.DisableColor || logFile != nil,
    77  		DisableTimestamp: !logOptions.Timestamp && logFile != nil,
    78  		FullTimestamp:    logOptions.Timestamp,
    79  		TimestampFormat:  "-0700 2006-01-02 15:04:05",
    80  	}
    81  	var factory Factory
    82  	if options.Observable {
    83  		factory = NewObservableFactory(logFormatter, logWriter, options.PlatformWriter)
    84  	} else {
    85  		factory = NewFactory(logFormatter, logWriter, options.PlatformWriter)
    86  	}
    87  	if logOptions.Level != "" {
    88  		logLevel, err := ParseLevel(logOptions.Level)
    89  		if err != nil {
    90  			return nil, E.Cause(err, "parse log level")
    91  		}
    92  		factory.SetLevel(logLevel)
    93  	} else {
    94  		factory.SetLevel(LevelTrace)
    95  	}
    96  	if logFile != nil {
    97  		if options.Observable {
    98  			factory = &observableFactoryWithFile{
    99  				ObservableFactory: factory.(ObservableFactory),
   100  				file:              logFile,
   101  			}
   102  		} else {
   103  			factory = &factoryWithFile{
   104  				Factory: factory,
   105  				file:    logFile,
   106  			}
   107  		}
   108  	}
   109  	return factory, nil
   110  }