forked from breck7/ScrollHub
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdashboard.js
93 lines (81 loc) · 2.37 KB
/
dashboard.js
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
const fs = require("fs")
const readline = require("readline")
class Dashboard {
constructor(inputFile) {
this.inputFile = inputFile
this.dailyStats = {}
}
parseLogEntry(entry) {
const regex = /(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z) ([\d.:]+) "(GET|POST) ([^"]+)" "([^"]+)"/
const match = entry.match(regex)
if (match) {
return {
timestamp: new Date(match[1]),
ip: match[2],
method: match[3],
path: match[4],
userAgent: match[5]
}
}
return null
}
updateDailyStats(entry) {
if (entry) {
const date = entry.timestamp.toISOString().split("T")[0]
if (!this.dailyStats[date]) {
this.dailyStats[date] = {
reads: 0,
writes: 0,
uniqueReaders: new Set(),
uniqueWriters: new Set()
}
}
if (entry.method.toUpperCase() === "GET") {
this.dailyStats[date].reads++
this.dailyStats[date].uniqueReaders.add(entry.ip)
} else if (entry.method.toUpperCase() === "POST") {
this.dailyStats[date].writes++
this.dailyStats[date].uniqueWriters.add(entry.ip)
}
}
}
finalizeDailyStats() {
Object.keys(this.dailyStats).forEach(date => {
this.dailyStats[date].readers = this.dailyStats[date].uniqueReaders.size
this.dailyStats[date].writers = this.dailyStats[date].uniqueWriters.size
delete this.dailyStats[date].uniqueReaders
delete this.dailyStats[date].uniqueWriters
})
}
async processLogFile() {
return new Promise((resolve, reject) => {
const fileStream = fs.createReadStream(this.inputFile)
const rl = readline.createInterface({
input: fileStream,
crlfDelay: Infinity
})
rl.on("line", line => {
const entry = this.parseLogEntry(line)
this.updateDailyStats(entry)
})
rl.on("close", () => {
this.finalizeDailyStats()
resolve()
})
fileStream.on("error", error => {
reject(error)
})
})
}
get csv() {
const csvHeader = "Date,Reads,Readers,Writes,Writers\n"
const csvRows = Object.entries(this.dailyStats)
.map(([date, stats]) => `${date},${stats.reads},${stats.readers},${stats.writes},${stats.writers}`)
.join("\n")
return csvHeader + csvRows
}
getDailyStats() {
return this.dailyStats
}
}
module.exports = { Dashboard }