github.heygears.com/openimsdk/tools@v0.0.49/log/file-rotatelogs/internal/fileutil/fileutil.go (about) 1 package fileutil 2 3 import ( 4 "os" 5 "path/filepath" 6 "time" 7 8 "github.com/lestrrat-go/strftime" 9 "github.com/pkg/errors" 10 ) 11 12 // GenerateFn creates a file name based on the pattern, the current time, and the 13 // rotation time. 14 // 15 // The bsase time that is used to generate the filename is truncated based 16 // on the rotation time. 17 func GenerateFn(pattern *strftime.Strftime, clock interface{ Now() time.Time }, rotationTime time.Duration) string { 18 now := clock.Now() 19 20 // XXX HACK: Truncate only happens in UTC semantics, apparently. 21 // observed values for truncating given time with 86400 secs: 22 // 23 // before truncation: 2018/06/01 03:54:54 2018-06-01T03:18:00+09:00 24 // after truncation: 2018/06/01 03:54:54 2018-05-31T09:00:00+09:00 25 // 26 // This is really annoying when we want to truncate in local time 27 // so we hack: we take the apparent local time in the local zone, 28 // and pretend that it's in UTC. do our math, and put it back to 29 // the local zone 30 var base time.Time 31 if now.Location() != time.UTC { 32 base = time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), now.Nanosecond(), time.UTC) 33 base = base.Truncate(rotationTime) 34 base = time.Date(base.Year(), base.Month(), base.Day(), base.Hour(), base.Minute(), base.Second(), base.Nanosecond(), base.Location()) 35 } else { 36 base = now.Truncate(rotationTime) 37 } 38 39 return pattern.FormatString(base) 40 } 41 42 // CreateFile creates a new file in the given path, creating parent directories 43 // as necessary 44 func CreateFile(filename string) (*os.File, error) { 45 // make sure the dir is existed, eg: 46 // ./foo/bar/baz/hello.log must make sure ./foo/bar/baz is existed 47 dirname := filepath.Dir(filename) 48 if err := os.MkdirAll(dirname, 0755); err != nil { 49 return nil, errors.Wrapf(err, "failed to create directory %s", dirname) 50 } 51 // if we got here, then we need to create a file 52 fh, err := os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644) 53 if err != nil { 54 return nil, errors.Errorf("failed to open file %s: %s", filename, err) 55 } 56 57 return fh, nil 58 }