-
Notifications
You must be signed in to change notification settings - Fork 0
/
log.go
154 lines (125 loc) · 2.99 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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package log
//go:generate go run $GOPATH/src/v2ray.com/core/common/errors/errorgen/main.go -pkg log -path App,Log
import (
"context"
"sync"
"v2ray.com/core"
"v2ray.com/core/common"
"v2ray.com/core/common/log"
)
// Instance is a log.Handler that handles logs.
type Instance struct {
sync.RWMutex
config *Config
accessLogger log.Handler
errorLogger log.Handler
active bool
}
// New creates a new log.Instance based on the given config.
func New(ctx context.Context, config *Config) (*Instance, error) {
g := &Instance{
config: config,
active: false,
}
log.RegisterHandler(g)
v := core.FromContext(ctx)
if v != nil {
common.Must(v.RegisterFeature((*log.Handler)(nil), g))
}
return g, nil
}
func (g *Instance) initAccessLogger() error {
switch g.config.AccessLogType {
case LogType_File:
creator, err := log.CreateFileLogWriter(g.config.AccessLogPath)
if err != nil {
return err
}
g.accessLogger = log.NewLogger(creator)
case LogType_Console:
g.accessLogger = log.NewLogger(log.CreateStdoutLogWriter())
default:
}
return nil
}
func (g *Instance) initErrorLogger() error {
switch g.config.ErrorLogType {
case LogType_File:
creator, err := log.CreateFileLogWriter(g.config.ErrorLogPath)
if err != nil {
return err
}
g.errorLogger = log.NewLogger(creator)
case LogType_Console:
g.errorLogger = log.NewLogger(log.CreateStdoutLogWriter())
default:
}
return nil
}
// Type implements common.HasType.
func (*Instance) Type() interface{} {
return (*Instance)(nil)
}
func (g *Instance) startInternal() error {
g.Lock()
defer g.Unlock()
if g.active {
return nil
}
g.active = true
if err := g.initAccessLogger(); err != nil {
return newError("failed to initialize access logger").Base(err).AtWarning()
}
if err := g.initErrorLogger(); err != nil {
return newError("failed to initialize error logger").Base(err).AtWarning()
}
return nil
}
// Start implements common.Runnable.Start().
func (g *Instance) Start() error {
if err := g.startInternal(); err != nil {
return err
}
newError("Logger started").AtDebug().WriteToLog()
return nil
}
// Handle implements log.Handler.
func (g *Instance) Handle(msg log.Message) {
g.RLock()
defer g.RUnlock()
if !g.active {
return
}
switch msg := msg.(type) {
case *log.AccessMessage:
if g.accessLogger != nil {
g.accessLogger.Handle(msg)
}
case *log.GeneralMessage:
if g.errorLogger != nil && msg.Severity <= g.config.ErrorLogLevel {
g.errorLogger.Handle(msg)
}
default:
// Swallow
}
}
// Close implements common.Closable.Close().
func (g *Instance) Close() error {
newError("Logger closing").AtDebug().WriteToLog()
g.Lock()
defer g.Unlock()
if !g.active {
return nil
}
g.active = false
common.Close(g.accessLogger)
g.accessLogger = nil
common.Close(g.errorLogger)
g.errorLogger = nil
return nil
}
func init() {
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
return New(ctx, config.(*Config))
}))
}