Skip to content

Commit

Permalink
Merge pull request #64914 from knz/backport21.1-64900
Browse files Browse the repository at this point in the history
  • Loading branch information
knz authored May 10, 2021
2 parents f05a57f + 35fea82 commit eb9e1a7
Show file tree
Hide file tree
Showing 4 changed files with 341 additions and 15 deletions.
105 changes: 96 additions & 9 deletions pkg/util/log/format_crdb_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ package log

import (
"strings"
"unicode/utf8"

"github.com/cockroachdb/cockroach/pkg/util/log/channel"
"github.com/cockroachdb/cockroach/pkg/util/log/severity"
Expand Down Expand Up @@ -298,19 +299,19 @@ func formatLogEntryInternalV2(entry logEntry, cp ttycolor.Profile) *buffer {
buf.Write(cp[ttycolor.Reset])
// Structured entries are guaranteed to fit on a single line already.
buf.WriteByte('{')
buf.maybeMultiLine(commonPrefixLen, '+', entry.payload.message, cp)
buf.maybeMultiLine(commonPrefixLen, '+', entry.payload.redactable, entry.payload.message, cp)
buf.WriteByte('}')
} else {
buf.WriteByte(' ')
buf.maybeMultiLine(commonPrefixLen, '+', entry.payload.message, cp)
buf.maybeMultiLine(commonPrefixLen, '+', entry.payload.redactable, entry.payload.message, cp)
}
if entry.stacks != nil {
buf.WriteByte('\n')
buf.Write(buf.Bytes()[0:commonPrefixLen])
buf.Write(cp[ttycolor.Green])
buf.WriteByte('!')
buf.Write(cp[ttycolor.Reset])
buf.maybeMultiLine(commonPrefixLen, '!', string(entry.stacks), cp)
buf.maybeMultiLine(commonPrefixLen, '!', false /* redactable */, string(entry.stacks), cp)
}

// Ensure there is a final newline.
Expand All @@ -319,12 +320,54 @@ func formatLogEntryInternalV2(entry logEntry, cp ttycolor.Profile) *buffer {
return buf
}

// crdbV2LongLineLen is the max length of a log line before it gets broken up into multiple lines.
// crdbV2LongLineLen is the max length of a log entry, in bytes, before
// it gets broken up into multiple lines.
// This maximum is applied to the size of the entry without considering
// the prefix (timestamp, location etc).
// The value is approximate: lines can be effectively shorter than
// this maximum. This margin exists so as to accommodate lines that
// end with a multi-byte UTF-8 sequence, as these cannot be broken up.
//
// NB: the value of 1KiB is mentioned in the format's documentation above. Keep them in sync.
const crdbV2LongLineLen = 1024
// This is implemented as a variable so it can be modified
// in unit tests.
// TODO(knz): This could also be made configurable by the user.
//
// NB: the value of this variable might be mentioned in the format's
// documentation above. Keep them in sync if necessary.
var crdbV2LongLineLen longLineLen

func init() {
crdbV2LongLineLen.set(16 * 1000)
}

type longLineLen int

func (l *longLineLen) set(v int) {
// We refuse to break a long entry in the middle of a UTF-8
// sequence, so the effective max length needs to be reduced by the
// maximum size of an UTF-8 sequence.
suffixLen := utf8.UTFMax
// We also refuse to break a long entry in the middle of a redaction
// marker. Additionally, if we observe a start redaction marker,
// we are going to insert a closing redaction marker after it
// before we break up the line.
if len(startRedactionMarker)+len(endRedactionMarker) > suffixLen {
suffixLen = len(startRedactionMarker) + len(endRedactionMarker)
}
newMax := v - suffixLen
if newMax < 1 {
panic("max line length cannot be zero or negative")
}
*l = longLineLen(newMax)
}

func (buf *buffer) maybeMultiLine(prefixLen int, contMark byte, msg string, cp ttycolor.Profile) {
func (l longLineLen) shouldBreak(lastLen int) bool {
return lastLen >= int(l)
}

func (buf *buffer) maybeMultiLine(
prefixLen int, contMark byte, redactable bool, msg string, cp ttycolor.Profile,
) {
var i int
for i = len(msg) - 1; i > 0 && msg[i] == '\n'; i-- {
msg = msg[:i]
Expand All @@ -333,6 +376,7 @@ func (buf *buffer) maybeMultiLine(prefixLen int, contMark byte, msg string, cp t
// which we've already copied into buf.
k := 0
lastLen := 0
betweenRedactionMarkers := false
for i := 0; i < len(msg); i++ {
if msg[i] == '\n' {
buf.WriteString(msg[k : i+1])
Expand All @@ -344,17 +388,60 @@ func (buf *buffer) maybeMultiLine(prefixLen int, contMark byte, msg string, cp t
lastLen = 0
continue
}
if lastLen >= crdbV2LongLineLen {
if crdbV2LongLineLen.shouldBreak(lastLen) {
buf.WriteString(msg[k:i])
if betweenRedactionMarkers {
// We are breaking a long line in-between redaction
// markers. Ensures that the opening and closing markers do
// not straddle log entries.
buf.WriteString(endRedactionMarker)
}
buf.WriteByte('\n')
buf.Write(buf.Bytes()[0:prefixLen])
buf.Write(cp[ttycolor.Green])
buf.WriteByte('|')
buf.Write(cp[ttycolor.Reset])
k = i
lastLen = 0
if betweenRedactionMarkers {
// See above: if we are splitting in-between redaction
// markers, continue the sensitive item on the new line.
buf.WriteString(startRedactionMarker)
lastLen += len(startRedactionMarker)
}
}
// Common case: single-byte runes and redaction marker known to
// start with a multi-byte sequence. Take a shortcut.
if markersStartWithMultiByteRune && msg[i] < utf8.RuneSelf {
lastLen++
continue
}
lastLen++
if redactable {
// If we see an opening redaction marker, remember this fact
// so that we close/open it properly.
if strings.HasPrefix(msg[i:], startRedactionMarker) {
betweenRedactionMarkers = true
lm := len(startRedactionMarker)
i += lm - 1
lastLen += lm
continue
} else if strings.HasPrefix(msg[i:], endRedactionMarker) {
betweenRedactionMarkers = false
le := len(endRedactionMarker)
i += le - 1
lastLen += le
continue
}
}

// Avoid breaking in the middle of UTF-8 sequences.
_, width := utf8.DecodeRuneInString(msg[i:])
i += width - 1
lastLen += width
}
buf.WriteString(msg[k:])
}

var startRedactionMarker = string(redact.StartMarker())
var endRedactionMarker = string(redact.EndMarker())
var markersStartWithMultiByteRune = startRedactionMarker[0] >= utf8.RuneSelf && endRedactionMarker[0] >= utf8.RuneSelf
53 changes: 53 additions & 0 deletions pkg/util/log/format_crdb_v2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"bytes"
"context"
"fmt"
"strings"
"testing"
"time"

Expand All @@ -35,6 +36,9 @@ func TestFormatCrdbV2(t *testing.T) {
ctx = logtags.AddTag(ctx, "s", "1")
ctx = logtags.AddTag(ctx, "long", "2")

defer func(prev int) { crdbV2LongLineLen.set(prev) }(int(crdbV2LongLineLen))
crdbV2LongLineLen.set(1024)

longLine := string(bytes.Repeat([]byte("a"), 1030))

withStack := func(e logEntry) logEntry {
Expand Down Expand Up @@ -125,3 +129,52 @@ func TestFormatCrdbV2(t *testing.T) {
})

}

func TestFormatCrdbV2LongLineBreaks(t *testing.T) {
f := formatCrdbV2{}
datadriven.RunTest(t, "testdata/crdb_v2_break_lines", func(t *testing.T, td *datadriven.TestData) string {
if td.Cmd != "run" {
t.Fatalf("unknown command: %s", td.Cmd)
}
var maxLen int
var redactable bool
td.ScanArgs(t, "maxlen", &maxLen)
td.ScanArgs(t, "redactable", &redactable)

defer func(prev int) { crdbV2LongLineLen.set(prev) }(int(crdbV2LongLineLen))
crdbV2LongLineLen.set(maxLen)

entry := logEntry{
payload: entryPayload{
redactable: redactable,
message: td.Input,
},
}
b := f.formatEntry(entry)
out := b.String()
putBuffer(b)

// Sanity check: verify that no payload is longer (in bytes) than the configured max length.
const prefix1 = "I000101 00:00:00.000000 0 :0 [-] "
const prefix2 = "I000101 00:00:00.000000 0 :0 ⋮ [-] "
lines := strings.Split(out, "\n")
for i, l := range lines {
l = strings.TrimSuffix(l, "\n")
if len(l) == 0 {
continue
}
l = strings.TrimPrefix(l, prefix1)
l = strings.TrimPrefix(l, prefix2)
// Remove the start or continutation marker
if l[0] != ' ' && l[0] != '|' {
t.Fatalf("unexpected continuation marker on line %d: %q", i+1, l)
}
l = l[1:]
if len(l) > maxLen {
t.Fatalf("line too large: %d bytes, expected max %d - %q", len(l), maxLen, l)
}
}

return out
})
}
12 changes: 6 additions & 6 deletions pkg/util/log/testdata/crdb_v2
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ I060102 15:04:05.654321 11 util/log/format_crdb_v2_test.go:123 ⋮ [noval,s‹1
I060102 15:04:05.654321 11 util/log/format_crdb_v2_test.go:123 ⋮ [noval,s‹1›,long=‹2›] +‹line with stack›
I060102 15:04:05.654321 11 util/log/format_crdb_v2_test.go:123 ⋮ [noval,s‹1›,long=‹2›] !this is a fake stack
#
I060102 15:04:05.654321 11 util/log/format_crdb_v2_test.go:123 [noval,s1,long=2] aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
I060102 15:04:05.654321 11 util/log/format_crdb_v2_test.go:123 [noval,s1,long=2] |aaaaaa
I060102 15:04:05.654321 11 util/log/format_crdb_v2_test.go:123 [noval,s1,long=2] aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
I060102 15:04:05.654321 11 util/log/format_crdb_v2_test.go:123 [noval,s1,long=2] |aaaaaaaaaaaa
#
I060102 15:04:05.654321 11 util/log/format_crdb_v2_test.go:123 ⋮ [noval,s‹1›,long=‹2›] ={"Timestamp":123,"EventType":"rename_database","DatabaseName":"‹aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
I060102 15:04:05.654321 11 util/log/format_crdb_v2_test.go:123 ⋮ [noval,s‹1›,long=‹2›] |aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa›"}
I060102 15:04:05.654321 11 util/log/format_crdb_v2_test.go:123 ⋮ [noval,s‹1›,long=‹2›] ={"Timestamp":123,"EventType":"rename_database","DatabaseName":"‹aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa›
I060102 15:04:05.654321 11 util/log/format_crdb_v2_test.go:123 ⋮ [noval,s‹1›,long=‹2›] |‹aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa›"}
#
E060102 15:04:05.654321 11 2@util/log/format_crdb_v2_test.go:123 ⋮ [noval,s‹1›,long=‹2›] hello ‹stack›
E060102 15:04:05.654321 11 2@util/log/format_crdb_v2_test.go:123 ⋮ [noval,s‹1›,long=‹2›] !this is aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
E060102 15:04:05.654321 11 2@util/log/format_crdb_v2_test.go:123 ⋮ [noval,s‹1›,long=‹2›] |aaaaaaaaaaaaaa fake stack
E060102 15:04:05.654321 11 2@util/log/format_crdb_v2_test.go:123 ⋮ [noval,s‹1›,long=‹2›] !this is aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
E060102 15:04:05.654321 11 2@util/log/format_crdb_v2_test.go:123 ⋮ [noval,s‹1›,long=‹2›] |aaaaaaaaaaaaaaaaaaaa fake stack
Loading

0 comments on commit eb9e1a7

Please sign in to comment.