@@ -86,6 +86,7 @@ type TerminalStringer interface {
86
86
// [DBUG] [May 16 20:58:45] remove route ns=haproxy addr=127.0.0.1:50002
87
87
func TerminalFormat (usecolor bool ) Format {
88
88
return FormatFunc (func (r * Record ) []byte {
89
+ msg := escapeMessage (r .Msg )
89
90
var color = 0
90
91
if usecolor {
91
92
switch r .Lvl {
@@ -122,19 +123,19 @@ func TerminalFormat(usecolor bool) Format {
122
123
123
124
// Assemble and print the log heading
124
125
if color > 0 {
125
- fmt .Fprintf (b , "\x1b [%dm%s\x1b [0m[%s|%s]%s %s " , color , lvl , r .Time .Format (termTimeFormat ), location , padding , r . Msg )
126
+ fmt .Fprintf (b , "\x1b [%dm%s\x1b [0m[%s|%s]%s %s " , color , lvl , r .Time .Format (termTimeFormat ), location , padding , msg )
126
127
} else {
127
- fmt .Fprintf (b , "%s[%s|%s]%s %s " , lvl , r .Time .Format (termTimeFormat ), location , padding , r . Msg )
128
+ fmt .Fprintf (b , "%s[%s|%s]%s %s " , lvl , r .Time .Format (termTimeFormat ), location , padding , msg )
128
129
}
129
130
} else {
130
131
if color > 0 {
131
- fmt .Fprintf (b , "\x1b [%dm%s\x1b [0m[%s] %s " , color , lvl , r .Time .Format (termTimeFormat ), r . Msg )
132
+ fmt .Fprintf (b , "\x1b [%dm%s\x1b [0m[%s] %s " , color , lvl , r .Time .Format (termTimeFormat ), msg )
132
133
} else {
133
- fmt .Fprintf (b , "%s[%s] %s " , lvl , r .Time .Format (termTimeFormat ), r . Msg )
134
+ fmt .Fprintf (b , "%s[%s] %s " , lvl , r .Time .Format (termTimeFormat ), msg )
134
135
}
135
136
}
136
137
// try to justify the log output for short messages
137
- length := utf8 .RuneCountInString (r . Msg )
138
+ length := utf8 .RuneCountInString (msg )
138
139
if len (r .Ctx ) > 0 && length < termMsgJust {
139
140
b .Write (bytes .Repeat ([]byte {' ' }, termMsgJust - length ))
140
141
}
@@ -167,6 +168,8 @@ func logfmt(buf *bytes.Buffer, ctx []interface{}, color int, term bool) {
167
168
v := formatLogfmtValue (ctx [i + 1 ], term )
168
169
if ! ok {
169
170
k , v = errorKey , formatLogfmtValue (k , term )
171
+ } else {
172
+ k = escapeString (k )
170
173
}
171
174
172
175
// XXX: we should probably check that all of your key bytes aren't invalid
@@ -471,7 +474,7 @@ func formatLogfmtBigInt(n *big.Int) string {
471
474
func escapeString (s string ) string {
472
475
needsQuoting := false
473
476
for _ , r := range s {
474
- // We quote everything below " (0x34 ) and above~ (0x7E), plus equal-sign
477
+ // We quote everything below " (0x22 ) and above~ (0x7E), plus equal-sign
475
478
if r <= '"' || r > '~' || r == '=' {
476
479
needsQuoting = true
477
480
break
@@ -482,3 +485,26 @@ func escapeString(s string) string {
482
485
}
483
486
return strconv .Quote (s )
484
487
}
488
+
489
+ // escapeMessage checks if the provided string needs escaping/quoting, similarly
490
+ // to escapeString. The difference is that this method is more lenient: it allows
491
+ // for spaces and linebreaks to occur without needing quoting.
492
+ func escapeMessage (s string ) string {
493
+ needsQuoting := false
494
+ for _ , r := range s {
495
+ // Carriage return and Line feed are ok
496
+ if r == 0xa || r == 0xd {
497
+ continue
498
+ }
499
+ // We quote everything below <space> (0x20) and above~ (0x7E),
500
+ // plus equal-sign
501
+ if r < ' ' || r > '~' || r == '=' {
502
+ needsQuoting = true
503
+ break
504
+ }
505
+ }
506
+ if ! needsQuoting {
507
+ return s
508
+ }
509
+ return strconv .Quote (s )
510
+ }
0 commit comments