Skip to content

Commit b874e6c

Browse files
committed
add: [sshd] html templating
1 parent 3812ce4 commit b874e6c

File tree

2 files changed

+158
-6
lines changed

2 files changed

+158
-6
lines changed

load.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
function imgLoad(image) {
2+
'use strict';
3+
// Create new promise with the Promise() constructor;
4+
// This has as its argument a function with two parameters, resolve and reject
5+
return new Promise(function (resolve, reject) {
6+
// Standard XHR to load an image
7+
var request = new XMLHttpRequest();
8+
var url = 'http://127.0.0.1:4444/data/sshd/'+image+'.svg'
9+
request.open('GET', url);
10+
request.responseType = 'blob';
11+
12+
// When the request loads, check whether it was successful
13+
request.onload = function () {
14+
if (request.status === 200) {
15+
// If successful, resolve the promise by passing back the request response
16+
resolve(request.response);
17+
} else {
18+
// If it fails, reject the promise with a error message
19+
reject(new Error('Image didn\'t load successfully; error code:' + request.statusText));
20+
}
21+
};
22+
23+
request.onerror = function () {
24+
// Also deal with the case when the entire request fails to begin with
25+
// This is probably a network error, so reject the promise with an appropriate message
26+
reject(new Error('There was a network error.'));
27+
};
28+
29+
// Send the request
30+
request.send();
31+
});
32+
}
33+
34+
function loadImage(date, type) {
35+
'use strict';
36+
console.log(date);
37+
console.log(type);
38+
// Get a reference to the body element, and create a new image object
39+
var holder = document.querySelector('#imageholder'),
40+
myImage = new Image();
41+
42+
myImage.crossOrigin = ""; // or "anonymous"
43+
44+
// Call the function with the URL we want to load, but then chain the
45+
// promise then() method on to the end of it. This contains two callbacks
46+
imgLoad(date+'/'+date+':'+type).then(function (response) {
47+
// The first runs when the promise resolves, with the request.reponse specified within the resolve() method.
48+
var imageURL = window.URL.createObjectURL(response);
49+
myImage.src = imageURL;
50+
holder.innerHTML = "";
51+
holder.appendChild(myImage);
52+
// The second runs when the promise is rejected, and logs the Error specified with the reject() method.
53+
}, function (Error) {
54+
console.log(Error);
55+
});
56+
}

logparser/sshd.go

Lines changed: 102 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package logparser
22

