From f1b81e66d14f0ba87b0a9367e488f15a0a8b8678 Mon Sep 17 00:00:00 2001 From: kshitij-k-osmosys <121787214+kshitij-k-osmosys@users.noreply.github.com> Date: Thu, 19 Dec 2024 12:24:27 +0530 Subject: [PATCH 1/4] chore: bump version to 4.2.1 (#375) --- apps/api/package-lock.json | 4 ++-- apps/api/package.json | 2 +- apps/portal/package-lock.json | 4 ++-- apps/portal/package.json | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/api/package-lock.json b/apps/api/package-lock.json index 3096f674..1c736c23 100644 --- a/apps/api/package-lock.json +++ b/apps/api/package-lock.json @@ -1,12 +1,12 @@ { "name": "osmox", - "version": "4.2.0", + "version": "4.2.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "osmox", - "version": "4.2.0", + "version": "4.2.1", "license": "MIT", "dependencies": { "@apollo/server": "^4.11.2", diff --git a/apps/api/package.json b/apps/api/package.json index 22a3eb28..957f0343 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -1,6 +1,6 @@ { "name": "osmox", - "version": "4.2.0", + "version": "4.2.1", "description": "Centralized multi-channel notification management component for streamlined communication across email, SMS, WhatsApp, and push notifications.", "author": "Osmosys Software Solutions Private Limited", "license": "MIT", diff --git a/apps/portal/package-lock.json b/apps/portal/package-lock.json index 2c791512..90910ed6 100644 --- a/apps/portal/package-lock.json +++ b/apps/portal/package-lock.json @@ -1,12 +1,12 @@ { "name": "osmox-portal", - "version": "4.2.0", + "version": "4.2.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "osmox-portal", - "version": "4.2.0", + "version": "4.2.1", "dependencies": { "@angular/animations": "^18.2.10", "@angular/cdk": "^17.3.10", diff --git a/apps/portal/package.json b/apps/portal/package.json index e6e37eca..dcbf14e3 100644 --- a/apps/portal/package.json +++ b/apps/portal/package.json @@ -1,6 +1,6 @@ { "name": "osmox-portal", - "version": "4.2.0", + "version": "4.2.1", "scripts": { "ng": "ng", "start": "ng serve", From 319d361722b5a4c524321685e75c3b55658b6cfc Mon Sep 17 00:00:00 2001 From: Harish-osmosys <121787291+Harish-osmosys@users.noreply.github.com> Date: Thu, 2 Jan 2025 11:13:26 +0530 Subject: [PATCH 2/4] feat: integrate slogger with current logging (#376) --- apps/api/.env.example | 6 ++ .../src/common/logger/slogerr.transport.ts | 81 +++++++++++++++++++ apps/api/src/config/logger.config.ts | 9 +++ 3 files changed, 96 insertions(+) create mode 100644 apps/api/src/common/logger/slogerr.transport.ts diff --git a/apps/api/.env.example b/apps/api/.env.example index 1f0943ad..0f2f9b45 100644 --- a/apps/api/.env.example +++ b/apps/api/.env.example @@ -17,6 +17,12 @@ MAX_RETRY_COUNT=3 # Max retry count, default is 3 ARCHIVE_LIMIT=1000 # Max notifications to archive, default is 1000 ARCHIVE_INTERVAL=3600 # Interval (in seconds) for archiving notifications, default 3600 (every 1 hour) +# Slogger configuration +SLOGGER_LOG_TYPE= +SLOGGER_LOG_LEVEL=error #Log level, default is error +SLOGERR_API_ENDPOINT= #Slogger log api url +SLOGERR_API_TOKEN= #Slogger api token + # Logger configuration LOG_LEVEL=info # Log level, default is info COMBINED_LOG_MAX_SIZE=150m # Max file size for combined logs. Set 0 for no size limit, default 150m diff --git a/apps/api/src/common/logger/slogerr.transport.ts b/apps/api/src/common/logger/slogerr.transport.ts new file mode 100644 index 00000000..c1090507 --- /dev/null +++ b/apps/api/src/common/logger/slogerr.transport.ts @@ -0,0 +1,81 @@ +import { HttpService } from '@nestjs/axios'; +import TransportStream = require('winston-transport'); +import { TransportStreamOptions } from 'winston-transport'; +import { ConfigService } from '@nestjs/config'; +import { Logger } from '@nestjs/common/services/logger.service'; +import { firstValueFrom } from 'rxjs'; + +interface CustomTransportOptions extends TransportStreamOptions { + httpService: HttpService; + configService: ConfigService; +} + +interface LogInfo { + level: string; + message: string; + timestamp?: string; + context?: string; + stack?: string; + severity: string; +} + +export class SlogerrTransport extends TransportStream { + private readonly httpService: HttpService; + private readonly configService: ConfigService; + private readonly logger = new Logger(SlogerrTransport.name); + + constructor(options: CustomTransportOptions) { + super(options); + this.httpService = options.httpService; + this.configService = options.configService; + } + + async log(info: LogInfo, callback: () => void): Promise { + const allowedLevels = (this.configService.get('SLOGGER_LOG_LEVEL') || 'error') + .split(',') + .map((level) => level.trim()); + const logType = this.configService.get('SLOGGER_LOG_TYPE') || 'Exceptions'; + + if (allowedLevels.includes(info.level)) { + const apiEndpoint = this.configService.get('SLOGERR_API_ENDPOINT'); + const apiKey = this.configService.get('SLOGERR_API_TOKEN'); + + this.logger.log(`Log Info: ${JSON.stringify(info)}`); + + const logCreatedOn = info.timestamp || new Date().toISOString(); + + try { + const response = await firstValueFrom( + this.httpService.post( + apiEndpoint, + { + moduleName: info.context || 'Unknown Module', + logDescription: info.message, + logType: logType, + logCreatedOn: logCreatedOn, + severity: info.severity, + logData: { + message: info.message, + stack: info.stack, + context: info.context, + }, + }, + { headers: { 'slogerr-secure-api-key': apiKey } }, + ), + ); + + if (response.status !== 200) { + this.logger.error( + `Failed to send log to Slogerr. Status: ${response.status}, Message: ${response.statusText}`, + ); + } else { + this.logger.log('Error log successfully sent to Slogerr', response); + } + } catch (error) { + this.logger.error('Failed to send log to Slogerr', error.message); + } + } + + callback(); + } +} diff --git a/apps/api/src/config/logger.config.ts b/apps/api/src/config/logger.config.ts index acb97507..edaae46c 100644 --- a/apps/api/src/config/logger.config.ts +++ b/apps/api/src/config/logger.config.ts @@ -1,13 +1,16 @@ import { WinstonModule, utilities as nestWinstonModuleUtilities } from 'nest-winston'; import { transports, format } from 'winston'; import { join } from 'path'; +import { HttpService } from '@nestjs/axios'; import { v4 as uuidv4 } from 'uuid'; import 'winston-daily-rotate-file'; import { ConfigService } from '@nestjs/config'; import { name as applicationName } from 'package.json'; import DailyRotateFile from 'winston-daily-rotate-file'; +import { SlogerrTransport } from 'src/common/logger/slogerr.transport'; const configService = new ConfigService(); +const httpService = new HttpService(); const logDir = 'logs'; @@ -77,6 +80,11 @@ if (errorLogMaxSize === '0') { errorLogOptions.maxSize = '20m'; } +const slogerrTransport = new SlogerrTransport({ + httpService, + configService, +}); + const transportsConfig = [ new transports.Console({ format: format.combine( @@ -87,6 +95,7 @@ const transportsConfig = [ }), new transports.DailyRotateFile(combinedLogOptions), new transports.DailyRotateFile(errorLogOptions), + slogerrTransport, ]; export const loggerConfig = WinstonModule.createLogger({ From 7e1e7cbf9d69efa7d87159a1ec681bbeafd275b5 Mon Sep 17 00:00:00 2001 From: Harish-osmosys <121787291+Harish-osmosys@users.noreply.github.com> Date: Wed, 8 Jan 2025 15:22:10 +0530 Subject: [PATCH 3/4] feat: make slogger logging optional (#377) --- apps/api/.env.example | 1 + apps/api/src/config/logger.config.ts | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/api/.env.example b/apps/api/.env.example index 0f2f9b45..3784da41 100644 --- a/apps/api/.env.example +++ b/apps/api/.env.example @@ -22,6 +22,7 @@ SLOGGER_LOG_TYPE= SLOGGER_LOG_LEVEL=error #Log level, default is error SLOGERR_API_ENDPOINT= #Slogger log api url SLOGERR_API_TOKEN= #Slogger api token +ENABLE_SLOGERR=false #default set to false # Logger configuration LOG_LEVEL=info # Log level, default is info diff --git a/apps/api/src/config/logger.config.ts b/apps/api/src/config/logger.config.ts index edaae46c..55f640bb 100644 --- a/apps/api/src/config/logger.config.ts +++ b/apps/api/src/config/logger.config.ts @@ -18,6 +18,8 @@ const logDir = 'logs'; const combinedLogMaxSize = configService.get('COMBINED_LOG_MAX_SIZE'); const errorLogMaxSize = configService.get('ERROR_LOG_MAX_SIZE'); +const enableSlogger = configService.get('ENABLE_SLOGERR') || 'false'; + const logFormat = format.combine( format.timestamp(), format.printf((info) => { @@ -95,7 +97,7 @@ const transportsConfig = [ }), new transports.DailyRotateFile(combinedLogOptions), new transports.DailyRotateFile(errorLogOptions), - slogerrTransport, + ...(enableSlogger === 'true' ? [slogerrTransport] : []), ]; export const loggerConfig = WinstonModule.createLogger({ From ca08424a71da9f7d121507941b58b92249f7e933 Mon Sep 17 00:00:00 2001 From: Harish-osmosys <121787291+Harish-osmosys@users.noreply.github.com> Date: Wed, 8 Jan 2025 15:36:43 +0530 Subject: [PATCH 4/4] fix: add try-catch block in archive controller (#379) --- .../archived-notifications.controller.ts | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/apps/api/src/modules/archived-notifications/archived-notifications.controller.ts b/apps/api/src/modules/archived-notifications/archived-notifications.controller.ts index 9310d76a..e0d5f024 100644 --- a/apps/api/src/modules/archived-notifications/archived-notifications.controller.ts +++ b/apps/api/src/modules/archived-notifications/archived-notifications.controller.ts @@ -1,12 +1,27 @@ -import { Controller, Post } from '@nestjs/common'; +import { Controller, HttpException, Logger, Post } from '@nestjs/common'; import { ArchivedNotificationsService } from './archived-notifications.service'; @Controller('archived-notifications') export class ArchivedNotificationsController { - constructor(private readonly archivedNotificationService: ArchivedNotificationsService) {} + constructor( + private readonly archivedNotificationService: ArchivedNotificationsService, + private logger: Logger = new Logger(ArchivedNotificationsController.name), + ) {} @Post('archive') async addNotificationsToQueue(): Promise { - this.archivedNotificationService.archiveCompletedNotificationsCron(); + try { + this.logger.debug('Archiving completed notifications...'); + await this.archivedNotificationService.archiveCompletedNotificationsCron(); + this.logger.log('Notifications archived successfully.'); + } catch (error) { + if (error instanceof HttpException) { + throw error; + } + + this.logger.error('Error while archiving notifications'); + this.logger.error(JSON.stringify(error, ['message', 'stack'], 2)); + throw error; + } } }