The collector
At the center of Trove is a single, bundled OpenTelemetry Collector — shipped
as a sidecar binary (trove-otelcol) inside the app and supervised by the Rust
core. Every signal from every harness flows through it; nothing reaches a backend
without passing through it first. This page explains what it does and why a local
collector is the right design.
harnesses ──OTLP──▶ trove-otelcol (127.0.0.1) ──OTLP──▶ your backends receive · normalize · exportWhy a local collector
Section titled “Why a local collector”Pointing each harness directly at your backend works at small scale but breaks down fast. A single local collector solves problems that per-harness direct export can’t:
- Credentials live once. Without a collector, your backend API key ends up copied into every harness’s config and shell rc. With one, the secret lives in exactly one place Trove owns (and in your OS keychain) — rotating a key stops being an archaeology project.
- Buffering. If a backend is down or rate-limited, the collector holds and retries instead of silently dropping telemetry at each source.
- Normalization. Cross-vendor Tier A synthesis happens in one place rather than fighting per-tool namespaces.
- One PII gate and one cardinality bound. Redaction and cardinality control live in a single config you can reason about.
What it does
Section titled “What it does”Receive (localhost only)
Section titled “Receive (localhost only)”The collector runs an OTLP receiver bound to 127.0.0.1 (gRPC on :4317, HTTP on
:4318). It accepts telemetry only from your own machine — it is not a network
service, and it does not listen on any public interface.
Normalize and tag
Section titled “Normalize and tag”As batches pass through, the collector applies Trove’s overlays: it back-fills the
harness.id resource attribute where needed, runs the per-harness
metricstransform blocks that synthesize Tier A metrics
from native signals (using action: insert, so Tier B passes through untouched),
and applies the opt-in identity overlay. These
overlays are exactly what the Mappings tab edits.
Export per backend (fan-out)
Section titled “Export per backend (fan-out)”For each enabled platform, the collector configures a dedicated exporter and broadcasts every signal to all of them at once. Each exporter succeeds or fails independently — which is what lets a single backend’s outage show as a red health pill while the others keep flowing.
Reversible managed regions
Section titled “Reversible managed regions”Trove patches each harness’s config to point it at the collector by writing a managed region — a block bracketed by sentinel comments. That bracket is the entire footprint of an “Enable”: clicking Disable removes the region and restores the file byte-for-byte. The same mechanism applies whether Trove is flipping a native OTLP flag or installing a best-effort shell-rc wrapper (see Harness coverage). Atomic writes mean there are no half-applied states.
Supervised by the Tauri core
Section titled “Supervised by the Tauri core”The collector is not something you start or babysit — the Rust core owns it for the app’s entire lifetime:
- Spawned at startup, with a health probe (the collector’s
health_checkextension on127.0.0.1:13133) confirming it’s actually up before traffic flows. - Restarted on crash, with exponential backoff (starting at 500 ms, capped at 5 s); a run that survives long enough resets the backoff.
- Reloaded on config change — enabling a harness, adding a backend, or applying a mapping regenerates the collector config and triggers a brief reload (a 1–3 second blip is normal).
- Shut down cleanly when you quit the app, so it never orphans into a stray background process.
The current state of this lifecycle is what the Overview tab summarizes and the Logs tab tails.
Files it owns
Section titled “Files it owns”| What | Location (macOS / Linux / Windows) |
|---|---|
| Generated config | collector.yaml in the app support / config directory |
| Log (rotating, 10 MiB cap) | collector.log (+ .1) in the logs / state directory |
| Sidecar binary | next to the app executable as trove-otelcol |
The config is codegen’d from your wizard, harness, platform, and mapping choices — you never hand-edit it, and Trove regenerates it on every relevant change.