log: allow external definition of log handling (#1561)

* poc

* linter: fix

---------

Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io>
This commit is contained in:
Ryan O'Hara-Reid
2024-07-19 10:10:27 +10:00
committed by GitHub
parent 90fee94c76
commit db59b8540e
3 changed files with 42 additions and 4 deletions

17
log/custom_log_hooks.go Normal file
View File

@@ -0,0 +1,17 @@
package log
// CustomLogHook is a function type for external log handling. It should return
// true if the library's internal logging system should be bypassed, or false
// if the library's internal logging system should be used.
type CustomLogHook func(header, subLoggerName string, a ...any) (bypassLibraryLogSystem bool)
var customLogHook CustomLogHook
// SetCustomLogHook sets a custom log hook function that allows the complete
// bypass of the library's internal logging system. This is useful for
// implementing custom log handling.
func SetCustomLogHook(h CustomLogHook) {
mu.Lock()
customLogHook = h
mu.Unlock()
}

View File

@@ -0,0 +1,11 @@
package log
import "testing"
func TestSetCustomLoghook(t *testing.T) {
t.Parallel()
logHook := func(_ string, _ string, _ ...interface{}) (bypassLibraryLogSystem bool) {
return false
}
SetCustomLogHook(logHook)
}

View File

@@ -264,12 +264,22 @@ func (l *fields) stage(header string, deferFunc deferral) {
logFieldsPool.Put(l) logFieldsPool.Put(l)
} }
// stageln stages a log event // stageln logs a message with the given header and arguments. It uses the
func (l *fields) stageln(header string, a ...interface{}) { // custom log hook if set, otherwise falls back to the library's internal log
// system.
func (l *fields) stageln(header string, a ...any) {
if customLogHook != nil && customLogHook(header, l.name, a...) {
return
}
l.stage(header, func() string { return fmt.Sprint(a...) }) l.stage(header, func() string { return fmt.Sprint(a...) })
} }
// stagef stages a log event // stagef logs a formatted message with the given header and arguments. It uses
func (l *fields) stagef(header, format string, a ...interface{}) { // the custom log hook if set, otherwise falls back to the library's internal
// log system.
func (l *fields) stagef(header, format string, a ...any) {
if customLogHook != nil && customLogHook(header, l.name, fmt.Sprintf(format, a...)) {
return
}
l.stage(header, func() string { return fmt.Sprintf(format, a...) }) l.stage(header, func() string { return fmt.Sprintf(format, a...) })
} }