Skip to content
This repository has been archived by the owner on Jul 19, 2021. It is now read-only.

Commit

Permalink
Merge pull request #24 from lestrrat-go/topic/gh-23
Browse files Browse the repository at this point in the history
Calculate t using time zone offsets
  • Loading branch information
lestrrat authored Jun 2, 2018
2 parents 81893a5 + cb66a47 commit 3b4f34a
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 3 deletions.
23 changes: 20 additions & 3 deletions rotatelogs.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,26 @@ func New(p string, options ...Option) (*RotateLogs, error) {

func (rl *RotateLogs) genFilename() string {
now := rl.clock.Now()
diff := time.Duration(now.UnixNano()) % rl.rotationTime
t := now.Add(time.Duration(-1 * diff))
return rl.pattern.FormatString(t)

// XXX HACK: Truncate only happens in UTC semantics, apparently.
// observed values for truncating given time with 86400 secs:
//
// before truncation: 2018/06/01 03:54:54 2018-06-01T03:18:00+09:00
// after truncation: 2018/06/01 03:54:54 2018-05-31T09:00:00+09:00
//
// This is really annoying when we want to truncate in local time
// so we hack: we take the apparent local time in the local zone,
// and pretend that it's in UTC. do our math, and put it back to
// the local zone
var base time.Time
if now.Location() != time.UTC {
base = time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), now.Nanosecond(), time.UTC)
base = base.Truncate(time.Duration(rl.rotationTime))
base = time.Date(base.Year(), base.Month(), base.Day(), base.Hour(), base.Minute(), base.Second(), base.Nanosecond(), base.Location())
} else {
base = now.Truncate(time.Duration(rl.rotationTime))
}
return rl.pattern.FormatString(base)
}

// Write satisfies the io.Writer interface. It writes to the
Expand Down
54 changes: 54 additions & 0 deletions rotatelogs_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package rotatelogs_test

import (
"fmt"
"io"
"io/ioutil"
"log"
Expand Down Expand Up @@ -358,3 +359,56 @@ func TestRotationGenerationalNames(t *testing.T) {
defer rl.Close()
})
}

type ClockFunc func() time.Time

func (f ClockFunc) Now() time.Time {
return f()
}

func TestGHIssue23(t *testing.T) {
dir, err := ioutil.TempDir("", "file-rotatelogs-generational")
if !assert.NoError(t, err, `creating temporary directory should succeed`) {
return
}
defer os.RemoveAll(dir)

for _, locName := range []string{"Asia/Tokyo", "Pacific/Honolulu"} {
loc, _ := time.LoadLocation(locName)
tests := []struct {
Expected string
Clock rotatelogs.Clock
}{
{
Expected: filepath.Join(dir, strings.ToLower(strings.Replace(locName, "/", "_", -1)) + ".201806010000.log"),
Clock: ClockFunc(func() time.Time {
return time.Date(2018, 6, 1, 3, 18, 0, 0, loc)
}),
},
{
Expected: filepath.Join(dir, strings.ToLower(strings.Replace(locName, "/", "_", -1)) + ".201712310000.log"),
Clock: ClockFunc(func() time.Time {
return time.Date(2017, 12, 31, 23, 52, 0, 0, loc)
}),
},
}
for _, test := range tests {
t.Run(fmt.Sprintf("location = %s, time = %s", locName, test.Clock.Now().Format(time.RFC3339)), func(t *testing.T) {
template := strings.ToLower(strings.Replace(locName, "/", "_", -1)) + ".%Y%m%d%H%M.log"
rl, err := rotatelogs.New(
filepath.Join(dir, template),
rotatelogs.WithClock(test.Clock), // we're not using WithLocation, but it's the same thing
)
if !assert.NoError(t, err, "rotatelogs.New should succeed") {
return
}

t.Logf("expected %s", test.Expected)
rl.Rotate()
if !assert.Equal(t, test.Expected, rl.CurrentFileName(), "file names should match") {
return
}
})
}
}
}

0 comments on commit 3b4f34a

Please sign in to comment.