-
-
Notifications
You must be signed in to change notification settings - Fork 43
/
formatter.go
83 lines (71 loc) · 1.94 KB
/
formatter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package golog
import (
"encoding/json"
"io"
"sync"
)
// Formatter is responsible to print a log to the logger's writer.
type Formatter interface {
// The name of the formatter.
String() string
// Set any options and return a clone,
// generic. See `Logger.SetFormat`.
Options(opts ...interface{}) Formatter
// Writes the "log" to "dest" logger.
Format(dest io.Writer, log *Log) bool
}
// JSONFormatter is a Formatter type for JSON logs.
type JSONFormatter struct {
Indent string
// Use one encoder per level, do not create new each time.
// Even if the jser can set a different formatter for each level
// on SetLevelFormat, the encoding's writers may be different
// if that ^ is not called but SetLevelOutput did provide a different writer.
encoders map[Level]*json.Encoder
mu sync.RWMutex // encoders locker.
encMu sync.Mutex // encode action locker.
}
// String returns the name of the Formatter.
// In this case it returns "json".
// It's used to map the formatter names with their implementations.
func (f *JSONFormatter) String() string {
return "json"
}
// Options sets the options for the JSON Formatter (currently only indent).
func (f *JSONFormatter) Options(opts ...interface{}) Formatter {
formatter := &JSONFormatter{
Indent: " ",
encoders: make(map[Level]*json.Encoder, len(Levels)),
}
for _, opt := range opts {
if opt == nil {
continue
}
if indent, ok := opt.(string); ok {
formatter.Indent = indent
break
}
}
return formatter
}
// Format prints the logs in JSON format.
//
// Usage:
// logger.SetFormat("json") or
// logger.SetLevelFormat("info", "json")
func (f *JSONFormatter) Format(dest io.Writer, log *Log) bool {
f.mu.RLock()
enc, ok := f.encoders[log.Level]
f.mu.RUnlock()
if !ok {
enc = json.NewEncoder(dest)
enc.SetIndent("", f.Indent)
f.mu.Lock()
f.encoders[log.Level] = enc
f.mu.Unlock()
}
f.encMu.Lock()
err := enc.Encode(log)
f.encMu.Unlock()
return err == nil
}