teleminal
v0.1.1
Published
A bounded, interactive terminal for live OpenTelemetry metrics and logs.
Downloads
48
Maintainers
Readme
Teleminal
Teleminal is a bounded, interactive terminal for live OpenTelemetry metrics and logs. Run it as a local OTLP/HTTP receiver or embed the same core and renderer into a Node.js service through the official OpenTelemetry SDK extension points.
It is intentionally a live development and operational view, not a telemetry database or forwarding collector. Every retained series, sample, log, query cache, command history, and request has a hard bound.
Highlights
- OTLP/HTTP metrics and logs over protobuf or JSON, including gzip.
- Loopback-only receiver defaults and explicit non-loopback warnings.
- Official
MetricReaderandLogRecordProcessorembedded adapters. - Counters, gauges, explicit and exponential histograms, rates, resets, and bounded sample history.
- Responsive Ink UI with wide, medium, narrow, simple, and non-TTY modes.
- Menus, breadcrumbs, details, filters, grouping, sorting, help, commands, and configurable shortcuts.
- Tables, trends, bars, histograms, box plots, percentile bands, CDFs, ridgelines, coverage fields, SLO burn rates and burndowns, small multiples, temporal and spatial heatmaps, gauges, status matrices, scatter plots, Pareto and waterfall charts, range timelines, rankings, change views, and log timelines.
- A deterministic
demomode with bounded fake metrics and logs plus a nested visualisation gallery. - A self-contained production React/Ink bundle, even when the host application uses
NODE_ENV=development. - Strict modern TypeScript with explicit public contracts and no application globals.
Requires Node.js 22 or later.
Five-minute standalone start
Start the local receiver and interactive terminal:
npx teleminalPoint an OpenTelemetry application at it:
export OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
node your-instrumented-service.jsThe default endpoints are:
metrics http://127.0.0.1:4318/v1/metrics
logs http://127.0.0.1:4318/v1/logsUseful alternatives:
teleminal start --mode demo
teleminal start --mode simple --page overview
teleminal start --port 4320
teleminal validate --config ./teleminal.config.ts
teleminal print-default-configdemo mode seeds bounded fake telemetry and opens a nested gallery where each visualisation is a
selectable page. Press 1–9 to choose at each menu level and 0 to go back one level. It is
useful for exploring Teleminal without configuring an OpenTelemetry sender.
See standalone and sender configuration for an official OpenTelemetry Node SDK example.
Five-minute embedded start
Install Teleminal alongside the OpenTelemetry SDK packages already used by the service:
npm install teleminal \
@opentelemetry/api \
@opentelemetry/sdk-logs \
@opentelemetry/sdk-metricsimport { LoggerProvider } from '@opentelemetry/sdk-logs';
import { MeterProvider } from '@opentelemetry/sdk-metrics';
import { createTeleminal } from 'teleminal/embedded';
const terminal = createTeleminal({
mode: 'interactive',
title: 'Payments service',
});
const meterProvider = new MeterProvider({
readers: [terminal.metricReader],
});
const loggerProvider = new LoggerProvider({
processors: [terminal.logRecordProcessor],
});
await terminal.start();
// Create meters and loggers through meterProvider and loggerProvider as usual.
process.once('SIGTERM', async () => {
await terminal.stop();
await Promise.all([meterProvider.shutdown(), loggerProvider.shutdown()]);
});The embedded API does not register globals, intercept console, or call process.exit(). See
embedded use and lifecycle.
Configuration
Create teleminal.config.ts:
import { defineConfig } from 'teleminal/config';
export default defineConfig({
initialPage: 'overview',
mode: 'interactive',
receiver: {
host: '127.0.0.1',
maximumConcurrentRequests: 16,
maximumDecompressedBytes: 16 * 1024 * 1024,
maximumRecordsPerRequest: 100_000,
maximumRequestBytes: 4 * 1024 * 1024,
port: 4318,
requestTimeoutMs: 10_000,
},
retention: {
maximumLogRecords: 2_000,
maximumMetricSeries: 10_000,
},
title: 'Local telemetry',
});Configuration discovery, environment precedence, validation, page definitions, and every bound are covered in the configuration reference.
Package entry points
| Import | Purpose |
| -------------------- | -------------------------------------------------------- |
| teleminal | Core snapshots, queries, metrics, logs, and shared types |
| teleminal/embedded | Official SDK adapters and embedded lifecycle |
| teleminal/receiver | Importable headless OTLP/HTTP receiver |
| teleminal/config | defineConfig and configuration/page types |
| teleminal/testing | Fake clock and fake terminal |
No public entry point exports React, Ink, components, contexts, or hooks.
Security boundary
The receiver has no authentication. It binds to 127.0.0.1 by default. A non-loopback --host is
an explicit opt-in and prints a warning. Do not expose it to an untrusted network without an
authenticated proxy and network controls. Telemetry can contain secrets and personal data; Teleminal
bounds values but does not redact them.
See SECURITY.md and the receiver security guide.
Documentation
- Standalone CLI and OTLP senders
- Embedded use
- Configuration reference
- Page authoring
- Metrics and histogram semantics
- Log explorer
- Shortcuts
- Command palette
- Themes and terminal capabilities
- Lifecycle and shutdown
- Memory and cardinality limits
- Non-TTY behaviour
- Production React/Ink bundle
- Troubleshooting
- Extension guide
- Terminal screenshots
- Building and publishing the npm package
- Runnable sender
- Runnable embedded service
- Runnable importable receiver
Development
npm ci
npm run verify
npm run profile:longevity
npm run validate:package
npm run package:buildnpm run verify checks formatting, strict lint defaults, TypeScript, tests, the production build, a
development-host/production-React smoke test, and the package contents. It performs only an npm pack
dry run; it does not publish.
npm run validate:package builds and locally packs the package, then installs that tarball into two
temporary strict TypeScript applications. One imports the headless receiver and one uses the real
OpenTelemetry embedded adapters. It deletes the temporary applications afterward and does not
publish.
npm run package:build runs every release check and writes the publishable tarball to artifacts/.
It does not publish. See the release guide for the exact preview and publishing
commands.
After npm login, npm run release:npm performs the verified build, registry preview, and public
publish as one fail-fast workflow. Add -- --dry-run to stop after the preview.
