-
Notifications
You must be signed in to change notification settings - Fork 166
Conversation
This is limited to time & size based rotation + log compression.
I'll add one more thing - parsing of human readable sizes (like |
cmd/geth/flags.go
Outdated
Value: 0, | ||
} | ||
LogMaxTotalSizeFlag = cli.IntFlag{ | ||
Name: "log-max-total-size,log-maxtotalsize", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest naming this log-total-max-size,log-totalmaxsize
to stick with the convention established where <max|min>-size
and max-age
are "syntax units." What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
cmd/geth/flags.go
Outdated
Value: 0, | ||
} | ||
LogIntervalFlag = cli.StringFlag{ | ||
Name: "log-interval", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And this one may log-rotate-interval
to avoid confusion with log-status
which also controls an interval. And/or log-rotation-interval
?
cmd/geth/flags.go
Outdated
Usage: "Maximum age of the oldest log file, valid time units: 'ns', 'us' (or 'µs'), 'ms', 's', 'm', 'h'", | ||
Value: "0", | ||
} | ||
LogCompressFlag = cli.BoolFlag{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we make this a BoolTFlag
to enable by default?
I guess this would entail establishing defaults for max/min size and age as well, but if we're going to be generating the logs anyways it might be reasonable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't want to change the default behavior of keeping logs forever by default.
Enabling compression by default seems very reasonable, min/max size also, but I'm not sure about the max age and total size.
My new proposition for default values:
- compression: true
- rotation-interval: hourly,
- min-size: 1MB or less?
- max-size: I think 10-20 MB should be OK for hourly rotaiton interval (I was running with 50MB limit for few hours, and only time-based rotation happened)
- max-age, total-max-size - 0 (keep logs forever)
This gives usable logs - easy to seek by date/time, fine-grained if we wan't to remove old ones, compressed files are quite small so they are easy to search even with editor (not only grep
).
I think we should run geth
version with output/log split, with default level/verbosity/etc, for some time, and find sane defaults for log rotation empirically.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those defaults seem very reasonable to me. And agree that we should get an empirical sense. We can also, after getting an averaged empirical sense for a timeframe, do a little extrapolation to give a general sense of log growth too. Like if geth makes 50MB of logs a day running full time, then it will make 350MB a week...
cmd/geth/flags.go
Outdated
} | ||
LogMaxAgeFlag = cli.StringFlag{ | ||
Name: "log-max-age,log-maxage", | ||
Usage: "Maximum age of the oldest log file, valid time units: 'ns', 'us' (or 'µs'), 'ms', 's', 'm', 'h'", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we also add 'd'
and 'w'
for days and weeks? For me at least that would be convenient ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And wait a second... max age of oldest log file in nanoseconds?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The units are copied from documentation of time.ParseDuration
function. I'll change this, i think 'h', 'd', 'w' should be sufficient. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, I think those'll be fine
Running notes as I review... A couple of questions:
|
cmd/geth/main.go
Outdated
@@ -223,6 +230,40 @@ func makeCLIApp() (app *cli.App) { | |||
|
|||
runtime.GOMAXPROCS(runtime.NumCPU()) | |||
|
|||
// log-rotation options |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can shove this logic off to its own file cmd/geth/log_context.go
? I've also got a bunch of this kind of stuff from the display logs too and it feels yucky to clutter main.go
with all this logic.
// shouldRotate checks if we need to rotate the current log file | ||
func (sb *syncBuffer) shouldRotate(len int, now time.Time) bool { | ||
newLen := sb.nbytes + uint64(len) | ||
if newLen <= MinSize { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about adding
if MaxSize == 0 {
return false
}
or?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I see, nm. Because we might not care about size, but care just about age. Gotcha.
logger/glog/glog.go
Outdated
func (sb *syncBuffer) rotateOld(now time.Time) { | ||
logs, err := getLogFiles() | ||
if err != nil { | ||
sb.logger.exit(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just an idea -- what about using Fatal(err)
here (and below)? sb.logger.exit
will write the error to fmt
which is stdout
and since normally geth logs go through stderr
some users might not catch it if they're using 2>
redirect?
return logFiles[i].timestamp < logFiles[j].timestamp | ||
}) | ||
return logFiles, nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we handle this err
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit tricky loop construct from glog
itself ;) It searches for first usable logging directory (configured one or temporary directory). To be consistent with rest of glog
, we're complaining only when no directories work for us.
logger/glog/glog.go
Outdated
return logs | ||
} | ||
|
||
func extractTimestamp(logFile, preffix string) string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor spelling error: "preffix" should be "prefix"
@@ -428,6 +432,309 @@ func TestLogBacktraceAt(t *testing.T) { | |||
} | |||
} | |||
|
|||
func TestExtractTimestamp(t *testing.T) { | |||
preffix := fmt.Sprintf("%s.%s.%s.log.", "geth_test", "sampleHost", "sampleUser") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/preffix/prefix cuz I'm a spelling nazi
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:%s/preffix/prefix/g
;)
logger/glog/glog_test.go
Outdated
{"valid WARNIG", preffix + "WARNING.20171202-210922.13848", "20171202-210922"}, | ||
{"valid gzipped", preffix + "WARNING.20171202-210922.13848.gz", "20171202-210922"}, | ||
{"extra long filename", preffix + "WARNING.20171202-210922.13848.gz.bak", "20171202-210922"}, | ||
{"to short filename", preffix + "WARNING.20171202-21092", ""}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/to/too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to :set spell
before next commit ;)
@@ -223,6 +229,11 @@ func makeCLIApp() (app *cli.App) { | |||
|
|||
runtime.GOMAXPROCS(runtime.NumCPU()) | |||
|
|||
err := setupLogRotation(ctx) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🌮 git add cmd/geth/*
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
return time.Duration(value), nil | ||
} | ||
|
||
// reinventing the wheel to avoid external dependency |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:)
Changes in
logger/glog
andcmd/geth
to implement highly configurable log rotation.This resolves #421.