Skip to content

Commit 3093e9a

Browse files
committed
log: save some cpu by simplifying coloring, avoid many cases of escaping
1 parent 1bc4719 commit 3093e9a

File tree

2 files changed

+66
-64
lines changed

2 files changed

+66
-64
lines changed

log/format.go

+47-46
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515

1616
const (
1717
timeFormat = "2006-01-02T15:04:05-0700"
18-
termTimeFormat = "01-02|15:04:05.000"
1918
floatFormat = 'f'
2019
termMsgJust = 40
2120
termCtxMaxPadding = 40
@@ -49,40 +48,43 @@ type TerminalStringer interface {
4948

5049
func (h *TerminalHandler) TerminalFormat(buf []byte, r slog.Record, usecolor bool) []byte {
5150
msg := escapeMessage(r.Message)
52-
var color = 0
51+
var color = ""
5352
if usecolor {
5453
switch r.Level {
5554
case LevelCrit:
56-
color = 35
55+
color = "\x1b[35m"
5756
case slog.LevelError:
58-
color = 31
57+
color = "\x1b[31m"
5958
case slog.LevelWarn:
60-
color = 33
59+
color = "\x1b[33m"
6160
case slog.LevelInfo:
62-
color = 32
61+
color = "\x1b[32m"
6362
case slog.LevelDebug:
64-
color = 36
63+
color = "\x1b[36m"
6564
case LevelTrace:
66-
color = 34
65+
color = "\x1b[34m"
6766
}
6867
}
6968
if buf == nil {
7069
buf = make([]byte, 0, 30+termMsgJust)
7170
}
7271
b := bytes.NewBuffer(buf)
73-
lvl := LevelAlignedString(r.Level)
74-
if color > 0 {
75-
// TODO improve this
76-
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %s ", color, lvl, r.Time.Format(termTimeFormat), msg)
72+
73+
if color != "" { // Start color
74+
b.WriteString(color)
75+
b.WriteString(LevelAlignedString(r.Level))
76+
b.WriteString("\x1b[0m")
7777
} else {
78-
b.WriteString(lvl)
79-
b.WriteString("[")
80-
writeTimeTermFormat(b, r.Time)
81-
b.WriteString("] ")
82-
b.WriteString(msg)
78+
b.WriteString(LevelAlignedString(r.Level))
8379
}
80+
b.WriteString("[")
81+
writeTimeTermFormat(b, r.Time)
82+
b.WriteString("] ")
83+
b.WriteString(msg)
84+
8485
// try to justify the log output for short messages
85-
length := utf8.RuneCountInString(msg)
86+
//length := utf8.RuneCountInString(msg)
87+
length := len(msg)
8688
if (r.NumAttrs()+len(h.attrs)) > 0 && length < termMsgJust {
8789
b.Write(spaces[:termMsgJust-length])
8890
}
@@ -92,17 +94,18 @@ func (h *TerminalHandler) TerminalFormat(buf []byte, r slog.Record, usecolor boo
9294
return b.Bytes()
9395
}
9496

95-
func (h *TerminalHandler) logfmt(buf *bytes.Buffer, r slog.Record, color int) {
97+
func (h *TerminalHandler) logfmt(buf *bytes.Buffer, r slog.Record, color string) {
9698
writeAttr := func(attr slog.Attr, first, last bool) {
9799
//if !first {
98100
buf.WriteByte(' ')
99101
//}
100-
key := escapeString(attr.Key)
101-
if color > 0 {
102-
// TODO improve this
103-
fmt.Fprintf(buf, "\x1b[%dm%s\x1b[0m=", color, key)
102+
103+
if color != "" {
104+
buf.WriteString(color)
105+
buf.Write(appendEscapeString(buf.AvailableBuffer(), attr.Key))
106+
buf.WriteString("\x1b[0m=")
104107
} else {
105-
buf.WriteString(key)
108+
buf.Write(appendEscapeString(buf.AvailableBuffer(), attr.Key))
106109
buf.WriteByte('=')
107110
}
108111
tmp := buf.AvailableBuffer()
@@ -302,34 +305,32 @@ func appendU256(dst []byte, n *uint256.Int) []byte {
302305
// escaping/quoting if needed.
303306
func appendEscapeString(dst []byte, s string) []byte {
304307
needsQuoting := false
308+
needsEscaping := false
305309
for _, r := range s {
306-
// We quote everything below " (0x22) and above~ (0x7E), plus equal-sign
307-
if r <= '"' || r > '~' || r == '=' {
310+
// If it contains spaces or equal-sign, we need to quote it.
311+
if r == ' ' || r == '=' {
308312
needsQuoting = true
309-
break
313+
continue
310314
}
311-
}
312-
if !needsQuoting {
313-
return append(dst, []byte(s)...)
314-
}
315-
return strconv.AppendQuote(dst, s)
316-
}
317-
318-
// escapeString checks if the provided string needs escaping/quoting, and
319-
// calls strconv.Quote if needed
320-
func escapeString(s string) string {
321-
needsQuoting := false
322-
for _, r := range s {
323-
// We quote everything below " (0x22) and above~ (0x7E), plus equal-sign
324-
if r <= '"' || r > '~' || r == '=' {
325-
needsQuoting = true
315+
// We need to escape it, if it contains
316+
// - character " (0x22) and lower (except space)
317+
// - characters above ~ (0x7E), plus equal-sign
318+
if r <= '"' || r > '~' {
319+
needsEscaping = true
326320
break
327321
}
328322
}
329-
if !needsQuoting {
330-
return s
323+
if needsEscaping {
324+
return strconv.AppendQuote(dst, s)
331325
}
332-
return strconv.Quote(s)
326+
// No escaping needed, but we might have to place within quote-marks, in case
327+
// it contained a space
328+
if needsQuoting {
329+
dst = append(dst, '"')
330+
dst = append(dst, []byte(s)...)
331+
return append(dst, '"')
332+
}
333+
return append(dst, []byte(s)...)
333334
}
334335

335336
// escapeMessage checks if the provided string needs escaping/quoting, similarly
@@ -355,7 +356,7 @@ func escapeMessage(s string) string {
355356
return strconv.Quote(s)
356357
}
357358

358-
// writeTimeTermFormat
359+
// writeTimeTermFormat writes on the format "01-02|15:04:05.000"
359360
func writeTimeTermFormat(buf *bytes.Buffer, t time.Time) {
360361
_, month, day := t.Date()
361362
writePosIntWidth(buf, int(month), 2)

log/logger_test.go

+19-18
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,10 @@ func TestLoggerOutput(t *testing.T) {
135135

136136
}
137137

138+
const termTimeFormat = "01-02|15:04:05.000"
139+
138140
func BenchmarkAppendFormat(b *testing.B) {
139141
var now = time.Now()
140-
141142
b.Run("fmt time.Format", func(b *testing.B) {
142143
for i := 0; i < b.N; i++ {
143144
fmt.Fprintf(io.Discard, "%s", now.Format(termTimeFormat))
@@ -149,22 +150,22 @@ func BenchmarkAppendFormat(b *testing.B) {
149150
now.AppendFormat(nil, termTimeFormat)
150151
}
151152
})
152-
//var buf = new(bytes.Buffer)
153-
//b.Run("time.Custom", func(b *testing.B) {
154-
// for i := 0; i < b.N; i++ {
155-
// writeTimeTermFormat(buf, now)
156-
// buf.Reset()
157-
// }
158-
//})
153+
var buf = new(bytes.Buffer)
154+
b.Run("time.Custom", func(b *testing.B) {
155+
for i := 0; i < b.N; i++ {
156+
writeTimeTermFormat(buf, now)
157+
buf.Reset()
158+
}
159+
})
159160
}
160161

161-
//func TestTimeFormat(t *testing.T) {
162-
// var now = time.Now()
163-
// want := now.AppendFormat(nil, termTimeFormat)
164-
// var b = new(bytes.Buffer)
165-
// writeTimeTermFormat(b, now)
166-
// have := b.Bytes()
167-
// if !bytes.Equal(have, want) {
168-
// t.Errorf("have != want\nhave: %q\nwant: %q\n", have, want)
169-
// }
170-
//}
162+
func TestTermTimeFormat(t *testing.T) {
163+
var now = time.Now()
164+
want := now.AppendFormat(nil, termTimeFormat)
165+
var b = new(bytes.Buffer)
166+
writeTimeTermFormat(b, now)
167+
have := b.Bytes()
168+
if !bytes.Equal(have, want) {
169+
t.Errorf("have != want\nhave: %q\nwant: %q\n", have, want)
170+
}
171+
}

0 commit comments

Comments
 (0)