mirror of
https://github.com/thepeacockproject/Peacock
synced 2024-11-22 22:12:45 +01:00
8ec9fb1824
Signed-off-by: Reece Dunham <me@rdil.rocks>
152 lines
4.3 KiB
TypeScript
152 lines
4.3 KiB
TypeScript
/*
|
|
* The Peacock Project - a HITMAN server replacement.
|
|
* Copyright (C) 2021-2023 The Peacock Project Team
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
import type { NextFunction, Response } from "express"
|
|
import type { RequestWithJwt } from "./types/types"
|
|
import picocolors from "picocolors"
|
|
|
|
/**
|
|
* Represents the different log levels.
|
|
*/
|
|
export enum LogLevel {
|
|
/**
|
|
* For errors. Displays in red.
|
|
*/
|
|
ERROR,
|
|
/**
|
|
* For warnings. Displays in yellow.
|
|
*/
|
|
WARN,
|
|
/**
|
|
* For information. Displays in blue.
|
|
* This is also the fallback for invalid log level values.
|
|
*/
|
|
INFO,
|
|
/**
|
|
* For debugging.
|
|
* Displays in light blue, but only if the `DEBUG` environment variable is set to "*", "yes", "true", or "peacock".
|
|
*/
|
|
DEBUG,
|
|
/**
|
|
* For outputting stacktraces.
|
|
*/
|
|
TRACE,
|
|
}
|
|
|
|
const isDebug = ["*", "true", "peacock", "yes"].includes(
|
|
process.env.DEBUG || "false",
|
|
)
|
|
|
|
/**
|
|
* Adds leading zeros to a number so that the length of the string will always
|
|
* be the number of places specified.
|
|
*
|
|
* @param num The number.
|
|
* @param places The intended width of the number (character count).
|
|
* @example
|
|
* zeroPad(5, 2) // -> "05"
|
|
*/
|
|
const zeroPad = (num: string | number, places: number) =>
|
|
String(num).padStart(places, "0")
|
|
|
|
/**
|
|
* Outputs all given arguments as a debug level indented JSON-message to the console.
|
|
*
|
|
* @param args The values to log.
|
|
*/
|
|
export function logDebug(...args: unknown[]): void {
|
|
log(LogLevel.DEBUG, JSON.stringify(args, undefined, " "))
|
|
}
|
|
|
|
/**
|
|
* Outputs a log message to the console.
|
|
*
|
|
* @param level The message's level.
|
|
* @param data The data to output.
|
|
* @see LogLevel
|
|
*/
|
|
export function log(level: LogLevel, data: string): void {
|
|
const m = data ?? "No message specified"
|
|
const now = new Date()
|
|
const stampParts: number[] = [
|
|
now.getHours(),
|
|
now.getMinutes(),
|
|
now.getSeconds(),
|
|
]
|
|
const millis = zeroPad(now.getMilliseconds(), 3)
|
|
const timestamp = `${stampParts
|
|
.map((part) => zeroPad(part, 2))
|
|
.join(":")}:${millis}`
|
|
|
|
const header = picocolors.gray(timestamp)
|
|
let outputTransport: (
|
|
message?: unknown,
|
|
...optionalParams: unknown[]
|
|
) => void
|
|
let levelString: string
|
|
|
|
switch (level) {
|
|
case LogLevel.ERROR:
|
|
outputTransport = console.error
|
|
levelString = picocolors.red("Error")
|
|
break
|
|
case LogLevel.WARN:
|
|
outputTransport = console.warn
|
|
levelString = picocolors.yellow("Warn")
|
|
break
|
|
case LogLevel.INFO:
|
|
default:
|
|
outputTransport = console.log
|
|
levelString = picocolors.blue("Info")
|
|
break
|
|
case LogLevel.DEBUG:
|
|
if (!isDebug) {
|
|
return
|
|
}
|
|
outputTransport = console.log
|
|
levelString = picocolors.blueBright("Debug")
|
|
break
|
|
case LogLevel.TRACE:
|
|
outputTransport = console.trace
|
|
levelString = picocolors.bgYellow("Trace")
|
|
break
|
|
}
|
|
|
|
outputTransport(`[${header}] [${levelString}] ${m}`)
|
|
}
|
|
|
|
/**
|
|
* Express middleware that logs all requests and their details with the info log level.
|
|
*
|
|
* @param req The Express request object.
|
|
* @param res The Express response object.
|
|
* @param next The Express next function.
|
|
* @see LogLevel.INFO
|
|
*/
|
|
export function loggingMiddleware(
|
|
req: RequestWithJwt,
|
|
res: Response,
|
|
next?: NextFunction,
|
|
): void {
|
|
log(
|
|
LogLevel.INFO,
|
|
`${picocolors.green(req.method)} ${picocolors.underline(req.url)}`,
|
|
)
|
|
next?.()
|
|
}
|