github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/app/log/log.go (about)

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