Initial commit of spamalytics v0.1
This commit is contained in:
commit
9223bee84c
4 changed files with 3851 additions and 0 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
.DS_Store
|
||||||
|
data.js
|
||||||
|
spam.log
|
||||||
|
spamalytics
|
55
index.html
Normal file
55
index.html
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Spamalytics</title>
|
||||||
|
<style type="text/css">
|
||||||
|
body {
|
||||||
|
text-align:center;
|
||||||
|
font-family: helvetica;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
display: inline;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Spamalytics</h1>
|
||||||
|
<canvas id="weeklyLine" width="500" height="400"></canvas>
|
||||||
|
<div id="weeklyLineInfo"></div>
|
||||||
|
<div class="monthlyInfo">
|
||||||
|
<h3>Last 30 Days</h3>
|
||||||
|
<p id="monthlyPregreet"></p>
|
||||||
|
<p id="monthlyNoqueue"></p>
|
||||||
|
<p id="monthlyQuarantine"></p>
|
||||||
|
<p id="monthlySpam"></p>
|
||||||
|
<p id="monthlyHam"></p>
|
||||||
|
</div>
|
||||||
|
<script src="Chart.js"></script>
|
||||||
|
<script src="data.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
var options = {
|
||||||
|
legendTemplate : '<ul class="legend">'
|
||||||
|
+'<% for (var i=0; i<datasets.length; i++) { %>'
|
||||||
|
+'<li>'
|
||||||
|
+'<span style=\"color:<%=datasets[i].strokeColor%>\">'
|
||||||
|
+'<% if (datasets[i].label) { %><%= datasets[i].label %><% } %>'
|
||||||
|
+'</span>'
|
||||||
|
+'</li>'
|
||||||
|
+'<% } %>'
|
||||||
|
+'</ul>'
|
||||||
|
};
|
||||||
|
|
||||||
|
var ctx = document.getElementById("weeklyLine").getContext("2d");
|
||||||
|
var weeklyLine = new Chart(ctx).Line(data, options);
|
||||||
|
document.getElementById('weeklyLineInfo').innerHTML = weeklyLine.generateLegend();
|
||||||
|
document.getElementById('monthlyPregreet').innerHTML = "Pregreet: " + data['monthlyPregreet'];
|
||||||
|
document.getElementById('monthlyNoqueue').innerHTML = "No Queue: " + data['monthlyNoqueue'];
|
||||||
|
document.getElementById('monthlyQuarantine').innerHTML = "Quarantined: " + data['monthlyQuarantine'];
|
||||||
|
document.getElementById('monthlySpam').innerHTML = "Total Spam: " + data['monthlySpam'];
|
||||||
|
document.getElementById('monthlyHam').innerHTML = "Total Ham: " + data['monthlyHam'];
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
315
spamalytics.go
Normal file
315
spamalytics.go
Normal file
|
@ -0,0 +1,315 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"bufio"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
"strconv"
|
||||||
|
"bytes"
|
||||||
|
"sort"
|
||||||
|
"io/ioutil"
|
||||||
|
"flag"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func check(e error) {
|
||||||
|
if e != nil {
|
||||||
|
panic(e)
|
||||||
|
} // if e != nil
|
||||||
|
} // func check
|
||||||
|
|
||||||
|
func readLines ( path string ) ( []string, error ) {
|
||||||
|
file, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
} // if err != nil
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
var lines []string
|
||||||
|
scanner := bufio.NewScanner(file)
|
||||||
|
for scanner.Scan() {
|
||||||
|
lines = append(lines, scanner.Text())
|
||||||
|
} // for scanner.Scan()
|
||||||
|
return lines, scanner.Err()
|
||||||
|
} // func readlines
|
||||||
|
|
||||||
|
type Record struct {
|
||||||
|
date string
|
||||||
|
pregreet int
|
||||||
|
noqueue int
|
||||||
|
quarantine int
|
||||||
|
ham int
|
||||||
|
} // type Record struct
|
||||||
|
type DataMap map[string]*Record
|
||||||
|
|
||||||
|
func load (dataset DataMap, date string, str string, num int) ( DataMap ) {
|
||||||
|
if rec, ok := dataset[date]; ok {
|
||||||
|
if str == "PREGREET" {
|
||||||
|
if rec.pregreet < num {
|
||||||
|
rec.pregreet = num
|
||||||
|
} // if pregreet < num
|
||||||
|
} else if str == "NOQUEUE" {
|
||||||
|
if rec.noqueue < num {
|
||||||
|
rec.noqueue = num
|
||||||
|
} // if noqueue < num
|
||||||
|
} else if str == "QUARANTINED" {
|
||||||
|
if rec.quarantine < num {
|
||||||
|
rec.quarantine = num
|
||||||
|
} // if quarantine < num
|
||||||
|
} else if str == "HAM" {
|
||||||
|
if rec.ham < num {
|
||||||
|
rec.ham = num
|
||||||
|
} // if ham < num
|
||||||
|
} // if str == ...
|
||||||
|
dataset[date] = rec
|
||||||
|
} else {
|
||||||
|
rec := new(Record)
|
||||||
|
if str == "PREGREET" {
|
||||||
|
rec.pregreet = num
|
||||||
|
} else if str == "NOQUEUE" {
|
||||||
|
rec.noqueue = num
|
||||||
|
} else if str == "QUARANTINE" {
|
||||||
|
rec.quarantine = num
|
||||||
|
} else if str == "HAM" {
|
||||||
|
rec.ham = num
|
||||||
|
} // if str == ...
|
||||||
|
dataset[date] = rec
|
||||||
|
} // if dataset[date]
|
||||||
|
return dataset
|
||||||
|
} // func load
|
||||||
|
|
||||||
|
|
||||||
|
// Start main thread
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// Begin Arguments
|
||||||
|
sourceFile := flag.String("-source", "/var/log/spam.log", "The path to the spam log")
|
||||||
|
outfile := flag.String("-out", "data.js", "The path to the file you want to output.")
|
||||||
|
hamColor := flag.String("-hamcolor","rgba(80,220,80,1)","The color of the ham graph.")
|
||||||
|
hamFill := flag.String("-hamfill","rgba(80,220,80,0.2)","The fill color of the ham graph.")
|
||||||
|
quarantineColor := flag.String("-quarantinecolor","rgba(220,80,80,1)","The line color of the quarantine graph.")
|
||||||
|
quarantineFill := flag.String("-quarantinefill","rgba(220,80,80,0.2)","The fill color of the quarantine graph.")
|
||||||
|
noqueueColor := flag.String("-noqueuecolor","rgba(220,150,80,1)","The line color of the noqueue graph.")
|
||||||
|
noqueueFill := flag.String("-noqueuefill","rgba(220,150,80,0.2)","The fill color of the noqueue graph.")
|
||||||
|
pregreetColor := flag.String("-pregreetcolor","rgba(220,200,80,1)","The line color of the pregreet graph.")
|
||||||
|
pregreetFill := flag.String("-pregreetfill","rgba(220,200,80,0.2)","The fill color of the pregreet graph.")
|
||||||
|
flag.Parse()
|
||||||
|
// End Arguments
|
||||||
|
|
||||||
|
spamInfo, err := readLines(*sourceFile)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
} // if err != nil
|
||||||
|
|
||||||
|
// Start semi-constants
|
||||||
|
aWeekAgo := time.Now().AddDate(0,0,-7)
|
||||||
|
aMonthAgo := time.Now().AddDate(0,0,-30)
|
||||||
|
// End semi-constants
|
||||||
|
|
||||||
|
// Start temporary maps
|
||||||
|
weekly := make(map[string]*Record)
|
||||||
|
monthly := make(map[string]*Record)
|
||||||
|
// End temporary maps
|
||||||
|
|
||||||
|
for _, line := range spamInfo {
|
||||||
|
val := strings.Split(line, " ")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
} // if err != nil
|
||||||
|
|
||||||
|
dateFormat := "2006-01-02"
|
||||||
|
date, _ := time.Parse(dateFormat, val[0])
|
||||||
|
|
||||||
|
if date.After(aWeekAgo) {
|
||||||
|
count, err := strconv.Atoi(val[2])
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
} // if err != nil
|
||||||
|
weekly = load(weekly, val[0], val[1], count)
|
||||||
|
} // if date.After(aWeekAgo)
|
||||||
|
|
||||||
|
if date.After(aMonthAgo) {
|
||||||
|
count, err := strconv.Atoi(val[2])
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
} // if err != nil
|
||||||
|
monthly = load(monthly, val[0], val[1], count)
|
||||||
|
} // if date.After(aMonthAgo)
|
||||||
|
|
||||||
|
} //for line in spamInfo
|
||||||
|
|
||||||
|
var monthlyPregreet int
|
||||||
|
var monthlyNoqueue int
|
||||||
|
var monthlyQuarantine int
|
||||||
|
var monthlyHam int
|
||||||
|
|
||||||
|
for _, k := range monthly {
|
||||||
|
monthlyPregreet += k.pregreet
|
||||||
|
monthlyNoqueue += k.noqueue
|
||||||
|
monthlyQuarantine += k.quarantine
|
||||||
|
monthlyHam += k.ham
|
||||||
|
} // for k in monthly
|
||||||
|
|
||||||
|
monthlySpam := monthlyPregreet + monthlyNoqueue + monthlyQuarantine
|
||||||
|
|
||||||
|
var labels []string
|
||||||
|
for k := range weekly {
|
||||||
|
labels = append(labels, k)
|
||||||
|
} // for k in weekly
|
||||||
|
|
||||||
|
sort.Strings(labels)
|
||||||
|
|
||||||
|
// Make data.js string
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
|
||||||
|
buffer.WriteString("var data = {\n")
|
||||||
|
|
||||||
|
// Generate graph labels
|
||||||
|
buffer.WriteString("\tlabels: [")
|
||||||
|
for c, val := range labels {
|
||||||
|
buffer.WriteString("\"")
|
||||||
|
buffer.WriteString(val)
|
||||||
|
if c < (len(labels)-1) {
|
||||||
|
buffer.WriteString("\", ")
|
||||||
|
} else {
|
||||||
|
buffer.WriteString("\"")
|
||||||
|
}
|
||||||
|
} // for val in labels
|
||||||
|
buffer.WriteString("],\n")
|
||||||
|
buffer.WriteString("\tdatasets: [\n")
|
||||||
|
|
||||||
|
// Generate HAM dataset
|
||||||
|
buffer.WriteString("\t\t{\n\t\t\tlabel: \"Ham\",\n")
|
||||||
|
buffer.WriteString("\t\t\tfillColor: \"")
|
||||||
|
buffer.WriteString(*hamFill)
|
||||||
|
buffer.WriteString("\",\n")
|
||||||
|
buffer.WriteString("\t\t\tstrokeColor: \"")
|
||||||
|
buffer.WriteString(*hamColor)
|
||||||
|
buffer.WriteString("\",\n")
|
||||||
|
buffer.WriteString("\t\t\tpointColor: \"")
|
||||||
|
buffer.WriteString(*hamColor)
|
||||||
|
buffer.WriteString("\",\n")
|
||||||
|
buffer.WriteString("\t\t\tpointStrokeColor: \"#fff\",\n")
|
||||||
|
buffer.WriteString("\t\t\tpointHighlightFill: \"#fff\",\n")
|
||||||
|
buffer.WriteString("\t\t\tpointHighlightSroke: \"")
|
||||||
|
buffer.WriteString(*hamColor)
|
||||||
|
buffer.WriteString("\",\n")
|
||||||
|
buffer.WriteString("\t\t\tdata: [")
|
||||||
|
for c, val := range labels {
|
||||||
|
buffer.WriteString(strconv.Itoa(weekly[val].ham))
|
||||||
|
if c < (len(labels)-1) {
|
||||||
|
buffer.WriteString(", ")
|
||||||
|
} // if c < len(labels)
|
||||||
|
} // for val in labels
|
||||||
|
buffer.WriteString("]\n\t\t},\n")
|
||||||
|
|
||||||
|
// Generate quarantine dataset
|
||||||
|
buffer.WriteString("\t\t{\n\t\t\tlabel: \"Quarantine\",\n")
|
||||||
|
buffer.WriteString("\t\t\tfillColor: \"")
|
||||||
|
buffer.WriteString(*quarantineFill)
|
||||||
|
buffer.WriteString("\",\n")
|
||||||
|
buffer.WriteString("\t\t\tstrokeColor: \"")
|
||||||
|
buffer.WriteString(*quarantineColor)
|
||||||
|
buffer.WriteString("\",\n")
|
||||||
|
buffer.WriteString("\t\t\tpointColor: \"")
|
||||||
|
buffer.WriteString(*quarantineColor)
|
||||||
|
buffer.WriteString("\",\n")
|
||||||
|
buffer.WriteString("\t\t\tpointStrokeColor: \"#fff\",\n")
|
||||||
|
buffer.WriteString("\t\t\tpointHighlightFill: \"#fff\",\n")
|
||||||
|
buffer.WriteString("\t\t\tpointHighlightSroke: \"")
|
||||||
|
buffer.WriteString(*quarantineColor)
|
||||||
|
buffer.WriteString("\",\n")
|
||||||
|
buffer.WriteString("\t\t\tdata: [")
|
||||||
|
for c, val := range labels {
|
||||||
|
buffer.WriteString(strconv.Itoa(weekly[val].quarantine))
|
||||||
|
if c < (len(labels)-1) {
|
||||||
|
buffer.WriteString(", ")
|
||||||
|
} // if c < len(labels)
|
||||||
|
} // for val in labels
|
||||||
|
buffer.WriteString("]\n\t\t},\n")
|
||||||
|
|
||||||
|
// Generate noqueue dataset
|
||||||
|
buffer.WriteString("\t\t{\n\t\t\tlabel: \"No Queue\",\n")
|
||||||
|
buffer.WriteString("\t\t\tfillColor: \"")
|
||||||
|
buffer.WriteString(*noqueueFill)
|
||||||
|
buffer.WriteString("\",\n")
|
||||||
|
buffer.WriteString("\t\t\tstrokeColor: \"")
|
||||||
|
buffer.WriteString(*noqueueColor)
|
||||||
|
buffer.WriteString("\",\n")
|
||||||
|
buffer.WriteString("\t\t\tpointColor: \"")
|
||||||
|
buffer.WriteString(*noqueueColor)
|
||||||
|
buffer.WriteString("\",\n")
|
||||||
|
buffer.WriteString("\t\t\tpointStrokeColor: \"#fff\",\n")
|
||||||
|
buffer.WriteString("\t\t\tpointHighlightFill: \"#fff\",\n")
|
||||||
|
buffer.WriteString("\t\t\tpointHighlightSroke: \"")
|
||||||
|
buffer.WriteString(*noqueueColor)
|
||||||
|
buffer.WriteString("\",\n")
|
||||||
|
buffer.WriteString("\t\t\tdata: [")
|
||||||
|
for c, val := range labels {
|
||||||
|
buffer.WriteString(strconv.Itoa(weekly[val].noqueue))
|
||||||
|
if c < (len(labels)-1) {
|
||||||
|
buffer.WriteString(", ")
|
||||||
|
} // if c < len(labels)
|
||||||
|
} // for val in labels
|
||||||
|
buffer.WriteString("]\n\t\t},\n")
|
||||||
|
|
||||||
|
// Generate pregreet dataset
|
||||||
|
buffer.WriteString("\t\t{\n\t\t\tlabel: \"Pregreet\",\n")
|
||||||
|
buffer.WriteString("\t\t\tfillColor: \"")
|
||||||
|
buffer.WriteString(*pregreetFill)
|
||||||
|
buffer.WriteString("\",\n")
|
||||||
|
buffer.WriteString("\t\t\tstrokeColor: \"")
|
||||||
|
buffer.WriteString(*pregreetColor)
|
||||||
|
buffer.WriteString("\",\n")
|
||||||
|
buffer.WriteString("\t\t\tpointColor: \"")
|
||||||
|
buffer.WriteString(*pregreetColor)
|
||||||
|
buffer.WriteString("\",\n")
|
||||||
|
buffer.WriteString("\t\t\tpointStrokeColor: \"#fff\",\n")
|
||||||
|
buffer.WriteString("\t\t\tpointHighlightFill: \"#fff\",\n")
|
||||||
|
buffer.WriteString("\t\t\tpointHighlightSroke: \"")
|
||||||
|
buffer.WriteString(*pregreetColor)
|
||||||
|
buffer.WriteString("\",\n")
|
||||||
|
buffer.WriteString("\t\t\tdata: [")
|
||||||
|
for c, val := range labels {
|
||||||
|
buffer.WriteString(strconv.Itoa(weekly[val].pregreet))
|
||||||
|
if c < (len(labels)-1) {
|
||||||
|
buffer.WriteString(", ")
|
||||||
|
} // if c < len(labels)
|
||||||
|
} // for val in labels
|
||||||
|
buffer.WriteString("]\n\t\t}\n")
|
||||||
|
|
||||||
|
buffer.WriteString("\t],\n")
|
||||||
|
|
||||||
|
buffer.WriteString("\tmonthlyPregreet: \"")
|
||||||
|
buffer.WriteString(strconv.Itoa(monthlyPregreet))
|
||||||
|
buffer.WriteString("\",\n")
|
||||||
|
|
||||||
|
buffer.WriteString("\tmonthlyNoqueue: \"")
|
||||||
|
buffer.WriteString(strconv.Itoa(monthlyNoqueue))
|
||||||
|
buffer.WriteString("\",\n")
|
||||||
|
|
||||||
|
buffer.WriteString("\tmonthlyQuarantine: \"")
|
||||||
|
buffer.WriteString(strconv.Itoa(monthlyQuarantine))
|
||||||
|
buffer.WriteString("\",\n")
|
||||||
|
|
||||||
|
buffer.WriteString("\tmonthlySpam: \"")
|
||||||
|
buffer.WriteString(strconv.Itoa(monthlySpam))
|
||||||
|
buffer.WriteString("\",\n")
|
||||||
|
|
||||||
|
buffer.WriteString("\tmonthlyHam: \"")
|
||||||
|
buffer.WriteString(strconv.Itoa(monthlyHam))
|
||||||
|
buffer.WriteString("\"\n")
|
||||||
|
|
||||||
|
buffer.WriteString("};\n\n")
|
||||||
|
// End make data.js string
|
||||||
|
|
||||||
|
// Create data file
|
||||||
|
ioutil.WriteFile(*outfile, []byte(buffer.String()), 0644)
|
||||||
|
// End create data file
|
||||||
|
} // End main thread
|
Loading…
Reference in a new issue