mirror of
https://github.com/golang/go
synced 2024-11-23 11:00:08 -07:00
log/slog: rename and remove files
- Remove the norace_test.go files, moving their contents elsewhere. - Rename the internal/testutil package to internal/slogtest. - Remove value_unsafe.go, moving its contents to value.go. Updates golang/go#56345. Change-Id: I2a24ace5aea47f7a3067cd671f606c4fb279d744 Reviewed-on: https://go-review.googlesource.com/c/go/+/478197 Run-TryBot: Jonathan Amsterdam <jba@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@google.com>
This commit is contained in:
parent
acce3abb7e
commit
f17e7e8441
@ -386,7 +386,7 @@ var depsRules = `
|
||||
log/slog/internal, log/slog/internal/buffer,
|
||||
slices
|
||||
< log/slog
|
||||
< log/slog/internal/testutil;
|
||||
< log/slog/internal/slogtest;
|
||||
|
||||
NET, log
|
||||
< net/mail;
|
||||
|
@ -7,7 +7,7 @@ package slog_test
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"log/slog/internal/testutil"
|
||||
"log/slog/internal/slogtest"
|
||||
"os"
|
||||
)
|
||||
|
||||
@ -63,7 +63,7 @@ func (h *LevelHandler) Handler() slog.Handler {
|
||||
// Another typical use would be to decrease the log level (to LevelDebug, say)
|
||||
// during a part of the program that was suspected of containing a bug.
|
||||
func ExampleHandler_levelHandler() {
|
||||
th := slog.HandlerOptions{ReplaceAttr: testutil.RemoveTime}.NewTextHandler(os.Stdout)
|
||||
th := slog.HandlerOptions{ReplaceAttr: slogtest.RemoveTime}.NewTextHandler(os.Stdout)
|
||||
logger := slog.New(NewLevelHandler(slog.LevelWarn, th))
|
||||
logger.Info("not printed")
|
||||
logger.Warn("printed")
|
||||
|
@ -6,7 +6,7 @@ package slog_test
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"log/slog/internal/testutil"
|
||||
"log/slog/internal/slogtest"
|
||||
"os"
|
||||
)
|
||||
|
||||
@ -23,7 +23,7 @@ func (Token) LogValue() slog.Value {
|
||||
// with an alternative representation to avoid revealing secrets.
|
||||
func ExampleLogValuer_secret() {
|
||||
t := Token("shhhh!")
|
||||
logger := slog.New(slog.HandlerOptions{ReplaceAttr: testutil.RemoveTime}.
|
||||
logger := slog.New(slog.HandlerOptions{ReplaceAttr: slogtest.RemoveTime}.
|
||||
NewTextHandler(os.Stdout))
|
||||
logger.Info("permission granted", "user", "Perry", "token", t)
|
||||
|
||||
|
@ -6,7 +6,7 @@ package slog_test
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"log/slog/internal/testutil"
|
||||
"log/slog/internal/slogtest"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
@ -16,7 +16,7 @@ func ExampleGroup() {
|
||||
r, _ := http.NewRequest("GET", "localhost", nil)
|
||||
// ...
|
||||
|
||||
logger := slog.New(slog.HandlerOptions{ReplaceAttr: testutil.RemoveTime}.NewTextHandler(os.Stdout))
|
||||
logger := slog.New(slog.HandlerOptions{ReplaceAttr: slogtest.RemoveTime}.NewTextHandler(os.Stdout))
|
||||
slog.SetDefault(logger)
|
||||
|
||||
slog.Info("finished",
|
||||
|
@ -4,7 +4,11 @@
|
||||
|
||||
package buffer
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"internal/race"
|
||||
"internal/testenv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
b := New()
|
||||
@ -20,3 +24,18 @@ func Test(t *testing.T) {
|
||||
t.Errorf("got %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAlloc(t *testing.T) {
|
||||
if race.Enabled {
|
||||
t.Skip("skipping test in race mode")
|
||||
}
|
||||
testenv.SkipIfOptimizationOff(t)
|
||||
got := int(testing.AllocsPerRun(5, func() {
|
||||
b := New()
|
||||
defer b.Free()
|
||||
b.WriteString("not 1K worth of bytes")
|
||||
}))
|
||||
if got != 0 {
|
||||
t.Errorf("got %d allocs, want 0", got)
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +0,0 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package buffer
|
||||
|
||||
import (
|
||||
"internal/race"
|
||||
"internal/testenv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAlloc(t *testing.T) {
|
||||
if race.Enabled {
|
||||
t.Skip("skipping test in race mode")
|
||||
}
|
||||
testenv.SkipIfOptimizationOff(t)
|
||||
got := int(testing.AllocsPerRun(5, func() {
|
||||
b := New()
|
||||
defer b.Free()
|
||||
b.WriteString("not 1K worth of bytes")
|
||||
}))
|
||||
if got != 0 {
|
||||
t.Errorf("got %d allocs, want 0", got)
|
||||
}
|
||||
}
|
@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package testutil contains support functions for testing.
|
||||
package testutil
|
||||
// Package slogtest contains support functions for testing slog.
|
||||
package slogtest
|
||||
|
||||
import "log/slog"
|
||||
|
@ -7,6 +7,8 @@ package slog
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"internal/race"
|
||||
"internal/testenv"
|
||||
"io"
|
||||
"log"
|
||||
"path/filepath"
|
||||
@ -509,3 +511,15 @@ func callerPC(depth int) uintptr {
|
||||
runtime.Callers(depth, pcs[:])
|
||||
return pcs[0]
|
||||
}
|
||||
|
||||
func wantAllocs(t *testing.T, want int, f func()) {
|
||||
if race.Enabled {
|
||||
t.Skip("skipping test in race mode")
|
||||
}
|
||||
testenv.SkipIfOptimizationOff(t)
|
||||
t.Helper()
|
||||
got := int(testing.AllocsPerRun(5, f))
|
||||
if got != want {
|
||||
t.Errorf("got %d allocs, want %d", got, want)
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +0,0 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package slog
|
||||
|
||||
import (
|
||||
"internal/race"
|
||||
"internal/testenv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func wantAllocs(t *testing.T, want int, f func()) {
|
||||
if race.Enabled {
|
||||
t.Skip("skipping test in race mode")
|
||||
}
|
||||
testenv.SkipIfOptimizationOff(t)
|
||||
t.Helper()
|
||||
got := int(testing.AllocsPerRun(5, f))
|
||||
if got != want {
|
||||
t.Errorf("got %d allocs, want %d", got, want)
|
||||
}
|
||||
}
|
@ -10,10 +10,32 @@ import (
|
||||
"slices"
|
||||
"strconv"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Definitions for Value.
|
||||
// The Value type itself can be found in value_{safe,unsafe}.go.
|
||||
// A Value can represent any Go value, but unlike type any,
|
||||
// it can represent most small values without an allocation.
|
||||
// The zero Value corresponds to nil.
|
||||
type Value struct {
|
||||
// num holds the value for Kinds Int64, Uint64, Float64, Bool and Duration,
|
||||
// the string length for KindString, and nanoseconds since the epoch for KindTime.
|
||||
num uint64
|
||||
// If any is of type Kind, then the value is in num as described above.
|
||||
// If any is of type *time.Location, then the Kind is Time and time.Time value
|
||||
// can be constructed from the Unix nanos in num and the location (monotonic time
|
||||
// is not preserved).
|
||||
// If any is of type stringptr, then the Kind is String and the string value
|
||||
// consists of the length in num and the pointer in any.
|
||||
// Otherwise, the Kind is Any and any is the value.
|
||||
// (This implies that Attrs cannot store values of type Kind, *time.Location
|
||||
// or stringptr.)
|
||||
any any
|
||||
}
|
||||
|
||||
type (
|
||||
stringptr *byte // used in Value.any when the Value is a string
|
||||
groupptr *Attr // used in Value.any when the Value is a []Attr
|
||||
)
|
||||
|
||||
// Kind is the kind of a Value.
|
||||
type Kind int
|
||||
@ -58,8 +80,33 @@ func (k Kind) String() string {
|
||||
// (No user-provided value has this type.)
|
||||
type kind Kind
|
||||
|
||||
// Kind returns v's Kind.
|
||||
func (v Value) Kind() Kind {
|
||||
switch x := v.any.(type) {
|
||||
case Kind:
|
||||
return x
|
||||
case stringptr:
|
||||
return KindString
|
||||
case timeLocation:
|
||||
return KindTime
|
||||
case groupptr:
|
||||
return KindGroup
|
||||
case LogValuer:
|
||||
return KindLogValuer
|
||||
case kind: // a kind is just a wrapper for a Kind
|
||||
return KindAny
|
||||
default:
|
||||
return KindAny
|
||||
}
|
||||
}
|
||||
|
||||
//////////////// Constructors
|
||||
|
||||
// StringValue returns a new Value for a string.
|
||||
func StringValue(value string) Value {
|
||||
return Value{num: uint64(len(value)), any: stringptr(unsafe.StringData(value))}
|
||||
}
|
||||
|
||||
// IntValue returns a Value for an int.
|
||||
func IntValue(v int) Value {
|
||||
return Int64Value(int64(v))
|
||||
@ -114,7 +161,7 @@ func DurationValue(v time.Duration) Value {
|
||||
// GroupValue returns a new Value for a list of Attrs.
|
||||
// The caller must not subsequently mutate the argument slice.
|
||||
func GroupValue(as ...Attr) Value {
|
||||
return groupValue(as)
|
||||
return Value{num: uint64(len(as)), any: groupptr(unsafe.SliceData(as))}
|
||||
}
|
||||
|
||||
// AnyValue returns a Value for the supplied value.
|
||||
@ -192,7 +239,7 @@ func (v Value) Any() any {
|
||||
case KindLogValuer:
|
||||
return v.any
|
||||
case KindGroup:
|
||||
return v.uncheckedGroup()
|
||||
return v.group()
|
||||
case KindInt64:
|
||||
return int64(v.num)
|
||||
case KindUint64:
|
||||
@ -212,6 +259,21 @@ func (v Value) Any() any {
|
||||
}
|
||||
}
|
||||
|
||||
// String returns Value's value as a string, formatted like fmt.Sprint. Unlike
|
||||
// the methods Int64, Float64, and so on, which panic if v is of the
|
||||
// wrong kind, String never panics.
|
||||
func (v Value) String() string {
|
||||
if sp, ok := v.any.(stringptr); ok {
|
||||
return unsafe.String(sp, v.num)
|
||||
}
|
||||
var buf []byte
|
||||
return string(v.append(buf))
|
||||
}
|
||||
|
||||
func (v Value) str() string {
|
||||
return unsafe.String(v.any.(stringptr), v.num)
|
||||
}
|
||||
|
||||
// Int64 returns v's value as an int64. It panics
|
||||
// if v is not a signed integer.
|
||||
func (v Value) Int64() int64 {
|
||||
@ -297,7 +359,14 @@ func (v Value) LogValuer() LogValuer {
|
||||
// Group returns v's value as a []Attr.
|
||||
// It panics if v's Kind is not KindGroup.
|
||||
func (v Value) Group() []Attr {
|
||||
return v.group()
|
||||
if sp, ok := v.any.(groupptr); ok {
|
||||
return unsafe.Slice((*Attr)(sp), v.num)
|
||||
}
|
||||
panic("Group: bad kind")
|
||||
}
|
||||
|
||||
func (v Value) group() []Attr {
|
||||
return unsafe.Slice((*Attr)(v.any.(groupptr)), v.num)
|
||||
}
|
||||
|
||||
//////////////// Other
|
||||
@ -321,7 +390,7 @@ func (v Value) Equal(w Value) bool {
|
||||
case KindAny, KindLogValuer:
|
||||
return v.any == w.any // may panic if non-comparable
|
||||
case KindGroup:
|
||||
return slices.EqualFunc(v.uncheckedGroup(), w.uncheckedGroup(), Attr.Equal)
|
||||
return slices.EqualFunc(v.group(), w.group(), Attr.Equal)
|
||||
default:
|
||||
panic(fmt.Sprintf("bad kind: %s", k1))
|
||||
}
|
||||
|
@ -1,90 +0,0 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package slog
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// A Value can represent any Go value, but unlike type any,
|
||||
// it can represent most small values without an allocation.
|
||||
// The zero Value corresponds to nil.
|
||||
type Value struct {
|
||||
// num holds the value for Kinds Int64, Uint64, Float64, Bool and Duration,
|
||||
// the string length for KindString, and nanoseconds since the epoch for KindTime.
|
||||
num uint64
|
||||
// If any is of type Kind, then the value is in num as described above.
|
||||
// If any is of type *time.Location, then the Kind is Time and time.Time value
|
||||
// can be constructed from the Unix nanos in num and the location (monotonic time
|
||||
// is not preserved).
|
||||
// If any is of type stringptr, then the Kind is String and the string value
|
||||
// consists of the length in num and the pointer in any.
|
||||
// Otherwise, the Kind is Any and any is the value.
|
||||
// (This implies that Attrs cannot store values of type Kind, *time.Location
|
||||
// or stringptr.)
|
||||
any any
|
||||
}
|
||||
|
||||
type (
|
||||
stringptr *byte // used in Value.any when the Value is a string
|
||||
groupptr *Attr // used in Value.any when the Value is a []Attr
|
||||
)
|
||||
|
||||
// Kind returns v's Kind.
|
||||
func (v Value) Kind() Kind {
|
||||
switch x := v.any.(type) {
|
||||
case Kind:
|
||||
return x
|
||||
case stringptr:
|
||||
return KindString
|
||||
case timeLocation:
|
||||
return KindTime
|
||||
case groupptr:
|
||||
return KindGroup
|
||||
case LogValuer:
|
||||
return KindLogValuer
|
||||
case kind: // a kind is just a wrapper for a Kind
|
||||
return KindAny
|
||||
default:
|
||||
return KindAny
|
||||
}
|
||||
}
|
||||
|
||||
// StringValue returns a new Value for a string.
|
||||
func StringValue(value string) Value {
|
||||
return Value{num: uint64(len(value)), any: stringptr(unsafe.StringData(value))}
|
||||
}
|
||||
|
||||
func (v Value) str() string {
|
||||
return unsafe.String(v.any.(stringptr), v.num)
|
||||
}
|
||||
|
||||
// String returns Value's value as a string, formatted like fmt.Sprint. Unlike
|
||||
// the methods Int64, Float64, and so on, which panic if v is of the
|
||||
// wrong kind, String never panics.
|
||||
func (v Value) String() string {
|
||||
if sp, ok := v.any.(stringptr); ok {
|
||||
return unsafe.String(sp, v.num)
|
||||
}
|
||||
var buf []byte
|
||||
return string(v.append(buf))
|
||||
}
|
||||
|
||||
func groupValue(as []Attr) Value {
|
||||
return Value{num: uint64(len(as)), any: groupptr(unsafe.SliceData(as))}
|
||||
}
|
||||
|
||||
// group returns the Value's value as a []Attr.
|
||||
// It panics if the Value's Kind is not KindGroup.
|
||||
func (v Value) group() []Attr {
|
||||
if sp, ok := v.any.(groupptr); ok {
|
||||
return unsafe.Slice((*Attr)(sp), v.num)
|
||||
}
|
||||
panic("Group: bad kind")
|
||||
}
|
||||
|
||||
func (v Value) uncheckedGroup() []Attr {
|
||||
return unsafe.Slice((*Attr)(v.any.(groupptr)), v.num)
|
||||
}
|
Loading…
Reference in New Issue
Block a user