diff --git a/packages/backend-defaults/package.json b/packages/backend-defaults/package.json index 73f90fd153..ea5d0abd94 100644 --- a/packages/backend-defaults/package.json +++ b/packages/backend-defaults/package.json @@ -163,7 +163,6 @@ "luxon": "^3.0.0", "minimatch": "^9.0.0", "minimist": "^1.2.5", - "morgan": "^1.10.0", "mysql2": "^3.0.0", "node-fetch": "^2.7.0", "node-forge": "^1.3.1", @@ -193,7 +192,6 @@ "@types/base64-stream": "^1.0.2", "@types/concat-stream": "^2.0.0", "@types/http-errors": "^2.0.0", - "@types/morgan": "^1.9.0", "@types/node-forge": "^1.3.0", "@types/pg-format": "^1.0.5", "@types/stoppable": "^1.1.0", diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory.test.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory.test.ts index 1c99c0e020..f5256f5a25 100644 --- a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory.test.ts +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory.test.ts @@ -251,7 +251,7 @@ describe('MiddlewareFactory', () => { expect(logger.info).toHaveBeenCalledWith( expect.stringContaining( - '[20/Nov/2024:00:00:00 +0000] "GET / HTTP/1.1" 200 11 "-" "-"', + '[2024-11-20T00:00:00.000Z] "GET / HTTP/1.1" 200 11 "-" "-"', ), { type: 'incomingRequest', @@ -278,7 +278,7 @@ describe('MiddlewareFactory', () => { expect(logger.info).toHaveBeenCalledWith( expect.stringContaining( - '[20/Nov/2024:00:00:00 +0000] "GET / HTTP/1.1" 200 11 "test-referrer" "test-agent"', + '[2024-11-20T00:00:00.000Z] "GET / HTTP/1.1" 200 11 "test-referrer" "test-agent"', ), { type: 'incomingRequest', diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory.ts index 070ffb19cf..a22b783f24 100644 --- a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory.ts +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory.ts @@ -18,7 +18,6 @@ import { RootConfigService, LoggerService, } from '@backstage/backend-plugin-api'; -import { IncomingMessage, ServerResponse } from 'http'; import { Request, Response, @@ -28,7 +27,6 @@ import { } from 'express'; import cors from 'cors'; import helmet from 'helmet'; -import morgan, { TokenIndexer } from 'morgan'; import compression from 'compression'; import { readHelmetOptions } from './readHelmetOptions'; import { readCorsOptions } from './readCorsOptions'; @@ -46,27 +44,43 @@ import { import { NotImplementedError } from '@backstage/errors'; import { applyInternalErrorFilter } from './applyInternalErrorFilter'; -const getLogMessage = morgan.compile( - '[:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"', -); +type LogMeta = { + date: string; + method: string; + url: string; + status: number; + httpVersion: string; + userAgent?: string; + contentLength?: number; + referrer?: string; +}; -function getLogMeta( - tokens: TokenIndexer, - req: IncomingMessage, - res: ServerResponse, -) { - const status = Number(tokens.status(req, res)); - const contentLength = Number(tokens.res(req, res, 'content-length')); - return { - date: tokens.date(req, res, 'iso'), - method: tokens.method(req, res), - url: tokens.url(req, res), - httpVersion: tokens['http-version'](req, res), - status: isFinite(status) ? status : undefined, - contentLength: isFinite(contentLength) ? contentLength : undefined, - referrer: tokens.referrer(req, res), - userAgent: tokens.req(req, res, 'user-agent'), +function getLogMeta(req: Request, res: Response): LogMeta { + const referrer = req.headers.referer ?? req.headers.referrer; + const userAgent = req.headers['user-agent']; + const contentLength = Number(res.getHeader('content-length')); + + const meta: LogMeta = { + date: new Date().toISOString(), + method: req.method, + url: req.originalUrl ?? req.url, + status: res.statusCode, + httpVersion: `${req.httpVersionMajor}.${req.httpVersionMinor}`, }; + + if (userAgent) { + meta.userAgent = userAgent; + } + + if (isFinite(contentLength)) { + meta.contentLength = contentLength; + } + + if (referrer) { + meta.referrer = Array.isArray(referrer) ? referrer.join(', ') : referrer; + } + + return meta; } /** @@ -162,24 +176,23 @@ export class MiddlewareFactory { */ logging(): RequestHandler { const logger = this.#logger; - return morgan( - (tokens: TokenIndexer, req: IncomingMessage, res: ServerResponse) => { - const meta = getLogMeta(tokens, req, res); - const message = getLogMessage(tokens, req, res); - return JSON.stringify({ meta, message }); - }, - { - stream: { - write(json: string) { - const { meta, message } = JSON.parse(json); - logger.info(message.trimEnd(), { - type: 'incomingRequest', - ...meta, - }); + return (req: Request, res: Response, next: NextFunction) => { + res.on('finish', () => { + const meta = getLogMeta(req, res); + logger.info( + `[${meta.date}] "${meta.method} ${meta.url} HTTP/${ + meta.httpVersion + }" ${meta.status} ${meta.contentLength} "${meta.referrer ?? '-'}" "${ + meta.userAgent ?? '-' + }"`, + { + type: 'incomingRequest', + ...meta, }, - }, - }, - ); + ); + }); + next(); + }; } /** diff --git a/yarn.lock b/yarn.lock index cda2b4bbc0..caa650f862 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3611,7 +3611,6 @@ __metadata: "@types/cors": ^2.8.6 "@types/express": ^4.17.6 "@types/http-errors": ^2.0.0 - "@types/morgan": ^1.9.0 "@types/node-forge": ^1.3.0 "@types/pg-format": ^1.0.5 "@types/stoppable": ^1.1.0 @@ -3640,7 +3639,6 @@ __metadata: luxon: ^3.0.0 minimatch: ^9.0.0 minimist: ^1.2.5 - morgan: ^1.10.0 msw: ^1.0.0 mysql2: ^3.0.0 node-fetch: ^2.7.0