uptimeclarity:agent
UptimeClarity monitoring agent for Meteor 2.x and 3.x applications.
Instruments Meteor methods, publications, MongoDB queries, and event-loop lag, and ships batched telemetry to the UptimeClarity ingest API.
Install
meteor add uptimeclarity:agent
Quickstart
1// server/main.js 2import { Meteor } from 'meteor/meteor'; 3import { UptimeClarity } from 'meteor/uptimeclarity:agent'; 4 5Meteor.startup(() => { 6 UptimeClarity.start({ 7 apiKey: process.env.UPTIMECLARITY_API_KEY, 8 appName: 'my-app', 9 }); 10});
Generate an API key in the UptimeClarity dashboard at
https://uptimeclarity.com and expose it to the server as
UPTIMECLARITY_API_KEY (or any env var of your choice).
Configuration
| Option | Default | Description |
|---|---|---|
apiKey | (required) | UptimeClarity API key. |
appName | (required) | Identifier for this app in the dashboard. |
environment | NODE_ENV === 'production' ? 'production' : 'development' | Deployment label stamped on every event so dev and prod traffic can be filtered separately under a single API key. |
endpoint | https://api.uptimeclarity.com | Override for self-hosted / dev workers. |
sampleRate | 1.0 | Sampling rate (0.0–1.0). |
flushInterval | 10000 | Transport flush cadence in ms. |
trackMethods | true | Instrument Meteor.methods. |
trackPublications | true | Instrument Meteor.publish. |
trackMongo | true | Instrument Mongo.Collection operations. |
trackEventLoop | true | Sample event-loop lag every 5s; reports if >50ms. |
trackHost | true | Send periodic host heartbeats with OS, CPU, memory, and Node version. |
trackLiveQueries | true | Sample Meteor's reactive observer registry every ~30s and emit a per-collection / per-driver (change_stream / oplog / polling) snapshot. Powers the LiveQuery dashboard tab and the "reactive efficiency" headline metric. Meteor 3.5+. |
trackMongoPool | true | Sample the MongoDB driver's connection pool every ~30s (in-use / available / waiting / max). |
liveQueryIntervalMs | 30000 | LiveQuery sampler period in ms. |
mongoPoolIntervalMs | 30000 | Mongo pool sampler period in ms. |
detectLeaks | true | Run observer-leak heuristics (growing-count / stale / inactive / orphaned) over each LiveQuery snapshot and emit one observer_leak event per newly-detected leak. |
captureLogs | true | Wrap console.* (and Meteor's Log.* if installed) to forward log entries as app_log events. |
logLevels | ['warn','error','info'] | Console levels captured (debug and log-as-info opt-in). |
logSampleRate | 1.0 | 0–1; reduce on chatty apps. |
logMaxMessageLength | 4096 | Truncate long log messages to this many chars. |
trackJobs | true | Wrap msavin:sjobs Jobs.register to emit a job event per handler completion. No-op if sjobs isn't installed. |
slowJobMs | 1000 | Threshold (ms) above which jobs get a captured call-site stack. |
trackOutboundHttp | true | Wrap globalThis.fetch to record http_outbound events and stamp an X-Trace-Id header. |
slowHttpMs | 500 | Threshold (ms) above which outbound calls are flagged slow. |
traceHeader | 'X-Trace-Id' | Header name used for outbound trace propagation (e.g. 'traceparent' for W3C). |
httpUrlRedactor | (url) => url | Optional function to scrub URLs before they hit the dashboard (e.g. strip tokens). |
What it tracks
- Methods — duration of every
Meteor.methodcall, including async (Meteor 3.x) and sync handlers, plus errors. - Publications — time from subscription start to
ready()(or the returned promise resolving on Meteor 3.x). - MongoDB —
find,findOne,insert,update,remove,upsertper collection, with a structural query fingerprint (values redacted) and aslowflag for queries > 200 ms. - Event loop lag —
setImmediateround-trip sampled every 5 s; reports any lag > 50 ms. - LiveQueries (Meteor 3.5+) — every ~30 s, snapshots all active observer
multiplexers and classifies each one as
change_stream,oplog, orpolling. Reports per-collection counts and the headline "reactive efficiency" ratio ((change_stream + oplog) / total). - Observer leaks — four heuristics over the LiveQuery snapshots:
growing observer count per collection across N consecutive samples,
stale multiplexers alive >24h with no activity, inactive multiplexers
alive >30 minutes with zero recorded change events, and orphaned
multiplexers whose parent subscription has closed. Each new leak emits
one
observer_leakevent so the dashboard can alert. - MongoDB connection pool — every ~30 s, samples each topology server's pool: in-use, available, pending, wait queue, configured max.
- Application logs —
console.log/info/warn/error/debugand MeteorLog.*calls are forwarded asapp_logevents with structured metadata. Cyclic objects,Errorinstances, and very long messages are handled safely. - Background jobs (
msavin:sjobs) — every registered job handler is wrapped to emit ajobevent on completion. Both thethis.success()/this.failure()callback idiom and Promise-returning handlers are supported; whichever signal fires first wins. Slow jobs capture a call-site stack like slow methods. - Outbound HTTP — every
fetch()call from the application server emits anhttp_outboundevent with method, host, path, status, and duration. We stamp anX-Trace-Idheader (configurable, e.g.'traceparent'for W3C) so downstream services receiving the request can correlate it with the parent operation.
Custom Metrics API
1import { UptimeClarity } from 'meteor/uptimeclarity:agent'; 2 3// Counters — monotonically increasing totals (rates computed at query time). 4UptimeClarity.counter('orders_created'); 5UptimeClarity.counter('cache_hits', 1, { region: 'us-east' }); 6 7// Timers — record a duration sample. P50/P95/P99 surfaced in the dashboard. 8UptimeClarity.timer('payment_ms', durationMs, { provider: 'stripe' }); 9 10// Gauges — point-in-time observation. Last-value-wins on the read path. 11UptimeClarity.gauge('queue_depth', queue.length); 12 13// Stopwatch sugar — awaits the function, records its wall-clock time. 14await UptimeClarity.timeAsync('charge_credit_card', async () => { 15 return stripe.charges.create({ /* ... */ }); 16}); 17 18// Generic escape hatch (kind/tags fully under your control). 19UptimeClarity.trackMetric('feature_flag_eval', 1, { 20 kind: 'counter', 21 tags: { flag: 'new_checkout', enabled: true }, 22});
Tags are capped at 8 keys per metric and 64 chars per value.
Application logs
1// Programmatic log API — useful when you already have a structured logger. 2UptimeClarity.addLog('error', 'payment failed', { 3 user_id: userId, 4 charge_id: charge.id, 5 reason: err.code, 6}); 7 8// console.* and Meteor's Log.* are captured automatically when 9// `captureLogs: true` (the default). 10console.warn('cache miss for', cacheKey); // → emitted as app_log warn
Methods and publications already registered before UptimeClarity.start()
runs are wrapped retroactively, so import order does not matter.
Stopping the agent
1UptimeClarity.stop();
Flushes any buffered events and clears the event-loop sampler.
Compatibility
- Meteor 2.8+ and Meteor 3.x
- Server-only (the package is not exported to the client)
Development
This package lives inside the uptimeclarity.com monorepo. Unit tests live in
test/ and run under Vitest with mocked meteor/meteor and
meteor/mongo globals:
pnpm --filter uptimeclarity-meteor-agent-tests test
A live integration sandbox (real Meteor 3 app driving every hook) is provided
under packages/meteor-agent-testapp.
License
MIT — see LICENSE.