Highly ambitious ATProtocol AppView service and sdks
1// Request logging middleware for the frontend server
2import {
3 red,
4 green,
5 yellow,
6 blue,
7 magenta,
8 cyan,
9 gray,
10 bold,
11 dim,
12} from "@std/fmt/colors";
13
14function getStatusColor(status: number): (text: string) => string {
15 if (status >= 500) return red;
16 if (status >= 400) return yellow;
17 if (status >= 300) return cyan;
18 if (status >= 200) return green;
19 return gray;
20}
21
22function getMethodColor(method: string): (text: string) => string {
23 switch (method) {
24 case "GET":
25 return blue;
26 case "POST":
27 return green;
28 case "PUT":
29 return yellow;
30 case "DELETE":
31 return red;
32 case "PATCH":
33 return magenta;
34 default:
35 return gray;
36 }
37}
38
39export function logRequest(
40 req: Request,
41 start: number,
42 response: Response
43): void {
44 const duration = Date.now() - start;
45 const url = new URL(req.url);
46 const method = req.method;
47 const status = response.status;
48 const userAgent = req.headers.get("user-agent") || "-";
49 const referer = req.headers.get("referer") || "-";
50
51 const methodColored = getMethodColor(method)(method);
52 const statusColored = getStatusColor(status)(status.toString());
53 const pathColored = bold(`${url.pathname}${url.search}`);
54 const durationColored =
55 duration > 1000
56 ? red(`${duration}ms`)
57 : duration > 500
58 ? yellow(`${duration}ms`)
59 : dim(`${duration}ms`);
60
61 console.log(
62 `${methodColored} ${pathColored} ${statusColored} ${durationColored} ${gray(
63 `- ${userAgent} - ${referer}`
64 )}`
65 );
66}
67
68export function createLoggingHandler(
69 handler: (req: Request) => Response | Promise<Response>
70) {
71 return async function loggingHandler(req: Request): Promise<Response> {
72 const start = Date.now();
73
74 try {
75 const response = await handler(req);
76 logRequest(req, start, response);
77 return response;
78 } catch (error) {
79 const duration = Date.now() - start;
80 const url = new URL(req.url);
81 const message = error instanceof Error ? error.message : String(error);
82 const methodColored = getMethodColor(req.method)(req.method);
83 const pathColored = bold(`${url.pathname}${url.search}`);
84 const errorColored = red("ERROR");
85 const durationColored = red(`${duration}ms`);
86
87 console.error(
88 `${methodColored} ${pathColored} ${errorColored} ${durationColored} ${red(
89 `- ${message}`
90 )}`
91 );
92
93 // Return a generic 500 error
94 const response = new Response("Internal Server Error", { status: 500 });
95 logRequest(req, start, response);
96 return response;
97 }
98 };
99}