117 lines
3.7 KiB
TypeScript
117 lines
3.7 KiB
TypeScript
import { Handler, Server } from "./server"
|
|
import Script from "./Script"
|
|
import { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs"
|
|
import { mkdir } from "node:fs"
|
|
import ScriptUtils from "./ScriptUtils"
|
|
import { IncomingMessage } from "node:http"
|
|
|
|
class ServerErrorReport extends Script {
|
|
private errorReport = 0
|
|
|
|
constructor() {
|
|
super("A server which receives and logs error reports")
|
|
}
|
|
|
|
private getFilename(logDirectory: string, d: Date): string {
|
|
return (
|
|
logDirectory +
|
|
"/" +
|
|
d.getUTCFullYear() +
|
|
"_" +
|
|
(d.getUTCMonth() + 1) +
|
|
"_" +
|
|
d.getUTCDate() +
|
|
".lines.json"
|
|
)
|
|
}
|
|
|
|
public reportError(
|
|
path: string,
|
|
queryParams: URLSearchParams,
|
|
req: IncomingMessage,
|
|
body: string | undefined,
|
|
logDirectory: string
|
|
): string {
|
|
if (!body) {
|
|
throw '{"error": "No body; use a post request"}'
|
|
}
|
|
console.log(body)
|
|
const ip = <string>req.headers["x-forwarded-for"]
|
|
|
|
try {
|
|
body = JSON.parse(body)
|
|
} catch (e) {
|
|
// could not parse, we'll save it as is
|
|
}
|
|
const d = new Date()
|
|
const file = this.getFilename(logDirectory, d)
|
|
const date = d.toISOString()
|
|
const contents = "\n" + JSON.stringify({ ip, index: this.errorReport, date, message: body })
|
|
if (!existsSync(file)) {
|
|
writeFileSync(file, contents)
|
|
} else {
|
|
appendFileSync(file, contents)
|
|
}
|
|
this.errorReport++
|
|
return `{"status":"ok", "nr": ${this.errorReport}}`
|
|
}
|
|
|
|
async main(args: string[]): Promise<void> {
|
|
const logDirectory = args[0] ?? "./error_logs"
|
|
console.log("Logging to directory", logDirectory)
|
|
if (!existsSync(logDirectory)) {
|
|
mkdirSync(logDirectory)
|
|
console.log("Created this directory")
|
|
}
|
|
|
|
if (!existsSync(logDirectory + "/csp")) {
|
|
mkdirSync(logDirectory + "/csp")
|
|
console.log("Created this directory")
|
|
}
|
|
|
|
new Server(2348, {}, [
|
|
{
|
|
mustMatch: "status",
|
|
mimetype: "application/json",
|
|
handle: async () => {
|
|
const filename = this.getFilename(logDirectory, new Date())
|
|
let errorsToday = 0
|
|
if (existsSync(filename)) {
|
|
const contents = readFileSync(filename, "utf8")
|
|
errorsToday = contents.split("\n").length
|
|
}
|
|
return JSON.stringify({
|
|
online: true,
|
|
errors_today: errorsToday,
|
|
})
|
|
},
|
|
},
|
|
{
|
|
mustMatch: "report",
|
|
mimetype: "application/json",
|
|
handle: async (
|
|
path: string,
|
|
queryParams: URLSearchParams,
|
|
req: IncomingMessage,
|
|
body: string | undefined
|
|
) => {
|
|
return this.reportError(path, queryParams, req, body, logDirectory)
|
|
},
|
|
},
|
|
{
|
|
mustMatch: "csp",
|
|
mimetype: "application/json",
|
|
handle: async (
|
|
path: string,
|
|
queryParams: URLSearchParams,
|
|
req: IncomingMessage,
|
|
body: string | undefined
|
|
) => {
|
|
return this.reportError(path, queryParams, req, body, logDirectory + "/csp")
|
|
},
|
|
},
|
|
])
|
|
}
|
|
}
|
|
|
|
new ServerErrorReport().run()
|