@omen.foundation/node-microservice-runtime 0.1.63 → 0.1.65

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omen.foundation/node-microservice-runtime",
3
- "version": "0.1.63",
3
+ "version": "0.1.65",
4
4
  "description": "Beamable microservice runtime for Node.js/TypeScript services.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1049,14 +1049,41 @@ export function getCollectorProcessStatus(): {
1049
1049
  startError: string | null;
1050
1050
  initError: string | null;
1051
1051
  stderr: string[];
1052
+ isPreInstalled?: boolean;
1053
+ binaryPath?: string | null;
1054
+ configPath?: string | null;
1052
1055
  } {
1056
+ // Check if collector is actually running successfully - if so, clear stale initError
1057
+ const processAlive = globalCollectorProcess !== null &&
1058
+ globalCollectorProcess.exitCode === null &&
1059
+ globalCollectorProcess.killed === false;
1060
+
1061
+ const stderrText = globalCollectorStderr.join('\n');
1062
+ const isReady = stderrText.includes('Everything is ready') ||
1063
+ stderrText.includes('Begin running and processing data');
1064
+
1065
+ // If collector is running and ready, clear stale initError (might be from failed download attempt)
1066
+ // The error could be from an initial download attempt that failed, but collector started successfully using pre-installed binary
1067
+ const actualInitError = (processAlive && isReady) ? null : globalCollectorInitError;
1068
+
1069
+ // Check if collector binary is pre-installed
1070
+ const basePath = getCollectorStoragePath();
1071
+ const binaryName = getCollectorBinaryName();
1072
+ const configName = 'clickhouse-config.yaml';
1073
+ const binaryPath = join(basePath, binaryName);
1074
+ const configPath = join(basePath, configName);
1075
+ const isPreInstalled = existsSync(binaryPath) && existsSync(configPath);
1076
+
1053
1077
  return {
1054
1078
  hasProcess: globalCollectorProcess !== null,
1055
1079
  pid: globalCollectorProcess?.pid ?? null,
1056
1080
  exitCode: globalCollectorExitCode,
1057
1081
  startError: globalCollectorStartError,
1058
- initError: globalCollectorInitError,
1082
+ initError: actualInitError, // Clear if collector is running and ready
1059
1083
  stderr: [...globalCollectorStderr], // Return a copy
1084
+ isPreInstalled,
1085
+ binaryPath: isPreInstalled ? binaryPath : null,
1086
+ configPath: isPreInstalled ? configPath : null,
1060
1087
  };
1061
1088
  }
1062
1089
 
package/src/logger.ts CHANGED
@@ -562,50 +562,31 @@ export function createLogger(env: EnvironmentConfig, options: LoggerFactoryOptio
562
562
  level: 'info',
563
563
  }, process.stdout);
564
564
 
565
- // Create provider synchronously - since endpoint is explicitly provided,
566
- // initializeOtlpLogging will skip discovery and create provider directly
567
- let provider: LoggerProvider | null = null;
568
- let completed = false;
569
-
565
+ // Create OTLP provider asynchronously (non-blocking)
566
+ // Since endpoint is explicitly provided and collector is already ready,
567
+ // this should complete quickly, but we don't block for it
570
568
  initializeOtlpLogging(
571
569
  options.serviceName,
572
570
  options.qualifiedServiceName,
573
571
  env,
574
572
  initLogger
575
- ).then((result) => {
576
- provider = result;
577
- completed = true;
578
- if (result) {
573
+ ).then((provider) => {
574
+ if (provider) {
575
+ otlpProviderRef.provider = provider;
579
576
  initLogger.info(`[OTLP] OTLP provider created using existing collector at ${options.otlpEndpoint}`);
577
+ initLogger.info(`[OTLP] OpenTelemetry logging initialized. Endpoint: ${options.otlpEndpoint}/v1/logs, Service: ${options.serviceName || 'unknown'}`);
578
+ } else {
579
+ initLogger.warn('[OTLP] OTLP provider creation returned null, structured logs will not be sent via OTLP');
580
+ otlpProviderRef.provider = null;
580
581
  }
581
582
  }).catch((error) => {
582
- initLogger.error(`[OTLP] Failed to create OTLP provider: ${error instanceof Error ? error.message : String(error)}`);
583
- completed = true;
584
- provider = null;
585
- });
586
-
587
- // Wait briefly for provider creation (should be very fast, < 1 second)
588
- // eslint-disable-next-line @typescript-eslint/no-require-imports
589
- const deasync = require('deasync');
590
- const startTime = Date.now();
591
- const timeout = 2000; // 2 second timeout (should be fast since no discovery needed)
592
-
593
- deasync.loopWhile(() => {
594
- if (Date.now() - startTime >= timeout) {
595
- return false;
596
- }
597
- return !completed;
583
+ const errorMsg = error instanceof Error ? error.message : String(error);
584
+ initLogger.error(`[OTLP] Failed to create OTLP provider: ${errorMsg}`);
585
+ otlpProviderRef.provider = null;
598
586
  });
599
587
 
600
- // CRITICAL: Only set provider if it was successfully created
601
- // This ensures structured logs are only created when OTLP is ready
602
- if (provider) {
603
- otlpProviderRef.provider = provider;
604
- initLogger.info(`[OTLP] OpenTelemetry logging initialized. Endpoint: ${options.otlpEndpoint}/v1/logs, Service: ${options.serviceName || 'unknown'}`);
605
- } else {
606
- initLogger.warn('[OTLP] OTLP provider creation failed, structured logs will not be sent via OTLP');
607
- otlpProviderRef.provider = null;
608
- }
588
+ // Don't wait - logger will work immediately with console output,
589
+ // and OTLP will be added when the provider is ready (very quickly since collector is already running)
609
590
 
610
591
  // Restore original endpoint if it existed
611
592
  if (originalEndpoint !== undefined) {