forked from dfuentes/haproxyparse
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
125 lines (110 loc) · 2.8 KB
/
main.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
package main
import (
"bufio"
"bytes"
"flag"
"fmt"
"log"
"os"
"strings"
"text/template"
"time"
)
var (
method string
start string
end string
normalized bool
extrasFormat string
)
func init() {
flag.StringVar(&method, "m", "", "Only output lines with the specified http method (GET,POST,etc)")
flag.StringVar(&start, "s", "", "Only output lines starting after specified date (in RFC3339 format)")
flag.StringVar(&end, "e", "", "Only output lines starting before specified date (in RFC3339 format)")
flag.BoolVar(&normalized, "n", false, "Use normalized timestamps (all requests evenly spaced one second apart")
flag.StringVar(&extrasFormat, "f", "", "Format to pull haproxy log attributes into go-bench \"extras\" param")
}
func main() {
flag.Parse()
var extrasTemplate *template.Template
var err error
if extrasFormat != "" {
extrasTemplate, err = template.New("extras").Parse(extrasFormat)
if err != nil {
log.Fatalf("error parsing extras template: %s", err)
}
}
var startTime time.Time
var endTime time.Time
if start != "" {
startTime = parseTime(start)
}
if end != "" {
endTime = parseTime(end)
}
var scanner *bufio.Scanner
if flag.NArg() > 0 {
fd, err := os.Open(flag.Arg(0))
if err != nil {
log.Fatalf("error opening input file: %s", err)
}
scanner = bufio.NewScanner(fd)
} else {
scanner = bufio.NewScanner(os.Stdin)
}
totalOffset := int64(0)
first := true
var lastTime time.Time
var templateBuffer bytes.Buffer
for scanner.Scan() {
parsedline, err := parseLine(scanner.Text())
if err != nil {
continue
}
if start != "" && parsedline.Time.Before(startTime) {
continue
}
if end != "" && parsedline.Time.After(endTime) {
os.Exit(0)
}
if !parsedline.UriComplete {
continue
}
if method != "" && !equalsIgnoreCase(method, parsedline.HttpMethod) {
continue
}
if first {
lastTime = parsedline.Time
first = false
}
if normalized {
totalOffset += int64(1000)
} else {
totalOffset += int64(parsedline.Time.Sub(lastTime).Seconds() * 1000.0)
}
extras := ""
if extrasTemplate != nil {
if err = extrasTemplate.Execute(&templateBuffer, parsedline); err != nil {
log.Fatalf("error applying template: %s", err)
}
extras = templateBuffer.String()
templateBuffer.Reset()
}
fmt.Fprintf(os.Stdout, "%d,%s,%s,%s,%s\n", totalOffset, parsedline.HttpMethod, parsedline.HttpUri, parsedline.AuthHeader, extras)
lastTime = parsedline.Time
}
if err := scanner.Err(); err != nil {
log.Fatalf("error reading input: %s", err)
}
os.Exit(0)
}
func equalsIgnoreCase(a, b string) bool {
return strings.ToLower(a) == strings.ToLower(b)
}
func parseTime(t string) time.Time {
out, err := time.Parse(time.RFC3339, t)
if err != nil {
log.Fatalf("error parsing start time: %s", err)
}
return out
}