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