backend/src/middlewares/graphql-logger.ts (view raw)
1import chalk from "chalk";
2
3export default (_, { strapi }) => {
4 return async (ctx, next) => {
5 const start = Date.now();
6 await next();
7 const delta = Math.ceil(Date.now() - start);
8
9 if (ctx.url.startsWith("/graphql")) {
10 const user = ctx.state?.user?.username;
11 const { operationName = "", variables, query } = ctx.request.body || {};
12 const status = graphqlStatus(ctx.body);
13
14 strapi.log.http(
15 `${chalk.magenta(
16 "GRAPHQL"
17 )} ${operationName} (${delta} ms) ${graphqlCodeColor(status)}`,
18 {
19 meta: {
20 operationName,
21 variables,
22 query,
23 status,
24 delta,
25 user,
26 },
27 }
28 );
29 } else {
30 strapi.log.http(
31 `${ctx.method} ${ctx.url} (${delta} ms) ${httpCodeColor(ctx.status)}`
32 );
33 }
34 };
35};
36
37const graphqlStatus = (response) => {
38 if (!response) return "NOT FOUND";
39
40 try {
41 let errors = null;
42 if (typeof response === "string") {
43 const parsed = response ? JSON.parse(response) : {};
44 errors = parsed.errors;
45 } else errors = response?.errors;
46 if (errors) return "ERROR";
47 } catch (error) {
48 console.error("PARSE ERROR", error);
49 return "ERROR";
50 }
51
52 return "OK";
53};
54
55const graphqlCodeColor = (status) => {
56 switch (status) {
57 case "ERROR":
58 return chalk.red(status);
59 case "NOT_FOUND":
60 return chalk.yellow(status);
61 default:
62 return chalk.green(status);
63 }
64};
65
66const httpCodeColor = (code) => {
67 return code >= 500
68 ? chalk.red(code)
69 : code >= 400
70 ? chalk.yellow(code)
71 : code >= 300
72 ? chalk.cyan(code)
73 : code >= 200
74 ? chalk.green(code)
75 : code;
76};