github.com/Aoi-hosizora/ahlib-more@v1.5.1-0.20230404072844-256112befaf6/xlogrus/rotation_hook.go (about)

     1  package xlogrus
     2  
     3  import (
     4  	"github.com/Aoi-hosizora/ahlib-more/xrotation"
     5  	"github.com/sirupsen/logrus"
     6  	"time"
     7  )
     8  
     9  // rotationHookOptions is a type of RotationHook's option, each field can be set by RotationHookOption function type.
    10  type rotationHookOptions struct {
    11  	formatter logrus.Formatter
    12  	level     logrus.Level
    13  }
    14  
    15  // RotationHookOption represents an option type for RotationHook's option, can be created by WithXXX functions.
    16  type RotationHookOption func(*rotationHookOptions)
    17  
    18  // WithRotateFormatter creates an RotationHookOption to specify logrus.Formatter for rotation, defaults to logrus.JSONFormatter with time.RFC3339.
    19  func WithRotateFormatter(formatter logrus.Formatter) RotationHookOption {
    20  	return func(o *rotationHookOptions) {
    21  		o.formatter = formatter
    22  	}
    23  }
    24  
    25  // WithRotateLevel creates an RotationHookOption to specify the lowest logrus.Level for rotation, defaults to logrus.WarnLevel.
    26  func WithRotateLevel(level logrus.Level) RotationHookOption {
    27  	return func(o *rotationHookOptions) {
    28  		if level < logrus.PanicLevel || level > logrus.TraceLevel {
    29  			level = logrus.PanicLevel // -> 0
    30  		}
    31  		o.level = level
    32  	}
    33  }
    34  
    35  // RotationHook represents a logrus.Hook for xrotation.RotationLogger, which will gets automatically rotated when new file created.
    36  type RotationHook struct {
    37  	option   *rotationHookOptions
    38  	rotation *xrotation.RotationLogger
    39  }
    40  
    41  var _ logrus.Hook = (*RotationHook)(nil)
    42  
    43  const (
    44  	panicNilRotationLogger = "xlogrus: nil xrotation.RotationLogger"
    45  )
    46  
    47  // NewRotationHook creates a RotationHook with given xrotation.RotationLogger and RotationHookOption-s.
    48  //
    49  // Example:
    50  // 	l := logrus.New()
    51  // 	l.SetLevel(logrus.TraceLevel)
    52  // 	rotation, _ := xrotation.New(xrotation.WithFilenamePattern("logger.%Y%m%d.log"), ...)
    53  // 	hook, _ := NewRotationHook(
    54  // 		rotation,
    55  // 		WithRotateFormatter(&logrus.JSONFormatter{TimestampFormat: "2006-01-02 15:04:05"}),
    56  // 		WithRotateLevel(logrus.WarnLevel),
    57  // 	)
    58  // 	l.AddHook(hook)
    59  func NewRotationHook(rotation *xrotation.RotationLogger, options ...RotationHookOption) *RotationHook {
    60  	if rotation == nil {
    61  		panic(panicNilRotationLogger)
    62  	}
    63  	opt := &rotationHookOptions{level: logrus.Level(4294967295)} // -> as default level
    64  	for _, o := range options {
    65  		if o != nil {
    66  			o(opt)
    67  		}
    68  	}
    69  	if opt.formatter == nil {
    70  		opt.formatter = &logrus.JSONFormatter{TimestampFormat: time.RFC3339}
    71  	}
    72  	if opt.level == 4294967295 {
    73  		opt.level = logrus.WarnLevel
    74  	}
    75  	return &RotationHook{rotation: rotation, option: opt}
    76  }
    77  
    78  // Levels implements the logrus.Hook interface.
    79  func (r *RotationHook) Levels() []logrus.Level {
    80  	return logrus.AllLevels[:r.option.level+1]
    81  }
    82  
    83  // Fire writes logrus.Entry data to given xrotation.RotationLogger, and implements the logrus.Hook interface.
    84  func (r *RotationHook) Fire(entry *logrus.Entry) (err error) {
    85  	bs, err := r.option.formatter.Format(entry)
    86  	if err == nil {
    87  		_, _ = r.rotation.Write(bs)
    88  	}
    89  	return nil // ignore error
    90  }