Compare commits
2
Commits
main
..
f22461fe25
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f22461fe25 | ||
|
|
5d4b078304 |
@@ -27,8 +27,7 @@ files it depends on: .golangci.yml, REPO_POLICIES.md, .editorconfig,
|
||||
* 2026-08-10: fixed every handler discarding slog attributes: console,
|
||||
JSON and webhook handlers now emit record attributes, accumulate
|
||||
WithAttrs without mutating the receiver, and honour WithGroup;
|
||||
slog.Group values nest and LogValuer values are resolved; console
|
||||
keys and values holding invalid UTF-8 are quoted
|
||||
slog.Group values nest and LogValuer values are resolved
|
||||
* 2026-08-07: added canonical `.golangci.yml` (v2 schema), pinned the
|
||||
`Dockerfile` lint stage to golangci-lint v2.12.2 (tag+digest), and
|
||||
fixed all findings the v1→v2 jump surfaced without changing any
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// handlerAttrs is the attribute state every handler carries: the attributes
|
||||
@@ -263,20 +262,16 @@ func appendAttrText(out *strings.Builder, prefix string, attr slog.Attr) {
|
||||
out.WriteString(quoteIfNeeded(value.String()))
|
||||
}
|
||||
|
||||
// quoteIfNeeded quotes a key or a value, as slog.NewTextHandler does, when
|
||||
// leaving it bare would make the key=value pairs ambiguous or would write a
|
||||
// control character or invalid UTF-8 to the terminal. Unlike the stdlib, it
|
||||
// also quotes DEL (0x7f), which is a control character too.
|
||||
// quoteIfNeeded quotes a key or a value only when leaving it bare would make
|
||||
// the key=value pairs ambiguous, matching how the stdlib text handler reads.
|
||||
func quoteIfNeeded(text string) string {
|
||||
if text == "" {
|
||||
return `""`
|
||||
}
|
||||
|
||||
// Ranging over a string yields utf8.RuneError for each invalid byte;
|
||||
// strconv.Quote then escapes that byte, as in "bad\xffkey".
|
||||
for _, r := range text {
|
||||
if unicode.IsSpace(r) || !unicode.IsPrint(r) ||
|
||||
r == utf8.RuneError || r == '"' || r == '=' {
|
||||
r == '"' || r == '=' {
|
||||
return strconv.Quote(text)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -400,27 +400,6 @@ func TestConsoleHandlerQuotesKeysNeedingIt(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestConsoleHandlerQuotesInvalidUTF8 checks that a key or a value holding
|
||||
// invalid UTF-8 is quoted with the bad byte escaped, as slog.NewTextHandler
|
||||
// does, so the raw byte never reaches the terminal. Valid non-ASCII stays bare.
|
||||
func TestConsoleHandlerQuotesInvalidUTF8(t *testing.T) {
|
||||
output := captureStdout(t, func() {
|
||||
handler := simplelog.NewConsoleHandler()
|
||||
record := testRecord(
|
||||
"casting",
|
||||
slog.String("bad\xffkey", "v"),
|
||||
slog.String("raw", "bad\xffvalue"),
|
||||
slog.String("title", "Amélie"),
|
||||
)
|
||||
handle(t, handler, record)
|
||||
})
|
||||
|
||||
wantContains(t, output, ` "bad\xffkey"=v`)
|
||||
wantContains(t, output, ` raw="bad\xffvalue"`)
|
||||
wantContains(t, output, " title=Amélie")
|
||||
wantNotContains(t, output, "\xff")
|
||||
}
|
||||
|
||||
func TestConsoleHandlerWithAttrsAccumulates(t *testing.T) {
|
||||
output := captureStdout(t, func() {
|
||||
handler := simplelog.NewConsoleHandler().
|
||||
|
||||
Reference in New Issue
Block a user