ICMetrics. Monitor and Instrument Canister Metrics


:rocket: IC Metrics — on-chain monitoring & analytics for your canisters (live, looking for feedback!)

Hey everyone :waving_hand:

I’ve been heads-down building IC Metrics — a monitoring and analytics layer built natively for the Internet Computer, and I wanted to share it here now that it’s live.

The problem

If you’re running a canister in production, you probably know the pain: there’s no statsd, no Datadog agent, no easy way to answer “how many signups did we get today?” or “is our heap creeping up?” without writing your own storage and a dashboard from scratch. Off-chain analytics services also mean piping your on-chain activity through a centralized, off-chain pipe — which feels wrong for a canister that’s supposed to be verifiable end-to-end.

The idea

IC Metrics gives your dapp its own dedicated analytics canister — no external services, no off-chain database, 100% on the IC.

  1. Sign in with Internet Identity.
  2. Create an analytics canister for your dapp from the dashboard — it deploys a storage canister and wires your dapp canister up as a controller automatically.
  3. Drop in the ic-analytics-sdk crate and start recording metrics with one-line, fire-and-forget calls:
use ic_analytics_sdk::{AnalyticsClient, Metric, MetricValue};
use candid::Principal;

thread_local! {
    static ANALYTICS: AnalyticsClient = AnalyticsClient::new(
        Principal::from_text("YOUR-ANALYTICS-CANISTER-ID").unwrap()
    );
}

ANALYTICS.with(|a| {
    let _ = a.record_metric(Metric {
        key:   "user_signups".to_string(),
        name:  "User Sign-ups".to_string(),
        value: MetricValue::Counter(1),
    });
});

The call is a one-way inter-canister message, so it never blocks your update calls or costs you round-trip latency.

Not on Rust, or want to push metrics from an off-chain backend? There’s also a plain HTTP endpoint secured with API keys — a simple curl with a bearer token works too.

What you get

  • Counters, Gauges, Histograms, TimeSeries, and Logs — the metric primitives you’d expect, each with clear storage semantics (running totals, latest-value-wins, appended points, timestamped text).
  • Automatic timestamping — TimeSeries values are stamped with IC time automatically, so trend charts (latency, request rate, etc.) need zero extra bookkeeping.
  • A Rhai-based transformer engine — write small on-chain scripts that combine/derive metrics (e.g. compute a rolling average or a ratio between two counters) without shipping new canister code.
  • A live dashboard that polls your metrics and updates in real time, with per-canister cycles balance monitoring and one-click top-ups so your analytics canister never gets frozen silently.
  • Everything stored in stable memory on your own canister — you own the data, and it survives upgrades.

Try it

It’s early — I’d genuinely love feedback from people running canisters in prod: what metrics you actually want to see, whether the SDK ergonomics make sense, and what’s missing before you’d trust it for a real dapp. Bug reports and “this UX is confusing” comments are just as welcome as feature requests.

Thanks for reading — happy to answer questions about the architecture (registry canister ↔ per-user storage canister ↔ SDK) if anyone’s curious!