• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

semperai / amica-personas / 18257321905

05 Oct 2025 10:11AM UTC coverage: 19.184% (-0.8%) from 20.007%
18257321905

push

github

web-flow
Merge pull request #23 from kasumi-1/import-api

Add new API service with credit-based auth and monitoring

894 of 1155 branches covered (77.4%)

Branch coverage included in aggregate %.

0 of 1185 new or added lines in 15 files covered. (0.0%)

4589 of 27426 relevant lines covered (16.73%)

59.47 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/api/src/middleware/requestLogger.ts
NEW
1
import { randomUUID } from "node:crypto";
×
2
import type { IncomingMessage, ServerResponse } from "node:http";
3
import type { Request, RequestHandler, Response } from "express";
NEW
4
import { getReasonPhrase, StatusCodes } from "http-status-codes";
×
5
import type { LevelWithSilent } from "pino";
NEW
6
import { type CustomAttributeKeys, type Options, pinoHttp } from "pino-http";
×
7

NEW
8
import { env } from "@/utils/envConfig";
×
9

NEW
10
enum LogLevel {
×
NEW
11
  Fatal = "fatal",
×
NEW
12
  Error = "error",
×
NEW
13
  Warn = "warn",
×
NEW
14
  Info = "info",
×
NEW
15
  Debug = "debug",
×
NEW
16
  Trace = "trace",
×
NEW
17
  Silent = "silent",
×
18
}
19

20
type PinoCustomProps = {
21
  request: Request;
22
  response: Response;
23
  error: Error;
24
  responseBody: unknown;
25
};
26

NEW
27
const requestLogger = (options?: Options): RequestHandler[] => {
×
NEW
28
  const pinoOptions: Options = {
×
NEW
29
    enabled: true, // Enable logging in all environments
×
NEW
30
    customProps: customProps as unknown as Options["customProps"],
×
NEW
31
    redact: ["request.headers.authorization", "request.headers.cookie"], // Redact sensitive headers
×
NEW
32
    genReqId,
×
NEW
33
    customLogLevel,
×
NEW
34
    customSuccessMessage,
×
NEW
35
    customReceivedMessage: (req) => `request received: ${req.method}`,
×
NEW
36
    customErrorMessage: (_req, res) => `request errored with status code: ${res.statusCode}`,
×
NEW
37
    customAttributeKeys,
×
NEW
38
    ...options,
×
NEW
39
  };
×
NEW
40
  return [responseBodyMiddleware, pinoHttp(pinoOptions)];
×
NEW
41
};
×
42

NEW
43
const customAttributeKeys: CustomAttributeKeys = {
×
NEW
44
  req: "request",
×
NEW
45
  res: "response",
×
NEW
46
  err: "error",
×
NEW
47
  responseTime: "timeTaken",
×
NEW
48
};
×
49

NEW
50
const customProps = (req: Request, res: Response): PinoCustomProps => ({
×
NEW
51
  request: req,
×
NEW
52
  response: res,
×
NEW
53
  error: res.locals.err,
×
NEW
54
  responseBody: res.locals.responseBody,
×
NEW
55
});
×
56

NEW
57
const responseBodyMiddleware: RequestHandler = (_req, res, next) => {
×
NEW
58
  const isNotProduction = !env.isProduction;
×
NEW
59
  if (isNotProduction) {
×
NEW
60
    const originalSend = res.send;
×
NEW
61
    res.send = (content) => {
×
NEW
62
      res.locals.responseBody = content;
×
NEW
63
      res.send = originalSend;
×
NEW
64
      return originalSend.call(res, content);
×
NEW
65
    };
×
NEW
66
  }
×
NEW
67
  next();
×
NEW
68
};
×
69

NEW
70
const customLogLevel = (_req: IncomingMessage, res: ServerResponse<IncomingMessage>, err?: Error): LevelWithSilent => {
×
NEW
71
  if (err || res.statusCode >= StatusCodes.INTERNAL_SERVER_ERROR) return LogLevel.Error;
×
NEW
72
  if (res.statusCode >= StatusCodes.BAD_REQUEST) return LogLevel.Warn;
×
NEW
73
  if (res.statusCode >= StatusCodes.MULTIPLE_CHOICES) return LogLevel.Silent;
×
NEW
74
  return LogLevel.Info;
×
NEW
75
};
×
76

NEW
77
const customSuccessMessage = (req: IncomingMessage, res: ServerResponse<IncomingMessage>) => {
×
NEW
78
  if (res.statusCode === StatusCodes.NOT_FOUND) return getReasonPhrase(StatusCodes.NOT_FOUND);
×
NEW
79
  return `${req.method} completed`;
×
NEW
80
};
×
81

NEW
82
const genReqId = (req: IncomingMessage, res: ServerResponse<IncomingMessage>) => {
×
NEW
83
  const existingID = req.id ?? req.headers["x-request-id"];
×
NEW
84
  if (existingID) return existingID;
×
NEW
85
  const id = randomUUID();
×
NEW
86
  res.setHeader("X-Request-Id", id);
×
NEW
87
  return id;
×
NEW
88
};
×
89

NEW
90
export default requestLogger();
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc