barometer: update DMA's vendoring packages
[barometer.git] / src / dma / vendor / github.com / labstack / gommon / log / log.go
1 package log
2
3 import (
4         "bytes"
5         "encoding/json"
6         "fmt"
7         "io"
8         "os"
9         "path"
10         "runtime"
11         "strconv"
12         "sync"
13         "time"
14
15         "github.com/mattn/go-isatty"
16         "github.com/valyala/fasttemplate"
17
18         "github.com/labstack/gommon/color"
19 )
20
21 type (
22         Logger struct {
23                 prefix     string
24                 level      Lvl
25                 skip       int
26                 output     io.Writer
27                 template   *fasttemplate.Template
28                 levels     []string
29                 color      *color.Color
30                 bufferPool sync.Pool
31                 mutex      sync.Mutex
32         }
33
34         Lvl uint8
35
36         JSON map[string]interface{}
37 )
38
39 const (
40         DEBUG Lvl = iota + 1
41         INFO
42         WARN
43         ERROR
44         OFF
45         panicLevel
46         fatalLevel
47 )
48
49 var (
50         global        = New("-")
51         defaultHeader = `{"time":"${time_rfc3339_nano}","level":"${level}","prefix":"${prefix}",` +
52                 `"file":"${short_file}","line":"${line}"}`
53 )
54
55 func init() {
56         global.skip = 3
57 }
58
59 func New(prefix string) (l *Logger) {
60         l = &Logger{
61                 level:    INFO,
62                 skip:     2,
63                 prefix:   prefix,
64                 template: l.newTemplate(defaultHeader),
65                 color:    color.New(),
66                 bufferPool: sync.Pool{
67                         New: func() interface{} {
68                                 return bytes.NewBuffer(make([]byte, 256))
69                         },
70                 },
71         }
72         l.initLevels()
73         l.SetOutput(output())
74         return
75 }
76
77 func (l *Logger) initLevels() {
78         l.levels = []string{
79                 "-",
80                 l.color.Blue("DEBUG"),
81                 l.color.Green("INFO"),
82                 l.color.Yellow("WARN"),
83                 l.color.Red("ERROR"),
84                 "",
85                 l.color.Yellow("PANIC", color.U),
86                 l.color.Red("FATAL", color.U),
87         }
88 }
89
90 func (l *Logger) newTemplate(format string) *fasttemplate.Template {
91         return fasttemplate.New(format, "${", "}")
92 }
93
94 func (l *Logger) DisableColor() {
95         l.color.Disable()
96         l.initLevels()
97 }
98
99 func (l *Logger) EnableColor() {
100         l.color.Enable()
101         l.initLevels()
102 }
103
104 func (l *Logger) Prefix() string {
105         return l.prefix
106 }
107
108 func (l *Logger) SetPrefix(p string) {
109         l.prefix = p
110 }
111
112 func (l *Logger) Level() Lvl {
113         return l.level
114 }
115
116 func (l *Logger) SetLevel(v Lvl) {
117         l.level = v
118 }
119
120 func (l *Logger) Output() io.Writer {
121         return l.output
122 }
123
124 func (l *Logger) SetOutput(w io.Writer) {
125         l.output = w
126         if w, ok := w.(*os.File); !ok || !isatty.IsTerminal(w.Fd()) {
127                 l.DisableColor()
128         }
129 }
130
131 func (l *Logger) Color() *color.Color {
132         return l.color
133 }
134
135 func (l *Logger) SetHeader(h string) {
136         l.template = l.newTemplate(h)
137 }
138
139 func (l *Logger) Print(i ...interface{}) {
140         l.log(0, "", i...)
141         // fmt.Fprintln(l.output, i...)
142 }
143
144 func (l *Logger) Printf(format string, args ...interface{}) {
145         l.log(0, format, args...)
146 }
147
148 func (l *Logger) Printj(j JSON) {
149         l.log(0, "json", j)
150 }
151
152 func (l *Logger) Debug(i ...interface{}) {
153         l.log(DEBUG, "", i...)
154 }
155
156 func (l *Logger) Debugf(format string, args ...interface{}) {
157         l.log(DEBUG, format, args...)
158 }
159
160 func (l *Logger) Debugj(j JSON) {
161         l.log(DEBUG, "json", j)
162 }
163
164 func (l *Logger) Info(i ...interface{}) {
165         l.log(INFO, "", i...)
166 }
167
168 func (l *Logger) Infof(format string, args ...interface{}) {
169         l.log(INFO, format, args...)
170 }
171
172 func (l *Logger) Infoj(j JSON) {
173         l.log(INFO, "json", j)
174 }
175
176 func (l *Logger) Warn(i ...interface{}) {
177         l.log(WARN, "", i...)
178 }
179
180 func (l *Logger) Warnf(format string, args ...interface{}) {
181         l.log(WARN, format, args...)
182 }
183
184 func (l *Logger) Warnj(j JSON) {
185         l.log(WARN, "json", j)
186 }
187
188 func (l *Logger) Error(i ...interface{}) {
189         l.log(ERROR, "", i...)
190 }
191
192 func (l *Logger) Errorf(format string, args ...interface{}) {
193         l.log(ERROR, format, args...)
194 }
195
196 func (l *Logger) Errorj(j JSON) {
197         l.log(ERROR, "json", j)
198 }
199
200 func (l *Logger) Fatal(i ...interface{}) {
201         l.log(fatalLevel, "", i...)
202         os.Exit(1)
203 }
204
205 func (l *Logger) Fatalf(format string, args ...interface{}) {
206         l.log(fatalLevel, format, args...)
207         os.Exit(1)
208 }
209
210 func (l *Logger) Fatalj(j JSON) {
211         l.log(fatalLevel, "json", j)
212         os.Exit(1)
213 }
214
215 func (l *Logger) Panic(i ...interface{}) {
216         l.log(panicLevel, "", i...)
217         panic(fmt.Sprint(i...))
218 }
219
220 func (l *Logger) Panicf(format string, args ...interface{}) {
221         l.log(panicLevel, format, args...)
222         panic(fmt.Sprintf(format, args...))
223 }
224
225 func (l *Logger) Panicj(j JSON) {
226         l.log(panicLevel, "json", j)
227         panic(j)
228 }
229
230 func DisableColor() {
231         global.DisableColor()
232 }
233
234 func EnableColor() {
235         global.EnableColor()
236 }
237
238 func Prefix() string {
239         return global.Prefix()
240 }
241
242 func SetPrefix(p string) {
243         global.SetPrefix(p)
244 }
245
246 func Level() Lvl {
247         return global.Level()
248 }
249
250 func SetLevel(v Lvl) {
251         global.SetLevel(v)
252 }
253
254 func Output() io.Writer {
255         return global.Output()
256 }
257
258 func SetOutput(w io.Writer) {
259         global.SetOutput(w)
260 }
261
262 func SetHeader(h string) {
263         global.SetHeader(h)
264 }
265
266 func Print(i ...interface{}) {
267         global.Print(i...)
268 }
269
270 func Printf(format string, args ...interface{}) {
271         global.Printf(format, args...)
272 }
273
274 func Printj(j JSON) {
275         global.Printj(j)
276 }
277
278 func Debug(i ...interface{}) {
279         global.Debug(i...)
280 }
281
282 func Debugf(format string, args ...interface{}) {
283         global.Debugf(format, args...)
284 }
285
286 func Debugj(j JSON) {
287         global.Debugj(j)
288 }
289
290 func Info(i ...interface{}) {
291         global.Info(i...)
292 }
293
294 func Infof(format string, args ...interface{}) {
295         global.Infof(format, args...)
296 }
297
298 func Infoj(j JSON) {
299         global.Infoj(j)
300 }
301
302 func Warn(i ...interface{}) {
303         global.Warn(i...)
304 }
305
306 func Warnf(format string, args ...interface{}) {
307         global.Warnf(format, args...)
308 }
309
310 func Warnj(j JSON) {
311         global.Warnj(j)
312 }
313
314 func Error(i ...interface{}) {
315         global.Error(i...)
316 }
317
318 func Errorf(format string, args ...interface{}) {
319         global.Errorf(format, args...)
320 }
321
322 func Errorj(j JSON) {
323         global.Errorj(j)
324 }
325
326 func Fatal(i ...interface{}) {
327         global.Fatal(i...)
328 }
329
330 func Fatalf(format string, args ...interface{}) {
331         global.Fatalf(format, args...)
332 }
333
334 func Fatalj(j JSON) {
335         global.Fatalj(j)
336 }
337
338 func Panic(i ...interface{}) {
339         global.Panic(i...)
340 }
341
342 func Panicf(format string, args ...interface{}) {
343         global.Panicf(format, args...)
344 }
345
346 func Panicj(j JSON) {
347         global.Panicj(j)
348 }
349
350 func (l *Logger) log(v Lvl, format string, args ...interface{}) {
351         l.mutex.Lock()
352         defer l.mutex.Unlock()
353         buf := l.bufferPool.Get().(*bytes.Buffer)
354         buf.Reset()
355         defer l.bufferPool.Put(buf)
356         _, file, line, _ := runtime.Caller(l.skip)
357
358         if v >= l.level || v == 0 {
359                 message := ""
360                 if format == "" {
361                         message = fmt.Sprint(args...)
362                 } else if format == "json" {
363                         b, err := json.Marshal(args[0])
364                         if err != nil {
365                                 panic(err)
366                         }
367                         message = string(b)
368                 } else {
369                         message = fmt.Sprintf(format, args...)
370                 }
371
372                 _, err := l.template.ExecuteFunc(buf, func(w io.Writer, tag string) (int, error) {
373                         switch tag {
374                         case "time_rfc3339":
375                                 return w.Write([]byte(time.Now().Format(time.RFC3339)))
376                         case "time_rfc3339_nano":
377                                 return w.Write([]byte(time.Now().Format(time.RFC3339Nano)))
378                         case "level":
379                                 return w.Write([]byte(l.levels[v]))
380                         case "prefix":
381                                 return w.Write([]byte(l.prefix))
382                         case "long_file":
383                                 return w.Write([]byte(file))
384                         case "short_file":
385                                 return w.Write([]byte(path.Base(file)))
386                         case "line":
387                                 return w.Write([]byte(strconv.Itoa(line)))
388                         }
389                         return 0, nil
390                 })
391
392                 if err == nil {
393                         s := buf.String()
394                         i := buf.Len() - 1
395                         if s[i] == '}' {
396                                 // JSON header
397                                 buf.Truncate(i)
398                                 buf.WriteByte(',')
399                                 if format == "json" {
400                                         buf.WriteString(message[1:])
401                                 } else {
402                                         buf.WriteString(`"message":`)
403                                         buf.WriteString(strconv.Quote(message))
404                                         buf.WriteString(`}`)
405                                 }
406                         } else {
407                                 // Text header
408                                 buf.WriteByte(' ')
409                                 buf.WriteString(message)
410                         }
411                         buf.WriteByte('\n')
412                         l.output.Write(buf.Bytes())
413                 }
414         }
415 }