log.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. package log
  2. //go:generate go run $GOPATH/src/v2ray.com/core/common/errors/errorgen/main.go -pkg log -path App,Log
  3. import (
  4. "context"
  5. "sync"
  6. "v2ray.com/core"
  7. "v2ray.com/core/common"
  8. "v2ray.com/core/common/log"
  9. )
  10. // Instance is an app.Application that handles logs.
  11. type Instance struct {
  12. sync.RWMutex
  13. config *Config
  14. accessLogger log.Handler
  15. errorLogger log.Handler
  16. active bool
  17. }
  18. // New creates a new log.Instance based on the given config.
  19. func New(ctx context.Context, config *Config) (*Instance, error) {
  20. g := &Instance{
  21. config: config,
  22. active: true,
  23. }
  24. v := core.FromContext(ctx)
  25. if v != nil {
  26. common.Must(v.RegisterFeature((*log.Handler)(nil), g))
  27. }
  28. return g, nil
  29. }
  30. func (g *Instance) initAccessLogger() error {
  31. switch g.config.AccessLogType {
  32. case LogType_File:
  33. creator, err := log.CreateFileLogWriter(g.config.AccessLogPath)
  34. if err != nil {
  35. return err
  36. }
  37. g.accessLogger = log.NewLogger(creator)
  38. case LogType_Console:
  39. g.accessLogger = log.NewLogger(log.CreateStdoutLogWriter())
  40. default:
  41. }
  42. return nil
  43. }
  44. func (g *Instance) initErrorLogger() error {
  45. switch g.config.ErrorLogType {
  46. case LogType_File:
  47. creator, err := log.CreateFileLogWriter(g.config.ErrorLogPath)
  48. if err != nil {
  49. return err
  50. }
  51. g.errorLogger = log.NewLogger(creator)
  52. case LogType_Console:
  53. g.errorLogger = log.NewLogger(log.CreateStdoutLogWriter())
  54. default:
  55. }
  56. return nil
  57. }
  58. func (*Instance) Type() interface{} {
  59. return (*Instance)(nil)
  60. }
  61. // Start implements app.Application.Start().
  62. func (g *Instance) Start() error {
  63. newError("Logger starting").AtDebug().WriteToLog()
  64. g.Lock()
  65. defer g.Unlock()
  66. if g.active {
  67. return nil
  68. }
  69. g.active = true
  70. if err := g.initAccessLogger(); err != nil {
  71. return newError("failed to initialize access logger").Base(err).AtWarning()
  72. }
  73. if err := g.initErrorLogger(); err != nil {
  74. return newError("failed to initialize error logger").Base(err).AtWarning()
  75. }
  76. log.RegisterHandler(g)
  77. return nil
  78. }
  79. // Handle implements log.Handler.
  80. func (g *Instance) Handle(msg log.Message) {
  81. g.RLock()
  82. defer g.RUnlock()
  83. if !g.active {
  84. return
  85. }
  86. switch msg := msg.(type) {
  87. case *log.AccessMessage:
  88. if g.accessLogger != nil {
  89. g.accessLogger.Handle(msg)
  90. }
  91. case *log.GeneralMessage:
  92. if g.errorLogger != nil && msg.Severity <= g.config.ErrorLogLevel {
  93. g.errorLogger.Handle(msg)
  94. }
  95. default:
  96. // Swallow
  97. }
  98. }
  99. // Close implement app.Application.Close().
  100. func (g *Instance) Close() error {
  101. newError("Logger closing").AtDebug().WriteToLog()
  102. g.Lock()
  103. defer g.Unlock()
  104. if !g.active {
  105. return nil
  106. }
  107. g.active = false
  108. common.Close(g.accessLogger)
  109. common.Close(g.errorLogger)
  110. return nil
  111. }
  112. func init() {
  113. common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
  114. return New(ctx, config.(*Config))
  115. }))
  116. }