/
files.go
143 lines (130 loc) · 3.48 KB
/
files.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
package utils
import (
"bufio"
"fmt"
"log"
"os"
"strconv"
"strings"
)
type ELBIPInfo struct {
SourceIP string
SourceIPCount int
SourceIPLocation string
SourceIPGeoInfo GeoIpInfo
}
type ELBLogInfo []ELBIPInfo
//CreateFile will create a file with a given name
//It will check to ensure that it does not overwrite a file with the same name
func CreateFile(name string) (file *os.File, err error) {
splitName := strings.Split(name, ".")
lenSplit := len(splitName)
//prefix is everything leading up to the last period in the name
//suffix is everything after the last period in the name
var prefix, suffix string
if lenSplit == 1 {
prefix = splitName[0]
} else if lenSplit >= 2 {
prefix, suffix = splitName[lenSplit-2], splitName[lenSplit-1]
}
x := true
//Will loop through name appending to ensure that existing files with the same name are not overwritten
for i := 0; x; i++ {
if i == 0 {
//this if will check to see if the file exists
//if it does, continue the loop, otherwise create the file
if _, err := os.Stat(name); err == nil {
continue
} else {
file, err = os.Create(name)
x = false
}
} else {
if lenSplit == 1 {
name = prefix + strconv.Itoa(i)
} else {
name = prefix + strconv.Itoa(i) + "." + suffix
}
if _, err := os.Stat(name); err == nil {
continue
} else {
file, err = os.Create(name)
x = false
}
}
//Catch to break loop in case file reading goes wrong
if i >= 1000 {
fmt.Println("i >= 1000 in file name creation, breaking loop")
x = false
}
}
return
}
//This will create a new directory with the given path relative to where the script was run from
func MakeDir(path string) {
err := os.MkdirAll(path, 0755)
if err != nil {
if strings.Contains(err.Error(), "file exists") {
return
}
//TODO add a return error
log.Panic("could not create directory:", path, ":", err)
}
}
//ReadFile will open a file, and return a string slice with each line as a string
func ReadFile(path string) ([]string, error) {
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer file.Close()
var lines []string
scanner := bufio.NewScanner(file)
for scanner.Scan() {
//Remove empty lines from the report
if scanner.Text() == "" {
continue
}
lines = append(lines, scanner.Text())
}
return lines, scanner.Err()
}
//ParseELBLog will parse an elb log file and return the relevant details
//Will also check the Geo location of the IP if "geo" is true
func ParseELBLog(path string, geo bool) (ELBLogInfo, error) {
var info ELBLogInfo
lines, err := ReadFile(path)
if err != nil {
return info, err
}
for _, line := range lines {
//Split the log string and get the source IP address
splitLine := strings.Split(line, " ")
a := splitLine[2]
//IPs in ELB logs are in the format <ip>:<port> so need to split again
b := strings.Split(a, ":")
newIP := b[0]
//Search the current list of IPs and compare the IP of the new line
//If it is an IP already encountered, add 1 to count, otherwise add to the list
x := false
for index, ipInfo := range info {
if newIP == ipInfo.SourceIP {
info[index].SourceIPCount += 1
x = true
continue
}
}
if x == false {
var temp ELBIPInfo
temp.SourceIP = newIP
temp.SourceIPCount = 1
//TODO get top 5 IP locations in list, instead of all
if geo {
fmt.Println("Checking Geo Location for IP:", newIP)
temp.SourceIPGeoInfo, _ = GetIPGeoLocation(newIP)
}
info = append(info, temp)
}
}
return info, nil
}