diff --git a/README.md b/README.md index dcd3920..465c385 100644 --- a/README.md +++ b/README.md @@ -281,14 +281,16 @@ Visit: ### Official Plugins - **Logger** - Winston with multiple transports -- **Database** - Mongoose with circuit breaker +- **Database** - Mongoose/Prisma with circuit breaker +- **Scheduler** - Cron jobs with node-cron, timezone support, task management +- **Socket.IO** - Real-time communication with Redis adapter, JWT auth, namespaces +- **Telemetry** - OpenTelemetry with auto-instrumentation, multiple exporters - **Health** - Kubernetes-ready health checks ### Community Plugins (Coming Soon) -- Socket.IO - Real-time communication -- Redis - Caching layer -- Scheduler - Cron jobs and task queues +- Redis Cache - Distributed caching layer - Metrics - Prometheus integration +- GraphQL - GraphQL server support --- @@ -354,9 +356,8 @@ Special thanks to: - Full TypeScript ### 🚧 In Progress (v2.1) -- Metrics/Telemetry -- Socket.IO plugin - Redis cache plugin +- GraphQL support ### 📋 Planned (v2.2+) - GraphQL support diff --git a/package.json b/package.json index a2bee71..5473056 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@armco/node-starter-kit", - "version": "2.0.4", + "version": "2.0.5", "description": "Modern plugin-based starter kit for Node.js applications with TypeScript, security, and observability", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/v2/plugins/database/index.ts b/v2/plugins/database/index.ts index a4f05a1..26eddd6 100644 --- a/v2/plugins/database/index.ts +++ b/v2/plugins/database/index.ts @@ -52,7 +52,7 @@ export class DatabasePlugin extends BasePlugin { // Register in container context.container.singleton('database', this.adapter) - logger?.info('Database plugin installed') + logger?.info('[NSK][DATABASE] Plugin installed') } async start(): Promise { @@ -61,13 +61,13 @@ export class DatabasePlugin extends BasePlugin { } await this.adapter.connect() - this.getLogger()?.info('Database plugin started') + this.getLogger()?.info('[NSK][DATABASE] Plugin started') } async stop(): Promise { if (this.adapter) { await this.adapter.disconnect() - this.getLogger()?.info('Database plugin stopped') + this.getLogger()?.info('[NSK][DATABASE] Plugin stopped') } } diff --git a/v2/plugins/logger/index.ts b/v2/plugins/logger/index.ts index add5f03..62c5eb1 100644 --- a/v2/plugins/logger/index.ts +++ b/v2/plugins/logger/index.ts @@ -41,15 +41,15 @@ export class LoggerPlugin extends BasePlugin { // This allows direct usage: logger.info() without imports ;(global as any).logger = this.logger - this.logger.info(`Logger plugin installed: ${config.adapter || 'winston'}`) + this.logger.info(`[NSK][LOGGER] Plugin installed (adapter: ${config.adapter || 'winston'})`) } async start(): Promise { - this.logger?.info('Logger plugin started') + this.logger?.info('[NSK][LOGGER] Plugin started') } async stop(): Promise { - this.logger?.info('Logger plugin stopping') + this.logger?.info('[NSK][LOGGER] Plugin stopping') } } diff --git a/v2/plugins/scheduler/index.ts b/v2/plugins/scheduler/index.ts index ca76894..0378775 100644 --- a/v2/plugins/scheduler/index.ts +++ b/v2/plugins/scheduler/index.ts @@ -74,7 +74,7 @@ export class SchedulerPlugin extends BasePlugin { } this.logger = context.container.resolve('logger') - this.logger?.info('Installing Scheduler plugin') + this.logger?.info('[NSK][SCHEDULER] Installing plugin') // Create scheduler adapter this.adapter = await this.createAdapter() @@ -82,7 +82,7 @@ export class SchedulerPlugin extends BasePlugin { // Register adapter in container context.container.singleton('scheduler', this.adapter) - this.logger?.info('Scheduler plugin installed', { + this.logger?.info('[NSK][SCHEDULER] Plugin installed', { adapter: this.config?.adapter || 'node-cron', timezone: this.config?.timezone || 'UTC', }) @@ -96,7 +96,7 @@ export class SchedulerPlugin extends BasePlugin { return } - this.logger?.info('Starting Scheduler plugin') + this.logger?.info('[NSK][SCHEDULER] Starting plugin') // Schedule predefined tasks if (this.config?.tasks && this.config.tasks.length > 0) { @@ -120,13 +120,13 @@ export class SchedulerPlugin extends BasePlugin { ) } - this.logger?.info('Task scheduled', { + this.logger?.info('[NSK][SCHEDULER] Task scheduled', { name: taskConfig.name, schedule: taskConfig.schedule, once: taskConfig.once || false, }) } catch (error) { - this.logger?.error('Failed to schedule task', { + this.logger?.error('[NSK][SCHEDULER] Failed to schedule task', { name: taskConfig.name, error, }) @@ -134,7 +134,7 @@ export class SchedulerPlugin extends BasePlugin { } } - this.logger?.info('Scheduler plugin started', { + this.logger?.info('[NSK][SCHEDULER] Plugin started', { taskCount: this.adapter.getAllTasks().length, }) } @@ -147,13 +147,13 @@ export class SchedulerPlugin extends BasePlugin { return } - this.logger?.info('Stopping Scheduler plugin') + this.logger?.info('[NSK][SCHEDULER] Stopping plugin') try { this.adapter.stopAll() - this.logger?.info('Scheduler plugin stopped') + this.logger?.info('[NSK][SCHEDULER] Plugin stopped') } catch (error) { - this.logger?.error('Failed to stop Scheduler plugin', { error }) + this.logger?.error('[NSK][SCHEDULER] Failed to stop plugin', { error }) throw error } } @@ -200,7 +200,7 @@ export class SchedulerPlugin extends BasePlugin { timestamp: new Date(), } } catch (error) { - this.logger?.error('Scheduler health check failed', { error }) + this.logger?.error('[NSK][SCHEDULER] Health check failed', { error }) return { status: 'unhealthy', @@ -220,7 +220,7 @@ export class SchedulerPlugin extends BasePlugin { switch (adapter) { case 'node-cron': default: - this.logger?.debug('Creating node-cron scheduler adapter') + this.logger?.debug('[NSK][SCHEDULER] Creating node-cron adapter') const cronAdapter = new NodeCronAdapter(this.config || {}, this.logger) await cronAdapter.initialize() return cronAdapter diff --git a/v2/plugins/socket/index.ts b/v2/plugins/socket/index.ts index c94956d..218b3d9 100644 --- a/v2/plugins/socket/index.ts +++ b/v2/plugins/socket/index.ts @@ -60,12 +60,12 @@ export class SocketPlugin extends BasePlugin { await super.install(context) if (this.config?.enabled === false) { - this.logger?.info('Socket.IO plugin is disabled') + this.logger?.info('[NSK][SOCKET] Plugin is disabled') return } this.logger = context.container.resolve('logger') - this.logger?.info('Installing Socket.IO plugin') + this.logger?.info('[NSK][SOCKET] Installing plugin') // Create Socket.IO adapter this.adapter = new SocketIOAdapter(this.httpServer, this.config || {}, this.logger) @@ -73,7 +73,7 @@ export class SocketPlugin extends BasePlugin { // Register adapter in container context.container.singleton('socket', this.adapter) - this.logger?.info('Socket.IO plugin installed') + this.logger?.info('[NSK][SOCKET] Plugin installed') } /** @@ -84,13 +84,13 @@ export class SocketPlugin extends BasePlugin { return } - this.logger?.info('Starting Socket.IO plugin') + this.logger?.info('[NSK][SOCKET] Starting plugin') try { await this.adapter?.initialize() - this.logger?.info('Socket.IO plugin started') + this.logger?.info('[NSK][SOCKET] Plugin started') } catch (error) { - this.logger?.error('Failed to start Socket.IO plugin', { error }) + this.logger?.error('[NSK][SOCKET] Failed to start plugin', { error }) throw error } } @@ -103,13 +103,13 @@ export class SocketPlugin extends BasePlugin { return } - this.logger?.info('Stopping Socket.IO plugin') + this.logger?.info('[NSK][SOCKET] Stopping plugin') try { await this.adapter.close() - this.logger?.info('Socket.IO plugin stopped') + this.logger?.info('[NSK][SOCKET] Plugin stopped') } catch (error) { - this.logger?.error('Failed to stop Socket.IO plugin', { error }) + this.logger?.error('[NSK][SOCKET] Failed to stop plugin', { error }) throw error } } @@ -144,7 +144,7 @@ export class SocketPlugin extends BasePlugin { timestamp: new Date() } } catch (error) { - this.logger?.error('Socket.IO health check failed', { error }) + this.logger?.error('[NSK][SOCKET] Health check failed', { error }) return { status: 'unhealthy', diff --git a/v2/plugins/telemetry/index.ts b/v2/plugins/telemetry/index.ts index b032665..af433a8 100644 --- a/v2/plugins/telemetry/index.ts +++ b/v2/plugins/telemetry/index.ts @@ -75,7 +75,7 @@ export class OpenTelemetryPlugin extends BasePlugin { } this.logger = context.container.resolve('logger') - this.logger?.info('Installing OpenTelemetry plugin') + this.logger?.info('[NSK][TELEMETRY] Installing plugin') if (!this.config?.serviceName) { throw new Error('OpenTelemetry plugin requires "serviceName" in configuration') @@ -87,7 +87,7 @@ export class OpenTelemetryPlugin extends BasePlugin { // Register adapter in container context.container.singleton('opentelemetry', this.adapter) - this.logger?.info('OpenTelemetry plugin installed', { + this.logger?.info('[NSK][TELEMETRY] Plugin installed', { serviceName: this.config.serviceName, exporters: this.config.exporters, autoInstrumentation: this.config.autoInstrumentation, @@ -102,13 +102,13 @@ export class OpenTelemetryPlugin extends BasePlugin { return } - this.logger?.info('Starting OpenTelemetry plugin') + this.logger?.info('[NSK][TELEMETRY] Starting plugin') try { await this.adapter.initialize() - this.logger?.info('OpenTelemetry plugin started successfully') + this.logger?.info('[NSK][TELEMETRY] Plugin started successfully') } catch (error) { - this.logger?.error('Failed to start OpenTelemetry plugin', { error }) + this.logger?.error('[NSK][TELEMETRY] Failed to start plugin', { error }) throw error } } @@ -121,15 +121,15 @@ export class OpenTelemetryPlugin extends BasePlugin { return } - this.logger?.info('Stopping OpenTelemetry plugin') + this.logger?.info('[NSK][TELEMETRY] Stopping plugin') try { // Flush pending data before shutdown await this.adapter.flush() await this.adapter.shutdown() - this.logger?.info('OpenTelemetry plugin stopped') + this.logger?.info('[NSK][TELEMETRY] Plugin stopped') } catch (error) { - this.logger?.error('Failed to stop OpenTelemetry plugin', { error }) + this.logger?.error('[NSK][TELEMETRY] Failed to stop plugin', { error }) throw error } } @@ -170,7 +170,7 @@ export class OpenTelemetryPlugin extends BasePlugin { timestamp: new Date(), } } catch (error) { - this.logger?.error('OpenTelemetry health check failed', { error }) + this.logger?.error('[NSK][TELEMETRY] Health check failed', { error }) return { status: 'unhealthy',