-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathflexfile.go
149 lines (130 loc) · 3.97 KB
/
flexfile.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package main
/*
read and pares plaintext and compressed files (.gz)
date string parsing happens here
(c) Holger Berger 2016, under GPL
*/
import (
"bufio"
"compress/gzip"
"os"
"regexp"
"strings"
"time"
)
// LineT contains all data of a line
type LineT struct {
line []byte // line data
time time.Time // parsed time of line
host string // host of line
hoststart, hostend int // start and end of hostname in line for coloring
}
// rewrite of FileT allowing compressed files to be read
// and changing to line based storage in memory
// FlexFileT contains metadata and data of a read logfile
type FlexFileT struct {
filename string // name of the file
location *time.Location // cache for location
lines []LineT // file data
linecount int // number of line sin the file
}
// ReadFlexFile reads compressed or uncompressed files
func ReadFlexFile(filename string) (*FlexFileT, error) {
var (
newfile FlexFileT
err error
reader *bufio.Reader
)
newfile.filename = filename
osfile, err := os.Open(filename)
if err != nil {
return &newfile, err
}
newfile.location, err = time.LoadLocation("Europe/Berlin")
if err != nil {
panic("could not load timezone")
}
if strings.HasSuffix(filename, ".gz") {
newreader, err := gzip.NewReader(osfile)
if err != nil {
reader = bufio.NewReader(osfile)
} else {
reader = bufio.NewReader(newreader)
}
} else {
reader = bufio.NewReader(osfile)
}
// newfile.lines = make([][]byte, 0, 1024)
newfile.lines = make([]LineT, 0, 1024)
linecount := 0
for {
nextline, err := reader.ReadBytes('\n')
newline := new(LineT)
newline.line = nextline
newfile.lines = append(newfile.lines, *newline)
if err != nil {
break
}
linecount++
}
newfile.linecount = linecount
newfile.parseLines()
return &newfile, nil
}
// parseLines parses timestamps of all lines and stores them in FileT
// in two phases, first it matches with a regex to strip of rest of line, second
// it using the time.Parse functions
func (f *FlexFileT) parseLines() {
// Jul 24 06:29:28
fmt1, _ := regexp.Compile(`([a-zA-Z]{3}\s+[0-9]+ [0-9]{2}:[0-9]{2}:[0-9]{2}) (\S+)`)
// 2016-07-26T00:36:17.903571+02:00
fmt2, _ := regexp.Compile(`([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2})\.[0-9]+(\+[0-9]{2}):([0-9]{2}) (\S+)`)
for line, datestr := range f.lines[:f.linecount] {
// this is the reference time from the time modul, templates show this time
// Mon Jan 2 15:04:05 MST 2006
index1 := fmt1.FindSubmatchIndex(datestr.line)
if index1 != nil {
m1 := datestr.line[index1[1*2]:index1[1*2+1]]
m2 := datestr.line[index1[2*2]:index1[2*2+1]]
// FIXME hard coded year here, needs to replaced
t, err := time.ParseInLocation("2006 Jan 02 15:04:05", "2016 "+string(m1), f.location)
if err == nil {
f.lines[line].time = t
f.lines[line].host = string(m2)
f.lines[line].hoststart = index1[2*2]
f.lines[line].hostend = index1[2*2+1]
continue
} else {
// FIXME hard coded year here, needs to replaced
t, err := time.ParseInLocation("2006 Jan 2 15:04:05", "2016 "+string(m1), f.location)
if err == nil {
f.lines[line].time = t
f.lines[line].host = string(m2)
f.lines[line].hoststart = index1[2*2]
f.lines[line].hostend = index1[2*2+1]
continue
} else {
// FIXME wtf do we do here?
panic("could not parse date" + string(m1))
}
}
} else {
index2 := fmt2.FindSubmatchIndex(datestr.line)
if index2 != nil {
m1 := datestr.line[index2[1*2]:index2[1*2+1]]
m2 := datestr.line[index2[4*2]:index2[4*2+1]]
t, err := time.ParseInLocation("2006-01-02T15:04:05", string(m1), f.location)
if err == nil {
f.lines[line].time = t
f.lines[line].host = string(m2)
f.lines[line].hoststart = index2[4*2]
f.lines[line].hostend = index2[4*2+1]
continue
}
} else {
// FIXME wtf do we do here?
panic("unknown date format in " + string(datestr.line))
}
}
}
}