log.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. package log
  2. //go:generate go run github.com/xtls/xray-core/common/errors/errorgen
  3. import (
  4. "context"
  5. "sync"
  6. "github.com/xtls/xray-core/common"
  7. "github.com/xtls/xray-core/common/errors"
  8. "github.com/xtls/xray-core/common/log"
  9. )
  10. // Instance is a log.Handler 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. dns bool
  18. }
  19. // New creates a new log.Instance based on the given config.
  20. func New(ctx context.Context, config *Config) (*Instance, error) {
  21. g := &Instance{
  22. config: config,
  23. active: false,
  24. dns: config.EnableDnsLog,
  25. }
  26. log.RegisterHandler(g)
  27. // start logger instantly on inited
  28. // other modules would log during init
  29. if err := g.startInternal(); err != nil {
  30. return nil, err
  31. }
  32. errors.LogDebug(ctx, "Logger started")
  33. return g, nil
  34. }
  35. func (g *Instance) initAccessLogger() error {
  36. handler, err := createHandler(g.config.AccessLogType, HandlerCreatorOptions{
  37. Path: g.config.AccessLogPath,
  38. })
  39. if err != nil {
  40. return err
  41. }
  42. g.accessLogger = handler
  43. return nil
  44. }
  45. func (g *Instance) initErrorLogger() error {
  46. handler, err := createHandler(g.config.ErrorLogType, HandlerCreatorOptions{
  47. Path: g.config.ErrorLogPath,
  48. })
  49. if err != nil {
  50. return err
  51. }
  52. g.errorLogger = handler
  53. return nil
  54. }
  55. // Type implements common.HasType.
  56. func (*Instance) Type() interface{} {
  57. return (*Instance)(nil)
  58. }
  59. func (g *Instance) startInternal() error {
  60. g.Lock()
  61. defer g.Unlock()
  62. if g.active {
  63. return nil
  64. }
  65. g.active = true
  66. if err := g.initAccessLogger(); err != nil {
  67. return errors.New("failed to initialize access logger").Base(err).AtWarning()
  68. }
  69. if err := g.initErrorLogger(); err != nil {
  70. return errors.New("failed to initialize error logger").Base(err).AtWarning()
  71. }
  72. return nil
  73. }
  74. // Start implements common.Runnable.Start().
  75. func (g *Instance) Start() error {
  76. return g.startInternal()
  77. }
  78. // Handle implements log.Handler.
  79. func (g *Instance) Handle(msg log.Message) {
  80. g.RLock()
  81. defer g.RUnlock()
  82. if !g.active {
  83. return
  84. }
  85. switch msg := msg.(type) {
  86. case *log.AccessMessage:
  87. if g.accessLogger != nil {
  88. g.accessLogger.Handle(msg)
  89. }
  90. case *log.DNSLog:
  91. if g.dns && g.accessLogger != nil {
  92. g.accessLogger.Handle(msg)
  93. }
  94. case *log.GeneralMessage:
  95. if g.errorLogger != nil && msg.Severity <= g.config.ErrorLogLevel {
  96. g.errorLogger.Handle(msg)
  97. }
  98. default:
  99. // Swallow
  100. }
  101. }
  102. // Close implements common.Closable.Close().
  103. func (g *Instance) Close() error {
  104. errors.LogDebug(context.Background(), "Logger closing")
  105. g.Lock()
  106. defer g.Unlock()
  107. if !g.active {
  108. return nil
  109. }
  110. g.active = false
  111. common.Close(g.accessLogger)
  112. g.accessLogger = nil
  113. common.Close(g.errorLogger)
  114. g.errorLogger = nil
  115. return nil
  116. }
  117. func init() {
  118. common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
  119. return New(ctx, config.(*Config))
  120. }))
  121. }