~juju-qa/ubuntu/xenial/juju/xenial-2.0-beta3

« back to all changes in this revision

Viewing changes to src/gopkg.in/inconshreveable/log15.v2/logger.go

  • Committer: Martin Packman
  • Date: 2016-03-30 19:31:08 UTC
  • mfrom: (1.1.41)
  • Revision ID: martin.packman@canonical.com-20160330193108-h9iz3ak334uk0z5r
Merge new upstream source 2.0~beta3

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
package log15
2
 
 
3
 
import (
4
 
        "fmt"
5
 
        "runtime"
6
 
        "time"
7
 
)
8
 
 
9
 
const timeKey = "t"
10
 
const lvlKey = "lvl"
11
 
const msgKey = "msg"
12
 
const errorKey = "LOG15_ERROR"
13
 
 
14
 
type Lvl int
15
 
 
16
 
const (
17
 
        LvlCrit Lvl = iota
18
 
        LvlError
19
 
        LvlWarn
20
 
        LvlInfo
21
 
        LvlDebug
22
 
)
23
 
 
24
 
// Returns the name of a Lvl
25
 
func (l Lvl) String() string {
26
 
        switch l {
27
 
        case LvlDebug:
28
 
                return "dbug"
29
 
        case LvlInfo:
30
 
                return "info"
31
 
        case LvlWarn:
32
 
                return "warn"
33
 
        case LvlError:
34
 
                return "eror"
35
 
        case LvlCrit:
36
 
                return "crit"
37
 
        default:
38
 
                panic("bad level")
39
 
        }
40
 
}
41
 
 
42
 
// Returns the appropriate Lvl from a string name.
43
 
// Useful for parsing command line args and configuration files.
44
 
func LvlFromString(lvlString string) (Lvl, error) {
45
 
        switch lvlString {
46
 
        case "debug", "dbug":
47
 
                return LvlDebug, nil
48
 
        case "info":
49
 
                return LvlInfo, nil
50
 
        case "warn":
51
 
                return LvlWarn, nil
52
 
        case "error", "eror":
53
 
                return LvlError, nil
54
 
        case "crit":
55
 
                return LvlCrit, nil
56
 
        default:
57
 
                return LvlDebug, fmt.Errorf("Unknown level: %v", lvlString)
58
 
        }
59
 
}
60
 
 
61
 
// A Record is what a Logger asks its handler to write
62
 
type Record struct {
63
 
        Time     time.Time
64
 
        Lvl      Lvl
65
 
        Msg      string
66
 
        Ctx      []interface{}
67
 
        CallPC   [1]uintptr
68
 
        KeyNames RecordKeyNames
69
 
}
70
 
 
71
 
type RecordKeyNames struct {
72
 
        Time string
73
 
        Msg  string
74
 
        Lvl  string
75
 
}
76
 
 
77
 
// A Logger writes key/value pairs to a Handler
78
 
type Logger interface {
79
 
        // New returns a new Logger that has this logger's context plus the given context
80
 
        New(ctx ...interface{}) Logger
81
 
 
82
 
        // SetHandler updates the logger to write records to the specified handler.
83
 
        SetHandler(h Handler)
84
 
 
85
 
        // Log a message at the given level with context key/value pairs
86
 
        Debug(msg string, ctx ...interface{})
87
 
        Info(msg string, ctx ...interface{})
88
 
        Warn(msg string, ctx ...interface{})
89
 
        Error(msg string, ctx ...interface{})
90
 
        Crit(msg string, ctx ...interface{})
91
 
}
92
 
 
93
 
type logger struct {
94
 
        ctx []interface{}
95
 
        h   *swapHandler
96
 
}
97
 
 
98
 
