OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / go-kit / kit / log / value.go
1 package log
2
3 import (
4         "time"
5
6         "github.com/go-stack/stack"
7 )
8
9 // A Valuer generates a log value. When passed to With or WithPrefix in a
10 // value element (odd indexes), it represents a dynamic value which is re-
11 // evaluated with each log event.
12 type Valuer func() interface{}
13
14 // bindValues replaces all value elements (odd indexes) containing a Valuer
15 // with their generated value.
16 func bindValues(keyvals []interface{}) {
17         for i := 1; i < len(keyvals); i += 2 {
18                 if v, ok := keyvals[i].(Valuer); ok {
19                         keyvals[i] = v()
20                 }
21         }
22 }
23
24 // containsValuer returns true if any of the value elements (odd indexes)
25 // contain a Valuer.
26 func containsValuer(keyvals []interface{}) bool {
27         for i := 1; i < len(keyvals); i += 2 {
28                 if _, ok := keyvals[i].(Valuer); ok {
29                         return true
30                 }
31         }
32         return false
33 }
34
35 // Timestamp returns a timestamp Valuer. It invokes the t function to get the
36 // time; unless you are doing something tricky, pass time.Now.
37 //
38 // Most users will want to use DefaultTimestamp or DefaultTimestampUTC, which
39 // are TimestampFormats that use the RFC3339Nano format.
40 func Timestamp(t func() time.Time) Valuer {
41         return func() interface{} { return t() }
42 }
43
44 // TimestampFormat returns a timestamp Valuer with a custom time format. It
45 // invokes the t function to get the time to format; unless you are doing
46 // something tricky, pass time.Now. The layout string is passed to
47 // Time.Format.
48 //
49 // Most users will want to use DefaultTimestamp or DefaultTimestampUTC, which
50 // are TimestampFormats that use the RFC3339Nano format.
51 func TimestampFormat(t func() time.Time, layout string) Valuer {
52         return func() interface{} {
53                 return timeFormat{
54                         time:   t(),
55                         layout: layout,
56                 }
57         }
58 }
59
60 // A timeFormat represents an instant in time and a layout used when
61 // marshaling to a text format.
62 type timeFormat struct {
63         time   time.Time
64         layout string
65 }
66
67 func (tf timeFormat) String() string {
68         return tf.time.Format(tf.layout)
69 }
70
71 // MarshalText implements encoding.TextMarshaller.
72 func (tf timeFormat) MarshalText() (text []byte, err error) {
73         // The following code adapted from the standard library time.Time.Format
74         // method. Using the same undocumented magic constant to extend the size
75         // of the buffer as seen there.
76         b := make([]byte, 0, len(tf.layout)+10)
77         b = tf.time.AppendFormat(b, tf.layout)
78         return b, nil
79 }
80
81 // Caller returns a Valuer that returns a file and line from a specified depth
82 // in the callstack. Users will probably want to use DefaultCaller.
83 func Caller(depth int) Valuer {
84         return func() interface{} { return stack.Caller(depth) }
85 }
86
87 var (
88         // DefaultTimestamp is a Valuer that returns the current wallclock time,
89         // respecting time zones, when bound.
90         DefaultTimestamp = TimestampFormat(time.Now, time.RFC3339Nano)
91
92         // DefaultTimestampUTC is a Valuer that returns the current time in UTC
93         // when bound.
94         DefaultTimestampUTC = TimestampFormat(
95                 func() time.Time { return time.Now().UTC() },
96                 time.RFC3339Nano,
97         )
98
99         // DefaultCaller is a Valuer that returns the file and line where the Log
100         // method was invoked. It can only be used with log.With.
101         DefaultCaller = Caller(3)
102 )