@omen.foundation/node-microservice-runtime 0.1.48 → 0.1.50
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/dist/collector-manager.cjs +88 -41
- package/dist/collector-manager.d.ts.map +1 -1
- package/dist/collector-manager.js +119 -53
- package/dist/collector-manager.js.map +1 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +4 -1
- package/dist/logger.js.map +1 -1
- package/dist/runtime.cjs +1 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +8 -1
- package/dist/runtime.js.map +1 -1
- package/package.json +1 -1
- package/src/collector-manager.ts +99 -30
- package/src/logger.ts +4 -1
- package/src/runtime.ts +8 -1
|
@@ -82,6 +82,7 @@ let globalCollectorProcess = null;
|
|
|
82
82
|
let globalCollectorStartError = null;
|
|
83
83
|
let globalCollectorExitCode = null;
|
|
84
84
|
let globalCollectorStderr = [];
|
|
85
|
+
let globalCollectorStartupPromise = null;
|
|
85
86
|
let globalCollectorInitError = null;
|
|
86
87
|
function calculateSignature(pid, secret, uriPathAndQuery, body = null, version = '1') {
|
|
87
88
|
let dataToSign = `${secret}${pid}${version}${uriPathAndQuery}`;
|
|
@@ -640,56 +641,102 @@ async function discoverOrStartCollector(logger, standardOtelEnabled, env) {
|
|
|
640
641
|
if (!standardOtelEnabled) {
|
|
641
642
|
return null;
|
|
642
643
|
}
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
644
|
+
if (globalCollectorStartupPromise) {
|
|
645
|
+
logger.info('[Collector] Collector startup already in progress, waiting for existing startup to complete...');
|
|
646
|
+
try {
|
|
647
|
+
const result = await globalCollectorStartupPromise;
|
|
648
|
+
globalCollectorStartupPromise = null;
|
|
649
|
+
return result;
|
|
650
|
+
}
|
|
651
|
+
catch (error) {
|
|
652
|
+
logger.error(`[Collector] Existing startup promise failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
653
|
+
globalCollectorStartupPromise = null;
|
|
654
|
+
}
|
|
647
655
|
}
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
return null;
|
|
656
|
+
let existingEndpoint;
|
|
657
|
+
if (globalCollectorProcess) {
|
|
658
|
+
const processAlive = globalCollectorProcess.exitCode === null &&
|
|
659
|
+
globalCollectorProcess.killed === false;
|
|
660
|
+
if (processAlive) {
|
|
661
|
+
logger.info(`[Collector] Collector process already exists (PID ${globalCollectorProcess.pid}), waiting for it to be ready...`);
|
|
662
|
+
existingEndpoint = process.env.BEAM_OTLP_HTTP_ENDPOINT ?
|
|
663
|
+
`http://${process.env.BEAM_OTLP_HTTP_ENDPOINT}` :
|
|
664
|
+
'http://0.0.0.0:4318';
|
|
658
665
|
}
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
666
|
+
else {
|
|
667
|
+
logger.warn(`[Collector] Previous collector process (PID ${globalCollectorProcess.pid}) is dead, starting new one...`);
|
|
668
|
+
globalCollectorProcess = null;
|
|
669
|
+
globalCollectorExitCode = null;
|
|
670
|
+
globalCollectorStderr = [];
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
if (!globalCollectorProcess) {
|
|
674
|
+
const status = await isCollectorRunning();
|
|
675
|
+
if (status.isRunning && status.isReady && status.otlpEndpoint) {
|
|
676
|
+
logger.info(`[Collector] Found running collector at ${status.otlpEndpoint}`);
|
|
677
|
+
return `http://${status.otlpEndpoint}`;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
const startupPromise = (async () => {
|
|
681
|
+
try {
|
|
682
|
+
globalCollectorInitError = null;
|
|
683
|
+
let endpoint;
|
|
684
|
+
if (existingEndpoint) {
|
|
685
|
+
endpoint = existingEndpoint;
|
|
686
|
+
logger.info(`[Collector] Waiting for existing collector to become ready at ${endpoint}...`);
|
|
687
|
+
}
|
|
688
|
+
else {
|
|
689
|
+
logger.info('[Collector] Starting OpenTelemetry collector...');
|
|
690
|
+
const startResult = await startCollector(logger, undefined, env);
|
|
691
|
+
endpoint = startResult.endpoint;
|
|
692
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
693
|
+
if (globalCollectorExitCode !== null && globalCollectorExitCode !== 0) {
|
|
694
|
+
const errorMsg = `Collector process exited immediately with code ${globalCollectorExitCode}. ${globalCollectorStderr.length > 0 ? `Stderr: ${globalCollectorStderr.join('; ')}` : 'No stderr output.'}`;
|
|
695
|
+
globalCollectorInitError = errorMsg;
|
|
696
|
+
logger.error(`[Collector] ${errorMsg}`);
|
|
697
|
+
return null;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
const maxWaitTime = 60000;
|
|
701
|
+
const checkInterval = 500;
|
|
702
|
+
const maxChecks = Math.floor(maxWaitTime / checkInterval);
|
|
703
|
+
logger.info('[Collector] Waiting for collector to become ready...');
|
|
704
|
+
for (let i = 0; i < maxChecks; i++) {
|
|
705
|
+
await new Promise(resolve => setTimeout(resolve, checkInterval));
|
|
706
|
+
if (globalCollectorExitCode !== null && globalCollectorExitCode !== 0) {
|
|
707
|
+
const errorMsg = `Collector process exited during startup with code ${globalCollectorExitCode}. ${globalCollectorStderr.length > 0 ? `Stderr: ${globalCollectorStderr.join('; ')}` : 'No stderr output.'}`;
|
|
708
|
+
globalCollectorInitError = errorMsg;
|
|
709
|
+
logger.error(`[Collector] ${errorMsg}`);
|
|
710
|
+
return null;
|
|
711
|
+
}
|
|
712
|
+
const newStatus = await isCollectorRunning();
|
|
713
|
+
if (newStatus.isRunning && newStatus.isReady) {
|
|
714
|
+
logger.info(`[Collector] Collector is ready at ${newStatus.otlpEndpoint || endpoint}`);
|
|
715
|
+
return newStatus.otlpEndpoint ? `http://${newStatus.otlpEndpoint}` : endpoint;
|
|
716
|
+
}
|
|
717
|
+
if (i > 0 && i % 4 === 0) {
|
|
718
|
+
logger.info(`[Collector] Still waiting for collector to become ready... (${(i * checkInterval) / 1000}s elapsed)`);
|
|
719
|
+
}
|
|
720
|
+
}
|
|
665
721
|
if (globalCollectorExitCode !== null && globalCollectorExitCode !== 0) {
|
|
666
|
-
const errorMsg = `Collector process exited
|
|
722
|
+
const errorMsg = `Collector process exited with code ${globalCollectorExitCode}. ${globalCollectorStderr.length > 0 ? `Stderr: ${globalCollectorStderr.join('; ')}` : 'No stderr output.'}`;
|
|
667
723
|
globalCollectorInitError = errorMsg;
|
|
668
724
|
logger.error(`[Collector] ${errorMsg}`);
|
|
669
725
|
return null;
|
|
670
726
|
}
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
logger.info(`[Collector] Collector is ready at ${newStatus.otlpEndpoint || endpoint}`);
|
|
674
|
-
return newStatus.otlpEndpoint ? `http://${newStatus.otlpEndpoint}` : endpoint;
|
|
675
|
-
}
|
|
676
|
-
if (i > 0 && i % 4 === 0) {
|
|
677
|
-
logger.info(`[Collector] Still waiting for collector to become ready... (${(i * checkInterval) / 1000}s elapsed)`);
|
|
678
|
-
}
|
|
727
|
+
logger.error(`[Collector] Collector did not become ready within ${maxWaitTime / 1000} seconds`);
|
|
728
|
+
return null;
|
|
679
729
|
}
|
|
680
|
-
|
|
681
|
-
const errorMsg =
|
|
730
|
+
catch (err) {
|
|
731
|
+
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
682
732
|
globalCollectorInitError = errorMsg;
|
|
683
|
-
logger.error(`[Collector] ${errorMsg}`);
|
|
733
|
+
logger.error(`[Collector] Failed to start collector: ${errorMsg}`);
|
|
684
734
|
return null;
|
|
685
735
|
}
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
logger.error(`[Collector] Failed to start collector: ${errorMsg}`);
|
|
693
|
-
return null;
|
|
694
|
-
}
|
|
736
|
+
})();
|
|
737
|
+
globalCollectorStartupPromise = startupPromise;
|
|
738
|
+
startupPromise.finally(() => {
|
|
739
|
+
globalCollectorStartupPromise = null;
|
|
740
|
+
});
|
|
741
|
+
return await startupPromise;
|
|
695
742
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collector-manager.d.ts","sourceRoot":"","sources":["../src/collector-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,YAAY,EAAE,MAAM,eAAe,CAAC;AAOpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAInC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAYpD,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;
|
|
1
|
+
{"version":3,"file":"collector-manager.d.ts","sourceRoot":"","sources":["../src/collector-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,YAAY,EAAE,MAAM,eAAe,CAAC;AAOpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAInC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAYpD,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAuCD;;GAEG;AACH,UAAU,qBAAqB;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAqCD;;;;GAIG;AACH,wBAAsB,0BAA0B,CAC9C,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,qBAAqB,CAAC,CAwChC;AA0OD;;GAEG;AACH,wBAAgB,8BAA8B,IAAI;IAChD,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,aAAa,GAAG,KAAK,GAAG,SAAS,CAAC;CAC3C,CAoBA;AAED;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,eAAe,CAAC,CAyEnE;AA0BD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAYjG;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,GAAG,EAAE,iBAAiB,EACtB,SAAS,GAAE,MAAc,GACxB,MAAM,GAAG,IAAI,CA8Ef;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,MAAM,EACrB,GAAG,CAAC,EAAE,iBAAiB,GACtB,OAAO,CAAC;IAAE,OAAO,EAAE,YAAY,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAgNtD;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI;IAC3C,UAAU,EAAE,OAAO,CAAC;IACpB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CASA;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,MAAM,EACd,mBAAmB,EAAE,OAAO,EAC5B,GAAG,CAAC,EAAE,iBAAiB,GACtB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAmJxB"}
|
|
@@ -41,6 +41,8 @@ let globalCollectorProcess = null;
|
|
|
41
41
|
let globalCollectorStartError = null;
|
|
42
42
|
let globalCollectorExitCode = null;
|
|
43
43
|
let globalCollectorStderr = [];
|
|
44
|
+
// Track if collector startup is in progress to prevent duplicate starts
|
|
45
|
+
let globalCollectorStartupPromise = null;
|
|
44
46
|
let globalCollectorInitError = null; // Tracks errors from discoverOrStartCollector
|
|
45
47
|
/**
|
|
46
48
|
* Calculates Beamable signature for signed requests
|
|
@@ -744,69 +746,133 @@ export async function discoverOrStartCollector(logger, standardOtelEnabled, env)
|
|
|
744
746
|
if (!standardOtelEnabled) {
|
|
745
747
|
return null;
|
|
746
748
|
}
|
|
747
|
-
//
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
749
|
+
// CRITICAL: Check if collector startup is already in progress
|
|
750
|
+
// This prevents duplicate collector starts if this function is called multiple times
|
|
751
|
+
// (e.g., if setupCollectorBeforeLogging times out but the promise is still running)
|
|
752
|
+
if (globalCollectorStartupPromise) {
|
|
753
|
+
logger.info('[Collector] Collector startup already in progress, waiting for existing startup to complete...');
|
|
754
|
+
try {
|
|
755
|
+
const result = await globalCollectorStartupPromise;
|
|
756
|
+
// Clear the promise after it completes (success or failure)
|
|
757
|
+
globalCollectorStartupPromise = null;
|
|
758
|
+
return result;
|
|
759
|
+
}
|
|
760
|
+
catch (error) {
|
|
761
|
+
logger.error(`[Collector] Existing startup promise failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
762
|
+
// Clear the promise so we can retry
|
|
763
|
+
globalCollectorStartupPromise = null;
|
|
764
|
+
// Fall through to start a new one
|
|
765
|
+
}
|
|
752
766
|
}
|
|
753
|
-
//
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
const
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
+
// CRITICAL: Check if we already have a collector process starting/running
|
|
768
|
+
// This prevents duplicate collector starts if this function is called multiple times
|
|
769
|
+
let existingEndpoint;
|
|
770
|
+
if (globalCollectorProcess) {
|
|
771
|
+
// Check if process is still alive
|
|
772
|
+
const processAlive = globalCollectorProcess.exitCode === null &&
|
|
773
|
+
globalCollectorProcess.killed === false;
|
|
774
|
+
if (processAlive) {
|
|
775
|
+
logger.info(`[Collector] Collector process already exists (PID ${globalCollectorProcess.pid}), waiting for it to be ready...`);
|
|
776
|
+
// Use the configured endpoint from environment (we started it earlier)
|
|
777
|
+
existingEndpoint = process.env.BEAM_OTLP_HTTP_ENDPOINT ?
|
|
778
|
+
`http://${process.env.BEAM_OTLP_HTTP_ENDPOINT}` :
|
|
779
|
+
'http://0.0.0.0:4318';
|
|
780
|
+
// Fall through to the wait logic below (don't start a new collector)
|
|
781
|
+
}
|
|
782
|
+
else {
|
|
783
|
+
// Process is dead, clear it and start fresh
|
|
784
|
+
logger.warn(`[Collector] Previous collector process (PID ${globalCollectorProcess.pid}) is dead, starting new one...`);
|
|
785
|
+
globalCollectorProcess = null;
|
|
786
|
+
globalCollectorExitCode = null;
|
|
787
|
+
globalCollectorStderr = [];
|
|
767
788
|
}
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
const
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
789
|
+
}
|
|
790
|
+
// First, check if collector is already running (via UDP discovery)
|
|
791
|
+
if (!globalCollectorProcess) {
|
|
792
|
+
const status = await isCollectorRunning();
|
|
793
|
+
if (status.isRunning && status.isReady && status.otlpEndpoint) {
|
|
794
|
+
logger.info(`[Collector] Found running collector at ${status.otlpEndpoint}`);
|
|
795
|
+
return `http://${status.otlpEndpoint}`;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
// Collector not running - start it (or wait for existing one to be ready)
|
|
799
|
+
// Wrap the entire startup logic in a promise that we track globally
|
|
800
|
+
// This prevents duplicate starts if this function is called multiple times
|
|
801
|
+
const startupPromise = (async () => {
|
|
802
|
+
try {
|
|
803
|
+
// Clear any previous init error
|
|
804
|
+
globalCollectorInitError = null;
|
|
805
|
+
let endpoint;
|
|
806
|
+
if (existingEndpoint) {
|
|
807
|
+
// Collector already starting, just wait for it to be ready
|
|
808
|
+
endpoint = existingEndpoint;
|
|
809
|
+
logger.info(`[Collector] Waiting for existing collector to become ready at ${endpoint}...`);
|
|
810
|
+
}
|
|
811
|
+
else {
|
|
812
|
+
// Start a new collector
|
|
813
|
+
logger.info('[Collector] Starting OpenTelemetry collector...');
|
|
814
|
+
const startResult = await startCollector(logger, undefined, env);
|
|
815
|
+
endpoint = startResult.endpoint;
|
|
816
|
+
// Check if collector process exited immediately (crashed)
|
|
817
|
+
// Wait a bit longer to see if it crashes right after starting
|
|
818
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
819
|
+
if (globalCollectorExitCode !== null && globalCollectorExitCode !== 0) {
|
|
820
|
+
const errorMsg = `Collector process exited immediately with code ${globalCollectorExitCode}. ${globalCollectorStderr.length > 0 ? `Stderr: ${globalCollectorStderr.join('; ')}` : 'No stderr output.'}`;
|
|
821
|
+
globalCollectorInitError = errorMsg;
|
|
822
|
+
logger.error(`[Collector] ${errorMsg}`);
|
|
823
|
+
return null;
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
// CRITICAL: Wait for collector to be fully ready before returning
|
|
827
|
+
// We'll wait up to 60 seconds, checking every 500ms
|
|
828
|
+
// This ensures the collector is actually ready to receive logs before we continue
|
|
829
|
+
const maxWaitTime = 60000; // 60 seconds
|
|
830
|
+
const checkInterval = 500; // Check every 500ms
|
|
831
|
+
const maxChecks = Math.floor(maxWaitTime / checkInterval);
|
|
832
|
+
logger.info('[Collector] Waiting for collector to become ready...');
|
|
833
|
+
for (let i = 0; i < maxChecks; i++) {
|
|
834
|
+
await new Promise(resolve => setTimeout(resolve, checkInterval));
|
|
835
|
+
// Check if process exited during wait
|
|
836
|
+
if (globalCollectorExitCode !== null && globalCollectorExitCode !== 0) {
|
|
837
|
+
const errorMsg = `Collector process exited during startup with code ${globalCollectorExitCode}. ${globalCollectorStderr.length > 0 ? `Stderr: ${globalCollectorStderr.join('; ')}` : 'No stderr output.'}`;
|
|
838
|
+
globalCollectorInitError = errorMsg;
|
|
839
|
+
logger.error(`[Collector] ${errorMsg}`);
|
|
840
|
+
return null;
|
|
841
|
+
}
|
|
842
|
+
const newStatus = await isCollectorRunning();
|
|
843
|
+
if (newStatus.isRunning && newStatus.isReady) {
|
|
844
|
+
logger.info(`[Collector] Collector is ready at ${newStatus.otlpEndpoint || endpoint}`);
|
|
845
|
+
return newStatus.otlpEndpoint ? `http://${newStatus.otlpEndpoint}` : endpoint;
|
|
846
|
+
}
|
|
847
|
+
// Log progress every 2 seconds
|
|
848
|
+
if (i > 0 && i % 4 === 0) {
|
|
849
|
+
logger.info(`[Collector] Still waiting for collector to become ready... (${(i * checkInterval) / 1000}s elapsed)`);
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
// Check one more time if process exited
|
|
778
853
|
if (globalCollectorExitCode !== null && globalCollectorExitCode !== 0) {
|
|
779
|
-
const errorMsg = `Collector process exited
|
|
854
|
+
const errorMsg = `Collector process exited with code ${globalCollectorExitCode}. ${globalCollectorStderr.length > 0 ? `Stderr: ${globalCollectorStderr.join('; ')}` : 'No stderr output.'}`;
|
|
780
855
|
globalCollectorInitError = errorMsg;
|
|
781
856
|
logger.error(`[Collector] ${errorMsg}`);
|
|
782
857
|
return null;
|
|
783
858
|
}
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
return newStatus.otlpEndpoint ? `http://${newStatus.otlpEndpoint}` : endpoint;
|
|
788
|
-
}
|
|
789
|
-
// Log progress every 2 seconds
|
|
790
|
-
if (i > 0 && i % 4 === 0) {
|
|
791
|
-
logger.info(`[Collector] Still waiting for collector to become ready... (${(i * checkInterval) / 1000}s elapsed)`);
|
|
792
|
-
}
|
|
859
|
+
// Collector did not become ready within timeout
|
|
860
|
+
logger.error(`[Collector] Collector did not become ready within ${maxWaitTime / 1000} seconds`);
|
|
861
|
+
return null;
|
|
793
862
|
}
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
const errorMsg = `Collector process exited with code ${globalCollectorExitCode}. ${globalCollectorStderr.length > 0 ? `Stderr: ${globalCollectorStderr.join('; ')}` : 'No stderr output.'}`;
|
|
863
|
+
catch (err) {
|
|
864
|
+
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
797
865
|
globalCollectorInitError = errorMsg;
|
|
798
|
-
logger.error(`[Collector] ${errorMsg}`);
|
|
866
|
+
logger.error(`[Collector] Failed to start collector: ${errorMsg}`);
|
|
799
867
|
return null;
|
|
800
868
|
}
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
return null;
|
|
810
|
-
}
|
|
869
|
+
})();
|
|
870
|
+
// Store the promise globally so other calls to this function can wait for it
|
|
871
|
+
globalCollectorStartupPromise = startupPromise;
|
|
872
|
+
// Clear the promise when it completes (so we don't keep waiting on old promises)
|
|
873
|
+
startupPromise.finally(() => {
|
|
874
|
+
globalCollectorStartupPromise = null;
|
|
875
|
+
});
|
|
876
|
+
return await startupPromise;
|
|
811
877
|
}
|
|
812
878
|
//# sourceMappingURL=collector-manager.js.map
|