autotel-devtools 6.0.1 → 6.1.1

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.
@@ -440,13 +440,16 @@ var DevtoolsServer = class {
440
440
  addTraces(traces) {
441
441
  for (const trace of traces) this.addTrace(trace);
442
442
  }
443
+ // `errors` is full-state on every broadcast (the client replaces, not appends),
444
+ // so non-trace broadcasts must echo the current error groups rather than `[]` —
445
+ // otherwise a log/metric arriving after an error would wipe it from the UI.
443
446
  addLog(log) {
444
447
  this.logs = appendWithLimit(this.logs, log, this.limits.maxLogCount);
445
- this.broadcast({ traces: [], metrics: [], logs: [log], errors: [] });
448
+ this.broadcast({ traces: [], metrics: [], logs: [log], errors: this.errorAggregator.getErrorGroups() });
446
449
  }
447
450
  addLogs(logs) {
448
451
  this.logs = appendManyWithLimit(this.logs, logs, this.limits.maxLogCount);
449
- this.broadcast({ traces: [], metrics: [], logs, errors: [] });
452
+ this.broadcast({ traces: [], metrics: [], logs, errors: this.errorAggregator.getErrorGroups() });
450
453
  }
451
454
  addMetric(metric) {
452
455
  this.metrics = appendWithLimit(
@@ -454,7 +457,7 @@ var DevtoolsServer = class {
454
457
  metric,
455
458
  this.limits.maxMetricCount
456
459
  );
457
- this.broadcast({ traces: [], metrics: [metric], logs: [], errors: [] });
460
+ this.broadcast({ traces: [], metrics: [metric], logs: [], errors: this.errorAggregator.getErrorGroups() });
458
461
  }
459
462
  getCurrentData() {
460
463
  return {
@@ -1393,7 +1396,38 @@ function decodeOtlpMetricsRequest(body) {
1393
1396
  return decodeRequest("opentelemetry.proto.metrics.v1.ExportMetricsServiceRequest", body);
1394
1397
  }
1395
1398
 
1399
+ // src/server/identity.ts
1400
+ var DEVTOOLS_IDENTITY = "autotel-devtools";
1401
+ async function probePortHolder(host, port, timeoutMs = 500) {
1402
+ const authority = host.includes(":") ? `[${host}]` : host;
1403
+ const controller = new AbortController();
1404
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
1405
+ try {
1406
+ const res = await fetch(`http://${authority}:${port}/healthz`, {
1407
+ signal: controller.signal
1408
+ });
1409
+ if (res.headers.get("x-autotel-devtools")) return "autotel-devtools";
1410
+ try {
1411
+ const body = await res.json();
1412
+ if (body && body.service === DEVTOOLS_IDENTITY) return "autotel-devtools";
1413
+ } catch {
1414
+ }
1415
+ return "foreign";
1416
+ } catch {
1417
+ return "none";
1418
+ } finally {
1419
+ clearTimeout(timer);
1420
+ }
1421
+ }
1422
+
1396
1423
  // src/server/http.ts
1424
+ function sendOtlpError(res, req, e) {
1425
+ sendJson(res, 400, {
1426
+ error: "Invalid OTLP payload",
1427
+ message: e instanceof Error ? e.message : String(e),
1428
+ contentType: req.headers["content-type"] ?? null
1429
+ });
1430
+ }
1397
1431
  var PROTOBUF_DECODERS = {
1398
1432
  traces: decodeOtlpTraceRequest,
1399
1433
  logs: decodeOtlpLogsRequest,
@@ -1414,6 +1448,18 @@ function findPackageRoot() {
1414
1448
  return dir;
1415
1449
  }
1416
1450
  var FULLPAGE_HTML = `<!DOCTYPE html><html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>autotel-devtools</title><style>*{margin:0;padding:0;box-sizing:border-box}html,body{height:100%;width:100%;overflow:hidden}</style></head><body><script src="/widget.js?mode=fullpage"></script></body></html>`;
1451
+ var cachedVersion = null;
1452
+ function getVersion() {
1453
+ if (cachedVersion !== null) return cachedVersion;
1454
+ let version = "unknown";
1455
+ try {
1456
+ const pkg = JSON.parse(fs.readFileSync(path.resolve(findPackageRoot(), "package.json"), "utf8"));
1457
+ if (typeof pkg.version === "string") version = pkg.version;
1458
+ } catch {
1459
+ }
1460
+ cachedVersion = version;
1461
+ return version;
1462
+ }
1417
1463
  var cachedWidgetJs = null;
1418
1464
  function getWidgetJs() {
1419
1465
  if (!cachedWidgetJs) {
@@ -1440,6 +1486,8 @@ function attachDevtoolsRoutes(httpServer, devtools) {
1440
1486
  res.setHeader("Access-Control-Allow-Origin", "*");
1441
1487
  res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
1442
1488
  res.setHeader("Access-Control-Allow-Headers", "Content-Type");
1489
+ res.setHeader("x-autotel-devtools", getVersion());
1490
+ res.setHeader("Access-Control-Expose-Headers", "x-autotel-devtools");
1443
1491
  if (req.method === "OPTIONS") {
1444
1492
  res.writeHead(204);
1445
1493
  res.end();
@@ -1458,7 +1506,12 @@ function attachDevtoolsRoutes(httpServer, devtools) {
1458
1506
  return;
1459
1507
  }
1460
1508
  if (req.method === "GET" && url === "/healthz") {
1461
- sendJson(res, 200, { ok: true, clients: devtools.clientCount });
1509
+ sendJson(res, 200, {
1510
+ ok: true,
1511
+ service: DEVTOOLS_IDENTITY,
1512
+ version: getVersion(),
1513
+ clients: devtools.clientCount
1514
+ });
1462
1515
  return;
1463
1516
  }
1464
1517
  if (req.method === "GET" && url === "/v1/traces") {
@@ -1478,7 +1531,7 @@ function attachDevtoolsRoutes(httpServer, devtools) {
1478
1531
  devtools.addTraces(traces);
1479
1532
  sendJson(res, 200, { acceptedTraces: traces.length });
1480
1533
  } catch (e) {
1481
- sendJson(res, 400, { error: "Invalid OTLP payload", message: e instanceof Error ? e.message : String(e) });
1534
+ sendOtlpError(res, req, e);
1482
1535
  }
1483
1536
  return;
1484
1537
  }
@@ -1489,7 +1542,7 @@ function attachDevtoolsRoutes(httpServer, devtools) {
1489
1542
  devtools.addLogs(logs);
1490
1543
  sendJson(res, 200, { acceptedLogs: logs.length });
1491
1544
  } catch (e) {
1492
- sendJson(res, 400, { error: "Invalid OTLP payload", message: e instanceof Error ? e.message : String(e) });
1545
+ sendOtlpError(res, req, e);
1493
1546
  }
1494
1547
  return;
1495
1548
  }
@@ -1499,7 +1552,7 @@ function attachDevtoolsRoutes(httpServer, devtools) {
1499
1552
  const count = countOtlpMetrics(payload);
1500
1553
  sendJson(res, 200, { acceptedMetrics: count });
1501
1554
  } catch (e) {
1502
- sendJson(res, 400, { error: "Invalid OTLP payload", message: e instanceof Error ? e.message : String(e) });
1555
+ sendOtlpError(res, req, e);
1503
1556
  }
1504
1557
  return;
1505
1558
  }
@@ -1512,6 +1565,7 @@ function createDevtoolsHttpServer(devtools, _options = {}) {
1512
1565
  return server;
1513
1566
  }
1514
1567
 
1568
+ exports.DEVTOOLS_IDENTITY = DEVTOOLS_IDENTITY;
1515
1569
  exports.DevtoolsLogExporter = DevtoolsLogExporter;
1516
1570
  exports.DevtoolsRemoteExporter = DevtoolsRemoteExporter;
1517
1571
  exports.DevtoolsServer = DevtoolsServer;
@@ -1528,6 +1582,7 @@ exports.decodeOtlpTraceRequest = decodeOtlpTraceRequest;
1528
1582
  exports.isProtobufContentType = isProtobufContentType;
1529
1583
  exports.parseOtlpLogs = parseOtlpLogs;
1530
1584
  exports.parseOtlpTraces = parseOtlpTraces;
1585
+ exports.probePortHolder = probePortHolder;
1531
1586
  exports.resolveTelemetryLimits = resolveTelemetryLimits;
1532
1587
  //# sourceMappingURL=index.cjs.map
1533
1588
  //# sourceMappingURL=index.cjs.map