forked from pivotal-cf/brokerapi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
chug.go
129 lines (105 loc) · 2.2 KB
/
chug.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
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
package chug
import (
"bufio"
"encoding/json"
"errors"
"io"
"strconv"
"strings"
"time"
"github.com/pivotal-golang/lager"
)
type Entry struct {
IsLager bool
Raw []byte
Log LogEntry
}
type LogEntry struct {
Timestamp time.Time
LogLevel lager.LogLevel
Source string
Message string
Session string
Error error
Trace string
Data lager.Data
}
func Chug(reader io.Reader, out chan<- Entry) {
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
out <- entry(scanner.Bytes())
}
close(out)
}
func entry(raw []byte) (entry Entry) {
copiedBytes := make([]byte, len(raw))
copy(copiedBytes, raw)
entry = Entry{
IsLager: false,
Raw: copiedBytes,
}
rawString := string(raw)
idx := strings.Index(rawString, "{")
if idx == -1 {
return
}
var lagerLog lager.LogFormat
decoder := json.NewDecoder(strings.NewReader(rawString[idx:]))
err := decoder.Decode(&lagerLog)
if err != nil {
return
}
entry.Log, entry.IsLager = convertLagerLog(lagerLog)
return
}
func convertLagerLog(lagerLog lager.LogFormat) (LogEntry, bool) {
timestamp, err := strconv.ParseFloat(lagerLog.Timestamp, 64)
if err != nil {
return LogEntry{}, false
}
data := lagerLog.Data
var logErr error
dataErr, ok := lagerLog.Data["error"]
if ok {
errorString, ok := dataErr.(string)
if !ok {
return LogEntry{}, false
}
logErr = errors.New(errorString)
delete(lagerLog.Data, "error")
}
var logTrace string
dataTrace, ok := lagerLog.Data["trace"]
if ok {
logTrace, ok = dataTrace.(string)
if !ok {
return LogEntry{}, false
}
delete(lagerLog.Data, "trace")
}
var logSession string
dataSession, ok := lagerLog.Data["session"]
if ok {
logSession, ok = dataSession.(string)
if !ok {
return LogEntry{}, false
}
delete(lagerLog.Data, "session")
}
messageComponents := strings.Split(lagerLog.Message, ".")
n := len(messageComponents)
if n <= 1 {
return LogEntry{}, false
}
logMessage := strings.Join(messageComponents[1:], ".")
return LogEntry{
Timestamp: time.Unix(0, int64(timestamp*1e9)),
LogLevel: lagerLog.LogLevel,
Source: lagerLog.Source,
Message: logMessage,
Session: logSession,
Error: logErr,
Trace: logTrace,
Data: data,
}, true
}