diff --git a/caddy/caddymain/run.go b/caddy/caddymain/run.go index f7269c88c..03c11a128 100644 --- a/caddy/caddymain/run.go +++ b/caddy/caddymain/run.go @@ -56,6 +56,8 @@ func init() { flag.StringVar(&certmagic.Email, "email", "", "Default ACME CA account email address") flag.DurationVar(&certmagic.HTTPTimeout, "catimeout", certmagic.HTTPTimeout, "Default ACME CA HTTP timeout") flag.StringVar(&logfile, "log", "", "Process log file") + flag.IntVar(&logRollMB, "log-roll-mb", 100, "Roll process log when it reaches this many megabytes (0 to disable rolling)") + flag.BoolVar(&logRollCompress, "log-roll-compress", true, "Gzip-compress rolled process log files") flag.StringVar(&caddy.PidFile, "pidfile", "", "Path to write pid file") flag.BoolVar(&caddy.Quiet, "quiet", false, "Quiet mode (no initialization output)") flag.StringVar(&revoke, "revoke", "", "Hostname for which to revoke the certificate") @@ -84,12 +86,26 @@ func Run() { case "": log.SetOutput(ioutil.Discard) default: - log.SetOutput(&lumberjack.Logger{ - Filename: logfile, - MaxSize: 100, - MaxAge: 14, - MaxBackups: 10, - }) + if logRollMB > 0 { + log.SetOutput(&lumberjack.Logger{ + Filename: logfile, + MaxSize: logRollMB, + MaxAge: 14, + MaxBackups: 10, + Compress: logRollCompress, + }) + } else { + err := os.MkdirAll(filepath.Dir(logfile), 0755) + if err != nil { + mustLogFatalf("%v", err) + } + f, err := os.OpenFile(logfile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + mustLogFatalf("%v", err) + } + // don't close file; log should be writeable for duration of process + log.SetOutput(f) + } } //Load all additional envs as soon as possible @@ -501,6 +517,8 @@ var ( cpu string envFile string logfile string + logRollMB int + logRollCompress bool revoke string version bool plugins bool diff --git a/caddyhttp/httpserver/logger.go b/caddyhttp/httpserver/logger.go index 1fc262419..cd2c26674 100644 --- a/caddyhttp/httpserver/logger.go +++ b/caddyhttp/httpserver/logger.go @@ -23,7 +23,7 @@ import ( "strings" "sync" - "github.com/hashicorp/go-syslog" + gsyslog "github.com/hashicorp/go-syslog" "github.com/mholt/caddy" ) @@ -162,7 +162,7 @@ selectwriter: return err } - if l.Roller != nil { + if l.Roller != nil && !l.Roller.Disabled { file.Close() l.Roller.Filename = l.Output l.writer = l.Roller.GetLogWriter() diff --git a/caddyhttp/httpserver/roller.go b/caddyhttp/httpserver/roller.go index 8f259ee9c..a87828fb2 100644 --- a/caddyhttp/httpserver/roller.go +++ b/caddyhttp/httpserver/roller.go @@ -20,11 +20,12 @@ import ( "path/filepath" "strconv" - "gopkg.in/natefinch/lumberjack.v2" + lumberjack "gopkg.in/natefinch/lumberjack.v2" ) // LogRoller implements a type that provides a rolling logger. type LogRoller struct { + Disabled bool Filename string MaxSize int MaxAge int @@ -66,10 +67,11 @@ func IsLogRollerSubdirective(subdir string) bool { return subdir == directiveRotateSize || subdir == directiveRotateAge || subdir == directiveRotateKeep || - subdir == directiveRotateCompress + subdir == directiveRotateCompress || + subdir == directiveRotateDisable } -var invalidRollerParameterErr = errors.New("invalid roller parameter") +var errInvalidRollParameter = errors.New("invalid roller parameter") // ParseRoller parses roller contents out of c. func ParseRoller(l *LogRoller, what string, where ...string) error { @@ -79,16 +81,16 @@ func ParseRoller(l *LogRoller, what string, where ...string) error { // rotate_compress doesn't accept any parameters. // others only accept one parameter - if (what == directiveRotateCompress && len(where) != 0) || - (what != directiveRotateCompress && len(where) != 1) { - return invalidRollerParameterErr + if ((what == directiveRotateCompress || what == directiveRotateDisable) && len(where) != 0) || + ((what != directiveRotateCompress && what != directiveRotateDisable) && len(where) != 1) { + return errInvalidRollParameter } var ( value int err error ) - if what != directiveRotateCompress { + if what != directiveRotateCompress && what != directiveRotateDisable { value, err = strconv.Atoi(where[0]) if err != nil { return err @@ -96,6 +98,8 @@ func ParseRoller(l *LogRoller, what string, where ...string) error { } switch what { + case directiveRotateDisable: + l.Disabled = true case directiveRotateSize: l.MaxSize = value case directiveRotateAge: @@ -127,6 +131,7 @@ const ( // defaultRotateKeep is 10 files. defaultRotateKeep = 10 + directiveRotateDisable = "rotate_disable" directiveRotateSize = "rotate_size" directiveRotateAge = "rotate_age" directiveRotateKeep = "rotate_keep" @@ -134,5 +139,7 @@ const ( ) // lumberjacks maps log filenames to the logger -// that is being used to keep them rolled/maintained. -var lumberjacks = make(map[string]*lumberjack.Logger) +// that is being used to keep them rolled/maintained; +// if rolling is disabled, it's just a regular +// *os.File, not a lumberjack +var lumberjacks = make(map[string]io.Writer) diff --git a/vendor/gopkg.in/natefinch/lumberjack.v2/lumberjack.go b/vendor/gopkg.in/natefinch/lumberjack.v2/lumberjack.go index ca19da440..46d97c553 100644 --- a/vendor/gopkg.in/natefinch/lumberjack.v2/lumberjack.go +++ b/vendor/gopkg.in/natefinch/lumberjack.v2/lumberjack.go @@ -104,7 +104,7 @@ type Logger struct { LocalTime bool `json:"localtime" yaml:"localtime"` // Compress determines if the rotated log files should be compressed - // using gzip. + // using gzip. The default is not to perform compression. Compress bool `json:"compress" yaml:"compress"` size int64 diff --git a/vendor/manifest b/vendor/manifest index 97273930a..a2473037e 100644 --- a/vendor/manifest +++ b/vendor/manifest @@ -733,7 +733,7 @@ "importpath": "gopkg.in/natefinch/lumberjack.v2", "repository": "https://gopkg.in/natefinch/lumberjack.v2", "vcs": "git", - "revision": "df99d62fd42d8b3752c8a42c6723555372c02a03", + "revision": "7d6a1875575e09256dc552b4c0e450dcd02bd10e", "branch": "v2.0", "notests": true },