diff --git a/.changeset/funny-tips-push.md b/.changeset/funny-tips-push.md new file mode 100644 index 0000000000..224e6a073a --- /dev/null +++ b/.changeset/funny-tips-push.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-defaults': patch +--- + +update the `morgan` middleware to use a custom format to prevent PII from being logged diff --git a/.github/vale/config/vocabularies/Backstage/accept.txt b/.github/vale/config/vocabularies/Backstage/accept.txt index bad61de7ff..320bb2e0ce 100644 --- a/.github/vale/config/vocabularies/Backstage/accept.txt +++ b/.github/vale/config/vocabularies/Backstage/accept.txt @@ -243,6 +243,7 @@ Mkdocs monorepo Monorepo monorepos +morgan msgraph msw multiton diff --git a/docs/backend-system/core-services/root-http-router.md b/docs/backend-system/core-services/root-http-router.md index b3522e1752..88a10455f5 100644 --- a/docs/backend-system/core-services/root-http-router.md +++ b/docs/backend-system/core-services/root-http-router.md @@ -52,19 +52,49 @@ You can configure the root HTTP Router service by passing the options to the `cr ```ts import { rootHttpRouterServiceFactory } from '@backstage/backend-app-api'; +import { RequestHandler } from 'express'; +import morgan from 'morgan'; const backend = createBackend(); backend.add( rootHttpRouterServiceFactory({ configure: ({ app, middleware, routes, config, logger, lifecycle }) => { + // Refer to https://expressjs.com/en/guide/writing-middleware.html on how to write express middleware + const customMiddleware = { + logging(): RequestHandler { + const middlewareLogger = logger.child({ + type: 'incomingRequest', + }); + return (req, res, next) => { + // Custom Logging Implementation + next(); + }; + }, + // Default logging middleware uses the [morgan](https://github.com/expressjs/morgan) middleware which you can configure with custom formats. + morganLogging(): RequestHandler { + const middlewareLogger = logger.child({ + type: 'incomingRequest', + }); + const customMorganFormat = + '[:date[clf]] ":method :url HTTP/:http-version" :status ":user-agent"'; + return morgan(customMorganFormat, { + stream: { + write(message: string) { + logger.info(message.trimEnd()); + }, + }, + }); + }, + }; + // the built in middleware is provided through an option in the configure function app.use(middleware.helmet()); app.use(middleware.cors()); app.use(middleware.compression()); // you can add you your own middleware in here - app.use(custom.logging()); + app.use(customMiddleware.logging()); // here the routes that are registered by other plugins app.use(routes); diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory.ts index 77136fd7e5..f38c10820a 100644 --- a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory.ts +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory.ts @@ -140,8 +140,9 @@ export class MiddlewareFactory { const logger = this.#logger.child({ type: 'incomingRequest', }); - - return morgan('combined', { + const customMorganFormat = + '[:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"'; + return morgan(customMorganFormat, { stream: { write(message: string) { logger.info(message.trimEnd());