Skip to content

Commit

Permalink
nest: Add PreNest marker (and other cleanups)
Browse files Browse the repository at this point in the history
The PreNest marker allows us to drop the empty-string delimiters from
library callers and still get readable output from fmt.Print-style
renderers.  I've added a new unit test showing that log
implementations that want to detect Markers should use
reflect.DeepEqual or something else that is stricter than ==.

I've also adjusted the expected order of keys in the unit-test map.
Currently this output is unstable, but [1,2,3] will have the order
stabilized in future Go releases.  The change here sets us up for
compatibility with that new logic.

I've also made the Newf and Logf implementations more compact by
turning them into wrappers around New and Log respectively.

[1]: https://go-review.googlesource.com/c/go/+/142737/
[2]: golang/go@a440cc0
[3]: golang/go#21095
  • Loading branch information
wking committed Nov 12, 2018
1 parent 86a9864 commit 0049de3
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 9 deletions.
37 changes: 31 additions & 6 deletions nest/nest.go
Expand Up @@ -8,17 +8,45 @@ import (
"github.com/go-log/log"
)

const (
// PreNest is a marker placed between the parent and child values
// when calling the wrapped Log method. For example:
//
// parent := SomeLogger()
// child := New(parent, "a", "b")
// child.Log("c", "d")
//
// will result in:
//
// parent.Log("a", "b", PreLog, "c", "d")
PreNest Marker = "pre-nest"
)

// Marker is a string synonym. The type difference allows underlying
// log implementations to distinguish between the PreNest marker and a
// "pre-nest" string literal.
type Marker string

// String returns a single space (regardless of the underlying marker
// string). This makes the output of parent loggers based on a
// fmt.Print style more readable, because fmt.Print only inserts space
// between two non-string operands.
func (m Marker) String() string {
return " "
}

type logger struct {
logger log.Logger
values []interface{}
}

func (logger *logger) Log(v ...interface{}) {
logger.logger.Log(append(logger.values, v...)...)
values := append(logger.values, PreNest)
logger.logger.Log(append(values, v...)...)
}

func (logger *logger) Logf(format string, v ...interface{}) {
logger.logger.Log(append(logger.values, fmt.Sprintf(format, v...))...)
logger.Log(fmt.Sprintf(format, v...))
}

func New(log log.Logger, v ...interface{}) *logger {
Expand All @@ -29,8 +57,5 @@ func New(log log.Logger, v ...interface{}) *logger {
}

func Newf(log log.Logger, format string, v ...interface{}) *logger {
return &logger{
logger: log,
values: []interface{}{fmt.Sprintf(format, v...)},
}
return New(log, fmt.Sprintf(format, v...))
}
17 changes: 14 additions & 3 deletions nest/nest_test.go
@@ -1,17 +1,18 @@
package nest

import (
"reflect"
"testing"

"github.com/go-log/log/capture"
)

func TestNew(t *testing.T) {
base := capture.New()
logger := New(base, " ", map[string]interface{}{"key": "value", "count": 1}, " ")
logger := New(base, map[string]interface{}{"count": 1, "key": "value"})
logger.Log("Log()", "arg")
logger.Logf("Logf(%s)", "arg")
expectedEntries := []string{" map[key:value count:1] Log()arg", " map[key:value count:1] Logf(arg)"}
expectedEntries := []string{"map[count:1 key:value] Log()arg", "map[count:1 key:value] Logf(arg)"}
for i, expectedEntry := range expectedEntries {
if i >= len(base.Entries) {
t.Errorf("missing expected entry %d: %q", i, expectedEntry)
Expand All @@ -32,7 +33,7 @@ func TestNewf(t *testing.T) {
logger := Newf(base, "wrap(%s,%d)", "a", 1)
logger.Log("Log()", "arg")
logger.Logf("Logf(%s)", "arg")
expectedEntries := []string{"wrap(a,1)Log()arg", "wrap(a,1)Logf(arg)"}
expectedEntries := []string{"wrap(a,1) Log()arg", "wrap(a,1) Logf(arg)"}
for i, expectedEntry := range expectedEntries {
if i >= len(base.Entries) {
t.Errorf("missing expected entry %d: %q", i, expectedEntry)
Expand All @@ -47,3 +48,13 @@ func TestNewf(t *testing.T) {
t.Errorf("additional unexpected entries: %v", base.Entries[len(expectedEntries):])
}
}

func TestPreNestComparison(t *testing.T) {
if PreNest != "pre-nest" {
t.Fatal("the type difference is insufficient to break equality")
}

if reflect.DeepEqual(PreNest, "pre-nest") {
t.Fatal("DeepEqual should be able to distinguish the marker")
}
}

0 comments on commit 0049de3

Please sign in to comment.