-
Notifications
You must be signed in to change notification settings - Fork 0
/
parser.go
129 lines (117 loc) · 3.37 KB
/
parser.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 mtga
import (
"encoding/json"
"fmt"
"log"
"strings"
"github.com/di-wu/mtga/thread"
"github.com/di-wu/mtga/thread/connect_resp"
)
// Parser is a structure that holds all the parser's callbacks.
type Parser struct {
onZoneChange func(change ZoneChange)
onConnectResp func(resp connect_resp.Response)
// thread
onSingleTreadLog func(first string)
Single
onThreadLog func(log thread.Log)
Outgoing
Incoming
Unhandled
MinusOne
ToMatch
MatchTo
// unknown
onUnknownLog func(message string)
}
// Parse parses a raw log (returned by the tails logs channel).
// It calls the callback that matches that parsed log.
func (parser *Parser) Parse(l RawLog) {
// empty log
if len(l) == 0 {
return
}
first := strings.TrimSpace(l[0])
if len(l) == 1 {
switch {
case strings.HasPrefix(first, "[UnityCrossThreadLogger]"):
line := strings.TrimPrefix(first, "[UnityCrossThreadLogger]")
if parser.onSingleTreadLog != nil {
parser.onSingleTreadLog(line)
}
parser.parseSingleTreadLog(line)
case strings.HasPrefix(first, "<<<<<<<<<<"):
parser.parserZoneChange(first)
default:
if parser.onUnknownLog != nil {
parser.onUnknownLog(fmt.Sprintf("Unparsed log: %s", first))
}
}
return
}
switch remaining := l[1:]; {
case strings.HasPrefix(first, "[UnityCrossThreadLogger]"):
threadLog := thread.NewLog(strings.TrimPrefix(first, "[UnityCrossThreadLogger]"), remaining)
if threadLog.Type == "" {
if parser.onUnknownLog != nil {
parser.onUnknownLog(fmt.Sprintf("Unparsed thread log: %s\n%s", first, remaining))
}
}
if parser.onThreadLog != nil {
parser.onThreadLog(threadLog)
}
parser.parseMultilineTreadLog(threadLog)
default:
if parser.onUnknownLog != nil {
parser.onUnknownLog(fmt.Sprintf("Unparsed log: %s\n%s", first, remaining))
}
}
}
// OnSingleLineTreadLog attaches the given callback, which will be called on single line thread log.
func (parser *Parser) OnSingleLineTreadLog(callback func(log string)) {
parser.onSingleTreadLog = callback
}
// OnTreadLog attaches the given callback, which will be called on every thread log.
func (parser *Parser) OnTreadLog(callback func(log thread.Log)) {
parser.onThreadLog = callback
}
func (parser *Parser) parseMultilineTreadLog(l thread.Log) {
if len(l.Raw) <= 2 {
return
}
switch l.Type {
case thread.Outgoing:
parser.parseOutgoingThreadLog(l)
case thread.Incoming:
parser.parseIncomingThreadLog(l)
case thread.ConnectResp:
if parser.onConnectResp != nil {
var resp connect_resp.Response
err := json.Unmarshal(l.Raw, &resp)
if err != nil {
log.Fatalln(err)
}
parser.onConnectResp(resp)
}
case thread.Unhandled:
parser.parseUnhandledThreadLog(l)
case thread.MinusOne:
parser.parseMinusOneThreadLog(l)
case thread.ToMatch:
parser.parseToMatchThreadLog(l)
case thread.MatchTo:
parser.parseMatchToThreadLog(l)
default:
if parser.onUnknownLog != nil {
parser.onUnknownLog(fmt.Sprintf("Unparsed thread log: %s\n%s", l.Type, string(l.Raw)))
}
}
}
// OnConnectResponse attaches the given callback, which will be called on getting the connection response.
func (parser *Parser) OnConnectResponse(callback func(resp connect_resp.Response)) {
parser.onConnectResp = callback
}
// OnUnknownLog attaches the given callback, which will be called on unparsed logs.
func (parser *Parser) OnUnknownLog(callback func(message string)) {
parser.onUnknownLog = callback
}