How to Collect Metrics from an iroh Endpoint: Complete Socket Monitoring Guide

To collect metrics from an iroh Endpoint, call the metrics() method on a live Endpoint instance, which returns a snapshot of counters tracking bytes sent/received, connection events, and transport activity.

The iroh crate embeds a built-in metrics system that records detailed counters for all socket-level activity. Every iroh::Endpoint implements the MetricsGroup trait from the iroh_metrics crate, exposing network telemetry through a zero-overhead API. This guide demonstrates how to access these metrics directly from your application code according to the n0-computer/iroh source.

What Metrics Are Available

The iroh Endpoint tracks comprehensive socket-level statistics defined in iroh/src/socket/metrics.rs. These counters record:

  • Transport bytes: send_ipv4, send_ipv6, and send_relay for outgoing data; recv_data_ipv4, recv_data_ipv6, recv_data_relay, and recv_data_custom for incoming data
  • Connection lifecycle: num_conns_opened and num_conns_closed tracking handshaked connections
  • Path discovery: paths_direct, paths_relay, and paths_custom showing transport path utilization
  • Hole-punching: holepunch_attempts counting NAT traversal events
  • Actor loop: actor_tick_main and actor_tick_msg for internal async runtime monitoring

Accessing Metrics via the Endpoint API

The Endpoint type provides the metrics() method as the primary interface for collecting metrics. This method returns a clone of the current Metrics struct, ensuring thread-safe access to counter snapshots without blocking the underlying socket operations.

The Endpoint automatically registers its metrics group with the global collector during initialization via the #[metrics(name = "socket", default)] attribute defined in iroh/src/socket/metrics.rs.

Implementation Details

Internally, iroh uses the iroh_metrics crate to manage metric collection. The Metrics struct in iroh/src/socket/metrics.rs implements the MetricsGroup trait, which enables automatic registration with the global collector. You can also manually register groups via iroh_metrics::register_group if building custom collectors.

Code Examples

Basic Metrics Collection

Fetch metrics periodically from a running Endpoint:

use iroh::Endpoint;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let endpoint = Endpoint::builder()
        .bind_udp(0)
        .await?;

    loop {
        let snap = endpoint.metrics();
        
        println!("IPv4 bytes sent: {}", snap.send_ipv4.get());
        println!("IPv6 bytes sent: {}", snap.send_ipv6.get());
        println!("Relay bytes sent: {}", snap.send_relay.get());
        println!("Hole-punch attempts: {}", snap.holepunch_attempts.get());
        println!("Connections opened: {}", snap.num_conns_opened.get());
        
        tokio::time::sleep(std::time::Duration::from_secs(30)).await;
    }
}

Exporting to JSON

The Metrics struct derives Serialize, enabling structured export to monitoring systems:

use serde_json::to_string_pretty;

let json = to_string_pretty(&endpoint.metrics())?;
println!("{}", json);

Summary

  • Call endpoint.metrics() on any live Endpoint to collect metrics from an iroh Endpoint
  • Counters are defined in iroh/src/socket/metrics.rs and track bytes sent/received, connections, and transport paths
  • The MetricsGroup trait from iroh_metrics enables automatic registration with the global collector
  • Metrics snapshots are clones of internal state, ensuring non-blocking access
  • Export to JSON or integrate with Prometheus using the Serialize implementation

Frequently Asked Questions

What counters does the iroh Endpoint track?

The Endpoint tracks transport-specific byte counters (send_ipv4, send_ipv6, send_relay, recv_data_ipv4, recv_data_ipv6, recv_data_relay), connection lifecycle events (num_conns_opened, num_conns_closed), path statistics (paths_direct, paths_relay, paths_custom), and hole-punching attempts (holepunch_attempts). These are defined in iroh/src/socket/metrics.rs.

How do I register custom metrics collectors?

Use iroh_metrics::register_group to manually register a MetricsGroup implementation with the global collector. While the Endpoint auto-registers its socket metrics via the #[metrics] attribute, custom components require explicit registration to participate in the same collection pipeline.

Can I export metrics to Prometheus?

Yes. Because the Metrics struct implements Serialize, you can serialize snapshots to JSON and feed them into Prometheus via a bridge, or implement the iroh_metrics traits to write a custom Prometheus exporter that polls endpoint.metrics() periodically.

Where are the metrics defined in the source code?

The socket-level metrics are defined in iroh/src/socket/metrics.rs within the iroh crate. The Endpoint type that exposes the metrics() method is defined in iroh/src/endpoint.rs, and the public API is re-exported through iroh/src/lib.rs.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →