From d45c615e736be68f9091c8788d9756496e852b3e Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Thu, 13 Nov 2025 00:28:15 +0000 Subject: [PATCH] feat(telemetry): collect high level provide DHT sweep settings (#11056) * telemetry: collect provideDHTSweepEnabled Fixes #11055. * telemetry: track custom Provide.DHT.Interval and MaxWorkers collects whether users customize Interval and MaxWorkers from defaults to help identify if defaults need adjustment * docs: improve telemetry documentation structure and clarity restructure docs/telemetry.md into meaningful sections (routing & discovery, content providing, network configuration), add exact config field paths for all tracked settings, and establish code as source of truth by linking from LogEvent struct while removing redundant field comments --------- Co-authored-by: Marcin Rataj --- docs/telemetry.md | 56 ++++++++++++++++++++------- plugin/plugins/telemetry/telemetry.go | 23 ++++++----- test/cli/telemetry_test.go | 3 ++ 3 files changed, 57 insertions(+), 25 deletions(-) diff --git a/docs/telemetry.md b/docs/telemetry.md index 001c416b6..5b053ed34 100644 --- a/docs/telemetry.md +++ b/docs/telemetry.md @@ -47,25 +47,51 @@ Or in your IPFS config file: The telemetry plugin collects the following anonymized data: ### General Information -- **Agent version**: The version of Kubo being used. -- **Platform details**: Operating system, architecture, and container status. -- **Uptime**: How long the node has been running, categorized into buckets. -- **Repo size**: Categorized into buckets (e.g., 1GB, 5GB, 10GB, etc.). + +- **UUID**: Anonymous identifier for this node +- **Agent version**: Kubo version string +- **Private network**: Whether running in a private IPFS network +- **Repository size**: Categorized into privacy-preserving buckets (1GB, 5GB, 10GB, 100GB, 500GB, 1TB, 10TB, >10TB) +- **Uptime**: Categorized into privacy-preserving buckets (1d, 2d, 3d, 7d, 14d, 30d, >30d) + +### Routing & Discovery + +- **Custom bootstrap peers**: Whether custom `Bootstrap` peers are configured +- **Routing type**: The `Routing.Type` configured for the node +- **Accelerated DHT client**: Whether `Routing.AcceleratedDHTClient` is enabled +- **Delegated routing count**: Number of `Routing.DelegatedRouters` configured +- **AutoConf enabled**: Whether `AutoConf.Enabled` is set +- **Custom AutoConf URL**: Whether custom `AutoConf.URL` is configured +- **mDNS**: Whether `Discovery.MDNS.Enabled` is set + +### Content Providing + +- **Provide and Reprovide strategy**: The `Provide.Strategy` configured +- **Sweep-based provider**: Whether `Provide.DHT.SweepEnabled` is set +- **Custom Interval**: Whether custom `Provide.DHT.Interval` is configured +- **Custom MaxWorkers**: Whether custom `Provide.DHT.MaxWorkers` is configured ### Network Configuration -- **Private network**: Whether the node is running in a private network. -- **Bootstrap peers**: Whether custom bootstrap peers are used. -- **Routing type**: Whether the node uses DHT, IPFS, or a custom routing setup. -- **AutoNAT settings**: Whether AutoNAT is enabled and its reachability status. -- **AutoConf settings**: Whether AutoConf is enabled and whether a custom URL is used. -- **Swarm settings**: Whether hole punching is enabled, and whether public IP addresses are used. -### TLS and Discovery -- **AutoTLS settings**: Whether WSS is enabled and whether a custom domain suffix is used. -- **Discovery settings**: Whether mDNS is enabled. +- **AutoNAT service mode**: The `AutoNAT.ServiceMode` configured +- **AutoNAT reachability**: Current reachability status determined by AutoNAT +- **Hole punching**: Whether `Swarm.EnableHolePunching` is enabled +- **Circuit relay addresses**: Whether the node advertises circuit relay addresses +- **Public IPv4 addresses**: Whether the node has public IPv4 addresses +- **Public IPv6 addresses**: Whether the node has public IPv6 addresses +- **AutoWSS**: Whether `AutoTLS.AutoWSS` is enabled +- **Custom domain suffix**: Whether custom `AutoTLS.DomainSuffix` is configured -### Reprovider Strategy -- The strategy used for reprovider (e.g., "all", "pinned"...). +### Platform Information + +- **Operating system**: The OS the node is running on +- **CPU architecture**: The architecture the node is running on +- **Container detection**: Whether the node is running inside a container +- **VM detection**: Whether the node is running inside a virtual machine + +### Code Reference + +Data is organized in the `LogEvent` struct at [`plugin/plugins/telemetry/telemetry.go`](https://github.com/ipfs/kubo/blob/master/plugin/plugins/telemetry/telemetry.go). This struct is the authoritative source of truth for all telemetry data, including privacy-preserving buckets for repository size and uptime. Note that this documentation may not always be up-to-date - refer to the code for the current implementation. --- diff --git a/plugin/plugins/telemetry/telemetry.go b/plugin/plugins/telemetry/telemetry.go index f96fc0805..054cd6601 100644 --- a/plugin/plugins/telemetry/telemetry.go +++ b/plugin/plugins/telemetry/telemetry.go @@ -78,6 +78,7 @@ var uptimeBuckets = []time.Duration{ } // A LogEvent is the object sent to the telemetry endpoint. +// See https://github.com/ipfs/kubo/blob/master/docs/telemetry.md for details. type LogEvent struct { UUID string `json:"uuid"` @@ -91,7 +92,10 @@ type LogEvent struct { UptimeBucket time.Duration `json:"uptime_bucket"` - ReproviderStrategy string `json:"reprovider_strategy"` + ReproviderStrategy string `json:"reprovider_strategy"` + ProvideDHTSweepEnabled bool `json:"provide_dht_sweep_enabled"` + ProvideDHTIntervalCustom bool `json:"provide_dht_interval_custom"` + ProvideDHTMaxWorkersCustom bool `json:"provide_dht_max_workers_custom"` RoutingType string `json:"routing_type"` RoutingAcceleratedDHTClient bool `json:"routing_accelerated_dht_client"` @@ -352,6 +356,7 @@ func (p *telemetryPlugin) Start(n *core.IpfsNode) error { func (p *telemetryPlugin) prepareEvent() { p.collectBasicInfo() p.collectRoutingInfo() + p.collectProvideInfo() p.collectAutoNATInfo() p.collectAutoConfInfo() p.collectSwarmInfo() @@ -360,13 +365,6 @@ func (p *telemetryPlugin) prepareEvent() { p.collectPlatformInfo() } -// Collects: -// * AgentVersion -// * PrivateNetwork -// * RepoSizeBucket -// * BootstrappersCustom -// * UptimeBucket -// * ReproviderStrategy func (p *telemetryPlugin) collectBasicInfo() { p.event.AgentVersion = ipfs.GetUserAgentVersion() @@ -406,8 +404,6 @@ func (p *telemetryPlugin) collectBasicInfo() { break } p.event.UptimeBucket = uptimeBucket - - p.event.ReproviderStrategy = p.config.Provide.Strategy.WithDefault(config.DefaultProvideStrategy) } func (p *telemetryPlugin) collectRoutingInfo() { @@ -416,6 +412,13 @@ func (p *telemetryPlugin) collectRoutingInfo() { p.event.RoutingDelegatedCount = len(p.config.Routing.DelegatedRouters) } +func (p *telemetryPlugin) collectProvideInfo() { + p.event.ReproviderStrategy = p.config.Provide.Strategy.WithDefault(config.DefaultProvideStrategy) + p.event.ProvideDHTSweepEnabled = p.config.Provide.DHT.SweepEnabled.WithDefault(config.DefaultProvideDHTSweepEnabled) + p.event.ProvideDHTIntervalCustom = !p.config.Provide.DHT.Interval.IsDefault() + p.event.ProvideDHTMaxWorkersCustom = !p.config.Provide.DHT.MaxWorkers.IsDefault() +} + type reachabilityHost interface { Reachability() network.Reachability } diff --git a/test/cli/telemetry_test.go b/test/cli/telemetry_test.go index 69b87e80d..ea174d638 100644 --- a/test/cli/telemetry_test.go +++ b/test/cli/telemetry_test.go @@ -205,6 +205,9 @@ func TestTelemetry(t *testing.T) { "repo_size_bucket", "uptime_bucket", "reprovider_strategy", + "provide_dht_sweep_enabled", + "provide_dht_interval_custom", + "provide_dht_max_workers_custom", "routing_type", "routing_accelerated_dht_client", "routing_delegated_count",