-
Notifications
You must be signed in to change notification settings - Fork 21
/
log_pre_1.21.go
66 lines (58 loc) · 1.33 KB
/
log_pre_1.21.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
//go:build !go1.21
// +build !go1.21
package log
import (
"bufio"
"io"
stdlog "log"
"os"
"strings"
)
var (
stdLogWriter *io.PipeWriter
redirectComplete chan struct{}
)
// RedirectGoStdLog is used to redirect Go's internal std log output to this logger AND registers a handler for slog
// that redirects slog output to this logger.
func RedirectGoStdLog(redirect bool) {
if (redirect && stdLogWriter != nil) || (!redirect && stdLogWriter == nil) {
// already redirected or already not redirected
return
}
if !redirect {
stdlog.SetOutput(os.Stderr)
// will stop scanner reading PipeReader
_ = stdLogWriter.Close()
stdLogWriter = nil
<-redirectComplete
return
}
ready := make(chan struct{})
redirectComplete = make(chan struct{})
// last option is to redirect
go func() {
var r *io.PipeReader
r, stdLogWriter = io.Pipe()
defer func() {
_ = r.Close()
}()
stdlog.SetOutput(stdLogWriter)
defer func() {
close(redirectComplete)
redirectComplete = nil
}()
scanner := bufio.NewScanner(r)
close(ready)
for scanner.Scan() {
txt := scanner.Text()
if strings.Contains(txt, "error") {
WithField("stdlog", true).Error(txt)
} else if strings.Contains(txt, "warning") {
WithField("stdlog", true).Warn(txt)
} else {
WithField("stdlog", true).Notice(txt)
}
}
}()
<-ready
}