Initial commit of spamalytics v0.1

This commit is contained in:
Andrew Davidson 2015-05-09 20:33:25 -04:00
commit 9223bee84c
4 changed files with 3851 additions and 0 deletions

4
.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
.DS_Store
data.js
spam.log
spamalytics

3477
Chart.js vendored Normal file

File diff suppressed because it is too large Load diff

55
index.html Normal file
View 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
View 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