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