func (l *logger) write(msg string, lvl Lvl, ctx []interface{}) {
99
 
        r := Record{
100
 
                Time: time.Now(),
101
 
                Lvl:  lvl,
102
 
                Msg:  msg,
103
 
                Ctx:  newContext(l.ctx, ctx),
104
 
                KeyNames: RecordKeyNames{
105
 
                        Time: timeKey,
106
 
                        Msg:  msgKey,
107
 
                        Lvl:  lvlKey,
108
 
                },
109
 
        }
110
 
        runtime.Callers(3, r.CallPC[:])
111
 
        l.h.Log(&r)
112
 
}
113
 
 
114
 
func (l *logger) New(ctx ...interface{}) Logger {
115
 
        child := &logger{newContext(l.ctx, ctx), new(swapHandler)}
116
 
        child.SetHandler(l.h)
117
 
        return child
118
 
}
119
 
 
120
 
func newContext(prefix []interface{}, suffix []interface{}) []interface{} {
121
 
        normalizedSuffix := normalize(suffix)
122
 
        newCtx := make([]interface{}, len(prefix)+len(normalizedSuffix))
123
 
        n := copy(newCtx, prefix)
124
 
        copy(newCtx[n:], normalizedSuffix)
125
 
        return newCtx
126
 
}
127
 
 
128
 
func (l *logger) Debug(msg string, ctx ...interface{}) {
129
 
        l.write(msg, LvlDebug, ctx)
130
 
}
131
 
 
132
 
func (l *logger) Info(msg string, ctx ...interface{}) {
133
 
        l.write(msg, LvlInfo, ctx)
134
 
}
135
 
 
136
 
func (l *logger) Warn(msg string, ctx ...interface{}) {
137
 
        l.write(msg, LvlWarn, ctx)
138
 
}
139
 
 
140
 
func (l *logger) Error(msg string, ctx ...interface{}) {
141
 
        l.write(msg, LvlError, ctx)
142
 
}
143
 
 
144
 
func (l *logger) Crit(msg string, ctx ...interface{}) {
145
 
        l.write(msg, LvlCrit, ctx)
146
 
}
147
 
 
148
 
func (l *logger) SetHandler(h Handler) {
149
 
        l.h.Swap(h)
150
 
}
151
 
 
152
 
func normalize(ctx []interface{}) []interface{} {
153
 
        // if the caller passed a Ctx object, then expand it
154
 
        if len(ctx) == 1 {
155
 
                if ctxMap, ok := ctx[0].(Ctx); ok {
156
 
                        ctx = ctxMap.toArray()
157
 
                }
158
 
        }
159
 
 
160
 
        // ctx needs to be even because it's a series of key/value pairs
161
 
        // no one wants to check for errors on logging functions,
162
 
        // so instead of erroring on bad input, we'll just make sure
163
 
        // that things are the right length and users can fix bugs
164
 
        // when they see the output looks wrong
165
 
        if len(ctx)%2 != 0 {
166
 
                ctx = append(ctx, nil, errorKey, "Normalized odd number of arguments by adding nil")
167
 
        }
168
 
 
169
 
        return ctx
170
 
}
171
 
 
172
 
// Lazy allows you to defer calculation of a logged value that is expensive
173
 
// to compute until it is certain that it must be evaluated with the given filters.
174
 
//
175
 
// Lazy may also be used in conjunction with a Logger's New() function
176
 
// to generate a child logger which always reports the current value of changing
177
 
// state.
178
 
//
179
 
// You may wrap any function which takes no arguments to Lazy. It may return any
180
 
// number of values of any type.
181
 
type Lazy struct {
182
 
        Fn interface{}
183
 
}
184
 
 
185
 
// Ctx is a map of key/value pairs to pass as context to a log function
186
 
// Use this only if you really need greater safety around the arguments you pass
187
 
// to the logging functions.
188
 
type Ctx map[string]interface{}
189
 
 
190
 
func (c Ctx) toArray() []interface{} {
191
 
        arr := make([]interface{}, len(c)*2)
192
 
 
193
 
        i := 0
194
 
        for k, v := range c {
195
 
                arr[i] = k
196
 
                arr[i+1] = v
197
 
                i += 2
198
 
        }
199
 
 
200
 
        return arr
201
 
}