@@ -28,25 +28,37 @@ const (
28
28
type LogWarningCallbackFunc func (componentName , componentID , funcName string , actorName interface {}, err error , msg string )
29
29
30
30
var (
31
- // LatestWarnings are a small number of the most recent log messages (warnings and info messages ) kept in memory for retrieval and inspection.
31
+ // LatestWarnings are a small number of the most recent log messages
32
+ // (warnings and info messages) kept in memory for retrieval and inspection.
32
33
LatestLogs = datastruct .NewRingBuffer (NumLatestLogEntries )
33
34
34
35
// LatestWarnings are a small number of the most recent warning log messages kept in memory for retrieval and inspection.
35
36
LatestWarnings = datastruct .NewRingBuffer (NumLatestLogEntries )
36
37
37
- // LatestWarningActors are a small number of actors that have recently generated warning messages.
38
- // The LRU buffer helps to gain a more comprehensive picture of the actors that have resulted in warning log messages by
39
- // working as a conditional filter, so that only the first instance of warning from an actor (identified by component name + function name +
40
- // actor name) will be added to the in-memory warning log buffer. The subsequent warning messages of that actor will be excluded from the
41
- // warning buffer. The actor will get another chance to show up in the warning buffer when it eventually becomes stale and is subsequently
42
- // evicted by this LRU buffer.
43
- LatestWarningActors = datastruct .NewLeastRecentlyUsedBuffer (NumLatestLogEntries / 4 )
38
+ // LatestWarningActors a small number of log entry actors that have
39
+ // generated the latest log messages. The buffer provides a daemon-agnostic
40
+ // mechanism that de-duplicates repeated log messages, to avoid flooding
41
+ // stderr too hard, and makes the latest log entries retrieved on-demand
42
+ // much easier to read.
43
+ LatestWarningActors = datastruct .NewLeastRecentlyUsedBuffer (NumLatestLogEntries )
44
+
45
+ // LatestLogMessageContent are small number of recent log messages.
46
+ // The buffer provides a daemon-agnostic mechanism that de-duplicates
47
+ // repeated log messages, to avoid flooding stderr too hard, and makes the
48
+ // latest log entries retrieved on-demand much easier to read.
49
+ LatestLogMessageContent = datastruct .NewLeastRecentlyUsedBuffer (NumLatestLogEntries )
44
50
45
51
// LogWarningCallback is invoked in a separate goroutine after any logger has processed a warning message.
46
52
// The function must avoid generating a warning log message of itself, to avoid an infinite recursion.
47
53
GlobalLogWarningCallback LogWarningCallbackFunc = nil
48
54
)
49
55
56
+ // Clear the global LRU buffers used for de-duplicating log messages.
57
+ func ClearDedupBuffers () {
58
+ LatestWarningActors .Clear ()
59
+ LatestLogMessageContent .Clear ()
60
+ }
61
+
50
62
/*
51
63
LoggerIDField is a field of Logger's ComponentID, all fields that make up a ComponentID offer log entry a clue as to
52
64
which component instance generated the log message.
@@ -124,45 +136,49 @@ func callerName(skip int) string {
124
136
return filepath .Base (file ) + ":" + funName
125
137
}
126
138
127
- // Print a log message and keep the message in warnings buffer.
128
- func (logger * Logger ) Warning (actorName interface {}, err error , template string , values ... interface {}) {
129
- functionName := callerName (2 )
130
- msg := logger .Format (functionName , actorName , err , template , values ... )
131
- msgWithTime := time .Now ().Format ("2006-01-02 15:04:05 " ) + msg
132
- log .Print (msg )
133
- // All warning messages to to the latest logs buffer
134
- LatestLogs .Push (msgWithTime )
139
+ func (logger * Logger ) warning (funcName string , actorName interface {}, err error , template string , values ... interface {}) {
135
140
// As determined by the LRU buffer, only the first instance of warning from this actor (identified by component name + function name +
136
141
// actor name) will be added to the in-memory warning log buffer, this helps to gain a more comprehensive picture of actors behind latest
137
142
// warning messages by suppressing the most noisy actors.
138
- if alreadyPresent , _ := LatestWarningActors .Add (functionName + fmt .Sprint (actorName )); ! alreadyPresent {
139
- LatestWarnings .Push (msgWithTime )
140
- if GlobalLogWarningCallback != nil {
141
- go GlobalLogWarningCallback (logger .ComponentName , logger .getComponentIDs (), functionName , actorName , err , fmt .Sprintf (template , values ... ))
142
- }
143
+ if alreadyPresent , _ := LatestWarningActors .Add (funcName + fmt .Sprint (actorName )); alreadyPresent {
144
+ return
143
145
}
144
- }
146
+ msg := logger .Format (funcName , actorName , err , template , values ... )
147
+ log .Print (msg )
145
148
146
- // Print a log message and keep the message in latest log buffer. If there is an error, also keep the message in warnings buffer.
147
- func (logger * Logger ) Info (actorName interface {}, err error , template string , values ... interface {}) {
148
- functionName := callerName (2 )
149
- msg := logger .Format (functionName , actorName , err , template , values ... )
150
149
msgWithTime := time .Now ().Format ("2006-01-02 15:04:05 " ) + msg
151
150
LatestLogs .Push (msgWithTime )
152
- log .Print (msg )
153
- // If the log message comes with an error, treat it as a warning.
151
+ LatestWarnings .Push (msgWithTime )
152
+
153
+ if GlobalLogWarningCallback != nil {
154
+ go GlobalLogWarningCallback (logger .ComponentName , logger .getComponentIDs (), funcName , actorName , err , fmt .Sprintf (template , values ... ))
155
+ }
156
+ }
157
+
158
+ // Print a log message and keep the message in warnings buffer.
159
+ func (logger * Logger ) Warning (actorName interface {}, err error , template string , values ... interface {}) {
160
+ funcName := callerName (2 )
161
+ logger .warning (funcName , actorName , err , template , values ... )
162
+ }
163
+
164
+ func (logger * Logger ) info (funcName string , actorName interface {}, err error , template string , values ... interface {}) {
154
165
if err != nil {
155
- // As determined by the LRU buffer, only the first instance of warning from this actor (identified by component name + function name +
156
- // actor name) will be added to the in-memory warning log buffer, this helps to gain a more comprehensive picture of actors behind latest
157
- // warning messages by suppressing the most noisy actors.
158
- if alreadyPresent , _ := LatestWarningActors .Add (functionName + fmt .Sprint (actorName )); ! alreadyPresent {
159
- LatestWarnings .Push (msgWithTime )
160
- if GlobalLogWarningCallback != nil {
161
- go GlobalLogWarningCallback (logger .ComponentName , logger .getComponentIDs (), functionName , actorName , err , fmt .Sprintf (template , values ... ))
162
- }
163
- }
166
+ // If the log message comes with an error, treat it as a warning.
167
+ logger .warning (funcName , actorName , err , template , values ... )
168
+ }
169
+ msg := logger .Format (funcName , actorName , err , template , values ... )
170
+ if alreadyPresent , _ := LatestLogMessageContent .Add (msg ); alreadyPresent {
164
171
return
165
172
}
173
+ msgWithTime := time .Now ().Format ("2006-01-02 15:04:05 " ) + msg
174
+ log .Print (msg )
175
+ LatestLogs .Push (msgWithTime )
176
+ }
177
+
178
+ // Print a log message and keep the message in latest log buffer. If there is an error, also keep the message in warnings buffer.
179
+ func (logger * Logger ) Info (actorName interface {}, err error , template string , values ... interface {}) {
180
+ funcName := callerName (2 )
181
+ logger .info (funcName , actorName , err , template , values ... )
166
182
}
167
183
168
184
func (logger * Logger ) Abort (actorName interface {}, err error , template string , values ... interface {}) {
0 commit comments