From 733440cf3dd5f2dc2e27cc1483bf139eeb13cefd Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Tue, 1 Nov 2016 14:22:37 +0000 Subject: [PATCH] GZip logs by default --- src/github.com/matrix-org/go-neb/goneb.go | 2 +- vendor/manifest | 4 +- .../github.com/matrix-org/dugong/fshook.go | 46 +++++++++++++++++-- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/github.com/matrix-org/go-neb/goneb.go b/src/github.com/matrix-org/go-neb/goneb.go index 6f1e75f..eef917f 100644 --- a/src/github.com/matrix-org/go-neb/goneb.go +++ b/src/github.com/matrix-org/go-neb/goneb.go @@ -224,7 +224,7 @@ func main() { filepath.Join(e.LogDir, "info.log"), filepath.Join(e.LogDir, "warn.log"), filepath.Join(e.LogDir, "error.log"), - nil, &dugong.DailyRotationSchedule{}, + nil, &dugong.DailyRotationSchedule{GZip: true}, )) } diff --git a/vendor/manifest b/vendor/manifest index 0f2e1da..7ef95ff 100644 --- a/vendor/manifest +++ b/vendor/manifest @@ -132,7 +132,7 @@ { "importpath": "github.com/matrix-org/dugong", "repository": "https://github.com/matrix-org/dugong", - "revision": "07b01e0bea3c53627f5a3fc9c5f36ad145a4b086", + "revision": "193b8f88e381d12f2d53023fba25e43fc81dc5ac", "branch": "master" }, { @@ -314,4 +314,4 @@ "branch": "v2" } ] -} +} \ No newline at end of file diff --git a/vendor/src/github.com/matrix-org/dugong/fshook.go b/vendor/src/github.com/matrix-org/dugong/fshook.go index 8081dc1..be539ab 100644 --- a/vendor/src/github.com/matrix-org/dugong/fshook.go +++ b/vendor/src/github.com/matrix-org/dugong/fshook.go @@ -1,9 +1,12 @@ package dugong import ( + "compress/gzip" "fmt" log "github.com/Sirupsen/logrus" + "io" "os" + "path/filepath" "sync/atomic" "time" ) @@ -13,6 +16,8 @@ type RotationScheduler interface { // ShouldRotate returns true if the file should be rotated. The suffix to apply // to the filename is returned as the 2nd arg. ShouldRotate() (bool, string) + // ShouldGZip returns true if the file should be gzipped when it is rotated. + ShouldGZip() bool } // DailyRotationSchedule rotates log files daily. Logs are only rotated @@ -20,6 +25,7 @@ type RotationScheduler interface { // the process on Day 4 then stop it and start it on Day 7, no rotation will // occur when the process starts. type DailyRotationSchedule struct { + GZip bool rotateAfter *time.Time } @@ -53,6 +59,10 @@ func (rs *DailyRotationSchedule) ShouldRotate() (bool, string) { return false, "" } +func (rs *DailyRotationSchedule) ShouldGZip() bool { + return rs.GZip +} + // NewFSHook makes a logging hook that writes formatted // log entries to info, warn and error log files. Each log file // contains the messages with that severity or higher. If a formatter is @@ -107,7 +117,7 @@ func (hook *fsHook) writeEntry(entry *log.Entry) error { if hook.scheduler != nil { if should, suffix := hook.scheduler.ShouldRotate(); should { - if err := hook.rotate(suffix); err != nil { + if err := hook.rotate(suffix, hook.scheduler.ShouldGZip()); err != nil { return err } } @@ -150,13 +160,19 @@ func (hook *fsHook) Levels() []log.Level { // This requires no locking as the goroutine calling this is the same // one which does the logging. Since we don't hold open a handle to the // file when writing, a simple Rename is all that is required. -func (hook *fsHook) rotate(suffix string) error { +func (hook *fsHook) rotate(suffix string, gzip bool) error { for _, fpath := range []string{hook.errorPath, hook.warnPath, hook.infoPath} { - if err := os.Rename(fpath, fpath+suffix); err != nil { + logFilePath := fpath + suffix + if err := os.Rename(fpath, logFilePath); err != nil { // e.g. because there were no errors in error.log for this day fmt.Fprintf(os.Stderr, "Error rotating file %s: %v\n", fpath, err) + continue // don't try to gzip if we failed to rotate + } + if gzip { + if err := gzipFile(logFilePath); err != nil { + fmt.Fprintf(os.Stderr, "Failed to gzip file %s: %v\n", logFilePath, err) + } } - } return nil } @@ -170,3 +186,25 @@ func logToFile(path string, msg []byte) error { _, err = fd.Write(msg) return err } + +func gzipFile(fpath string) error { + reader, err := os.Open(fpath) + if err != nil { + return err + } + + filename := filepath.Base(fpath) + target := filepath.Join(filepath.Dir(fpath), filename+".gz") + writer, err := os.Create(target) + if err != nil { + return err + } + defer writer.Close() + + archiver := gzip.NewWriter(writer) + archiver.Name = filename + defer archiver.Close() + + _, err = io.Copy(archiver, reader) + return err +}