33
import (
44
"fmt"
5+
"html/template"
56
"log"
67
"math"
78
"os"
@@ -83,7 +84,7 @@ func (s *SshdParser) Parse(logline string) error {
8384
// Check if dates are the same
8485
if oldest != dstr {
8586
// Check who is the oldest
86-
parsedOldest, _ := time.Parse("2006-01-02", oldest)
87+
parsedOldest, _ := time.Parse("20060102", oldest)
8788
if parsedTime.Before(parsedOldest) {
8889
r.Do("SET", "oldest", dstr)
8990
}
@@ -101,7 +102,7 @@ func (s *SshdParser) Parse(logline string) error {
101102
// Check if dates are the same
102103
if newest != dstr {
103104
// Check who is the newest
104-
parsedNewest, _ := time.Parse("2006-01-02", newest)
105+
parsedNewest, _ := time.Parse("20060102", newest)
105106
if parsedTime.After(parsedNewest) {
106107
r.Do("SET", "newest", dstr)
107108
}
@@ -228,6 +229,95 @@ func (s *SshdParser) Compile() error {
228229
}
229230
}
230231

232+
// Write html file for navigating plots
233+
const tpl = `
234+
<!DOCTYPE html>
235+
<html>
236+
<head>
237+
<meta charset="UTF-8">
238+
<title>{{.Title}}</title>
239+
<script>
240+
var currentType = "statsusername";
241+
var currentDay = {{.MaxDate}};
242+
</script>
243+
<script src="load.js"></script>
244+
<style>
245+
body {
246+
background: white
247+
}
248+
#imageholder {
249+
background: black;
250+
color: white;
251+
padding: 1em;
252+
position: absolute;
253+
top: 50%;
254+
left: 50%;
255+
margin-right: -50%;
256+
transform: translate(-50%, -40%)
257+
}
258+
span {
259+
float: left;
260+
clear: left;
261+
}
262+
</style>
263+
</head>
264+
<body onload="loadImage({{.Current}}, currentType)">
265+
<span>
266+
<label for="statsday">Statistics for: </label>
267+
<input id="statsday" type="date" value="{{.MaxDate}}" min="{{.MinDate}}" max="{{.MaxDate}}" onchange="currentDay = this.value.replace(/-/g, ''); loadImage(currentDay, currentType)"/>
268+
</span>
269+
<span>
270+
<label for="statstype">Type: </label>
271+
<select selected="statsusername" onchange="currentType = this.value; loadImage(currentDay.replace(/-/g, ''), currentType)">
272+
<option value="statsusername">Usernames</option>
273+
<option value="statssrc">Sources</option>
274+
<option value="statshost">Hosts</option>
275+
</select>
276+
</span>
277+
<span id="imageholder"></span>
278+
</body>
279+
</html>`
280+
281+
// Get oldest / newest entries
282+
var newest string
283+
var oldest string
284+
if newest, err = redis.String(r.Do("GET", "newest")); err == redis.ErrNil {
285+
r.Close()
286+
return err
287+
}
288+
if oldest, err = redis.String(r.Do("GET", "oldest")); err == redis.ErrNil {
289+
r.Close()
290+
return err
291+
}
292+
parsedOldest, _ := time.Parse("20060102", oldest)
293+
parsedNewest, _ := time.Parse("20060102", newest)
294+
parsedOldestStr := parsedOldest.Format("2006-01-02")
295+
parsedNewestStr := parsedNewest.Format("2006-01-02")
296+
297+
check := func(err error) {
298+
if err != nil {
299+
log.Fatal(err)
300+
}
301+
}
302+
t, err := template.New("webpage").Parse(tpl)
303+
check(err)
304+
305+
data := struct {
306+
Title string
307+
Current string
308+
MinDate string
309+
MaxDate string
310+
}{
311+
Title: "sshd failed logins statistics",
312+
MinDate: parsedOldestStr,
313+
MaxDate: parsedNewestStr,
314+
Current: newest,
315+
}
316+
f, err := os.OpenFile("statistics.html", os.O_RDWR|os.O_CREATE, 0666)
317+
defer f.Close()
318+
err = t.Execute(f, data)
319+
check(err)
320+
231321
return nil
232322
}
233323

@@ -286,23 +376,29 @@ func plotStats(s *SshdParser, v string) error {
286376
p.NominalY(keys...)
287377

288378
// Create folder to store plots
289-
290379
if _, err := os.Stat("data"); os.IsNotExist(err) {
291380
err := os.Mkdir("data", 0700)
292381
if err != nil {
293382
return err
294383
}
295384
}
296385

297-
if _, err := os.Stat(filepath.Join("data", stype[0])); os.IsNotExist(err) {
298-
err := os.Mkdir(filepath.Join("data", stype[0]), 0700)
386+
if _, err := os.Stat(filepath.Join("data", "sshd")); os.IsNotExist(err) {
387+
err := os.Mkdir(filepath.Join("data", "sshd"), 0700)
388+
if err != nil {
389+
return err
390+
}
391+
}
392+
393+
if _, err := os.Stat(filepath.Join("data", "sshd", stype[0])); os.IsNotExist(err) {
394+
err := os.Mkdir(filepath.Join("data", "sshd", stype[0]), 0700)
299395
if err != nil {
300396
return err
301397
}
302398
}
303399

304400
xsize := 3 + vg.Length(math.Round(float64(len(keys)/2)))
305-
if err := p.Save(15*vg.Centimeter, xsize*vg.Centimeter, filepath.Join("data", stype[0], fmt.Sprintf("%v.svg", v))); err != nil {
401+
if err := p.Save(15*vg.Centimeter, xsize*vg.Centimeter, filepath.Join("data", "sshd", stype[0], fmt.Sprintf("%v.svg", v))); err != nil {
306402
return err
307403
}
308404

0 commit comments

Comments
 (0)