async function main()

in scripts/local_telemetry.js [71:217]


async function main() {
  // 1. Ensure binaries are available, downloading if necessary.
  // Binaries are stored in the project's .gemini/otel/bin directory
  // to avoid modifying the user's system.
  if (!fileExists(BIN_DIR)) fs.mkdirSync(BIN_DIR, { recursive: true });

  const otelcolPath = await ensureBinary(
    'otelcol-contrib',
    'open-telemetry/opentelemetry-collector-releases',
    (version, platform, arch, ext) =>
      `otelcol-contrib_${version}_${platform}_${arch}.${ext}`,
    'otelcol-contrib',
    false, // isJaeger = false
  ).catch((e) => {
    console.error(`๏ฟฝ๏ฟฝ๏ฟฝ Error getting otelcol-contrib: ${e.message}`);
    return null;
  });
  if (!otelcolPath) process.exit(1);

  const jaegerPath = await ensureBinary(
    'jaeger',
    'jaegertracing/jaeger',
    (version, platform, arch, ext) =>
      `jaeger-${version}-${platform}-${arch}.${ext}`,
    'jaeger',
    true, // isJaeger = true
  ).catch((e) => {
    console.error(`๐Ÿ›‘ Error getting jaeger: ${e.message}`);
    return null;
  });
  if (!jaegerPath) process.exit(1);

  // 2. Kill any existing processes to ensure a clean start.
  console.log('๐Ÿงน Cleaning up old processes and logs...');
  try {
    execSync('pkill -f "otelcol-contrib"');
    console.log('โœ… Stopped existing otelcol-contrib process.');
  } catch (_e) {} // eslint-disable-line no-empty
  try {
    execSync('pkill -f "jaeger"');
    console.log('โœ… Stopped existing jaeger process.');
  } catch (_e) {} // eslint-disable-line no-empty
  try {
    if (fileExists(OTEL_LOG_FILE)) fs.unlinkSync(OTEL_LOG_FILE);
    console.log('โœ… Deleted old collector log.');
  } catch (e) {
    if (e.code !== 'ENOENT') console.error(e);
  }
  try {
    if (fileExists(JAEGER_LOG_FILE)) fs.unlinkSync(JAEGER_LOG_FILE);
    console.log('โœ… Deleted old jaeger log.');
  } catch (e) {
    if (e.code !== 'ENOENT') console.error(e);
  }

  let jaegerProcess, collectorProcess;
  let jaegerLogFd, collectorLogFd;

  const originalSandboxSetting = manageTelemetrySettings(
    true,
    'http://localhost:4317',
    'local',
  );

  registerCleanup(
    () => [jaegerProcess, collectorProcess],
    () => [jaegerLogFd, collectorLogFd],
    originalSandboxSetting,
  );

  if (!fileExists(OTEL_DIR)) fs.mkdirSync(OTEL_DIR, { recursive: true });
  fs.writeFileSync(OTEL_CONFIG_FILE, OTEL_CONFIG_CONTENT);
  console.log('๐Ÿ“„ Wrote OTEL collector config.');

  // Start Jaeger
  console.log(`๐Ÿš€ Starting Jaeger service... Logs: ${JAEGER_LOG_FILE}`);
  jaegerLogFd = fs.openSync(JAEGER_LOG_FILE, 'a');
  jaegerProcess = spawn(
    jaegerPath,
    ['--set=receivers.otlp.protocols.grpc.endpoint=localhost:14317'],
    { stdio: ['ignore', jaegerLogFd, jaegerLogFd] },
  );
  console.log(`โณ Waiting for Jaeger to start (PID: ${jaegerProcess.pid})...`);

  try {
    await waitForPort(JAEGER_PORT);
    console.log(`โœ… Jaeger started successfully.`);
  } catch (_) {
    console.error(`๐Ÿ›‘ Error: Jaeger failed to start on port ${JAEGER_PORT}.`);
    if (jaegerProcess && jaegerProcess.pid) {
      process.kill(jaegerProcess.pid, 'SIGKILL');
    }
    if (fileExists(JAEGER_LOG_FILE)) {
      console.error('๐Ÿ“„ Jaeger Log Output:');
      console.error(fs.readFileSync(JAEGER_LOG_FILE, 'utf-8'));
    }
    process.exit(1);
  }

  // Start the primary OTEL collector
  console.log(`๐Ÿš€ Starting OTEL collector... Logs: ${OTEL_LOG_FILE}`);
  collectorLogFd = fs.openSync(OTEL_LOG_FILE, 'a');
  collectorProcess = spawn(otelcolPath, ['--config', OTEL_CONFIG_FILE], {
    stdio: ['ignore', collectorLogFd, collectorLogFd],
  });
  console.log(
    `โณ Waiting for OTEL collector to start (PID: ${collectorProcess.pid})...`,
  );

  try {
    await waitForPort(4317);
    console.log(`โœ… OTEL collector started successfully.`);
  } catch (_) {
    console.error(`๐Ÿ›‘ Error: OTEL collector failed to start on port 4317.`);
    if (collectorProcess && collectorProcess.pid) {
      process.kill(collectorProcess.pid, 'SIGKILL');
    }
    if (fileExists(OTEL_LOG_FILE)) {
      console.error('๐Ÿ“„ OTEL Collector Log Output:');
      console.error(fs.readFileSync(OTEL_LOG_FILE, 'utf-8'));
    }
    process.exit(1);
  }

  [jaegerProcess, collectorProcess].forEach((proc) => {
    if (proc) {
      proc.on('error', (err) => {
        console.error(`${proc.spawnargs[0]} process error:`, err);
        process.exit(1);
      });
    }
  });

  console.log(`
โœจ Local telemetry environment is running.`);
  console.log(
    `
๐Ÿ”Ž View traces in the Jaeger UI: http://localhost:${JAEGER_PORT}`,
  );
  console.log(`๐Ÿ“Š View metrics in the logs and metrics: ${OTEL_LOG_FILE}`);
  console.log(
    `
๐Ÿ“„ Tail logs and metrics in another terminal: tail -f ${OTEL_LOG_FILE}`,
  );
  console.log(`
Press Ctrl+C to exit.`);
}