delete unused code (#3504)
This commit is contained in:
@@ -2,10 +2,8 @@ package log
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"sync"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/go-logr/zapr"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
@@ -14,15 +12,6 @@ import (
|
||||
var (
|
||||
// Global, default log level control.
|
||||
globalLogLevel levelSetter = zap.NewAtomicLevel()
|
||||
|
||||
// Map of name -> level control for independently setting log levels. A new
|
||||
// control is registered via WithNamedLevel. This map is never cleaned up
|
||||
// and new entries will overwrite previous values. Currently, this is
|
||||
// acceptable behavior because WithNamedLevel is used sparingly.
|
||||
globalControls map[string]levelSetter = make(map[string]levelSetter, 16)
|
||||
// globalControls is protected (both read and write) by a mutex to make it
|
||||
// thread safe. Access is low frequency, so performance is not a concern.
|
||||
globalControlsLock sync.Mutex
|
||||
)
|
||||
|
||||
type levelSetter interface {
|
||||
@@ -45,65 +34,6 @@ func SetLevelForControl(control levelSetter, level int8) {
|
||||
control.SetLevel(zapcore.Level(-level))
|
||||
}
|
||||
|
||||
// SetLevelFor sets the log level for a given named control.
|
||||
func SetLevelFor(name string, level int8) {
|
||||
globalControlsLock.Lock()
|
||||
defer globalControlsLock.Unlock()
|
||||
if control, ok := globalControls[name]; ok {
|
||||
SetLevelForControl(control, level)
|
||||
return
|
||||
}
|
||||
// Create a new control so registering a control with the same name will
|
||||
// inherit the existing level.
|
||||
globalControls[name] = newAtomicLevelAt(level)
|
||||
}
|
||||
|
||||
// AddLeveler adds a log level control to a logr.Logger.
|
||||
func AddLeveler(l logr.Logger, control levelSetter) (logr.Logger, error) {
|
||||
zapLogger, err := getZapLogger(l)
|
||||
if err != nil {
|
||||
return l, err
|
||||
}
|
||||
|
||||
zapLogger = zapLogger.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core {
|
||||
return NewLevelCore(core, control)
|
||||
}))
|
||||
return zapr.NewLogger(zapLogger), nil
|
||||
}
|
||||
|
||||
// WithNamedLevel creates a child logger with a new name and independent log
|
||||
// level control (see SetLevelFor). NOTE: if name already exists, the existing
|
||||
// controller will be used, otherwise a new controller is created with level
|
||||
// matching the parent's log level.
|
||||
func WithNamedLevel(logger logr.Logger, name string) logr.Logger {
|
||||
logger = logger.WithName(name)
|
||||
|
||||
globalControlsLock.Lock()
|
||||
defer globalControlsLock.Unlock()
|
||||
|
||||
var leveler levelSetter
|
||||
if currentControl, ok := globalControls[name]; ok {
|
||||
leveler = currentControl
|
||||
} else {
|
||||
leveler = newAtomicLevelAt(findLevel(logger))
|
||||
globalControls[name] = leveler
|
||||
}
|
||||
newLogger, err := AddLeveler(logger, leveler)
|
||||
if err != nil {
|
||||
return logger
|
||||
}
|
||||
return newLogger
|
||||
}
|
||||
|
||||
// newAtomicLevelAt is a helper function to create a zap.AtomicLevel
|
||||
// initialized with a level. We cannot use zap.NewAtomicLevelAt here because of
|
||||
// a quirk with logr levels (see SetLevelForControl).
|
||||
func newAtomicLevelAt(level int8) zap.AtomicLevel {
|
||||
control := zap.NewAtomicLevel()
|
||||
SetLevelForControl(control, level)
|
||||
return control
|
||||
}
|
||||
|
||||
// findLevel probes a logr.Logger to figure out what level it is at via binary
|
||||
// search. We only search [0, 128), so worst case is ~7 checks.
|
||||
func findLevel(logger logr.Logger) int8 {
|
||||
|
||||
@@ -3,16 +3,12 @@ package log
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/getsentry/sentry-go"
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
@@ -217,290 +213,6 @@ func TestWithLeveler(t *testing.T) {
|
||||
assert.Contains(t, buf2.String(), "line 3")
|
||||
}
|
||||
|
||||
func TestWithNamedLevelMoreVerbose(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
globalControls = make(map[string]levelSetter, 16)
|
||||
|
||||
l1 := zap.NewAtomicLevel()
|
||||
logger, flush := New(
|
||||
"service-name",
|
||||
WithConsoleSink(&buf, WithLeveler(l1)),
|
||||
)
|
||||
|
||||
childLogger := WithNamedLevel(logger, "child")
|
||||
|
||||
SetLevelForControl(l1, 1)
|
||||
SetLevelFor("child", 2)
|
||||
|
||||
logger.V(0).Info("line 1")
|
||||
logger.V(1).Info("line 2")
|
||||
logger.V(2).Info("line 3")
|
||||
childLogger.V(0).Info("line A")
|
||||
childLogger.V(1).Info("line B")
|
||||
childLogger.V(2).Info("line C")
|
||||
assert.Nil(t, flush())
|
||||
|
||||
// output should contain up to verbosity 1
|
||||
assert.Equal(t, []string{
|
||||
"info-0\tservice-name\tline 1",
|
||||
"info-1\tservice-name\tline 2",
|
||||
"info-0\tservice-name.child\tline A",
|
||||
"info-1\tservice-name.child\tline B",
|
||||
}, splitLines(buf.String()))
|
||||
}
|
||||
|
||||
func TestWithNamedLevelLessVerbose(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
globalControls = make(map[string]levelSetter, 16)
|
||||
|
||||
l1 := zap.NewAtomicLevel()
|
||||
logger, flush := New(
|
||||
"service-name",
|
||||
WithConsoleSink(&buf, WithLeveler(l1)),
|
||||
)
|
||||
|
||||
childLogger := WithNamedLevel(logger, "child")
|
||||
|
||||
SetLevelForControl(l1, 1)
|
||||
SetLevelFor("child", 0)
|
||||
|
||||
logger.V(0).Info("line 1")
|
||||
logger.V(1).Info("line 2")
|
||||
logger.V(2).Info("line 3")
|
||||
childLogger.V(0).Info("line A")
|
||||
childLogger.V(1).Info("line B")
|
||||
childLogger.V(2).Info("line C")
|
||||
assert.Nil(t, flush())
|
||||
|
||||
// output should contain up to verbosity 1 for parent
|
||||
// and verbosity 0 for child
|
||||
assert.Equal(t, []string{
|
||||
"info-0\tservice-name\tline 1",
|
||||
"info-1\tservice-name\tline 2",
|
||||
"info-0\tservice-name.child\tline A",
|
||||
}, splitLines(buf.String()))
|
||||
}
|
||||
|
||||
func TestNestedWithNamedLevel(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
globalControls = make(map[string]levelSetter, 16)
|
||||
|
||||
grandParent, flush := New("grandParent", WithConsoleSink(&buf, WithLevel(1)))
|
||||
parent := WithNamedLevel(grandParent, "parent")
|
||||
child := WithNamedLevel(parent, "child")
|
||||
|
||||
SetLevelFor("parent", 0)
|
||||
SetLevelFor("child", 2)
|
||||
|
||||
grandParent.V(0).Info("line 1")
|
||||
parent.V(0).Info("line 2")
|
||||
child.V(0).Info("line 3")
|
||||
|
||||
grandParent.V(1).Info("line 4")
|
||||
parent.V(1).Info("line 5")
|
||||
child.V(1).Info("line 6")
|
||||
|
||||
grandParent.V(2).Info("line 7")
|
||||
parent.V(2).Info("line 8")
|
||||
child.V(2).Info("line 9")
|
||||
|
||||
assert.Nil(t, flush())
|
||||
|
||||
lines := splitLines(buf.String())
|
||||
assert.Equal(t, 4, len(lines))
|
||||
|
||||
assert.Equal(t, `info-0 grandParent line 1`, lines[0])
|
||||
assert.Equal(t, `info-0 grandParent.parent line 2`, lines[1])
|
||||
assert.Equal(t, `info-0 grandParent.parent.child line 3`, lines[2])
|
||||
assert.Equal(t, `info-1 grandParent line 4`, lines[3])
|
||||
}
|
||||
|
||||
func TestSiblingsWithNamedLevel(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
globalControls = make(map[string]levelSetter, 16)
|
||||
|
||||
parent, flush := New("parent", WithConsoleSink(&buf, WithLevel(1)))
|
||||
alice := WithNamedLevel(parent, "alice")
|
||||
bob := WithNamedLevel(parent, "bob")
|
||||
|
||||
SetLevelFor("alice", 0)
|
||||
SetLevelFor("bob", 2)
|
||||
|
||||
parent.V(0).Info("line 1")
|
||||
alice.V(0).Info("line 2")
|
||||
bob.V(0).Info("line 3")
|
||||
|
||||
parent.V(1).Info("line 4")
|
||||
alice.V(1).Info("line 5")
|
||||
bob.V(1).Info("line 6")
|
||||
|
||||
parent.V(2).Info("line 7")
|
||||
alice.V(2).Info("line 8")
|
||||
bob.V(2).Info("line 9")
|
||||
|
||||
assert.Nil(t, flush())
|
||||
lines := splitLines(buf.String())
|
||||
assert.Equal(t, 5, len(lines))
|
||||
|
||||
assert.Equal(t, `info-0 parent line 1`, lines[0])
|
||||
assert.Equal(t, `info-0 parent.alice line 2`, lines[1])
|
||||
assert.Equal(t, `info-0 parent.bob line 3`, lines[2])
|
||||
assert.Equal(t, `info-1 parent line 4`, lines[3])
|
||||
assert.Equal(t, `info-1 parent.bob line 6`, lines[4])
|
||||
}
|
||||
|
||||
func TestWithNamedLevelConcurrency(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
globalControls = make(map[string]levelSetter, 16)
|
||||
|
||||
parent, flush := New("parent", WithConsoleSink(&buf))
|
||||
|
||||
alice := WithNamedLevel(parent, "alice")
|
||||
bob := WithNamedLevel(parent, "bob")
|
||||
|
||||
var wg sync.WaitGroup
|
||||
f := func(logger logr.Logger) {
|
||||
defer wg.Done()
|
||||
for i := 0; i < 100_000; i++ {
|
||||
logger.Info(fmt.Sprintf("%06d", i))
|
||||
}
|
||||
}
|
||||
wg.Add(3)
|
||||
go f(parent)
|
||||
go f(alice)
|
||||
go f(bob)
|
||||
wg.Wait()
|
||||
|
||||
assert.Nil(t, flush())
|
||||
logLines := splitLines(buf.String())
|
||||
assert.Equal(t, 300_000, len(logLines))
|
||||
sort.Slice(logLines, func(i, j int) bool {
|
||||
return logLines[i] < logLines[j]
|
||||
})
|
||||
|
||||
for i := 0; i < 100_000; i++ {
|
||||
assert.Equal(t, fmt.Sprintf("info-0\tparent\t%06d", i), logLines[i])
|
||||
assert.Equal(t, fmt.Sprintf("info-0\tparent.alice\t%06d", i), logLines[i+100_000])
|
||||
assert.Equal(t, fmt.Sprintf("info-0\tparent.bob\t%06d", i), logLines[i+200_000])
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithNamedLevelInheritance(t *testing.T) {
|
||||
t.Run("child inherits parent level", func(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
globalControls = make(map[string]levelSetter, 16)
|
||||
|
||||
parent, flush := New("parent", WithConsoleSink(&buf, WithLevel(2)))
|
||||
parent = parent.WithValues("key", "value")
|
||||
// child will inherit parent's log level 2
|
||||
child := WithNamedLevel(parent, "child")
|
||||
|
||||
parent.V(2).Info("yay")
|
||||
child.V(2).Info("yay again")
|
||||
assert.Nil(t, flush())
|
||||
|
||||
logLines := splitLines(buf.String())
|
||||
assert.Equal(t, []string{
|
||||
`info-2 parent yay {"key": "value"}`,
|
||||
`info-2 parent.child yay again {"key": "value"}`,
|
||||
}, logLines)
|
||||
})
|
||||
|
||||
t.Run("child inherits existing named level", func(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
globalControls = make(map[string]levelSetter, 16)
|
||||
|
||||
parent, flush := New("parent", WithConsoleSink(&buf, WithLevel(2)))
|
||||
parent = parent.WithValues("key", "value")
|
||||
SetLevelFor("child", 0)
|
||||
// child will inherit existing named level 0
|
||||
child := WithNamedLevel(parent, "child")
|
||||
|
||||
parent.V(2).Info("yay")
|
||||
child.V(2).Info("yay again")
|
||||
assert.Nil(t, flush())
|
||||
|
||||
logLines := splitLines(buf.String())
|
||||
assert.Equal(t, []string{`info-2 parent yay {"key": "value"}`}, logLines)
|
||||
})
|
||||
}
|
||||
|
||||
func TestExistingChildLevel(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
globalControls = make(map[string]levelSetter, 16)
|
||||
|
||||
parent, flush := New("parent", WithConsoleSink(&buf, WithLevel(2)))
|
||||
|
||||
SetLevelFor("child", 2)
|
||||
// child should start with a level of 2 due to SetLevelFor above
|
||||
child := WithNamedLevel(parent, "child")
|
||||
|
||||
parent.V(2).Info("yay")
|
||||
child.V(2).Info("yay again")
|
||||
assert.Nil(t, flush())
|
||||
|
||||
assert.Contains(t, buf.String(), "info-2\tparent\tyay")
|
||||
assert.Contains(t, buf.String(), "info-2\tparent.child\tyay again")
|
||||
}
|
||||
|
||||
func TestSinkWithNamedLevel(t *testing.T) {
|
||||
var buf1, buf2 bytes.Buffer
|
||||
globalControls = make(map[string]levelSetter, 16)
|
||||
|
||||
parent, flush := New(
|
||||
"parent",
|
||||
WithConsoleSink(&buf1, WithLevel(0)),
|
||||
WithConsoleSink(&buf2, WithLevel(2)),
|
||||
)
|
||||
child := WithNamedLevel(parent, "child")
|
||||
|
||||
for level := 0; level < 3; level++ {
|
||||
SetLevelFor("child", int8(level))
|
||||
child.Info("")
|
||||
child.V(1).Info("")
|
||||
child.V(2).Info("")
|
||||
}
|
||||
assert.Nil(t, flush())
|
||||
|
||||
// buf1 should get only level 0 logs
|
||||
assert.Equal(t, []string{
|
||||
"info-0\tparent.child",
|
||||
"info-0\tparent.child",
|
||||
"info-0\tparent.child",
|
||||
}, splitLines(buf1.String()))
|
||||
|
||||
assert.Equal(t, []string{
|
||||
// child level 0
|
||||
"info-0\tparent.child",
|
||||
// child level 1
|
||||
"info-0\tparent.child",
|
||||
"info-1\tparent.child",
|
||||
// child level 2
|
||||
"info-0\tparent.child",
|
||||
"info-1\tparent.child",
|
||||
"info-2\tparent.child",
|
||||
}, splitLines(buf2.String()))
|
||||
}
|
||||
|
||||
func TestAddLeveler(t *testing.T) {
|
||||
l1, l2 := zap.NewAtomicLevel(), zap.NewAtomicLevel()
|
||||
logger, _ := New("parent", WithConsoleSink(io.Discard, WithLeveler(l1)))
|
||||
|
||||
t.Run("child level more verbose", func(t *testing.T) {
|
||||
l1.SetLevel(0)
|
||||
l2.SetLevel(1)
|
||||
_, err := AddLeveler(logger, l2)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("child level less verbose", func(t *testing.T) {
|
||||
l1.SetLevel(1)
|
||||
l2.SetLevel(0)
|
||||
_, err := AddLeveler(logger, l2)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func splitLines(s string) []string {
|
||||
lines := strings.Split(strings.TrimSpace(s), "\n")
|
||||
logLines := make([]string, len(lines))
|
||||
@@ -521,28 +233,3 @@ func TestFindLevel(t *testing.T) {
|
||||
assert.Equal(t, i8, findLevel(logger))
|
||||
}
|
||||
}
|
||||
|
||||
func TestOverwriteWithNamedLevel(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
globalControls = make(map[string]levelSetter, 16)
|
||||
|
||||
parent, flush := New(
|
||||
"parent",
|
||||
WithConsoleSink(&buf, WithLevel(2)),
|
||||
)
|
||||
SetLevelFor("child", 0)
|
||||
child1 := WithNamedLevel(parent, "child")
|
||||
child2 := WithNamedLevel(parent, "child")
|
||||
SetLevelFor("child", 2)
|
||||
|
||||
child1.V(2).Info("")
|
||||
child2.V(2).Info("")
|
||||
|
||||
assert.Nil(t, flush())
|
||||
|
||||
// buf1 should get only level 0 logs
|
||||
assert.Equal(t, []string{
|
||||
"info-2\tparent.child",
|
||||
"info-2\tparent.child",
|
||||
}, splitLines(buf.String()))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user