85.1.54. pepsi-telemetry-client¶
per-host feature-telemetry aggregator and submitter
- Manual section:
1
85.1.54.1.1. Name¶
pepsi-telemetry-client - aggregate local feature-usage telemetry and submit it to the central collector.
85.1.54.1.2. Synopsis¶
pepsi-telemetry-client [GLOBAL-OPTIONS] serve
85.1.54.1.3. Description¶
pepsi-telemetry-client is the per-host producer side of Pepsi’s anonymous feature telemetry (the central collector is pepsi-telemetry(1)). It is a small long-lived daemon that:
listens on a local UNIX socket for feature-usage events emitted by the Pepsi programs on the same host (the stage workers and pepsi-ingress(1), via the internal
telemetry_updateAPI);accumulates the events in memory — a per-interval count for each feature plus the cumulative set of features seen this run;
every
SUBMIT_INTERVAL(default: at most once per minute) submits the counts to the collector atTELEMETRY_SERVERunder this deployment’s anonymousSYSTEM_IDand resets the per-interval counts (re-merging them for retry if a submission fails);on shutdown (SIGINT/SIGTERM) makes one final submission so a clean stop does not lose the current interval.
It holds no secrets beyond the anonymous SYSTEM_ID; its only outbound
traffic is HTTPS to the collector. Its database connection (as the pepsi
role) serves two purposes and no others: a LISTEN on the
telemetry_changed channel, and the one-row pepsi.telemetry_client
liveness record described below. Without a database it still works, following
the configuration file on its heartbeat.
Telemetry is opt-in: unless [pepsi] SHARE_TELEMETRY has been set to
yes, the producer API is a no-op that opens no socket and the daemon runs
dormant — it binds no socket, gathers nothing and submits nothing. That is
what an installation which never answered the question gets, whether or not the
service unit is enabled. An absent option, an absent [pepsi] section and an
unparseable value all read as off — “I could not tell” is never consent — and
the switch is consulted before [pepsi-telemetry-client] is parsed at all,
so a typo in a section that cannot matter cannot affect a dormant daemon.
The producer programs connect to the socket lazily and tolerate the daemon being absent (events are simply dropped while it is down), so ordering between the daemon and the rest of the pipeline does not matter.
85.1.54.1.4. Dormant and active¶
The daemon re-reads the configuration file — the file, through the same single
reader of SHARE_TELEMETRY every other component uses — whenever
the
telemetry_changednotification arrives. Whoever rewrites the switch sends it after writing the file, in both directions: pepsi-setup(1) (runand the wizard) and thewrite-configtask ofpepsi-setup apply, through which the browser console changes it. The payload (on/off) is informational; the notification carries no authority, and a notification that disagrees with the file changes nothing;it receives
SIGHUP;its heartbeat fires (every minute), so a hand edit — or a notification missed while the database was away — takes effect within a minute anyway.
Going from dormant to active binds the socket and starts submitting. Going from
active to dormant — consent withdrawn — closes every producer connection,
removes the socket, and discards whatever was gathered and not yet sent
rather than making a final submission. An enabled daemon that cannot submit
(no usable SYSTEM_ID, or a [pepsi-telemetry-client] section that does
not parse) also stays dormant, and says why in its log and in its status row,
instead of exiting into a restart loop.
Producers install their sink once, at start-up. pepsi-dispatch(1) listens on the same channel and retires its stage workers, so the pipeline starts (or stops) reporting without a restart; the long-lived pepsi-ingress(1) and pepsi-httpd(1) start reporting after their next restart. (After switching off nothing they send is received: the socket is gone.)
85.1.54.1.4.1. The status row¶
The daemon keeps one row in pepsi.telemetry_client: whether the file it
last read has telemetry on, whether it is submitting, whether a usable
SYSTEM_ID is configured — a boolean, never the identifier — a short reason
when an enabled daemon is dormant, its version, and a heartbeat refreshed every
minute. A clean stop deletes the row; a row older than three heartbeats reads as
a daemon that is not running. pepsi-httpd(1), which may read the table
and not write it, uses it to decide whether the setup console can offer to
switch telemetry on (see Enabling from the console).
85.1.54.1.5. Enabling the service¶
pepsi.target deliberately does not start
pepsi-telemetry-client.service, unlike the pipeline’s own daemons: the target is
the single switch that starts the pipeline, so a unit it Wantsed would run on
every deployment whatever the operator answered. (The unit is PartOf= the
target, so stopping or restarting pepsi.target stops or restarts the telemetry
client. That direction is wanted; only the pulling-in is not.)
Instead pepsi-setup(1) arms the unit at the end of a successful
pepsi-setup run (which is also what the wizard offers to run for you) when
SHARE_TELEMETRY is on: enable --now. When it is off, setup leaves the
unit exactly as the operator left it — it never starts it, and it no longer stops
it: a running daemon is dormant and submits nothing, and keeping it running is
what lets the browser console offer to switch telemetry on later. Either way
setup then sends the telemetry_changed notification, so a running daemon
follows the new answer at once (turning telemetry off takes effect immediately,
not at the next heartbeat). A deployment that wants no telemetry daemon at all
disables the unit (systemctl disable --now pepsi-telemetry-client.service);
setup never undoes that while the answer is no.
On a host without systemd nothing is done and nothing is said about the unit —
there is no unit to arm. Where systemd does not know the unit (a source install,
say) setup says so only if telemetry is on, since a deployment that opted out has
nothing to do either way. Without root it logs the one systemctl command to
run.
With telemetry on and no valid SYSTEM_ID (setup was run without -c, so
there was nowhere to write one) the unit is armed all the same — the daemon stays
dormant and says why — and setup tells you to re-run pepsi-setup run -c
<FILE> so an identifier can be generated.
85.1.54.1.5.1. Enabling from the console¶
The browser setup console (pepsi-httpd(1)) asks the same
SHARE_TELEMETRY question, but it can only offer “yes” while this daemon is
running and has a usable SYSTEM_ID — the console never generates an
identifier, since minting one without consent is what opt-in rules out. When
either is missing the question is shown disabled, with directions, and an API
client that tries anyway is refused with 409 telemetry_client_not_ready. To
make the console able to switch telemetry on, on the server:
give
[pepsi]an identifier:SYSTEM_ID =followed by 64 hexadecimal characters, e.g. the output ofopenssl rand -hex 32;start the daemon:
systemctl enable --now pepsi-telemetry-client.service. It stays dormant, submitting nothing.
A console save that switches telemetry on then writes the file through the
privileged applier, which notifies the daemon; one that switches it off does the
same in the other direction. Switching off is never refused. A console save also
keeps an existing SYSTEM_ID, whatever the answer: it re-renders the whole
file, and used to drop the identifier (so that switching on again minted a
different one).
85.1.54.1.6. Submitted data¶
Two submissions are made (see pepsi-telemetry(1) for the endpoints):
POST /telemetry/usage— the per-interval feature counts, attributed to the Pepsi version the daemon was built as.POST /telemetry/features— the enabled-feature snapshot, derived from the cumulative set of features seen since the daemon started (a feature is reported enabled once it has been exercised at least once this run).
No personally identifying information is sent; the only identity is the random
256-bit SYSTEM_ID that pepsi-setup(1) generates.
85.1.54.1.7. Configuration¶
Global switches live in [pepsi] (shared with the producers):
SHARE_TELEMETRYMaster on/off switch. Opt-in: the default is
no. Until it is set toyesthe daemon stays dormant and the producer API does nothing.SYSTEM_IDThe anonymous 256-bit identifier (64 hex characters) submitted with every report. Generated automatically by pepsi-setup(1) once
SHARE_TELEMETRYis on — a deployment that has not opted in never has one generated for it; required before the daemon submits anything. An operator may add one by hand while telemetry is off (so that the console can offer the switch); that is the operator’s act, not setup’s.Treat it as write-capability material, not as a public label. The collector never issues it and never checks it beyond its shape, and a
/telemetry/featuressnapshot is authoritative for the(system_id, version)it names: it enables exactly the features it lists and marks every other stored one disabled. So anybody who learns this value can zero, or rewrite, this deployment’s whole contribution to the public report, and can inflate its usage counts. It is a 256-bit random value and is never echoed byGET /telemetry/report, so it cannot be guessed — but it sits inpepsi.conf, so do not paste that section into a bug report, support ticket or pastebin. Anonymity is unaffected either way; what leaks is the ability to forge this deployment’s numbers.TELEMETRY_SERVERCollector host (default
telemetry.pepsi.taler.net). The daemon submits tohttps://<server>/telemetry/{usage,features}. A value containing an explicitscheme://is honoured verbatim (e.g.http://localhost:18080for local testing).
The daemon’s own listener/submission knobs live in [pepsi-telemetry-client]:
UNIXPATHLocal listening socket (default
/run/pepsi-telemetry/socket). This is the same path the producers connect to, so changing it changes both sides.UNIXPATH_GROUP,UNIXPATH_MODEGroup and mode of the socket (defaults
pepsi-telemetryand0660), so thepepsi(stage workers) andpepsi-ingressusers can connect.SUBMIT_INTERVALInterval between submissions (default
60 s). Useh/m/sunits.MAX_FEATURESCap on the number of distinct feature names held in memory (default 4096), bounding memory against a misbehaving local producer.
85.1.54.1.8. Global Options¶
serve is the only subcommand. These global options precede it (a trailing
flag is rejected).
- -c FILE, –config FILE
Read the configuration from FILE instead of searching the default locations (
$XDG_CONFIG_HOME/pepsi.conf,$HOME/.config/pepsi.conf,/etc/pepsi/pepsi.conf,/etc/pepsi.conf). The shipped unit passes-c /etc/pepsi/pepsi.conf.- -L LOGLEVEL, –log LOGLEVEL
Set the logging verbosity. LOGLEVEL is one of
error,warn,info,debugortrace(default:info).- -v, –verbose
Show log messages from all sources, including third-party libraries.
- -h, –help
Print a usage summary and exit.
- -V, –version
Print the version and exit.
85.1.54.1.9. Files¶
/run/pepsi-telemetry/socketDefault UNIX socket the daemon listens on. The daemon creates the socket itself; the directory around it comes from the unit’s
RuntimeDirectory=pepsi-telemetry(mode0755, withRuntimeDirectoryPreserve=yesso a stop does not unlink a socket still bound inside it), and belongs to this unit alone. pepsi-telemetry(1), the collector, listens in/run/pepsi-collectorinstead: systemd chowns a runtime directory and everything in it to the declaring unit’sUser=on every start, so a collector socket in this directory would silently lose the front server’s group whenever this daemon started. Collector and client are meant for separate hosts in any case.
85.1.54.1.10. See also¶
pepsi-telemetry(1), pepsi-ingress(1), pepsi-setup(1), pepsi-httpd(1), pepsi-dispatch(1), pepsi.conf(5).