Last active
November 27, 2019 07:07
-
-
Save marisademeglio/73fa67ad4277ee9e1e5dabbc2906c0ab to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const path = require('path'); | |
const fs = require('fs'); | |
let logEntries = []; | |
let logs = fs.readdirSync('./logs'); | |
let logfile = log => path.join(__dirname, 'logs', log); | |
logs.map(log => { | |
let filename = logfile(log); | |
console.log(`Processing ${filename}`); | |
var lines = require('fs').readFileSync(filename, 'utf-8') | |
.split('\n') | |
lines.map(line => { | |
if (line.substr(0, 4) == '2019') { | |
let timestamp = line.split('INFO')[0]; | |
timestamp = timestamp.split(',')[0]; | |
let [date, time] = timestamp.split(' '); | |
timestamp = `${date}T${time}`; | |
let ipaddress = ''; | |
if (line.indexOf("Validation from") != -1) { | |
ipaddress = line.split('IP ')[1]; | |
} | |
let logEntry = { | |
"timestamp": new Date(timestamp), | |
"executed": line.indexOf('Validation from') != -1, | |
"ip": ipaddress | |
} | |
logEntries.push(logEntry); | |
} | |
// else skip it, it's not a timestamped entry | |
}) | |
}); | |
// sort by date | |
let sortedLogEntries = logEntries.sort((a, b) => { | |
if (a.timestamp > b.timestamp) { | |
return 1; | |
} | |
else if (a.timestamp < b.timestamp) { | |
return -1; | |
} | |
else { | |
return 0; | |
} | |
}); | |
let start = sortedLogEntries[0].timestamp; | |
let end = sortedLogEntries[sortedLogEntries.length - 1].timestamp; | |
console.log('start', start); | |
console.log('end', end); | |
let filteredLogEntries = sortedLogEntries.filter(entry => entry.executed === true); | |
function monthDiff(dateFrom, dateTo) { | |
return dateTo.getMonth() - dateFrom.getMonth() + | |
(12 * (dateTo.getFullYear() - dateFrom.getFullYear())) | |
} | |
function getEntriesInRange(dateFrom, dateTo) { | |
return filteredLogEntries.filter(entry => entry.timestamp >= dateFrom && entry.timestamp < dateTo); | |
} | |
// from here on just assume it's all in the same year and not december (no year rollover) | |
let numMonths = monthDiff(start, end); | |
let i; | |
let bymonth = []; | |
for (i = 1; i<= numMonths; i++) { | |
let monthEntries = getEntriesInRange(new Date(`${start.getFullYear()}-${start.getMonth() + i}-01`), | |
new Date(`${start.getFullYear()}-${start.getMonth() + i + 1}-01`)); | |
let uniqueIPs = new Set(monthEntries.map(e => e.ip)); | |
let thismonth = {"date": NiceDateStringMonth(monthEntries[0].timestamp), "entries": monthEntries, "unique": Array.from(uniqueIPs)}; | |
bymonth.push(thismonth); | |
} | |
function NiceDateString(d){ | |
function pad(n){return n<10 ? '0'+n : n} | |
return d.getFullYear()+'-' | |
+ pad(d.getMonth()+1)+'-' | |
+ pad(d.getDate()); | |
} | |
function NiceDateStringMonth(d) { | |
function pad(n){return n<10 ? '0'+n : n} | |
return d.getFullYear()+'-' | |
+ pad(d.getMonth()+1); | |
} | |
function numberWithCommas(x) { | |
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); | |
} | |
const HTML = ` | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>epubcheck web stats</title> | |
<style> | |
:root { | |
--color1: white; | |
--color2: #ffebcd; | |
--header: #af9b7d; | |
} | |
body { | |
font-family: Arial | |
} | |
main table { | |
border-collapse: collapse; | |
table-layout: fixed; | |
width: 100%; | |
} | |
th, td { | |
text-align: left; | |
font-size: smaller; | |
font-weight: normal; | |
vertical-align: top; | |
padding: 2vh; | |
} | |
thead { | |
background: var(--header); | |
font-size: larger; | |
font-weight: bold; | |
} | |
table tbody tr:nth-child(even) { | |
background-color: var(--color1); | |
} | |
table tbody tr:nth-child(odd) { | |
background-color: var(--color2); | |
} | |
</style> | |
</head> | |
<body> | |
<h1>epubcheck web stats</h1> | |
<p>From ${NiceDateString(start)} to ${NiceDateString(end)}</p> | |
<p>Entries in the table below, including unique IP count, are calculated from when a visitor ran epubcheck (as opposed to just merely visiting the site).</p> | |
<table> | |
<thead><tr><th>Month</th><th>Validations</th><th>Unique IPs</th></tr></thead> | |
<tbody> | |
${bymonth.map(m => ` | |
<tr> | |
<td>${m.date}</td> | |
<td>${numberWithCommas(m.entries.length)}</td> | |
<td>${numberWithCommas(m.unique.length)}</td> | |
</tr>`)} | |
</tbody> | |
</table> | |
</body> | |
</html>` | |
fs.writeFileSync("stats.html", HTML.replace(/tr>,/g, 'tr>')); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment