package file import ( "fmt" "io" "os" "path/filepath" "time" "github.com/juju/errors" "github.com/sirupsen/logrus" rotatelogs "github.com/lestrrat-go/file-rotatelogs" ) // NewHook will create a File Hook for logrus. func NewHook(c *ConfigStruct) (logrus.Hook, error) { err := c.IsValid() if err != nil { return nil, errors.Trace(err) } var w io.Writer if c.Rotate { rotateTime, _ := time.ParseDuration(*c.RotateTime) // let's construct log rotator options rotateOptions := []rotatelogs.Option{ rotatelogs.WithLinkName(c.Filename), rotatelogs.WithRotationTime(rotateTime), } if c.RotateMaxAge != nil { rotateMaxAge, _ := time.ParseDuration(*c.RotateMaxAge) rotateOptions = append(rotateOptions, rotatelogs.WithMaxAge(rotateMaxAge)) } else if c.RotateMaxFile != nil { rotateOptions = append( rotateOptions, rotatelogs.WithRotationCount(uint(*c.RotateMaxFile)), rotatelogs.WithMaxAge(-1), ) } w, err = rotatelogs.New( fmt.Sprintf("%s.%%Y%%m%%d%%H%%M", c.Filename), rotateOptions..., ) if err != nil { return nil, errors.Trace(err) } } else { dirname := filepath.Dir(c.Filename) if err := os.MkdirAll(dirname, 0750); err != nil { return nil, errors.NewNotSupported(err, fmt.Sprintf("failed to create directory %s", dirname)) } // if we got here, then we need to create a file fh, err := os.OpenFile(c.Filename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600) if err != nil { return nil, errors.NewNotSupported(err, fmt.Sprintf("failed to open file %s", c.Filename)) } w = fh } h := NewAsyncFileHook(w) return h, nil }