initial commit
[govpp.git] / vendor / github.com / Sirupsen / logrus / entry.go
1 package logrus
2
3 import (
4         "bytes"
5         "fmt"
6         "os"
7         "sync"
8         "time"
9 )
10
11 var bufferPool *sync.Pool
12
13 func init() {
14         bufferPool = &sync.Pool{
15                 New: func() interface{} {
16                         return new(bytes.Buffer)
17                 },
18         }
19 }
20
21 // Defines the key when adding errors using WithError.
22 var ErrorKey = "error"
23
24 // An entry is the final or intermediate Logrus logging entry. It contains all
25 // the fields passed with WithField{,s}. It's finally logged when Debug, Info,
26 // Warn, Error, Fatal or Panic is called on it. These objects can be reused and
27 // passed around as much as you wish to avoid field duplication.
28 type Entry struct {
29         Logger *Logger
30
31         // Contains all the fields set by the user.
32         Data Fields
33
34         // Time at which the log entry was created
35         Time time.Time
36
37         // Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic
38         Level Level
39
40         // Message passed to Debug, Info, Warn, Error, Fatal or Panic
41         Message string
42
43         // When formatter is called in entry.log(), an Buffer may be set to entry
44         Buffer *bytes.Buffer
45 }
46
47 func NewEntry(logger *Logger) *Entry {
48         return &Entry{
49                 Logger: logger,
50                 // Default is three fields, give a little extra room
51                 Data: make(Fields, 5),
52         }
53 }
54
55 // Returns the string representation from the reader and ultimately the
56 // formatter.
57 func (entry *Entry) String() (string, error) {
58         serialized, err := entry.Logger.Formatter.Format(entry)
59         if err != nil {
60                 return "", err
61         }
62         str := string(serialized)
63         return str, nil
64 }
65
66 // Add an error as single field (using the key defined in ErrorKey) to the Entry.
67 func (entry *Entry) WithError(err error) *Entry {
68         return entry.WithField(ErrorKey, err)
69 }
70
71 // Add a single field to the Entry.
72 func (entry *Entry) WithField(key string, value interface{}) *Entry {
73         return entry.WithFields(Fields{key: value})
74 }
75
76 // Add a map of fields to the Entry.
77 func (entry *Entry) WithFields(fields Fields) *Entry {
78         data := make(Fields, len(entry.Data)+len(fields))
79         for k, v := range entry.Data {
80                 data[k] = v
81         }
82         for k, v := range fields {
83                 data[k] = v
84         }
85         return &Entry{Logger: entry.Logger, Data: data}
86 }
87
88 // This function is not declared with a pointer value because otherwise
89 // race conditions will occur when using multiple goroutines
90 func (entry Entry) log(level Level, msg string) {
91         var buffer *bytes.Buffer
92         entry.Time = time.Now()
93         entry.Level = level
94         entry.Message = msg
95
96         if err := entry.Logger.Hooks.Fire(level, &entry); err != nil {
97                 entry.Logger.mu.Lock()
98                 fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
99                 entry.Logger.mu.Unlock()
100         }
101         buffer = bufferPool.Get().(*bytes.Buffer)
102         buffer.Reset()
103         defer bufferPool.Put(buffer)
104         entry.Buffer = buffer
105         serialized, err := entry.Logger.Formatter.Format(&entry)
106         entry.Buffer = nil
107         if err != nil {
108                 entry.Logger.mu.Lock()
109                 fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
110                 entry.Logger.mu.Unlock()
111         } else {
112                 entry.Logger.mu.Lock()
113                 _, err = entry.Logger.Out.Write(serialized)
114                 if err != nil {
115                         fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
116                 }
117                 entry.Logger.mu.Unlock()
118         }
119
120         // To avoid Entry#log() returning a value that only would make sense for
121         // panic() to use in Entry#Panic(), we avoid the allocation by checking
122         // directly here.
123         if level <= PanicLevel {
124                 panic(&entry)
125         }
126 }
127
128 func (entry *Entry) Debug(args ...interface{}) {
129         if entry.Logger.Level >= DebugLevel {
130                 entry.log(DebugLevel, fmt.Sprint(args...))
131         }
132 }
133
134 func (entry *Entry) Print(args ...interface{}) {
135         entry.Info(args...)
136 }
137
138 func (entry *Entry) Info(args ...interface{}) {
139         if entry.Logger.Level >= InfoLevel {
140                 entry.log(InfoLevel, fmt.Sprint(args...))
141         }
142 }
143
144 func (entry *Entry) Warn(args ...interface{}) {
145         if entry.Logger.Level >= WarnLevel {
146                 entry.log(WarnLevel, fmt.Sprint(args...))
147         }
148 }
149
150 func (entry *Entry) Warning(args ...interface{}) {
151         entry.Warn(args...)
152 }
153
154 func (entry *Entry) Error(args ...interface{}) {
155         if entry.Logger.Level >= ErrorLevel {
156                 entry.log(ErrorLevel, fmt.Sprint(args...))
157         }
158 }
159
160 func (entry *Entry) Fatal(args ...interface{}) {
161         if entry.Logger.Level >= FatalLevel {
162                 entry.log(FatalLevel, fmt.Sprint(args...))
163         }
164         Exit(1)
165 }
166
167 func (entry *Entry) Panic(args ...interface{}) {
168         if entry.Logger.Level >= PanicLevel {
169                 entry.log(PanicLevel, fmt.Sprint(args...))
170         }
171         panic(fmt.Sprint(args...))
172 }
173
174 // Entry Printf family functions
175
176 func (entry *Entry) Debugf(format string, args ...interface{}) {
177         if entry.Logger.Level >= DebugLevel {
178                 entry.Debug(fmt.Sprintf(format, args...))
179         }
180 }
181
182 func (entry *Entry) Infof(format string, args ...interface{}) {
183         if entry.Logger.Level >= InfoLevel {
184                 entry.Info(fmt.Sprintf(format, args...))
185         }
186 }
187
188 func (entry *Entry) Printf(format string, args ...interface{}) {
189         entry.Infof(format, args...)
190 }
191
192 func (entry *Entry) Warnf(format string, args ...interface{}) {
193         if entry.Logger.Level >= WarnLevel {
194                 entry.Warn(fmt.Sprintf(format, args...))
195         }
196 }
197
198 func (entry *Entry) Warningf(format string, args ...interface{}) {
199         entry.Warnf(format, args...)
200 }
201
202 func (entry *Entry) Errorf(format string, args ...interface{}) {
203         if entry.Logger.Level >= ErrorLevel {
204                 entry.Error(fmt.Sprintf(format, args...))
205         }
206 }
207
208 func (entry *Entry) Fatalf(format string, args ...interface{}) {
209         if entry.Logger.Level >= FatalLevel {
210                 entry.Fatal(fmt.Sprintf(format, args...))
211         }
212         Exit(1)
213 }
214
215 func (entry *Entry) Panicf(format string, args ...interface{}) {
216         if entry.Logger.Level >= PanicLevel {
217                 entry.Panic(fmt.Sprintf(format, args...))
218         }
219 }
220
221 // Entry Println family functions
222
223 func (entry *Entry) Debugln(args ...interface{}) {
224         if entry.Logger.Level >= DebugLevel {
225                 entry.Debug(entry.sprintlnn(args...))
226         }
227 }
228
229 func (entry *Entry) Infoln(args ...interface{}) {
230         if entry.Logger.Level >= InfoLevel {
231                 entry.Info(entry.sprintlnn(args...))
232         }
233 }
234
235 func (entry *Entry) Println(args ...interface{}) {
236         entry.Infoln(args...)
237 }
238
239 func (entry *Entry) Warnln(args ...interface{}) {
240         if entry.Logger.Level >= WarnLevel {
241                 entry.Warn(entry.sprintlnn(args...))
242         }
243 }
244
245 func (entry *Entry) Warningln(args ...interface{}) {
246         entry.Warnln(args...)
247 }
248
249 func (entry *Entry) Errorln(args ...interface{}) {
250         if entry.Logger.Level >= ErrorLevel {
251                 entry.Error(entry.sprintlnn(args...))
252         }
253 }
254
255 func (entry *Entry) Fatalln(args ...interface{}) {
256         if entry.Logger.Level >= FatalLevel {
257                 entry.Fatal(entry.sprintlnn(args...))
258         }
259         Exit(1)
260 }
261
262 func (entry *Entry) Panicln(args ...interface{}) {
263         if entry.Logger.Level >= PanicLevel {
264                 entry.Panic(entry.sprintlnn(args...))
265         }
266 }
267
268 // Sprintlnn => Sprint no newline. This is to get the behavior of how
269 // fmt.Sprintln where spaces are always added between operands, regardless of
270 // their type. Instead of vendoring the Sprintln implementation to spare a
271 // string allocation, we do the simplest thing.
272 func (entry *Entry) sprintlnn(args ...interface{}) string {
273         msg := fmt.Sprintln(args...)
274         return msg[:len(msg)-1]
275 }