OSDN Git Service

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