diff --git a/src/helpers/logging/__mocks__/logger.js b/src/helpers/logging/__mocks__/logger.js deleted file mode 100644 index d0cba7f..0000000 --- a/src/helpers/logging/__mocks__/logger.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * @returns {Logger} - */ -export function createLogger() { - // @ts-expect-error - stub only for tests - return /** @type {Logger} */ ({ - info: jest.fn(), - level: '1', - fatal: jest.fn(), - error: jest.fn(), - debug: jest.fn(), - trace: jest.fn(), - silent: jest.fn(), - warn: jest.fn() - }) -} - -/** - * @import { Logger } from 'pino' - */ diff --git a/src/helpers/logging/logger.js b/src/helpers/logging/logger.js index 7e7e63f..e71e12f 100644 --- a/src/helpers/logging/logger.js +++ b/src/helpers/logging/logger.js @@ -5,6 +5,10 @@ import { loggerOptions } from '~/src/helpers/logging/logger-options.js' /** * Create a logger instance. */ -export function createLogger() { +function createPinoLogger() { return pino(loggerOptions) } + +// Singleton logger instance - pino adds 'exit' listeners to process, +// so we reuse a single instance to avoid MaxListenersExceededWarning +export const logger = createPinoLogger() diff --git a/src/index.js b/src/index.js index 0bfa919..156aa74 100644 --- a/src/index.js +++ b/src/index.js @@ -2,9 +2,7 @@ import { chdir } from 'node:process' import { getErrorMessage } from '@defra/forms-model' -import { createLogger } from '~/src/helpers/logging/logger.js' - -const logger = createLogger() +import { logger } from '~/src/helpers/logging/logger.js' // Move working directory to build output chdir(import.meta.dirname) diff --git a/src/messaging/event.js b/src/messaging/event.js index befe3c1..762dede 100644 --- a/src/messaging/event.js +++ b/src/messaging/event.js @@ -6,7 +6,7 @@ import { } from '@aws-sdk/client-sqs' import { config } from '~/src/config/index.js' -import { createLogger } from '~/src/helpers/logging/logger.js' +import { logger } from '~/src/helpers/logging/logger.js' import { sqsClient } from '~/src/messaging/sqs.js' export const receiveMessageTimeout = config.get('receiveMessageTimeout') @@ -16,8 +16,6 @@ const deadLetterQueueArn = config.get('sqsEventsDlqArn') const maxNumberOfMessages = config.get('maxNumberOfMessages') const visibilityTimeout = config.get('visibilityTimeout') -const logger = createLogger() - /** * @type {ReceiveMessageCommandInput} */ diff --git a/src/messaging/event.test.js b/src/messaging/event.test.js index ebc7342..884b687 100644 --- a/src/messaging/event.test.js +++ b/src/messaging/event.test.js @@ -17,7 +17,13 @@ import { resubmitDlqMessage } from '~/src/messaging/event.js' -jest.mock('~/src/helpers/logging/logger.js') +jest.mock('~/src/helpers/logging/logger.js', () => ({ + logger: { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn() + } +})) describe('event', () => { const snsMock = mockClient(SQSClient) diff --git a/src/plugins/auth/auth.test.js b/src/plugins/auth/auth.test.js index 6dbf822..31a7c42 100644 --- a/src/plugins/auth/auth.test.js +++ b/src/plugins/auth/auth.test.js @@ -3,11 +3,11 @@ const mockActualTestWarnFn = jest.fn() const mockActualTestInfoFn = jest.fn() jest.mock('~/src/helpers/logging/logger.js', () => ({ - createLogger: jest.fn().mockReturnValue({ + logger: { error: mockActualTestErrorFn, warn: mockActualTestWarnFn, info: mockActualTestInfoFn - }) + } })) jest.mock('~/src/config/index.js', () => ({ diff --git a/src/plugins/auth/index.js b/src/plugins/auth/index.js index aa4ff81..40dbbee 100644 --- a/src/plugins/auth/index.js +++ b/src/plugins/auth/index.js @@ -1,15 +1,13 @@ import Jwt from '@hapi/jwt' import { config } from '~/src/config/index.js' -import { createLogger } from '~/src/helpers/logging/logger.js' +import { logger } from '~/src/helpers/logging/logger.js' import { getUserScopes } from '~/src/service/entitlements/service.js' const oidcJwksUri = config.get('oidcJwksUri') const oidcVerifyAud = config.get('oidcVerifyAud') const oidcVerifyIss = config.get('oidcVerifyIss') -const logger = createLogger() - /** * Validates user credentials from JWT token * @param {Artifacts} artifacts - JWT artifacts diff --git a/src/routes/admin.js b/src/routes/admin.js index 03acbe1..a72ae7d 100644 --- a/src/routes/admin.js +++ b/src/routes/admin.js @@ -1,7 +1,7 @@ import { Scopes } from '@defra/forms-model' import Joi from 'joi' -import { createLogger } from '~/src/helpers/logging/logger.js' +import { logger } from '~/src/helpers/logging/logger.js' import { deleteDlqMessage, receiveDlqMessages, @@ -9,8 +9,6 @@ import { resubmitDlqMessage } from '~/src/messaging/event.js' -const logger = createLogger() - const OK_RESPONSE = 200 const messageIdSchema = Joi.object({ diff --git a/src/server.js b/src/server.js index f7aba04..801ad86 100644 --- a/src/server.js +++ b/src/server.js @@ -2,9 +2,7 @@ import { getErrorMessage } from '@defra/forms-model' import { createServer } from '~/src/api/server.js' import { config } from '~/src/config/index.js' -import { createLogger } from '~/src/helpers/logging/logger.js' - -const logger = createLogger() +import { logger } from '~/src/helpers/logging/logger.js' process.on('unhandledRejection', (err) => { logger.error( diff --git a/src/service/entitlements/service.js b/src/service/entitlements/service.js index f686316..d689ab5 100644 --- a/src/service/entitlements/service.js +++ b/src/service/entitlements/service.js @@ -1,12 +1,11 @@ import Boom from '@hapi/boom' import { config } from '~/src/config/index.js' -import { createLogger } from '~/src/helpers/logging/logger.js' +import { logger } from '~/src/helpers/logging/logger.js' import { getJson } from '~/src/lib/fetch.js' const entitlementUrl = config.get('entitlementUrl') const entitlementsEndpoint = new URL('/', entitlementUrl) -const logger = createLogger() /** * Fetches user scopes from the entitlements API diff --git a/src/service/entitlements/service.test.js b/src/service/entitlements/service.test.js index 3708142..9be47ce 100644 --- a/src/service/entitlements/service.test.js +++ b/src/service/entitlements/service.test.js @@ -37,7 +37,7 @@ describe('entitlements service', () => { } })) jest.doMock('~/src/helpers/logging/logger.js', () => ({ - createLogger: jest.fn().mockReturnValue(mockLogger) + logger: mockLogger })) const fetchModule = await import('~/src/lib/fetch.js') diff --git a/src/service/events.js b/src/service/events.js index 421cdbe..6b57fe6 100644 --- a/src/service/events.js +++ b/src/service/events.js @@ -2,11 +2,9 @@ import { formAdapterSubmissionMessagePayloadSchema } from '@defra/forms-engine-p import { getErrorMessage } from '@defra/forms-model' import Joi from 'joi' -import { createLogger } from '~/src/helpers/logging/logger.js' +import { logger } from '~/src/helpers/logging/logger.js' import { deleteEventMessage } from '~/src/messaging/event.js' -const logger = createLogger() - /** * @param {Message} message * @returns {FormAdapterSubmissionMessage} diff --git a/src/service/events.test.js b/src/service/events.test.js index 29c238b..35a08a6 100644 --- a/src/service/events.test.js +++ b/src/service/events.test.js @@ -17,7 +17,13 @@ import { } from '~/src/service/events.js' jest.mock('~/src/messaging/event.js') -jest.mock('~/src/helpers/logging/logger.js') +jest.mock('~/src/helpers/logging/logger.js', () => ({ + logger: { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn() + } +})) jest.mock('~/src/config/index.js', () => ({ config: { get: jest.fn(() => { diff --git a/src/service/notify.js b/src/service/notify.js index c56a469..9e50bce 100644 --- a/src/service/notify.js +++ b/src/service/notify.js @@ -2,7 +2,7 @@ import { isFeedbackForm, replaceCustomControllers } from '@defra/forms-model' import { config } from '~/src/config/index.js' import { getBoomErrorMessage } from '~/src/helpers/logging/error-helper.js' -import { createLogger } from '~/src/helpers/logging/logger.js' +import { logger } from '~/src/helpers/logging/logger.js' import { getFormDefinition, getFormMetadata } from '~/src/lib/manager.js' import { sendNotification } from '~/src/lib/notify.js' import { getFormatter } from '~/src/service/mappers/formatters/index.js' @@ -10,7 +10,6 @@ import { getUserConfirmationEmailBody } from '~/src/service/mappers/user-confirm const templateId = config.get('notifyTemplateId') const notifyReplyToId = config.get('notifyReplyToId') -const logger = createLogger() /** * Sends one or more mails to GovNotify diff --git a/src/service/notify.test.js b/src/service/notify.test.js index a9f2fb8..b67b2b2 100644 --- a/src/service/notify.test.js +++ b/src/service/notify.test.js @@ -25,11 +25,11 @@ import { } from '~/src/service/notify.js' jest.mock('~/src/helpers/logging/logger.js', () => ({ - createLogger: () => ({ + logger: { info: jest.fn(), error: jest.fn(), debug: jest.fn() - }) + } })) jest.mock('nunjucks', () => { const environment = { diff --git a/src/tasks/receive-messages.js b/src/tasks/receive-messages.js index 2cd2461..ff61874 100644 --- a/src/tasks/receive-messages.js +++ b/src/tasks/receive-messages.js @@ -1,14 +1,12 @@ import { getErrorMessage } from '@defra/forms-model' -import { createLogger } from '~/src/helpers/logging/logger.js' +import { logger } from '~/src/helpers/logging/logger.js' import { receiveEventMessages, receiveMessageTimeout } from '~/src/messaging/event.js' import { handleEvent } from '~/src/service/index.js' -const logger = createLogger() - /** * @returns {Promise} */ diff --git a/src/tasks/receive-messages.test.js b/src/tasks/receive-messages.test.js index e78f04a..c180250 100644 --- a/src/tasks/receive-messages.test.js +++ b/src/tasks/receive-messages.test.js @@ -7,7 +7,13 @@ import { handleEvent } from '~/src/service/index.js' import { runTask, runTaskOnce } from '~/src/tasks/receive-messages.js' jest.mock('~/src/messaging/event.js') jest.mock('~/src/service/index.js') -jest.mock('~/src/helpers/logging/logger.js') +jest.mock('~/src/helpers/logging/logger.js', () => ({ + logger: { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn() + } +})) describe('receive-messages', () => { const message = /** @type {Message} */ ({