log: Remove trailing newlines and escape internal newlines. (#4925)

Fixes #4914.
This commit is contained in:
Jacob Hoffman-Andrews 2020-07-06 14:17:23 -07:00 committed by GitHub
parent df58af1406
commit cb06fe8e13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 27 additions and 3 deletions

View File

@ -138,7 +138,8 @@ type logWriter struct {
}
func (lw logWriter) Write(p []byte) (n int, err error) {
lw.Logger.Info(string(p))
// Lines received by logWriter will always have a trailing newline.
lw.Logger.Info(strings.Trim(string(p), "\n"))
return
}

View File

@ -194,3 +194,12 @@ func TestReadConfigFile(t *testing.T) {
test.AssertNotError(t, err, "ReadConfigFile(../test/config/notify-mailer.json) errored")
test.AssertEquals(t, c.NotifyMailer.SMTPConfig.Server, "localhost")
}
func TestLogWriter(t *testing.T) {
mock := blog.UseMock()
lw := logWriter{mock}
_, _ = lw.Write([]byte("hi\n"))
lines := mock.GetAllMatching(".*")
test.AssertEquals(t, len(lines), 1)
test.AssertEquals(t, lines[0], "INFO: hi")
}

View File

@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"hash/crc32"
"io"
"log/syslog"
"os"
"path"
@ -60,7 +61,7 @@ func New(log *syslog.Writer, stdoutLogLevel int, syslogLogLevel int) (Logger, er
return nil, errors.New("Attempted to use a nil System Logger.")
}
return &impl{
&bothWriter{log, stdoutLogLevel, syslogLogLevel, clock.New()},
&bothWriter{log, stdoutLogLevel, syslogLogLevel, clock.New(), os.Stdout},
}, nil
}
@ -118,6 +119,7 @@ type bothWriter struct {
stdoutLevel int
syslogLevel int
clk clock.Clock
stdout io.Writer
}
func LogLineChecksum(line string) string {
@ -138,6 +140,9 @@ func (w *bothWriter) logAtLevel(level syslog.Priority, msg string) {
const red = "\033[31m\033[1m"
const yellow = "\033[33m"
// Since messages are delimited by newlines, we have to escape any internal or
// trailing newlines before generating the checksum or outputting the message.
msg = strings.Replace(msg, "\n", "\\n", -1)
msg = fmt.Sprintf("%s %s", LogLineChecksum(msg), msg)
switch syslogAllowed := int(level) <= w.syslogLevel; level {
@ -175,7 +180,7 @@ func (w *bothWriter) logAtLevel(level syslog.Priority, msg string) {
}
if int(level) <= w.stdoutLevel {
if _, err := fmt.Printf("%s%s %s %s%s\n",
if _, err := fmt.Fprintf(w.stdout, "%s%s %s %s%s\n",
prefix,
w.clk.Now().Format("150405"),
path.Base(os.Args[0]),

View File

@ -1,6 +1,7 @@
package log
import (
"bytes"
"fmt"
"log"
"log/syslog"
@ -340,3 +341,11 @@ func TestStdoutFailure(t *testing.T) {
// Try to audit log something
log.AuditInfo("This should cause a panic, stdout is closed!")
}
func TestLogAtLevelEscapesNewlines(t *testing.T) {
var buf bytes.Buffer
w := &bothWriter{nil, 6, 0, clock.New(), &buf}
w.logAtLevel(6, "foo\nbar")
test.Assert(t, strings.Contains(buf.String(), "foo\\nbar"), "failed to escape newline")
}