Skip to content

Commit 33ee250

Browse files
authored
feat: add logging middleware (#36)
* deps: add dependency for chalk package * refractor: optimize cron status message display * lib(middleware): add logger middleware * feat: implement logger middleware
1 parent a737627 commit 33ee250

File tree

5 files changed

+82
-8
lines changed

5 files changed

+82
-8
lines changed

bun.lockb

354 Bytes
Binary file not shown.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
},
4646
"dependencies": {
4747
"@prisma/client": "^5.11.0",
48+
"chalk": "^5.3.0",
4849
"cron": "^3.1.6",
4950
"hono": "^4.1.0",
5051
"node-cache": "^5.1.2",

src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import "polyfills/BigInt";
44
import { Hono } from "hono";
55
import { cors } from "hono/cors";
66

7+
import logger from "middleware/logger";
78
import cache from "middleware/request-cache";
89
import rateLimit from "middleware/rate-limit";
910

@@ -23,6 +24,7 @@ import assignments from "routes/assignments";
2324
const app = new Hono().basePath("/api");
2425

2526
// middleware for the api
27+
app.use(logger);
2628
app.use("/*", cors());
2729
app.use(rateLimit);
2830
app.use(cache);

src/jobs/refresh.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import chalk from "chalk";
12
import { CronJob } from "cron";
23

34
import RequestCache from "classes/request-cache";
@@ -8,17 +9,16 @@ new CronJob(
89
async () => {
910
const startDate = Date.now();
1011
try {
11-
console.log("Refreshing source data");
12-
1312
await refreshAndStoreSourceData();
1413
RequestCache.flushAll();
15-
16-
const endDate = Date.now();
17-
console.log(`Source data refreshed in ${endDate - startDate}ms`);
14+
console.log(
15+
`${chalk.bold(chalk.magenta("CRON"))} Refreshed source data ${`(${Date.now() - startDate}ms)`}`,
16+
);
1817
} catch (err: any) {
19-
const endDate = Date.now();
20-
console.error(`Error refreshing source data in ${endDate - startDate}ms`);
21-
console.error(err);
18+
console.error(
19+
`${chalk.bold(chalk.red("ERROR"))} Error refreshing source data ${`(${Date.now() - startDate}ms)`}`,
20+
`\n${err}`,
21+
);
2222
}
2323
},
2424
null,

src/middleware/logger.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import chalk from "chalk";
2+
import type { Context, Next } from "hono";
3+
4+
const status = (code: number) => {
5+
let result;
6+
7+
if (!result && code >= 500) {
8+
result = chalk.red(code);
9+
}
10+
11+
if (!result && code >= 400) {
12+
result = chalk.yellow(code);
13+
}
14+
15+
if (!result && code >= 300) {
16+
result = chalk.green(code);
17+
}
18+
19+
if (!result && code >= 200) {
20+
result = chalk.green(code);
21+
}
22+
23+
if (!result) {
24+
result = chalk.gray(code);
25+
}
26+
27+
return chalk.bold(result);
28+
};
29+
30+
const method = (verb: string) => {
31+
let result;
32+
switch (verb) {
33+
case "GET":
34+
result = chalk.green(verb);
35+
break;
36+
case "POST":
37+
result = chalk.yellow(verb);
38+
break;
39+
case "PUT":
40+
result = chalk.blue(verb);
41+
break;
42+
case "PATCH":
43+
result = chalk.blue(verb);
44+
break;
45+
case "DELETE":
46+
result = chalk.red(verb);
47+
break;
48+
default:
49+
result = chalk.gray(verb);
50+
break;
51+
}
52+
53+
return chalk.bold(result);
54+
};
55+
56+
export default async function logger(ctx: Context, next: Next) {
57+
const start = Date.now();
58+
try {
59+
await next();
60+
} finally {
61+
const durationMs = Date.now() - start;
62+
const ip = ctx.req.header("X-Forwarded-For") || ctx.req.header("X-Real-IP");
63+
console.log(
64+
`${ip ? `${ip} | ` : ""}${method(
65+
ctx.req.method,
66+
)} ${ctx.req.path} ${status(ctx.res.status)} ${chalk.grey(
67+
`(${durationMs}ms)`,
68+
)}`,
69+
);
70+
}
71+
}

0 commit comments

Comments
 (0)