Skip to content
This repository has been archived by the owner on May 23, 2023. It is now read-only.

Commit

Permalink
Add convenience methods to log.Field
Browse files Browse the repository at this point in the history
Currently the only way to print a `Field` is to define an `Encoder`. This is a
lot of code to write, especially if it's needed just for debugging or a quick
test. Adding a `Value()` method that returns the value as an `interface{}`
(which can be passed to `fmt.Print` functions), as well as a `String()` method.

Also exporting the key field.
  • Loading branch information
RaduBerinde committed Sep 27, 2016
1 parent 0c3154a commit 372d82e
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 25 deletions.
86 changes: 61 additions & 25 deletions log/field.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package log

import "math"
import (
"fmt"
"math"
)

type fieldType int

Expand All @@ -20,13 +23,13 @@ const (
)

// Field instances are constructed via LogBool, LogString, and so on.
// Tracing implementations may then handle them via the Field.Process
// Tracing implementations may then handle them via the Field.Marshal
// method.
//
// "heavily influenced by" (i.e., partially stolen from)
// https://github.com/uber-go/zap
type Field struct {
key string
Key string
fieldType fieldType
numericVal int64
stringVal string
Expand All @@ -36,7 +39,7 @@ type Field struct {
// String adds a string-valued key:value pair to a Span.LogFields() record
func String(key, val string) Field {
return Field{
key: key,
Key: key,
fieldType: stringType,
stringVal: val,
}
Expand All @@ -49,7 +52,7 @@ func Bool(key string, val bool) Field {
numericVal = 1
}
return Field{
key: key,
Key: key,
fieldType: boolType,
numericVal: numericVal,
}
Expand All @@ -58,7 +61,7 @@ func Bool(key string, val bool) Field {
// Int adds an int-valued key:value pair to a Span.LogFields() record
func Int(key string, val int) Field {
return Field{
key: key,
Key: key,
fieldType: intType,
numericVal: int64(val),
}
Expand All @@ -67,7 +70,7 @@ func Int(key string, val int) Field {
// Int32 adds an int32-valued key:value pair to a Span.LogFields() record
func Int32(key string, val int32) Field {
return Field{
key: key,
Key: key,
fieldType: int32Type,
numericVal: int64(val),
}
Expand All @@ -76,7 +79,7 @@ func Int32(key string, val int32) Field {
// Int64 adds an int64-valued key:value pair to a Span.LogFields() record
func Int64(key string, val int64) Field {
return Field{
key: key,
Key: key,
fieldType: int64Type,
numericVal: val,
}
Expand All @@ -85,7 +88,7 @@ func Int64(key string, val int64) Field {
// Uint32 adds a uint32-valued key:value pair to a Span.LogFields() record
func Uint32(key string, val uint32) Field {
return Field{
key: key,
Key: key,
fieldType: uint32Type,
numericVal: int64(val),
}
Expand All @@ -94,7 +97,7 @@ func Uint32(key string, val uint32) Field {
// Uint64 adds a uint64-valued key:value pair to a Span.LogFields() record
func Uint64(key string, val uint64) Field {
return Field{
key: key,
Key: key,
fieldType: uint64Type,
numericVal: int64(val),
}
Expand All @@ -103,7 +106,7 @@ func Uint64(key string, val uint64) Field {
// Float32 adds a float32-valued key:value pair to a Span.LogFields() record
func Float32(key string, val float32) Field {
return Field{
key: key,
Key: key,
fieldType: float32Type,
numericVal: int64(math.Float32bits(val)),
}
Expand All @@ -112,7 +115,7 @@ func Float32(key string, val float32) Field {
// Float64 adds a float64-valued key:value pair to a Span.LogFields() record
func Float64(key string, val float64) Field {
return Field{
key: key,
Key: key,
fieldType: float64Type,
numericVal: int64(math.Float64bits(val)),
}
Expand All @@ -121,7 +124,7 @@ func Float64(key string, val float64) Field {
// Error adds an error with the key "error" to a Span.LogFields() record
func Error(err error) Field {
return Field{
key: "error",
Key: "error",
fieldType: errorType,
interfaceVal: err,
}
Expand All @@ -130,7 +133,7 @@ func Error(err error) Field {
// Object adds an object-valued key:value pair to a Span.LogFields() record
func Object(key string, obj interface{}) Field {
return Field{
key: key,
Key: key,
fieldType: objectType,
interfaceVal: obj,
}
Expand Down Expand Up @@ -173,28 +176,61 @@ type Encoder interface {
func (lf Field) Marshal(visitor Encoder) {
switch lf.fieldType {
case stringType:
visitor.EmitString(lf.key, lf.stringVal)
visitor.EmitString(lf.Key, lf.stringVal)
case boolType:
visitor.EmitBool(lf.key, lf.numericVal != 0)
visitor.EmitBool(lf.Key, lf.numericVal != 0)
case intType:
visitor.EmitInt(lf.key, int(lf.numericVal))
visitor.EmitInt(lf.Key, int(lf.numericVal))
case int32Type:
visitor.EmitInt32(lf.key, int32(lf.numericVal))
visitor.EmitInt32(lf.Key, int32(lf.numericVal))
case int64Type:
visitor.EmitInt64(lf.key, int64(lf.numericVal))
visitor.EmitInt64(lf.Key, int64(lf.numericVal))
case uint32Type:
visitor.EmitUint32(lf.key, uint32(lf.numericVal))
visitor.EmitUint32(lf.Key, uint32(lf.numericVal))
case uint64Type:
visitor.EmitUint64(lf.key, uint64(lf.numericVal))
visitor.EmitUint64(lf.Key, uint64(lf.numericVal))
case float32Type:
visitor.EmitFloat32(lf.key, math.Float32frombits(uint32(lf.numericVal)))
visitor.EmitFloat32(lf.Key, math.Float32frombits(uint32(lf.numericVal)))
case float64Type:
visitor.EmitFloat64(lf.key, math.Float64frombits(uint64(lf.numericVal)))
visitor.EmitFloat64(lf.Key, math.Float64frombits(uint64(lf.numericVal)))
case errorType:
visitor.EmitString(lf.key, lf.interfaceVal.(error).Error())
visitor.EmitString(lf.Key, lf.interfaceVal.(error).Error())
case objectType:
visitor.EmitObject(lf.key, lf.interfaceVal)
visitor.EmitObject(lf.Key, lf.interfaceVal)
case lazyLoggerType:
visitor.EmitLazyLogger(lf.interfaceVal.(LazyLogger))
}
}

// Value returns the field's value as interface{}.
func (lf Field) Value() interface{} {
switch lf.fieldType {
case stringType:
return lf.stringVal
case boolType:
return lf.numericVal != 0
case intType:
return int(lf.numericVal)
case int32Type:
return int32(lf.numericVal)
case int64Type:
return int64(lf.numericVal)
case uint32Type:
return uint32(lf.numericVal)
case uint64Type:
return uint64(lf.numericVal)
case float32Type:
return math.Float32frombits(uint32(lf.numericVal))
case float64Type:
return math.Float64frombits(uint64(lf.numericVal))
case errorType, objectType, lazyLoggerType:
return lf.interfaceVal
default:
return nil
}
}

// String returns a string representation of the key and value.
func (lf Field) String() string {
return fmt.Sprint(lf.Key, ":", lf.Value())
}
35 changes: 35 additions & 0 deletions log/field_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package log

import (
"fmt"
"testing"
)

func TestFieldString(t *testing.T) {
testCases := []struct {
field Field
expected string
}{
{
field: String("key", "value"),
expected: "key:value",
},
{
field: Bool("key", true),
expected: "key:true",
},
{
field: Int("key", 5),
expected: "key:5",
},
{
field: Error(fmt.Errorf("err msg")),
expected: "error:err msg",
},
}
for i, tc := range testCases {
if str := tc.field.String(); str != tc.expected {
t.Errorf("%d: expected '%s', got '%s'", i, tc.expected, str)
}
}
}

0 comments on commit 372d82e

Please sign in to comment.