# How the AgentsView Telemetry Reporting Mechanism Works and What Data It Collects

> Discover how AgentsView telemetry reporting works. Learn what data is collected and how it's sent to PostHog using the Kit telemetry package.

- Repository: [Kenn Software/agentsview](https://github.com/kenn-io/agentsview)
- Tags: internals
- Published: 2026-07-04

---

**AgentsView uses the Kit telemetry package to send a lightweight `daemon_active` event to PostHog once every 24 hours, transmitting only a randomized install ID and build metadata when the `AGENTSVIEW_TELEMETRY_ENABLED` environment variable is explicitly set.**

The open-source **AgentsView** project (kenn-io/agentsview) implements a minimal, privacy-focused telemetry reporting mechanism designed to track daemon health without compromising user privacy. The system leverages the Kit telemetry library to transmit whitelisted events to PostHog, but only activates when explicitly enabled via environment variables and skips all reporting during test execution.

## Environment-Based Enablement

Telemetry remains **disabled by default**. The system only activates when the `AGENTSVIEW_TELEMETRY_ENABLED` environment variable (or the generic `KIT_TELEMETRY_ENABLED` from the underlying Kit framework) evaluates to a truthy value.

In [`internal/telemetry/telemetry.go`](https://github.com/kenn-io/agentsview/blob/main/internal/telemetry/telemetry.go) (lines 41-43), the helper `EnabledFromEnv` checks this flag before allowing any reporter initialization:

```go
// EnabledFromEnv checks if telemetry is enabled via environment variables
func EnabledFromEnv() bool {
    // Checks AGENTSVIEW_TELEMETRY_ENABLED or KIT_TELEMETRY_ENABLED
}

```

If the flag is unset or falsy, `NewReporterOrDisabled` returns a no-op reporter that silently discards all events.

## Reporter Initialization and Install ID Generation

At program startup, the `main` function in [`cmd/agentsview/main.go`](https://github.com/kenn-io/agentsview/blob/main/cmd/agentsview/main.go) (lines 170-176) constructs the reporter via `telemetry.NewReporterOrDisabled`, passing a populated `telemetry.Options` struct containing the data directory, binary version, and Git commit hash.

During construction, the reporter generates or retrieves a unique **install ID** to identify the machine without exposing personal data. The `loadOrCreateInstallID` function in [`internal/telemetry/telemetry.go`](https://github.com/kenn-io/agentsview/blob/main/internal/telemetry/telemetry.go) (lines 40-52) checks for an existing UUID in the specified `DataDir`. If none exists, `randomInstallID` (lines 85-92) generates a new random UUID that persists across daemon restarts.

The reporter then initializes the underlying `PostHogReporter` through `newKitReporter` (lines 120-132), passing the install ID, version string, and commit hash to `kittelemetry.NewPostHogReporter`.

## Strict Event Whitelisting

AgentsView enforces a strict whitelist of permissible events. The `allowedEventOptions` map in [`internal/telemetry/telemetry.go`](https://github.com/kenn-io/agentsview/blob/main/internal/telemetry/telemetry.go) (lines 134-138) currently permits only a single event type:

```go
var allowedEventOptions = map[string]bool{
    "daemon_active": true,
}

```

Any attempt to capture non-whitelisted events is rejected by the reporter, ensuring that only the `daemon_active` heartbeat can be transmitted to the analytics server.

## Data Payload and Privacy Guarantees

Each `daemon_active` event transmits a minimal payload containing exactly five fields:

- **distinct_id**: The persistent install UUID generated during initialization
- **application**: Hard-coded string `"agentsview"`
- **env_prefix**: Hard-coded string `"AGENTSVIEW"` for logical grouping
- **version**: The binary version supplied at startup
- **commit**: The Git commit hash supplied at startup

The system intentionally excludes user-specific data, session identifiers, IP addresses, or system telemetry. The `CaptureDaemonActive` method in [`internal/telemetry/telemetry.go`](https://github.com/kenn-io/agentsview/blob/main/internal/telemetry/telemetry.go) (lines 82-93) constructs this payload and forwards it to the PostHog client only after verifying telemetry is enabled and the code is not running under `go test`.

## 24-Hour Periodic Reporting Loop

Once initialized, the reporter starts a background ticker via `startTelemetryPings` with a hardcoded interval of 24 hours (`telemetryPingInterval`). Every tick, the system invokes `captureTelemetryPing`, which calls `Reporter.CaptureDaemonActive`.

This method includes safeguards to prevent test environment pollution: it explicitly checks that the binary is not executing under `go test` before transmitting the event. Errors during capture are logged but do not interrupt daemon operation.

## Graceful Shutdown and Event Flushing

When the server receives a termination signal, the defer chain in [`cmd/agentsview/main.go`](https://github.com/kenn-io/agentsview/blob/main/cmd/agentsview/main.go) calls `Reporter.Close()` to flush any queued events to PostHog. The `Close` method in [`internal/telemetry/telemetry.go`](https://github.com/kenn-io/agentsview/blob/main/internal/telemetry/telemetry.go) (lines 13-18) ensures the underlying PostHog client drains its buffer before the process exits, preventing data loss during shutdown.

## Implementation Examples

The following patterns demonstrate how to interact with the telemetry system in AgentsView.

Initialize the reporter as done in the main binary:

```go
opts := telemetry.Options{
    DataDir:  "/path/to/telemetry",
    Version:  buildVersion,
    Commit:   buildCommit,
}
telemetryReporter := telemetry.NewReporterOrDisabled(opts)
defer telemetryReporter.Close()

```

Capture a daemon-active ping using the internal helper pattern:

```go
func captureTelemetryPing(ctx context.Context, reporter *telemetry.Reporter) {
    if err := reporter.CaptureDaemonActive(ctx); err != nil {
        log.Printf("capture telemetry event: %v", err)
    }
}

```

Manually validate and send events (only whitelisted events succeed):

```go
if reporter.EventAllowed(telemetry.EventDaemonActive) {
    props, _ := reporter.SanitizeProperties(telemetry.EventDaemonActive, map[string]any{
        "extra": "value",
    })
    _ = reporter.client.Capture(telemetry.EventDaemonActive, props)
}

```

## Summary

- **Opt-in activation**: Telemetry requires explicit enablement via `AGENTSVIEW_TELEMETRY_ENABLED` or `KIT_TELEMETRY_ENABLED` environment variables.
- **Minimal data collection**: Only the `daemon_active` event is permitted, sending a randomized install ID and build metadata (version, commit).
- **Privacy protection**: No user-specific data, session information, or system telemetry is transmitted.
- **24-hour reporting**: The daemon reports activity once per day via a background ticker.
- **Test exclusion**: The reporter automatically disables itself when running under `go test`.
- **Graceful shutdown**: The `Close()` method ensures all queued events flush to PostHog before process termination.

## Frequently Asked Questions

### Is telemetry enabled by default in AgentsView?

No. The telemetry reporting mechanism is opt-in only. Unless you explicitly set the `AGENTSVIEW_TELEMETRY_ENABLED` or `KIT_TELEMETRY_ENABLED` environment variable to a truthy value, the system initializes a disabled reporter that discards all events without transmitting network traffic.

### What identifying information does AgentsView collect?

The system collects only a randomized UUID (the **install ID**) generated during first startup and stored in the data directory, along with static build metadata including the binary version and Git commit hash. No username, hostname, IP address, or session data is included in the payload.

### How frequently does the daemon report telemetry?

AgentsView transmits the `daemon_active` event exactly once every 24 hours via a background ticker initialized in [`cmd/agentsview/main.go`](https://github.com/kenn-io/agentsview/blob/main/cmd/agentsview/main.go). The interval is hardcoded as `telemetryPingInterval = 24 * time.Hour` in the telemetry package.

### Can I verify what data is being sent before enabling telemetry?

Yes. You can inspect the `allowedEventOptions` map and `CaptureDaemonActive` method in [`internal/telemetry/telemetry.go`](https://github.com/kenn-io/agentsview/blob/main/internal/telemetry/telemetry.go) (lines 82-138) to confirm the exact payload structure. The source code explicitly limits transmissions to the five documented fields: `distinct_id`, `application`, `env_prefix`, `version`, and `commit`.