Added an impl for log-rotator

This commit is contained in:
Diptanu Choudhury 2016-01-13 17:16:25 -08:00
parent 4c7c7729bb
commit 9749ee301d
2 changed files with 111 additions and 0 deletions

71
client/driver/logs.go Normal file
View file

@ -0,0 +1,71 @@
package driver
import (
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"strings"
)
type LogRotator struct {
maxFiles int
fileSize int64
path string
fileName string
logFileIdx int
}
func NewLogRotor(path string, fileName string, maxFiles int, fileSize int64) (*LogRotator, error) {
files, err := ioutil.ReadDir(path)
if err != nil {
return nil, err
}
logFileIdx := 0
for _, f := range files {
if strings.HasPrefix(f.Name(), fileName) {
fileIdx := strings.TrimPrefix(f.Name(), fmt.Sprintf("%s.", fileName))
n, err := strconv.Atoi(fileIdx)
if err != nil {
continue
}
if n > logFileIdx {
logFileIdx = n
}
}
}
return &LogRotator{
maxFiles: maxFiles,
fileSize: fileSize,
path: path,
fileName: fileName,
logFileIdx: logFileIdx,
}, nil
}
func (l *LogRotator) Start(r io.Reader) error {
for {
logFileName := filepath.Join(l.path, fmt.Sprintf("%s.%d", l.fileName, l.logFileIdx))
f, err := os.OpenFile(logFileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 066)
if err != nil {
return err
}
remainingSize := l.fileSize
if finfo, err := os.Stat(logFileName); err == nil {
remainingSize = l.fileSize - finfo.Size()
}
if remainingSize < 1 {
l.logFileIdx = l.logFileIdx + 1
continue
}
if _, err := io.Copy(f, io.LimitReader(r, remainingSize)); err != nil {
return err
}
l.logFileIdx = l.logFileIdx + 1
}
return nil
}

View file

@ -0,0 +1,40 @@
package driver
import (
"os"
"path/filepath"
"testing"
)
func TestLogRotator_IncorrectPath(t *testing.T) {
incorrectPath := "/foo"
if _, err := NewLogRotor(incorrectPath, "redis.stdout", 10, 10); err == nil {
t.Fatal("expected err")
}
}
func TestLogRotator_FindCorrectIndex(t *testing.T) {
path := "/tmp/tmplogrator"
if err := os.Mkdir(path, os.ModeDir|os.ModePerm); err != nil {
t.Fatalf("test setup err: %v", err)
}
fname := filepath.Join(path, "redis.stdout.1")
if f, err := os.Create(fname); err == nil {
f.Close()
}
fname = filepath.Join(path, "redis.stdout.2")
if f, err := os.Create(fname); err == nil {
f.Close()
}
r, err := NewLogRotor(path, "redis.stdout", 10, 10)
if err != nil {
t.Fatalf("test setup err: %v", err)
}
if r.logFileIdx != 2 {
t.Fatalf("Expected log file idx: %v, actual: %v", 2, r.logFileIdx)
}
}