-
Notifications
You must be signed in to change notification settings - Fork 1
/
logger.go
151 lines (121 loc) · 3.36 KB
/
logger.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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package logging
import (
"errors"
"os"
"sync"
"github.com/deciduosity/grip/level"
"github.com/deciduosity/grip/message"
"github.com/deciduosity/grip/send"
)
// Grip provides the core implementation of the Logging interface. The
// interface is mirrored in the "grip" package's public interface, to
// provide a single, global logging interface that requires minimal
// configuration.
type Grip struct {
impl send.Sender
defaultLevel level.Priority
mu sync.RWMutex
}
// MakeGrip builds a new logging interface from a sender implmementation
func MakeGrip(s send.Sender) *Grip {
return &Grip{
impl: s,
defaultLevel: level.Info,
}
}
// NewGrip takes the name for a logging instance and creates a new
// Grip instance with configured with a local, standard output logging.
// The default level is "Notice" and the threshold level is "info."
func NewGrip(name string) *Grip {
sender, _ := send.NewNativeLogger(name,
send.LevelInfo{
Threshold: level.Trace,
Default: level.Trace,
})
return &Grip{impl: sender}
}
func (g *Grip) Name() string {
g.mu.RLock()
defer g.mu.RUnlock()
return g.impl.Name()
}
func (g *Grip) SetName(n string) {
g.mu.RLock()
defer g.mu.RUnlock()
g.impl.SetName(n)
}
func (g *Grip) SetLevel(info send.LevelInfo) error {
g.mu.RLock()
defer g.mu.RUnlock()
sl := g.impl.Level()
if !info.Default.IsValid() {
info.Default = sl.Default
}
if !info.Threshold.IsValid() {
info.Threshold = sl.Threshold
}
return g.impl.SetLevel(info)
}
func (g *Grip) Send(m interface{}) {
g.mu.RLock()
defer g.mu.RUnlock()
g.impl.Send(message.ConvertToComposer(g.defaultLevel, m))
}
// SetSender swaps send.Sender() implementations in a logging
// instance. Calls the Close() method on the existing instance before
// changing the implementation for the current instance. SetSender
// will configure the incoming sender to have the same name as well as
// default and threshold level as the outgoing sender.
func (g *Grip) SetSender(s send.Sender) error {
if s == nil {
return errors.New("cannot set the sender to nil")
}
g.mu.Lock()
defer g.mu.Unlock()
if err := s.SetLevel(g.impl.Level()); err != nil {
return err
}
if err := g.impl.Close(); err != nil {
return err
}
s.SetName(g.impl.Name())
g.impl = s
return nil
}
// GetSender returns the current Journaler's sender instance. Use this in
// combination with SetSender() to have multiple Journaler instances
// backed by the same send.Sender instance.
func (g *Grip) GetSender() send.Sender {
g.mu.RLock()
defer g.mu.RUnlock()
return g.impl
}
// Internal
// For sending logging messages, in most cases, use the
// Journaler.sender.Send() method, but we have a couple of methods to
// use for the Panic/Fatal helpers.
func (g *Grip) sendPanic(m message.Composer) {
// the Send method in the Sender interface will perform this
// check but to add fatal methods we need to do this here.
g.mu.RLock()
defer g.mu.RUnlock()
if g.impl.Level().ShouldLog(m) {
g.impl.Send(m)
panic(m.String())
}
}
func (g *Grip) sendFatal(m message.Composer) {
// the Send method in the Sender interface will perform this
// check but to add fatal methods we need to do this here.
g.mu.RLock()
defer g.mu.RUnlock()
if g.impl.Level().ShouldLog(m) {
g.impl.Send(m)
os.Exit(1)
}
}
func (g *Grip) send(m message.Composer) {
g.mu.RLock()
defer g.mu.RUnlock()
g.impl.Send(m)
}