mlog: redefine KVer to return a map[string]interface, not a KV, to allow other packages to implement KVer without importing mlog
This commit is contained in:
parent
fe07e1cfdc
commit
1562c4e8f6
@ -73,8 +73,8 @@ func (pk PublicKey) String() string {
|
||||
}
|
||||
|
||||
// KV implements the method for the mlog.KVer interface
|
||||
func (pk PublicKey) KV() mlog.KV {
|
||||
return mlog.KV{"publicKey": pk.String()}
|
||||
func (pk PublicKey) KV() map[string]interface{} {
|
||||
return map[string]interface{}{"publicKey": pk.String()}
|
||||
}
|
||||
|
||||
// MarshalText implements the method for the encoding.TextMarshaler interface
|
||||
@ -169,8 +169,8 @@ func (pk PrivateKey) String() string {
|
||||
}
|
||||
|
||||
// KV implements the method for the mlog.KVer interface
|
||||
func (pk PrivateKey) KV() mlog.KV {
|
||||
return mlog.KV{"privateKey": pk.String()}
|
||||
func (pk PrivateKey) KV() map[string]interface{} {
|
||||
return map[string]interface{}{"privateKey": pk.String()}
|
||||
}
|
||||
|
||||
// MarshalText implements the method for the encoding.TextMarshaler interface
|
||||
|
@ -51,8 +51,8 @@ func (s Signature) String() string {
|
||||
}
|
||||
|
||||
// KV implements the method for the mlog.KVer interface
|
||||
func (s Signature) KV() mlog.KV {
|
||||
return mlog.KV{"sig": s.String()}
|
||||
func (s Signature) KV() map[string]interface{} {
|
||||
return map[string]interface{}{"sig": s.String()}
|
||||
}
|
||||
|
||||
// MarshalText implements the method for the encoding.TextMarshaler interface
|
||||
|
@ -53,8 +53,8 @@ func (u UUID) Time() time.Time {
|
||||
}
|
||||
|
||||
// KV implements the method for the mlog.KVer interface
|
||||
func (u UUID) KV() mlog.KV {
|
||||
return mlog.KV{"uuid": u.String()}
|
||||
func (u UUID) KV() map[string]interface{} {
|
||||
return map[string]interface{}{"uuid": u.String()}
|
||||
}
|
||||
|
||||
// MarshalText implements the method for the encoding.TextMarshaler interface
|
||||
|
51
mlog/mlog.go
51
mlog/mlog.go
@ -76,26 +76,25 @@ var (
|
||||
// KVer is used to provide context to a log entry in the form of a dynamic set
|
||||
// of key/value pairs which can be different for every entry.
|
||||
//
|
||||
// Each returned KV should be modifiable.
|
||||
// Each returned map should be modifiable.
|
||||
type KVer interface {
|
||||
KV() KV
|
||||
KV() map[string]interface{}
|
||||
}
|
||||
|
||||
// KVerFunc is a function which implements the KVer interface by calling itself.
|
||||
type KVerFunc func() KV
|
||||
type KVerFunc func() map[string]interface{}
|
||||
|
||||
// KV implements the KVer interface by calling the KVerFunc itself.
|
||||
func (kvf KVerFunc) KV() KV {
|
||||
func (kvf KVerFunc) KV() map[string]interface{} {
|
||||
return kvf()
|
||||
}
|
||||
|
||||
// KV is a set of key/value pairs which provides context for a log entry by a
|
||||
// KVer. KV is itself also a KVer.
|
||||
// KV is a KVer which returns a copy of itself when KV is called.
|
||||
type KV map[string]interface{}
|
||||
|
||||
// KV implements the KVer method by returning a copy of the KV
|
||||
func (kv KV) KV() KV {
|
||||
nkv := make(KV, len(kv))
|
||||
// KV implements the KVer method by returning a copy of itself.
|
||||
func (kv KV) KV() map[string]interface{} {
|
||||
nkv := make(map[string]interface{}, len(kv))
|
||||
for k, v := range kv {
|
||||
nkv[k] = v
|
||||
}
|
||||
@ -110,17 +109,25 @@ func (kv KV) Set(k string, v interface{}) KV {
|
||||
return nkv
|
||||
}
|
||||
|
||||
// returns a key/value map which should not be written to. saves a map-cloning
|
||||
// if KVer is a KV
|
||||
func readOnlyKVM(kver KVer) map[string]interface{} {
|
||||
if kver == nil {
|
||||
return map[string]interface{}(nil)
|
||||
} else if kv, ok := kver.(KV); ok {
|
||||
return map[string]interface{}(kv)
|
||||
}
|
||||
return kver.KV()
|
||||
}
|
||||
|
||||
// this may take in any amount of nil values, but should never return nil
|
||||
func mergeInto(kv KVer, kvs ...KVer) KV {
|
||||
func mergeInto(kv KVer, kvs ...KVer) map[string]interface{} {
|
||||
if kv == nil {
|
||||
kv = KV(nil) // will return empty map when KV is called on it
|
||||
}
|
||||
kvm := kv.KV()
|
||||
for _, kv := range kvs {
|
||||
if kv == nil {
|
||||
continue
|
||||
}
|
||||
for k, v := range kv.KV() {
|
||||
for _, innerKV := range kvs {
|
||||
for k, v := range readOnlyKVM(innerKV) {
|
||||
kvm[k] = v
|
||||
}
|
||||
}
|
||||
@ -150,20 +157,20 @@ func MergeInto(kv KVer, kvs ...KVer) KVer {
|
||||
return merger{base: kv, rest: kvs}
|
||||
}
|
||||
|
||||
func (m merger) KV() KV {
|
||||
func (m merger) KV() map[string]interface{} {
|
||||
return mergeInto(m.base, m.rest...)
|
||||
}
|
||||
|
||||
// Prefix prefixes the all keys returned from the given KVer with the given
|
||||
// prefix string.
|
||||
func Prefix(kv KVer, prefix string) KVer {
|
||||
return KVerFunc(func() KV {
|
||||
kvv := kv.KV()
|
||||
newKVV := make(KV, len(kvv))
|
||||
for k, v := range kvv {
|
||||
newKVV[prefix+k] = v
|
||||
return KVerFunc(func() map[string]interface{} {
|
||||
kvm := readOnlyKVM(kv)
|
||||
newKVM := make(map[string]interface{}, len(kvm))
|
||||
for k, v := range kvm {
|
||||
newKVM[prefix+k] = v
|
||||
}
|
||||
return newKVV
|
||||
return newKVM
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -25,23 +25,23 @@ func TestKV(t *T) {
|
||||
massert.Len(kv.KV(), 0),
|
||||
))
|
||||
|
||||
// test that the KV method returns a new KV instance
|
||||
// test that the KV method returns a copy
|
||||
kv = KV{"foo": "a"}
|
||||
kv2 := kv.KV()
|
||||
kvm := kv.KV()
|
||||
kv["bur"] = "b"
|
||||
kv2["bar"] = "bb"
|
||||
kvm["bar"] = "bb"
|
||||
massert.Fatal(t, massert.All(
|
||||
massert.Equal(KV{"foo": "a", "bur": "b"}, kv),
|
||||
massert.Equal(KV{"foo": "a", "bar": "bb"}, kv2),
|
||||
massert.Equal(map[string]interface{}{"foo": "a", "bar": "bb"}, kvm),
|
||||
))
|
||||
|
||||
// test that the Set method returns a new KV instance
|
||||
// test that the Set method returns a copy
|
||||
kv = KV{"foo": "a"}
|
||||
kv2 = kv.Set("bar", "wat")
|
||||
kvm = kv.Set("bar", "wat")
|
||||
kv["bur"] = "ok"
|
||||
massert.Fatal(t, massert.All(
|
||||
massert.Equal(KV{"foo": "a", "bur": "ok"}, kv),
|
||||
massert.Equal(KV{"foo": "a", "bar": "wat"}, kv2),
|
||||
massert.Equal(map[string]interface{}{"foo": "a", "bar": "wat"}, kvm),
|
||||
))
|
||||
}
|
||||
|
||||
@ -144,7 +144,7 @@ func TestDefaultFormat(t *T) {
|
||||
|
||||
func TestMerge(t *T) {
|
||||
assertMerge := func(exp KV, kvs ...KVer) massert.Assertion {
|
||||
return massert.Equal(exp, Merge(kvs...).KV())
|
||||
return massert.Equal(exp.KV(), Merge(kvs...).KV())
|
||||
}
|
||||
|
||||
massert.Fatal(t, massert.All(
|
||||
@ -178,8 +178,8 @@ func TestMerge(t *T) {
|
||||
kv["a"] = "b"
|
||||
massert.Fatal(t, massert.All(
|
||||
massert.Equal(KV{"a": "b"}, kv),
|
||||
massert.Equal(KV{"a": "b"}, kv.KV()),
|
||||
massert.Equal(KV{"a": "b"}, mergedKV.KV()),
|
||||
massert.Equal(map[string]interface{}{"a": "b"}, kv.KV()),
|
||||
massert.Equal(map[string]interface{}{"a": "b"}, mergedKV.KV()),
|
||||
))
|
||||
}
|
||||
}
|
||||
@ -189,8 +189,8 @@ func TestPrefix(t *T) {
|
||||
prefixKV := Prefix(kv, "aa")
|
||||
|
||||
massert.Fatal(t, massert.All(
|
||||
massert.Equal(kv.KV(), KV{"foo": "bar"}),
|
||||
massert.Equal(prefixKV.KV(), KV{"aafoo": "bar"}),
|
||||
massert.Equal(kv.KV(), KV{"foo": "bar"}),
|
||||
massert.Equal(map[string]interface{}{"foo": "bar"}, kv.KV()),
|
||||
massert.Equal(map[string]interface{}{"aafoo": "bar"}, prefixKV.KV()),
|
||||
massert.Equal(map[string]interface{}{"foo": "bar"}, kv.KV()),
|
||||
))
|
||||
}
|
||||
|
@ -53,8 +53,8 @@ func MListen(ctx mctx.Context, network, defaultAddr string) net.Listener {
|
||||
return l
|
||||
}
|
||||
|
||||
func (l *listener) KV() mlog.KV {
|
||||
return mlog.KV{"addr": l.Addr().String()}
|
||||
func (l *listener) KV() map[string]interface{} {
|
||||
return map[string]interface{}{"addr": l.Addr().String()}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
Reference in New Issue
Block a user