This repository has been archived by the owner on Jul 29, 2022. It is now read-only.
/
logrus_writer.go
88 lines (74 loc) · 1.98 KB
/
logrus_writer.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
package terraform
import (
"bufio"
"encoding/json"
"io"
"io/ioutil"
"github.com/sirupsen/logrus"
)
type logrusWriter struct {
*io.PipeWriter
reader *io.PipeReader
done chan bool
}
func newLogrusWriter(logger logrus.FieldLogger, defaultLevel logrus.Level) *logrusWriter {
reader, writer := io.Pipe()
done := make(chan bool)
log := func(logger logrus.FieldLogger, level, message string) {
switch level {
case "debug":
logger.Debug(message)
case "info":
logger.Info(message)
case "warn":
logger.Warn(message)
case "error":
fallthrough
default:
logger.Error(message)
}
}
go func() {
// Log lines one at a time and mapped into logrus calls for visual clarity. The
// raw output written to the file will be unaffected.
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
var jsonText interface{}
if err := json.Unmarshal(scanner.Bytes(), &jsonText); err != nil {
log(logger, defaultLevel.String(), scanner.Text())
} else if jsonTextMap, ok := jsonText.(map[string]interface{}); !ok {
log(logger, defaultLevel.String(), scanner.Text())
} else {
level, _ := jsonTextMap["level"].(string)
msg, _ := jsonTextMap["msg"].(string)
// Clean up unused fields
delete(jsonTextMap, "msg")
delete(jsonTextMap, "level")
delete(jsonTextMap, "ts")
delete(jsonTextMap, "caller")
// Special case timings output. This will still be available
// in the results for use by ltparse.
if msg == "Timings" {
jsonTextMap["timings"] = "(omitted)"
}
log(logger.WithFields(logrus.Fields(jsonTextMap)), level, msg)
}
}
if err := scanner.Err(); err != nil {
logrus.Errorf("failed to scan and log: %s", err.Error())
// Drain the reader, otherwise the ssh session may not end.
io.Copy(ioutil.Discard, reader)
}
close(done)
}()
return &logrusWriter{
PipeWriter: writer,
reader: reader,
done: done,
}
}
func (w *logrusWriter) Close() error {
w.PipeWriter.Close()
<-w.done
return nil
}