From 4d28f87852d88a84b7fdac19fb7894f2bd40b612 Mon Sep 17 00:00:00 2001 From: Avior Date: Sun, 10 Dec 2023 02:07:44 +0100 Subject: [PATCH] feat: Upgrade logging to still be better than Astro's logging - Made errors more visible - Made dev logging compatible with Astro's logging - Made our logging more beautiful by copying Astro's colors node: The only thing I don't like is having different comportement depending on wether we are in PROD or dev, but it shouldn't affect anything as it's variable affection and `console.log` Signed-off-by: Avior --- src/middleware/logger.ts | 44 ++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/src/middleware/logger.ts b/src/middleware/logger.ts index 0cab96f..a7c4d2d 100644 --- a/src/middleware/logger.ts +++ b/src/middleware/logger.ts @@ -1,23 +1,49 @@ import { defineMiddleware } from "astro/middleware" import ResponseBuilder from 'libs/ResponseBuilder' -// `context` and `next` are automatically typed -export default defineMiddleware(async ({ request }, next) => { - const prefix = `[${new Date().toISOString()}] ${request.headers.get('user-agent')?.slice(0, 32).padEnd(32)} ${request.method.padEnd(7)}` - console.log(`${prefix} ${request.url}`) +/** + * Simple Middleware that handle the logging of requests and handling processing errors + */ +export default defineMiddleware(async ({ request, url }, next) => { + const now = new Date() + // Date of request User-Agent 32 first chars request Method + let prefix = `\x1b[2m${now.toISOString()}\x1b[22m ${request.headers.get('user-agent')?.slice(0, 32).padEnd(32)} ${request.method.padEnd(7)}` - // can crash if response crash + const fullURL = url.toString() + const path = fullURL.slice(fullURL.indexOf(url.pathname, fullURL.indexOf(url.host))) + + if (!import.meta.env.PROD) { + // time of request + prefix = `\x1b[2m${new Date().toLocaleTimeString('fr')}\x1b[22m` + } + + // HTTP Status Code Time to run request path of request + console.log(`${prefix} ${''.padStart(5, ' ')} ${''.padStart(7, ' ')} ${path}`) + + // Handle if the request die try { const res = await next() - console.log(`${prefix} ${res.status} ${request.url}`) + if (import.meta.env.PROD) { + // HTTP Status time to execute path of request + console.log(`${prefix} \x1b[34m[${res.status}]\x1b[0m \x1b[2m${(new Date().getTime() - now.getTime()).toFixed(0).padStart(5, ' ')}ms\x1b[22m ${path}`) + } return res } catch (e) { - console.log(`${prefix} 500 ${request.url}`) - console.error('-------------------------------') + if (import.meta.env.PROD) { + // time to execute path of request + console.log(`${prefix} \x1b[34m[500]\x1b[0m \x1b[2m${(new Date().getTime() - now.getTime()).toFixed(0).padStart(5, ' ')}ms\x1b[22m ${path}`) + } + + // add a full line dash to not miss it + const columns = (process?.stdout?.columns ?? 32) - 7 + const dashes = ''.padEnd(columns / 2, '-') + + // colorize the lines to make sur to not miss it + console.error(`\x1b[91m${dashes} ERROR ${dashes}\x1b[0m`) console.error(e) - console.error('-------------------------------') + console.error(`\x1b[91m${dashes} ERROR ${dashes}\x1b[0m`) return new ResponseBuilder() .status(500)