When logging with timestamps, append only until newline

When we log time timestamps, don't print a new timestamp for each
input - instead, print one at the start of every line, and then
wait until we hit a newline to print a new timestamp.

This still doesn't exactly mirror the Docker behavior (they don't
print until they receive an entire line, while we print any time
the logs file is appended to - so you can see partial lines being
typed in our system). Also, timestamps are recorded as the start
of a line being typed, as opposed to when the enter key is
pressed (on Docker).

(Worth noting that, while characters are printed as they are
typed, logs does respect the backspace key - so you'll also see
them disappear as the person typing realizes they've made a
mistake and retypes their command).

This is the closest we can get to Docker without major surgery on
the Kubernetes log-printing library, so I'm content to call this
an adequate solution.

Signed-off-by: Matthew Heon <mheon@redhat.com>
This commit is contained in:
Matthew Heon 2019-03-03 23:06:32 -05:00
parent e372837eb0
commit 429f2e63a0
1 changed files with 10 additions and 7 deletions

View File

@ -277,10 +277,11 @@ func readLog(reader *bufio.Reader, opts *LogOptions) []string {
// logWriter controls the writing into the stream based on the log options.
type logWriter struct {
stdout io.Writer
stderr io.Writer
opts *LogOptions
remain int64
stdout io.Writer
stderr io.Writer
opts *LogOptions
remain int64
doAppend bool
}
// errMaximumWrite is returned when all bytes have been written.
@ -309,14 +310,16 @@ func (w *logWriter) write(msg *logMessage) error {
return nil
}
line := msg.log
if w.opts.Timestamps {
if w.opts.Timestamps && !w.doAppend {
prefix := append([]byte(msg.timestamp.Format(timeFormat)), delimiter[0])
line = append(prefix, line...)
// Ensure that lines always end in a newline
if line[len(line)-1] != '\n' {
line = append(line, '\n')
w.doAppend = true
}
}
if w.doAppend && line[len(line)-1] == '\n' {
w.doAppend = false
}
// If the line is longer than the remaining bytes, cut it.
if int64(len(line)) > w.remain {
line = line[:w.remain]