Skip to content

Commit

Permalink
implement client log roation
Browse files Browse the repository at this point in the history
resolves #227
  • Loading branch information
sechmann committed Jul 14, 2023
1 parent cdcf3ca commit fd27d19
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 4 deletions.
2 changes: 1 addition & 1 deletion cmd/device-agent/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func main() {
handleSignals(programCancel)

logDir := filepath.Join(cfg.ConfigDir, "logs")
logger.SetupLogger(cfg.LogLevel, logDir, "agent.log")
logger.SetupLogger(cfg.LogLevel, logDir, "agent")

cfg.PopulateAgentConfiguration()

Expand Down
2 changes: 1 addition & 1 deletion cmd/helper/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func main() {

osConfigurator := helper.New(cfg)

logger.SetupLogger(cfg.LogLevel, config.LogDir, "helper.log")
logger.SetupLogger(cfg.LogLevel, config.LogDir, "helper")

log.Infof("naisdevice-helper %s starting up", version.Version)
log.Infof("configuration: %+v", cfg)
Expand Down
2 changes: 1 addition & 1 deletion cmd/systray/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func main() {
flag.Parse()

logDir := filepath.Join(cfg.ConfigDir, "logs")
logger.SetupLogger(cfg.LogLevel, logDir, "systray.log")
logger.SetupLogger(cfg.LogLevel, logDir, "systray")

conn, err := net.Dial("unix", cfg.GrpcAddress)
if err != nil {
Expand Down
Empty file added pkg/logger/agent_2020-12-31.log
Empty file.
15 changes: 14 additions & 1 deletion pkg/logger/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,31 @@ import (
"io"
"os"
"path/filepath"
"time"

log "github.com/sirupsen/logrus"
easy "github.com/t-tomalak/logrus-easy-formatter"
)

func SetupLogger(level, logDir, filename string) {
const logfileMaxAge = time.Hour * 24 * 7

func SetupLogger(level, logDir, name string) {
err := os.MkdirAll(logDir, 0o755)
if err != nil {
log.Fatalf("Creating log dir: %v", err)
}

err = deleteOldLogFiles(logDir, time.Now().Add(-logfileMaxAge))
if err != nil {
log.Errorf("unable to delete old log files: %v", err)
}

// clean up old log file without date
_ = os.Remove(filepath.Join(logDir, name+".log"))

filename := createLogFileName(name, time.Now())
logFilePath := filepath.Join(logDir, filename)

logFile, err := os.OpenFile(logFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o664)
if err != nil {
log.Fatalf("unable to open log file %s, error: %v", logFilePath, err)
Expand Down
109 changes: 109 additions & 0 deletions pkg/logger/logger_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package logger

import (
"os"
"testing"
"time"

"github.com/stretchr/testify/assert"
)

func TestRotate(t *testing.T) {

now, err := time.Parse(time.DateOnly, "2021-01-05")

week := time.Hour * 24 * 7

tests := []struct {
name string
expectDelete []string
expectKeep []string
}{
{
name: "don't touch other files",
expectDelete: []string{},
expectKeep: []string{
"other_file.log",
"other_file.log",
"agent_2021-01-05.log",
"agent_2019-99-99.log",
createLogFileName("other_systray", now.Add(-3*week)),
},
},
{
name: "keep young files",
expectDelete: []string{},
expectKeep: []string{
createLogFileName("agent", now.Add(-time.Hour*24*2)),
createLogFileName("systray", now.Add(-time.Hour*24*3)),
createLogFileName("helper", now.Add(-time.Hour*24*4)),
createLogFileName("helper", now.Add(-time.Hour*24*4)),
},
},
{
name: "delete old files",
expectDelete: []string{
createLogFileName("agent", now.Add(-2*week)),
createLogFileName("systray", now.Add(-3*week)),
createLogFileName("helper", now.Add(-512*week)),
},
expectKeep: []string{},
},
{
name: "mix of old and new files",
expectDelete: []string{
createLogFileName("agent", now.Add(-2*week)),
createLogFileName("systray", now.Add(-3*week)),
createLogFileName("helper", now.Add(-4*week)),
},
expectKeep: []string{
createLogFileName("agent", now.Add(-time.Hour*24*2)),
createLogFileName("systray", now.Add(-time.Hour*24*3)),
createLogFileName("helper", now.Add(-time.Hour*24*4)),
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
testDir := t.TempDir()
assert.NoError(t, err)

err := os.Chdir(testDir)
assert.NoError(t, err)

defer os.Chdir("..")

for _, fileName := range tt.expectDelete {
_, err = os.Create(fileName)
assert.NoError(t, err)
}

for _, fileName := range tt.expectKeep {
_, err = os.Create(fileName)
assert.NoError(t, err)
}

deleteOldLogFiles(testDir, now.Add(-time.Hour*24*7))

logdirFiles, err := os.ReadDir(".")
for _, shouldBeDeleted := range tt.expectDelete {
for _, f := range logdirFiles {
if f.Name() == shouldBeDeleted {
t.Errorf("file %q should be deleted", shouldBeDeleted)
}
}
}
outer:
for _, shouldBeKept := range tt.expectKeep {
for _, f := range logdirFiles {
if f.Name() == shouldBeKept {
continue outer
}
}
t.Errorf("file %q should be kept", shouldBeKept)
}
})
}

}
62 changes: 62 additions & 0 deletions pkg/logger/rotate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package logger

import (
"fmt"
"os"
"path/filepath"
"regexp"
"time"

log "github.com/sirupsen/logrus"
)

func deleteOldLogFiles(logDirPath string, treshold time.Time) error {
logFiles, err := os.ReadDir(logDirPath)
if err != nil {
return fmt.Errorf("open log dir: %w", err)
}

filesBeforeTreshold, err := filterOldFilesByDate(logFiles, treshold)
if err != nil {
return fmt.Errorf("filter old files: %w", err)
}

for _, logFile := range filesBeforeTreshold {
err := os.Remove(filepath.Join(logDirPath, logFile.Name()))
if err != nil {
return fmt.Errorf("remove log file: %w", err)
}
}

return nil
}

func filterOldFilesByDate(files []os.DirEntry, treshold time.Time) ([]os.DirEntry, error) {
var filesBeforeTreshold []os.DirEntry
filenameFormat := regexp.MustCompile(`^(agent|helper|systray)_(\d{4}-\d{2}-\d{2})\.log$`)

for _, logFile := range files {
matches := filenameFormat.FindAllStringSubmatch(logFile.Name(), -1)
if len(matches) != 1 || len(matches[0]) != 3 {
log.Debug("ignoring file: ", logFile)
continue
}

date := matches[0][2]
logDate, err := time.Parse(time.DateOnly, date)
if err != nil {
log.Errorf("filter old log files: unable to parse date: %q, err: %v", date, err)
continue
}

if logDate.Before(treshold) {
filesBeforeTreshold = append(filesBeforeTreshold, logFile)
}
}

return filesBeforeTreshold, nil
}

func createLogFileName(prefix string, t time.Time) string {
return fmt.Sprintf("%s_%s.log", prefix, t.Format(time.DateOnly))
}

0 comments on commit fd27d19

Please sign in to comment.