mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-10 18:45:53 +00:00
9e37d629ac
Telemetry could see only saved connections, so an install that tried to reach a node and could not was indistinguishable from one that never opened the add-node dialog. Both report zero configured connections and stall at the same activation stage. Fleet data shows that population is real and concentrated three to one in container deployments, and nothing recorded whether those installs attempted a connection at all. Record node connection test attempts and failures in a bounded, day-bucketed tally in the config directory, pruned to a 31-day retention window, and report both over the install-ID rotation window as node_test_attempts_30d and node_test_failures_30d. Recording starts only once a request carries a target and credentials, so an incomplete form is never counted as a node that could not be reached. A host string that turns out to be unusable does count, because the attempt was made and it failed. Only the add-node dialog endpoint is instrumented: instrumenting the unused test-config endpoint as well would double-count a single operator action. The tally holds counts alone. Hosts, credentials, and error text never enter it, which is why it is plain JSON rather than encrypted history.
36 lines
1.2 KiB
Go
36 lines
1.2 KiB
Go
package server
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/rcourtman/pulse-go-rewrite/internal/config"
|
|
"github.com/rcourtman/pulse-go-rewrite/internal/telemetry"
|
|
)
|
|
|
|
// applyNodeTestTelemetrySnapshot adds content-free node connection test counts
|
|
// from the local tally.
|
|
//
|
|
// ConfiguredConnections reports only connections that were saved, so without
|
|
// these an install that tried to reach a node and could not is indistinguishable
|
|
// from one that never opened the add-node dialog: both report zero connections
|
|
// and stall at the "secured" activation stage.
|
|
//
|
|
// The window is the shared install-ID rotation window, the same one the
|
|
// Pulse Intelligence counters use, so no counter outlives the pseudonymous
|
|
// identifier it is reported against.
|
|
func applyNodeTestTelemetrySnapshot(snap *telemetry.Snapshot, persistence *config.ConfigPersistence, now time.Time) {
|
|
if snap == nil || persistence == nil {
|
|
return
|
|
}
|
|
if now.IsZero() {
|
|
now = time.Now()
|
|
}
|
|
tally, err := persistence.LoadNodeTestTally()
|
|
if err != nil || tally == nil {
|
|
return
|
|
}
|
|
since := now.UTC().Add(-telemetry.PulseIntelligenceTelemetryWindow)
|
|
snap.NodeTestAttempts30d = tally.AttemptsSince(since)
|
|
snap.NodeTestFailures30d = tally.FailuresSince(since)
|
|
}
|