.. This file is part of PEPSI. Copyright (C) 2026 GNUnet e.V. PEPSI is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. ====================== pepsi-telemetry-client ====================== *The per-host feature-telemetry aggregator: collects local feature-usage events and submits anonymous aggregates to the central collector.* Role ==== ``pepsi-telemetry-client`` is the *producer* side of Pepsi's anonymous feature telemetry; the central collector is ``pepsi-telemetry``. It ships in the main Pepsi package and runs as a small daemon on every deployment that has telemetry enabled — and, dormant, on one that has not but wants the browser console to be able to switch it on. Run it with ``pepsi-telemetry-client serve``. The Pepsi programs on the host (the stage workers and ``pepsi-ingress``) report feature use through an internal, **non-blocking** ``telemetry_update`` call that hands a short feature name to this daemon over a local UNIX socket — the calling stage never waits on the network. The daemon aggregates those events and submits them to ``TELEMETRY_SERVER`` under the deployment's anonymous ``SYSTEM_ID``. How it works ============ * **Local socket.** The daemon listens on ``[pepsi-telemetry-client] UNIXPATH`` (default ``/run/pepsi-telemetry/socket``, a directory this unit owns alone — the collector listens in ``/run/pepsi-collector``), group-shared with the ``pepsi`` and ``pepsi-ingress`` users. Each producer holds one persistent connection for the lifetime of its process and reconnects if the daemon restarts; events are dropped (best-effort) while it is unreachable, so a producer is never blocked. * **In-memory aggregation.** A per-interval count is kept for each feature, plus the cumulative set of feature names seen since start-up (the enabled-features snapshot). The number of distinct names is capped by ``MAX_FEATURES``. * **Periodic submission.** Every ``SUBMIT_INTERVAL`` (default: at most once per minute) the daemon ``POST``\ s the per-interval counts to ``/telemetry/usage`` and the cumulative feature set to ``/telemetry/features``, then resets the per-interval counts. A failed usage submission is retained and retried next interval rather than lost. * **Clean shutdown.** On SIGINT/SIGTERM it makes one final submission before exiting. * **Dormant while off.** With telemetry off it binds no socket and gathers and submits nothing. It re-reads the configuration *file* on the ``telemetry_changed`` notification — sent, in both directions, by whoever rewrites the switch: ``pepsi-setup`` and the console's ``write-config`` task — on ``SIGHUP``, and every minute, and wakes up or goes back to sleep. Going dormant discards what was gathered and not yet sent. The notification carries no authority; only the file decides. * **Status row.** It keeps one row in ``pepsi.telemetry_client`` (running, enabled, submitting, whether a usable ``SYSTEM_ID`` is configured — a boolean, never the identifier — and a heartbeat), deleted on a clean stop. ``pepsi-httpd`` reads it to decide whether the setup console may offer to switch telemetry on. The daemon stamps each submission with the Pepsi release version it was built as, so the collector counts feature use per release. Configuration ============= The master switch is ``[pepsi] SHARE_TELEMETRY``, and it is **off by default**: telemetry is opt-in, so an installation that never answered the question runs no telemetry at all. Until it is set to ``yes`` the daemon stays dormant and the in-process ``telemetry_update`` calls are no-ops that open no socket — the whole path is inert whether or not the service unit is enabled. ``[pepsi] SYSTEM_ID`` (generated by :doc:`pepsi-setup`, but only once the switch is on) and ``TELEMETRY_SERVER`` (default ``telemetry.pepsi.taler.net``) complete the global configuration. The daemon's own listener and timing knobs are in ``[pepsi-telemetry-client]``: ``UNIXPATH`` (default ``/run/pepsi-telemetry/socket``), ``UNIXPATH_MODE`` (default ``0660``), ``UNIXPATH_GROUP`` (default ``pepsi-telemetry``, the group ``pepsi`` and ``pepsi-ingress`` are added to), ``SUBMIT_INTERVAL`` (default 60 s, which must use ``h``/``m``/``s`` units and may not be zero) and ``MAX_FEATURES`` (default 4096). See :manpage:`pepsi-telemetry-client(1)` and :manpage:`pepsi.conf(5)` for the full list. Enabling the service ==================== The unit is deliberately **not** started by ``pepsi.target``, unlike the pipeline's own daemons (it is ``PartOf=`` the target, so stopping or restarting the target does reach it): the target is the single switch that starts the pipeline, and a unit named there would run on every deployment whatever the operator answered. ``pepsi-setup run`` instead arms the unit at the end of a successful run when the switch is on (``systemctl enable --now``); when it is off it leaves the unit as the operator left it — never starting it, and no longer stopping it, because a running daemon is dormant and is what the console needs. Either way it then sends ``telemetry_changed``, so turning telemetry off takes effect at once. With the switch on and no valid ``SYSTEM_ID`` the unit is armed anyway; the daemon stays dormant and says why. On a host without systemd nothing is done (there is no unit to arm); where systemd does not know the unit, setup says so only when telemetry is on; without root it logs the one ``systemctl`` command to run. Enabling it from the console ---------------------------- The browser setup console offers "yes" only while the daemon is running and a ``SYSTEM_ID`` is configured; otherwise the question is disabled with directions, and an API request to switch on is refused (``409 telemetry_client_not_ready``). The console never generates an identifier. To let it offer the switch, on the server add ``SYSTEM_ID =`` and 64 hexadecimal characters (e.g. ``openssl rand -hex 32``) to ``[pepsi]`` and run ``systemctl enable --now pepsi-telemetry-client.service``. A console save keeps an existing identifier whatever the answer. Privacy ======= No personally identifying information leaves the host. The only identity is the random 256-bit ``SYSTEM_ID``; the payloads are feature names and counts. Nothing is shared unless an operator asks for it: the switch defaults to off, the setup wizard asks the question with ``no`` as the default answer, and no identifier is generated for a deployment that has not opted in. An operator who has opted in can stop sharing again by setting ``SHARE_TELEMETRY = NO`` — in the console, or in the file followed by ``pepsi-setup run`` (or ``SIGHUP``, or a minute's wait): the daemon then goes dormant and discards what it had not sent — or by stopping/disabling the ``pepsi-telemetry-client`` service directly. See also ======== :doc:`pepsi-telemetry` (the collector), :doc:`pepsi-setup`, :manpage:`pepsi-telemetry-client(1)`, :manpage:`pepsi.conf(5)`.