From 3efca89525472c7c967941e352eaad5a01c74a48 Mon Sep 17 00:00:00 2001 From: "courtmanr@gmail.com" Date: Mon, 27 Jul 2026 11:09:29 +0100 Subject: [PATCH] Document external probes and count adoption in telemetry Add availability_probe_targets and availability_probe_agents to the telemetry ping - counts only, no agent names or addresses - with the disclosure table updated in both privacy doc copies. Document the feature in the availability-checks configuration guide and the unified agent guide, including the ICMP capability caveat for containerized probes. Co-Authored-By: Claude Fable 5 --- docs/CONFIGURATION.md | 16 ++++++++++++++++ docs/PRIVACY.md | 2 ++ docs/UNIFIED_AGENT.md | 25 +++++++++++++++++++++++++ frontend-modern/public/docs/PRIVACY.md | 2 ++ internal/telemetry/telemetry.go | 9 +++++++++ pkg/server/server.go | 8 ++++++++ 6 files changed, 62 insertions(+) diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index bc89181c3..010c97934 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -502,6 +502,22 @@ Example API payload for simple ping monitoring: Pulse stores and returns that target as `protocol: "icmp"` so dashboards, alerts, and resource projections keep one canonical protocol value. +### External probes (Pro) + +By default every availability check runs from the Pulse server itself, which +means a check cannot report the one failure that matters most: the site +running Pulse losing its connectivity. With the Pro `external_probe` +entitlement, a check can instead be assigned to any connected Pulse agent +(`probeAgentId` in the API, "Run from" in the UI) — for example an agent on a +cloud VM or at another site. The assigned agent receives the check through +its signed agent configuration, runs it on the configured interval, and +reports results back with its reports; results are only accepted from the +currently assigned agent. An assigned check is not also run locally. If no +report arrives for several intervals the check shows as indeterminate +("no recent report from probe agent"), and if the entitlement lapses the +check automatically resumes running from the Pulse server. Checks without an +assignment are unaffected and remain available in every edition. + ### ICMP probe privileges ICMP probes run the system `ping` binary, which needs the `CAP_NET_RAW` diff --git a/docs/PRIVACY.md b/docs/PRIVACY.md index f5bb054ae..c0f2f0268 100644 --- a/docs/PRIVACY.md +++ b/docs/PRIVACY.md @@ -82,6 +82,8 @@ Every field is listed below with the reason it exists. Nothing else is included | VMware VMs | `35` | Understand VMware vSphere VM monitoring adoption in aggregate | | VMware datastores | `4` | Understand VMware datastore visibility adoption in aggregate | | Availability targets | `9` | Understand agentless availability-check adoption in aggregate | +| Availability probe targets | `2` | Understand external-probe adoption in aggregate; counts only, no agent names or addresses | +| Availability probe agents | `1` | Understand how many distinct probe agents installs deploy; counts only | | AI enabled | `true`/`false` | See whether AI features are actually used before expanding or removing them | | Patrol enabled | `true`/`false` | See whether proactive AI health patrol is used | | Discovery enabled | `true`/`false` | See whether network or model-backed discovery is used | diff --git a/docs/UNIFIED_AGENT.md b/docs/UNIFIED_AGENT.md index 6353eec69..d96e42b63 100644 --- a/docs/UNIFIED_AGENT.md +++ b/docs/UNIFIED_AGENT.md @@ -84,9 +84,34 @@ curl -fsSL http://:7655/install.sh | \ - **Host Metrics**: CPU, memory, disk, network I/O, temperatures - **Docker Monitoring**: Container metrics, health checks, Swarm support (when enabled) - **Kubernetes Monitoring**: Cluster, node, pod, and deployment health (when enabled) +- **External Probes** (Pro): runs availability checks assigned to this agent from the Pulse server and reports the results back — see below - **Auto-Update**: Automatically updates when a new version is released - **Multi-Platform**: Linux, macOS, Windows support +## External Probes (Pro) + +With the Pro `external_probe` entitlement, availability checks configured in +Pulse can be assigned to run from a specific agent instead of the Pulse +server (Settings -> Monitoring -> Availability checks -> "Run from"). This is +how you monitor a site from the outside: deploy the agent on a machine +elsewhere — a cloud VM, a Docker host at another location — and assign checks +to it. Alerting still happens on the Pulse server through your normal alert +routes. + +There is nothing to configure on the agent itself. Assignments arrive through +the agent's signed remote configuration, the agent runs each check on its +configured interval, and results are delivered with its regular reports. +Results survive temporary connectivity loss to the Pulse server in a bounded +in-memory queue; if the agent cannot deliver for several check intervals the +check shows as indeterminate in Pulse until reports resume. The module +appears as `availability` in the agent's module status when at least one +check is assigned. + +Note for ICMP (ping) checks: the probe uses the system `ping` binary. In +containers or hardened service units without `CAP_NET_RAW`, ICMP checks fail; +prefer TCP or HTTP checks there, or grant the capability. See "ICMP probe +privileges" in docs/CONFIGURATION.md. + ## Configuration | Flag | Env Var | Description | Default | diff --git a/frontend-modern/public/docs/PRIVACY.md b/frontend-modern/public/docs/PRIVACY.md index f5bb054ae..c0f2f0268 100644 --- a/frontend-modern/public/docs/PRIVACY.md +++ b/frontend-modern/public/docs/PRIVACY.md @@ -82,6 +82,8 @@ Every field is listed below with the reason it exists. Nothing else is included | VMware VMs | `35` | Understand VMware vSphere VM monitoring adoption in aggregate | | VMware datastores | `4` | Understand VMware datastore visibility adoption in aggregate | | Availability targets | `9` | Understand agentless availability-check adoption in aggregate | +| Availability probe targets | `2` | Understand external-probe adoption in aggregate; counts only, no agent names or addresses | +| Availability probe agents | `1` | Understand how many distinct probe agents installs deploy; counts only | | AI enabled | `true`/`false` | See whether AI features are actually used before expanding or removing them | | Patrol enabled | `true`/`false` | See whether proactive AI health patrol is used | | Discovery enabled | `true`/`false` | See whether network or model-backed discovery is used | diff --git a/internal/telemetry/telemetry.go b/internal/telemetry/telemetry.go index c88e936b1..ee558053e 100644 --- a/internal/telemetry/telemetry.go +++ b/internal/telemetry/telemetry.go @@ -25,6 +25,7 @@ // - Number of Pulse Agent hosts, Docker hosts/containers, and Kubernetes clusters/nodes/pods/deployments // - Number of storage resources, physical disks, Ceph clusters, and network shares // - Number of TrueNAS systems/VMs/apps, VMware hosts/VMs/datastores, and availability targets +// - Number of availability targets assigned to external probes, and of distinct probe agents // // Feature usage (booleans and counts, no content): // - Whether AI features are enabled @@ -204,6 +205,10 @@ type Ping struct { VMwareVMs int `json:"vmware_vms"` VMwareDatastores int `json:"vmware_datastores"` AvailabilityTargets int `json:"availability_targets"` + // Probe-assignment counts stay counts-only: no agent names, IDs, or + // addresses leave the install. + AvailabilityProbeTargets int `json:"availability_probe_targets"` + AvailabilityProbeAgents int `json:"availability_probe_agents"` // Feature usage (booleans and counts — no content) AIEnabled bool `json:"ai_enabled"` @@ -336,6 +341,8 @@ type Snapshot struct { VMwareVMs int VMwareDatastores int AvailabilityTargets int + AvailabilityProbeTargets int + AvailabilityProbeAgents int AIEnabled bool PatrolEnabled bool DiscoveryEnabled bool @@ -898,6 +905,8 @@ func applySnapshot(base Ping, fn SnapshotFunc) Ping { ping.VMwareVMs = s.VMwareVMs ping.VMwareDatastores = s.VMwareDatastores ping.AvailabilityTargets = s.AvailabilityTargets + ping.AvailabilityProbeTargets = s.AvailabilityProbeTargets + ping.AvailabilityProbeAgents = s.AvailabilityProbeAgents ping.AIEnabled = s.AIEnabled ping.PatrolEnabled = s.PatrolEnabled ping.DiscoveryEnabled = s.DiscoveryEnabled diff --git a/pkg/server/server.go b/pkg/server/server.go index 9f1dd9438..fb7ea4881 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -499,6 +499,14 @@ func Run(ctx context.Context, version string) error { } if targets, err := telemetryPersistence.LoadAvailabilityTargets(); err == nil { snap.ConfiguredConnections += len(targets) + probeAgents := make(map[string]struct{}) + for _, target := range targets { + if agentID := strings.TrimSpace(target.ProbeAgentID); agentID != "" { + snap.AvailabilityProbeTargets++ + probeAgents[agentID] = struct{}{} + } + } + snap.AvailabilityProbeAgents = len(probeAgents) } // Resource counts come from the tenant-aware monitor aggregate, not the