-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathlog.go
More file actions
162 lines (130 loc) · 4.37 KB
/
Copy pathlog.go
File metadata and controls
162 lines (130 loc) · 4.37 KB
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
152
153
154
155
156
157
158
159
160
161
162
package connect
import (
"sync/atomic"
"github.com/urnetwork/glog"
)
// Logging level convention in the `connect` package and generally for BringYour network components:
// Info:
// essential events for abnormal behavior. This level should be silent on normal operation,
// with the exception of infrequent data that is useful for monitoring flows:
// - backpressure and connectivity timeouts
// - recoverable abnormal exits.
// This includes exits caused by external behavior such as bad messages.
// [glog V(1)]
// key events for trace debuggung and statistics:
// - start/end traces
// - key system events with ids that can be used to trace flows
// [glog V(2)]
// specific use-case logging
// Warning:
// recovered unexpected crash details
// Error:
// unexpected crash details
// Log messages should be concise and start with a unique [component] tag
// where component is the relevant part of the system.
// `connect` is meant to be embedded, so components log through a `Logger`
// instance instead of the global glog functions. Each top-level settings
// struct has a `Log` field; nil resolves to `DefaultLogger()` at
// construction, and parents pass their logger down to the components they
// create. The glog-backed logger is the default, preserving the historical
// behavior. Embedders that need silence (e.g. a host running thousands of
// clients in one process) set `NewNoopLogger()` on the settings of the
// components they create, and `SetDefaultLogger` for the process-global
// components (message pool, trace).
//
// Outside of this file, glog must not be referenced directly.
type Logger interface {
Info(args ...any)
Infof(format string, args ...any)
Warningf(format string, args ...any)
Errorf(format string, args ...any)
V(level int32) Verbose
}
// Verbose mirrors `glog.V` for level-guarded logging,
// so that disabled levels skip argument formatting.
// `if glog.V(2) {` becomes `if log.V(2).Enabled() {`.
type Verbose interface {
Enabled() bool
Info(args ...any)
Infof(format string, args ...any)
}
var defaultLogger atomic.Pointer[Logger]
// DefaultLogger is the logger used by process-global components and wherever
// a settings `Log` is nil. The glog-backed logger unless `SetDefaultLogger`.
func DefaultLogger() Logger {
if log := defaultLogger.Load(); log != nil {
return *log
}
return glogLogger{}
}
// SetDefaultLogger replaces the package default logger. nil resets to the
// glog-backed logger. Components resolve their logger at construction, so
// set this before creating components.
func SetDefaultLogger(log Logger) {
if log == nil {
defaultLogger.Store(nil)
} else {
defaultLogger.Store(&log)
}
}
func loggerOrDefault(log Logger) Logger {
if log == nil {
return DefaultLogger()
}
return log
}
// NewGlogLogger returns the `Logger` backed by the global glog package.
func NewGlogLogger() Logger {
return glogLogger{}
}
// the depth variants keep the logged file:line at the caller
type glogLogger struct{}
func (self glogLogger) Info(args ...any) {
glog.InfoDepth(1, args...)
}
func (self glogLogger) Infof(format string, args ...any) {
glog.InfoDepthf(1, format, args...)
}
func (self glogLogger) Warningf(format string, args ...any) {
glog.WarningDepthf(1, format, args...)
}
func (self glogLogger) Errorf(format string, args ...any) {
glog.ErrorDepthf(1, format, args...)
}
func (self glogLogger) V(level int32) Verbose {
return glogVerbose(glog.VDepth(1, glog.Level(level)))
}
type glogVerbose glog.Verbose
func (self glogVerbose) Enabled() bool {
return bool(self)
}
func (self glogVerbose) Info(args ...any) {
glog.Verbose(self).InfoDepth(1, args...)
}
func (self glogVerbose) Infof(format string, args ...any) {
glog.Verbose(self).InfoDepthf(1, format, args...)
}
// NewNoopLogger returns a `Logger` that discards everything.
func NewNoopLogger() Logger {
return noopLogger{}
}
type noopLogger struct{}
func (self noopLogger) Info(args ...any) {
}
func (self noopLogger) Infof(format string, args ...any) {
}
func (self noopLogger) Warningf(format string, args ...any) {
}
func (self noopLogger) Errorf(format string, args ...any) {
}
func (self noopLogger) V(level int32) Verbose {
return noopVerbose{}
}
type noopVerbose struct{}
func (self noopVerbose) Enabled() bool {
return false
}
func (self noopVerbose) Info(args ...any) {
}
func (self noopVerbose) Infof(format string, args ...any) {
}