Skip to content

Commit

Permalink
Merge 1724b13 into ac5388f
Browse files Browse the repository at this point in the history
  • Loading branch information
yuuki committed Sep 10, 2018
2 parents ac5388f + 1724b13 commit bf00c27
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 14 deletions.
47 changes: 41 additions & 6 deletions check-log/lib/check-log.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package checklog
import (
"bufio"
"crypto/md5"
"encoding/json"
"fmt"
"io"
"io/ioutil"
Expand Down Expand Up @@ -275,7 +276,7 @@ func (opts *logOpts) searchLog(logFile string) (int64, int64, string, error) {
}

if !opts.NoState {
err = writeBytesToSkip(stateFile, skipBytes)
err = saveState(stateFile, &state{SkipBytes: skipBytes})
if err != nil {
log.Printf("writeByteToSkip failed: %s\n", err.Error())
}
Expand Down Expand Up @@ -346,20 +347,53 @@ func (opts *logOpts) match(line string) (bool, []string) {
return true, matches
}

type state struct {
SkipBytes int64 `json:"skip_bytes"`
}

func loadState(fname string) (*state, error) {
state := &state{}
_, err := os.Stat(fname)
if err == nil { // state file exists
b, err := ioutil.ReadFile(fname)
if err == nil {
err = json.Unmarshal(b, state)
}
return state, err
}
return nil, nil
}

var stateRe = regexp.MustCompile(`^([a-zA-Z]):[/\\]`)

func getStateFile(stateDir, f string, args []string) string {
return filepath.Join(
stateDir,
fmt.Sprintf(
"%s-%x",
"%s-%x.json",
stateRe.ReplaceAllString(f, `$1`+string(filepath.Separator)),
md5.Sum([]byte(strings.Join(args, " "))),
),
)
}

func getBytesToSkip(f string) (int64, error) {
state, err := loadState(f)
if err != nil {
return 0, err
}
if state != nil {
// json file exists
return state.SkipBytes, nil
}
// Fallback to read old style status file
// for backward compatibility.
// Once saved as new style file, the following will be unreachable.
oldf := strings.TrimSuffix(f, ".json")
return getBytesToSkipOld(oldf)
}

func getBytesToSkipOld(f string) (int64, error) {
_, err := os.Stat(f)
if err != nil {
return 0, nil
Expand All @@ -368,19 +402,20 @@ func getBytesToSkip(f string) (int64, error) {
if err != nil {
return 0, err
}

i, err := strconv.ParseInt(strings.Trim(string(b), " \r\n"), 10, 64)
if err != nil {
log.Printf("failed to getBytesToSkip (ignoring): %s", err)
}
return i, nil
}

func writeBytesToSkip(f string, num int64) error {
err := os.MkdirAll(filepath.Dir(f), 0755)
if err != nil {
func saveState(f string, state *state) error {
b, _ := json.Marshal(state)
if err := os.MkdirAll(filepath.Dir(f), 0755); err != nil {
return err
}
return writeFileAtomically(f, []byte(fmt.Sprintf("%d", num)))
return writeFileAtomically(f, b)
}

func writeFileAtomically(f string, contents []byte) error {
Expand Down
35 changes: 27 additions & 8 deletions check-log/lib/check-log_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,42 @@ import (

func TestGetStateFile(t *testing.T) {
sPath := getStateFile("/var/lib", "C:/Windows/hoge", []string{})
assert.Equal(t, "/var/lib/C/Windows/hoge-d41d8cd98f00b204e9800998ecf8427e", filepath.ToSlash(sPath), "drive letter should be cared")
assert.Equal(t, "/var/lib/C/Windows/hoge-d41d8cd98f00b204e9800998ecf8427e.json", filepath.ToSlash(sPath), "drive letter should be cared")

sPath = getStateFile("/var/lib", "/linux/hoge", []string{})
assert.Equal(t, "/var/lib/linux/hoge-d41d8cd98f00b204e9800998ecf8427e", filepath.ToSlash(sPath), "arguments should be cared")
assert.Equal(t, "/var/lib/linux/hoge-d41d8cd98f00b204e9800998ecf8427e.json", filepath.ToSlash(sPath), "arguments should be cared")

sPath = getStateFile("/var/lib", "/linux/hoge", []string{"aa", "BB"})
assert.Equal(t, "/var/lib/linux/hoge-c508092e97c59149a8644827e066ca83", filepath.ToSlash(sPath), "arguments should be cared")
assert.Equal(t, "/var/lib/linux/hoge-c508092e97c59149a8644827e066ca83.json", filepath.ToSlash(sPath), "arguments should be cared")
}

func TestWriteBytesToSkip(t *testing.T) {
f := ".tmp/fuga/piyo"
err := writeBytesToSkip(f, 15)
func TestSaveState(t *testing.T) {
f := ".tmp/fuga/piyo.json"
err := saveState(f, &state{SkipBytes: 15})
assert.Equal(t, err, nil, "err should be nil")

skipBytes, err := getBytesToSkip(f)
state, err := loadState(f)
assert.Equal(t, err, nil, "err should be nil")
assert.Equal(t, skipBytes, int64(15))
assert.Equal(t, state.SkipBytes, int64(15))
}

func TestGetBytesToSkip(t *testing.T) {
// fallback testing for backward compatibility
oldf := ".tmp/fuga/piyo"
newf := ".tmp/fuga/piyo.json"
state := &state{SkipBytes: 15}
writeFileAtomically(oldf, []byte(fmt.Sprintf("%d", state.SkipBytes)))
defer os.RemoveAll(".tmp")

n, err := getBytesToSkip(newf)
assert.Equal(t, err, nil, "err should be nil")
assert.Equal(t, state.SkipBytes, n)

saveState(newf, state)

n, err = getBytesToSkip(newf)
assert.Equal(t, err, nil, "err should be nil")
assert.Equal(t, state.SkipBytes, n)
}

func TestSearchReader(t *testing.T) {
Expand Down

0 comments on commit bf00c27

Please sign in to comment.