Telemetry
The TelemetryPlugin collects application metrics — HTTP request counts, response durations, error rates — and pushes them to the Putnami telemetry backend. You can also record custom counters, gauges, and histograms.
Getting started
Register the telemetry() plugin alongside http():
import { application, http, telemetry } from '@putnami/application';
const app = application()
.use(telemetry({ bearer: process.env.TELEMETRY_TOKEN }))
.use(http({ port: 3000 }));
await app.start();HTTP metrics are collected automatically. No further setup is needed.
What is collected automatically
The plugin registers a middleware that instruments every HTTP request:
| Metric | Type | Name pattern | Example |
|---|---|---|---|
| Request count | Counter | http.{METHOD}.{route}.{status} |
http.GET./api/users.200 |
| Response time | Histogram | http.{METHOD}.{route}.duration |
http.GET./api/users.duration |
| Client errors | Counter | http.error.4xx |
— |
| Server errors | Counter | http.error.5xx |
— |
Routes use the pattern (/users/[id]), not the resolved path (/users/123), to keep metric cardinality bounded.
SQL metrics (via @putnami/sql)
When the sql() plugin is used alongside telemetry(), SQL metrics are collected automatically:
| Metric | Type | Name pattern | Example |
|---|---|---|---|
| Query count | Counter | sql.{operation}.{table} |
sql.find.users |
| Query duration | Histogram | sql.{operation}.{table}.duration |
sql.save.orders.duration |
| Aggregate duration | Histogram | sql.query.duration |
— |
| Query errors | Counter | sql.{operation}.{table}.error |
sql.save.users.error |
| Aggregate errors | Counter | sql.query.error |
— |
| Slow queries | Counter | sql.query.slow |
— |
| Pool created | Counter | sql.pool.created |
— |
| Pool closed | Counter | sql.pool.closed |
— |
| Pool count | Gauge | sql.pool.count |
— |
Operations: find, save, saveMany, delete, deleteMany, exists.
Custom metrics
Three metric types are available. They are no-ops when telemetry is disabled, so you can call them unconditionally.
import { incCounter, setGauge, observeHistogram } from '@putnami/application';
// Counter — monotonically increasing
incCounter('app.orders.created');
incCounter('app.emails.sent', 3);
// Gauge — point-in-time value
setGauge('app.queue.size', pendingJobs.length);
// Histogram — distribution (count, sum, min, max per second)
const start = Date.now();
await processOrder(order);
observeHistogram('app.order.processing.duration', Date.now() - start);Configuration
telemetry({
enabled: true,
endpoint: 'https://telemetry.putnami.cloud/v1/runtime',
bearer: 'my-token',
flushIntervalS: 30,
app: 'my-service',
});| Option | Type | Default | Description |
|---|---|---|---|
enabled |
boolean |
true |
Enable or disable collection |
endpoint |
string |
https://telemetry.putnami.cloud/v1/runtime |
Telemetry ingest URL |
bearer |
string |
— | Bearer token for authentication |
flushIntervalS |
number |
30 |
Seconds between flushes |
app |
string |
— | Application identifier |
Or via YAML:
telemetry:
bearer: "..."
flushIntervalS: 30
app: "my-service"How aggregation works
Metrics are bucketed by Unix second in memory. A periodic timer drains completed buckets, builds a JSON payload, and POSTs it to the endpoint. On shutdown, all remaining buckets (including the current second) are flushed immediately.
The telemetry backend can adjust the flush interval dynamically by returning { "flushIntervalS": N } in the response. The plugin applies it without restart.
All telemetry failures are silently dropped — they never affect application behavior.