From bdd6ab5f192ee4b56352783cff94042284284334 Mon Sep 17 00:00:00 2001 From: Carlo Colombo Date: Mon, 19 Jul 2021 15:16:09 +0200 Subject: [PATCH] Adds configuration for request logging handler when creating the backend express app Signed-off-by: Carlo Colombo --- .changeset/fuzzy-pots-whisper.md | 15 +++++++++++++++ packages/backend-common/api-report.md | 11 +++++++++++ packages/backend-common/src/service/index.ts | 2 +- .../src/service/lib/ServiceBuilderImpl.ts | 16 +++++++++++++--- packages/backend-common/src/service/types.ts | 13 +++++++++++++ 5 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 .changeset/fuzzy-pots-whisper.md diff --git a/.changeset/fuzzy-pots-whisper.md b/.changeset/fuzzy-pots-whisper.md new file mode 100644 index 0000000000..772ba1fb43 --- /dev/null +++ b/.changeset/fuzzy-pots-whisper.md @@ -0,0 +1,15 @@ +--- +'@backstage/backend-common': patch +--- + +It's possible to customize the request logging handler when building the service. For example in your `backend` + +``` + const service = createServiceBuilder(module) + .loadConfig(config) + .setRequestLoggingHandler((logger?: Logger): RequestHandler => { + const actualLogger = (logger || getRootLogger()).child({ + type: 'incomingRequest', + }); + return expressWinston.logger({ ... +``` diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md index 571a26e5dc..2652dad122 100644 --- a/packages/backend-common/api-report.md +++ b/packages/backend-common/api-report.md @@ -439,6 +439,13 @@ export type ReadTreeResponseFile = { // @public export function requestLoggingHandler(logger?: Logger_2): RequestHandler; +// Warning: (ae-missing-release-tag) "RequestLoggingHandlerFactory" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type RequestLoggingHandlerFactory = ( + logger?: Logger_2, +) => RequestHandler; + // Warning: (ae-missing-release-tag) "resolvePackagePath" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public @@ -492,6 +499,9 @@ export type ServiceBuilder = { enableCors(options: cors.CorsOptions): ServiceBuilder; setHttpsSettings(settings: HttpsSettings): ServiceBuilder; addRouter(root: string, router: Router | RequestHandler): ServiceBuilder; + setRequestLoggingHandler( + requestLoggingHandler: RequestLoggingHandlerFactory, + ): ServiceBuilder; start(): Promise; }; @@ -593,6 +603,7 @@ export function useHotMemoize(_module: NodeModule, valueFactory: () => T): T; // src/service/types.d.ts:57:5 - (ae-forgotten-export) The symbol "HttpsSettings" needs to be exported by the entry point index.d.ts // src/service/types.d.ts:61:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/service/types.d.ts:62:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// src/service/types.d.ts:70:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-common/src/service/index.ts b/packages/backend-common/src/service/index.ts index 4eb0bf4a5a..d01f25fad3 100644 --- a/packages/backend-common/src/service/index.ts +++ b/packages/backend-common/src/service/index.ts @@ -16,4 +16,4 @@ export { createServiceBuilder } from './createServiceBuilder'; export { createStatusCheckRouter } from './createStatusCheckRouter'; -export type { ServiceBuilder } from './types'; +export type { ServiceBuilder, RequestLoggingHandlerFactory } from './types'; diff --git a/packages/backend-common/src/service/lib/ServiceBuilderImpl.ts b/packages/backend-common/src/service/lib/ServiceBuilderImpl.ts index 380d61abc8..7a3ebfed70 100644 --- a/packages/backend-common/src/service/lib/ServiceBuilderImpl.ts +++ b/packages/backend-common/src/service/lib/ServiceBuilderImpl.ts @@ -27,9 +27,9 @@ import { getRootLogger } from '../../logging'; import { errorHandler, notFoundHandler, - requestLoggingHandler, + requestLoggingHandler as defaultRequestLoggingHandler, } from '../../middleware'; -import { ServiceBuilder } from '../types'; +import { RequestLoggingHandlerFactory, ServiceBuilder } from '../types'; import { CspOptions, HttpsSettings, @@ -65,6 +65,7 @@ export class ServiceBuilderImpl implements ServiceBuilder { private cspOptions: Record | undefined; private httpsSettings: HttpsSettings | undefined; private routers: [string, Router][]; + private requestLoggingHandler: RequestLoggingHandlerFactory | undefined; // Reference to the module where builder is created - needed for hot module // reloading private module: NodeModule; @@ -144,6 +145,13 @@ export class ServiceBuilderImpl implements ServiceBuilder { return this; } + setRequestLoggingHandler( + requestLoggingHandler: RequestLoggingHandlerFactory, + ) { + this.requestLoggingHandler = requestLoggingHandler; + return this; + } + async start(): Promise { const app = express(); const { @@ -160,7 +168,9 @@ export class ServiceBuilderImpl implements ServiceBuilder { app.use(cors(corsOptions)); } app.use(compression()); - app.use(requestLoggingHandler(logger)); + app.use( + (this.requestLoggingHandler ?? defaultRequestLoggingHandler)(logger), + ); for (const [root, route] of this.routers) { app.use(root, route); } diff --git a/packages/backend-common/src/service/types.ts b/packages/backend-common/src/service/types.ts index 70f62acfca..f845397ca2 100644 --- a/packages/backend-common/src/service/types.ts +++ b/packages/backend-common/src/service/types.ts @@ -85,8 +85,21 @@ export type ServiceBuilder = { */ addRouter(root: string, router: Router | RequestHandler): ServiceBuilder; + /** + * Set the request logging handler + * + * If no handler is given the default one is used + * + * @param requestLoggingHandler a factory function that given a logger returns an handler + */ + setRequestLoggingHandler( + requestLoggingHandler: RequestLoggingHandlerFactory, + ): ServiceBuilder; + /** * Starts the server using the given settings. */ start(): Promise; }; + +export type RequestLoggingHandlerFactory = (logger?: Logger) => RequestHandler;