github.com/v2fly/v2ray-core/v4@v4.45.2/app/log/log.go (about) 1 //go:build !confonly 2 // +build !confonly 3 4 package log 5 6 //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen 7 8 import ( 9 "context" 10 "sync" 11 12 "github.com/v2fly/v2ray-core/v4/common" 13 "github.com/v2fly/v2ray-core/v4/common/log" 14 ) 15 16 // Instance is a log.Handler that handles logs. 17 type Instance struct { 18 sync.RWMutex 19 config *Config 20 accessLogger log.Handler 21 errorLogger log.Handler 22 active bool 23 } 24 25 // New creates a new log.Instance based on the given config. 26 func New(ctx context.Context, config *Config) (*Instance, error) { 27 g := &Instance{ 28 config: config, 29 active: false, 30 } 31 log.RegisterHandler(g) 32 33 // start logger instantly on inited 34 // other modules would log during init 35 if err := g.startInternal(); err != nil { 36 return nil, err 37 } 38 39 newError("Logger started").AtDebug().WriteToLog() 40 return g, nil 41 } 42 43 func (g *Instance) initAccessLogger() error { 44 handler, err := createHandler(g.config.AccessLogType, HandlerCreatorOptions{ 45 Path: g.config.AccessLogPath, 46 }) 47 if err != nil { 48 return err 49 } 50 g.accessLogger = handler 51 return nil 52 } 53 54 func (g *Instance) initErrorLogger() error { 55 handler, err := createHandler(g.config.ErrorLogType, HandlerCreatorOptions{ 56 Path: g.config.ErrorLogPath, 57 }) 58 if err != nil { 59 return err 60 } 61 g.errorLogger = handler 62 return nil 63 } 64 65 // Type implements common.HasType. 66 func (*Instance) Type() interface{} { 67 return (*Instance)(nil) 68 } 69 70 func (g *Instance) startInternal() error { 71 g.Lock() 72 defer g.Unlock() 73 74 if g.active { 75 return nil 76 } 77 78 g.active = true 79 80 if err := g.initAccessLogger(); err != nil { 81 return newError("failed to initialize access logger").Base(err).AtWarning() 82 } 83 if err := g.initErrorLogger(); err != nil { 84 return newError("failed to initialize error logger").Base(err).AtWarning() 85 } 86 87 return nil 88 } 89 90 // Start implements common.Runnable.Start(). 91 func (g *Instance) Start() error { 92 return g.startInternal() 93 } 94 95 // Handle implements log.Handler. 96 func (g *Instance) Handle(msg log.Message) { 97 g.RLock() 98 defer g.RUnlock() 99 100 if !g.active { 101 return 102 } 103 104 switch msg := msg.(type) { 105 case *log.AccessMessage: 106 if g.accessLogger != nil { 107 g.accessLogger.Handle(msg) 108 } 109 case *log.GeneralMessage: 110 if g.errorLogger != nil && msg.Severity <= g.config.ErrorLogLevel { 111 g.errorLogger.Handle(msg) 112 } 113 default: 114 // Swallow 115 } 116 } 117 118 // Close implements common.Closable.Close(). 119 func (g *Instance) Close() error { 120 newError("Logger closing").AtDebug().WriteToLog() 121 122 g.Lock() 123 defer g.Unlock() 124 125 if !g.active { 126 return nil 127 } 128 129 g.active = false 130 131 common.Close(g.accessLogger) 132 g.accessLogger = nil 133 134 common.Close(g.errorLogger) 135 g.errorLogger = nil 136 137 return nil 138 } 139 140 func init() { 141 common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { 142 return New(ctx, config.(*Config)) 143 })) 144 }