@omen.foundation/node-microservice-runtime 0.1.52 → 0.1.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/runtime.ts CHANGED
@@ -4,8 +4,9 @@ import { GatewayRequester } from './requester.js';
4
4
  import { AuthManager } from './auth.js';
5
5
  import { createLogger } from './logger.js';
6
6
  import { loadEnvironmentConfig } from './env.js';
7
- import { startCollectorAsync } from './collector-manager.js';
7
+ import { startCollectorAndWaitForReady } from './collector-manager.js';
8
8
  import pino from 'pino';
9
+ import deasync from 'deasync';
9
10
  import { listRegisteredServices, getServiceOptions, getConfigureServicesHandlers, getInitializeServicesHandlers } from './decorators.js';
10
11
  import { generateOpenApiDocument } from './docs.js';
11
12
  import { VERSION } from './index.js';
@@ -80,20 +81,50 @@ export class MicroserviceRuntime {
80
81
  const primaryService = registered[0];
81
82
  const qualifiedServiceName = `micro_${primaryService.qualifiedName}`;
82
83
 
83
- // STEP 3: Start collector asynchronously in background (NON-BLOCKING)
84
- // This allows the service to start immediately while collector downloads/starts
85
- // Logs will work immediately (stdout), OTLP will connect when collector is ready
86
- startupLogger.info('Starting OpenTelemetry collector setup in background (non-blocking)...');
87
- startCollectorAsync(this.env);
84
+ // STEP 3: Wait for collector to be ready BEFORE creating structured logger
85
+ // Portal logs (structured logs via OTLP) should only appear AFTER collector is ready
86
+ // This ensures all runtime startup logs are captured and appear in Portal
87
+ // Use deasync to wait synchronously (constructor can't be async)
88
+ startupLogger.info('Setting up OpenTelemetry collector (waiting for readiness before enabling Portal logs)...');
88
89
 
89
- // STEP 4: Create main logger immediately (service can start serving requests)
90
- // Logger works immediately via stdout, OTLP will connect when collector is ready
91
- // The logger will automatically start using OTLP once the collector is available
90
+ let otlpEndpoint: string | null = null;
91
+ let collectorReady = false;
92
+ let collectorError: string | null = null;
93
+
94
+ // Start collector setup asynchronously
95
+ startCollectorAndWaitForReady(this.env, 180000)
96
+ .then((endpoint) => {
97
+ otlpEndpoint = endpoint;
98
+ collectorReady = true;
99
+ if (endpoint) {
100
+ startupLogger.info(`Collector ready at ${endpoint}, creating structured logger for Portal logs...`);
101
+ } else {
102
+ startupLogger.warn('Collector setup did not complete in time, Portal logs will not be available');
103
+ }
104
+ })
105
+ .catch((error) => {
106
+ collectorError = error instanceof Error ? error.message : String(error);
107
+ collectorReady = true;
108
+ startupLogger.error(`Failed to setup collector: ${collectorError}`);
109
+ });
110
+
111
+ // Wait synchronously for collector to be ready (with timeout)
112
+ const startTime = Date.now();
113
+ const timeoutMs = 180000; // 3 minutes
114
+ deasync.loopWhile(() => {
115
+ if (Date.now() - startTime >= timeoutMs) {
116
+ return false; // Timeout
117
+ }
118
+ return !collectorReady; // Continue waiting if not ready
119
+ });
120
+
121
+ // STEP 4: Create main structured logger (collector is now ready, Portal logs will work)
122
+ // Pass the OTLP endpoint to ensure it uses the ready collector
92
123
  this.logger = createLogger(this.env, {
93
124
  name: 'beamable-node-microservice',
94
125
  serviceName: primaryService.name,
95
126
  qualifiedServiceName: qualifiedServiceName,
96
- // Don't pass otlpEndpoint - let it discover/connect when collector is ready
127
+ otlpEndpoint: otlpEndpoint || undefined, // Pass endpoint if collector was set up
97
128
  });
98
129
  this.serviceManager = new BeamableServiceManager(this.env, this.logger);
99
130