autotel-terminal 20.0.1 → 22.0.0
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/README.md +26 -0
- package/dist/cli.cjs +74 -15
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +74 -15
- package/dist/cli.js.map +1 -1
- package/package.json +3 -3
- package/src/cli.ts +34 -16
- package/src/listen.ts +84 -0
package/README.md
CHANGED
|
@@ -68,6 +68,32 @@ Port 4319 is used by default to avoid clashing with the standard OTLP port (4318
|
|
|
68
68
|
| `POST /v1/metrics` | Metrics | Accepts OTLP JSON metrics (acknowledged and counted) |
|
|
69
69
|
| `GET /healthz` | — | Health check |
|
|
70
70
|
|
|
71
|
+
When bound to a loopback host, the receiver listens on **both** `127.0.0.1`
|
|
72
|
+
and `::1`, so a `localhost` client connects regardless of how the OS resolves
|
|
73
|
+
`localhost` (macOS prefers IPv6 `::1`). The startup line prints every bound
|
|
74
|
+
address; an unbindable family becomes a warning, not a silent failure.
|
|
75
|
+
|
|
76
|
+
### Behind a dev-server proxy
|
|
77
|
+
|
|
78
|
+
If a dev server proxies `/v1/traces` to the terminal receiver, two bugs make
|
|
79
|
+
spans silently vanish:
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
// Express / http-proxy-middleware
|
|
83
|
+
app.use(
|
|
84
|
+
'/v1/traces',
|
|
85
|
+
createProxyMiddleware({
|
|
86
|
+
pathRewrite: () => '/v1/traces', // Express strips the mount prefix → would forward "/"
|
|
87
|
+
target: 'http://127.0.0.1:4319', // 127.0.0.1, not localhost (macOS resolves localhost → ::1)
|
|
88
|
+
changeOrigin: true,
|
|
89
|
+
}),
|
|
90
|
+
);
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The browser shows the request succeeding while the receiver stays empty — so
|
|
94
|
+
verify on the receiver (the TUI should show the spans), not just that the
|
|
95
|
+
request left the browser.
|
|
96
|
+
|
|
71
97
|
## Quick Start
|
|
72
98
|
|
|
73
99
|
### Recommended Usage
|
package/dist/cli.cjs
CHANGED
|
@@ -2761,6 +2761,54 @@ function renderTerminal(options = {}, stream) {
|
|
|
2761
2761
|
console.error("[autotel-terminal] Failed to render dashboard:", error);
|
|
2762
2762
|
}
|
|
2763
2763
|
}
|
|
2764
|
+
var LOOPBACK = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "::1"]);
|
|
2765
|
+
function formatAddress(host, port) {
|
|
2766
|
+
return host.includes(":") ? `[${host}]:${port}` : `${host}:${port}`;
|
|
2767
|
+
}
|
|
2768
|
+
function listenLoopbackDualStack(args) {
|
|
2769
|
+
const { primary, port, host, attachSecondary } = args;
|
|
2770
|
+
let sibling;
|
|
2771
|
+
const ready = new Promise(
|
|
2772
|
+
(resolve) => {
|
|
2773
|
+
const addresses = [];
|
|
2774
|
+
const warnings = [];
|
|
2775
|
+
const primaryHost = host === "localhost" ? "127.0.0.1" : host;
|
|
2776
|
+
primary.listen(port, primaryHost, () => {
|
|
2777
|
+
const addr = primary.address();
|
|
2778
|
+
const resolvedPort = addr && typeof addr === "object" ? addr.port : port;
|
|
2779
|
+
addresses.push(formatAddress(primaryHost, resolvedPort));
|
|
2780
|
+
if (!LOOPBACK.has(host)) {
|
|
2781
|
+
resolve({ addresses, warnings });
|
|
2782
|
+
return;
|
|
2783
|
+
}
|
|
2784
|
+
const siblingHost = primaryHost === "::1" ? "127.0.0.1" : "::1";
|
|
2785
|
+
const s = http.createServer();
|
|
2786
|
+
attachSecondary(s);
|
|
2787
|
+
const onError = (e) => {
|
|
2788
|
+
s.close();
|
|
2789
|
+
warnings.push(
|
|
2790
|
+
`could not also bind ${formatAddress(siblingHost, resolvedPort)} (${e.message}); clients using the ${siblingHost === "::1" ? "IPv6" : "IPv4"} form of "localhost" may not connect.`
|
|
2791
|
+
);
|
|
2792
|
+
resolve({ addresses, warnings });
|
|
2793
|
+
};
|
|
2794
|
+
s.once("error", onError);
|
|
2795
|
+
s.listen(resolvedPort, siblingHost, () => {
|
|
2796
|
+
s.off("error", onError);
|
|
2797
|
+
sibling = s;
|
|
2798
|
+
addresses.push(formatAddress(siblingHost, resolvedPort));
|
|
2799
|
+
resolve({ addresses, warnings });
|
|
2800
|
+
});
|
|
2801
|
+
});
|
|
2802
|
+
}
|
|
2803
|
+
);
|
|
2804
|
+
return {
|
|
2805
|
+
ready,
|
|
2806
|
+
closeSibling: () => new Promise((res) => {
|
|
2807
|
+
if (!sibling) return res();
|
|
2808
|
+
sibling.close(() => res());
|
|
2809
|
+
})
|
|
2810
|
+
};
|
|
2811
|
+
}
|
|
2764
2812
|
|
|
2765
2813
|
// src/cli-stream.ts
|
|
2766
2814
|
var CliTerminalSpanStream = class {
|
|
@@ -3132,7 +3180,7 @@ async function main() {
|
|
|
3132
3180
|
},
|
|
3133
3181
|
spanStream
|
|
3134
3182
|
);
|
|
3135
|
-
const
|
|
3183
|
+
const requestHandler = async (req, res) => {
|
|
3136
3184
|
if (req.method === "GET" && req.url === "/healthz") {
|
|
3137
3185
|
sendJson(res, 200, { ok: true });
|
|
3138
3186
|
return;
|
|
@@ -3170,23 +3218,34 @@ async function main() {
|
|
|
3170
3218
|
message: error instanceof Error ? error.message : String(error)
|
|
3171
3219
|
});
|
|
3172
3220
|
}
|
|
3221
|
+
};
|
|
3222
|
+
const server = http.createServer(requestHandler);
|
|
3223
|
+
const listeners = listenLoopbackDualStack({
|
|
3224
|
+
primary: server,
|
|
3225
|
+
port: options.port,
|
|
3226
|
+
host: options.host,
|
|
3227
|
+
attachSecondary: (s) => s.on("request", requestHandler)
|
|
3173
3228
|
});
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3229
|
+
const { addresses, warnings } = await listeners.ready;
|
|
3230
|
+
process.stdout.write(
|
|
3231
|
+
`[autotel-terminal] listening on ${addresses.join(" + ")}
|
|
3177
3232
|
`
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3233
|
+
);
|
|
3234
|
+
process.stdout.write(
|
|
3235
|
+
"[autotel-terminal] endpoints: /v1/traces, /v1/logs, /v1/metrics\n"
|
|
3236
|
+
);
|
|
3237
|
+
process.stdout.write(
|
|
3238
|
+
"[autotel-terminal] set OTEL_EXPORTER_OTLP_PROTOCOL=http/json and OTEL_EXPORTER_OTLP_ENDPOINT to this host/port\n"
|
|
3239
|
+
);
|
|
3240
|
+
for (const w of warnings) {
|
|
3241
|
+
process.stdout.write(`[autotel-terminal] \u26A0 ${w}
|
|
3242
|
+
`);
|
|
3243
|
+
}
|
|
3186
3244
|
const shutdown = () => {
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3245
|
+
Promise.all([
|
|
3246
|
+
new Promise((r) => server.close(() => r())),
|
|
3247
|
+
listeners.closeSibling()
|
|
3248
|
+
]).then(() => process.exit(0));
|
|
3190
3249
|
};
|
|
3191
3250
|
process.on("SIGINT", shutdown);
|
|
3192
3251
|
process.on("SIGTERM", shutdown);
|