From e372837eb0dcafdf2fb5c3029ba340bbd9117fc3 Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Sun, 3 Mar 2019 21:13:49 -0500 Subject: Ensure that each log line is newline-terminated When writing logs with timestamps to the terminal, ensure that each line is newline-terminated, so we don't end up with an unreadable mess with timestamps interspersed with the actual content being displayed. Signed-off-by: Matthew Heon --- pkg/logs/logs.go | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'pkg') diff --git a/pkg/logs/logs.go b/pkg/logs/logs.go index b104c592b..fe4474f8b 100644 --- a/pkg/logs/logs.go +++ b/pkg/logs/logs.go @@ -312,6 +312,10 @@ func (w *logWriter) write(msg *logMessage) error { if w.opts.Timestamps { 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') + } } // If the line is longer than the remaining bytes, cut it. if int64(len(line)) > w.remain { -- cgit v1.2.3-54-g00ecf From 429f2e63a0e2a3b1e084371ebed280a6288b7617 Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Sun, 3 Mar 2019 23:06:32 -0500 Subject: 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 --- pkg/logs/logs.go | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'pkg') diff --git a/pkg/logs/logs.go b/pkg/logs/logs.go index fe4474f8b..1d920d691 100644 --- a/pkg/logs/logs.go +++ b/pkg/logs/logs.go @@ -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] -- cgit v1.2.3-54-g00ecf From ff609a5ade6991ef1d8f892a7bce44a039fbe174 Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Sun, 3 Mar 2019 23:30:45 -0500 Subject: Add additional defense against 0-length log segfaults Signed-off-by: Matthew Heon --- pkg/logs/logs.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'pkg') diff --git a/pkg/logs/logs.go b/pkg/logs/logs.go index 1d920d691..bbd5509b1 100644 --- a/pkg/logs/logs.go +++ b/pkg/logs/logs.go @@ -313,11 +313,11 @@ func (w *logWriter) write(msg *logMessage) error { if w.opts.Timestamps && !w.doAppend { prefix := append([]byte(msg.timestamp.Format(timeFormat)), delimiter[0]) line = append(prefix, line...) - if line[len(line)-1] != '\n' { + if len(line) > 0 && line[len(line)-1] != '\n' { w.doAppend = true } } - if w.doAppend && line[len(line)-1] == '\n' { + if w.doAppend && len(line) > 0 && line[len(line)-1] == '\n' { w.doAppend = false } // If the line is longer than the remaining bytes, cut it. -- cgit v1.2.3-54-g00ecf