Operate a fleet
Everything here assumes the agent is already installed and publishing. Start with Install, Send one metric, and Verify it.
Command surface
The installed constellation-agent utility has a deliberately small surface:
constellation-agent {status|verify|test|debug on|off|logs [lines]}
constellation-agent emit <measurement> --entity-id <id> [--tag k=v] [--field k=v]
verify, test, and debug require root because they read the agent credential or write systemd drop-ins. status, logs, and emit do not.
Install, upgrade, and uninstall are handled by the installer script, not by this binary.
Status
sudo constellation-agent status
This is a passthrough to systemctl --no-pager --full status telegraf.
The systemd unit is named telegraf, not constellation-agent. The agent is a Telegraf process running a Constellation configuration, so every ordinary systemd verb targets telegraf:
sudo systemctl restart telegraf
sudo systemctl stop telegraf
sudo systemctl is-enabled telegraf
Logs
sudo constellation-agent logs # last 100 lines
sudo constellation-agent logs 500 # last 500 lines
sudo constellation-agent logs -f # follow
These wrap journalctl -u telegraf -o cat. The -o cat format drops journald's hostname prefix, which matters: with debug mode on, the agent writes raw line protocol to the log, and a hostname prefix would make those lines un-greppable by measurement name. Telegraf timestamps its own lines, so nothing is lost.
Grep for a specific measurement or entity:
sudo constellation-agent logs 2000 | grep ground_station
sudo constellation-agent logs -f | grep GS-001
Verification
verify is the only command that proves the full path. It writes a proof metric to the live socket and then polls the topology API until the same proof value is read back:
sudo constellation-agent verify
Success:
READY: telemetry proof verify-1785528000-4821 was read back
The two distinct failures tell you where the path broke:
| Output | Meaning |
|---|---|
FAIL: telemetry socket is missing | The agent is not running, or the socket was never created. Check status. |
FAIL: metric entered the local socket but proof … was not read back | Local handoff worked; delivery or ingest did not. Check logs and egress. |
Run verify after install, after any credential or egress change, and as a periodic fleet health check.
Testing without touching the live socket
test exercises the encode-and-write path against a scratch socket:
sudo constellation-agent test
It prints testing against a scratch socket; the live socket is untouched. Use it when you want to validate the agent's local behavior on a node that is actively publishing and must not be disturbed.
Debug mode
Debug mode makes the agent log every metric it processes as raw line protocol.
sudo constellation-agent debug on # -> debug output ON -- follow with: constellation-agent logs -f
sudo constellation-agent debug off # -> debug output OFF
sudo constellation-agent debug # -> reports current state
debug on writes a systemd drop-in and a Telegraf config fragment:
/etc/telegraf/telegraf.d/zz-constellation-debug.conf
/etc/systemd/system/telegraf.service.d/debug.conf
Turn it back off when you are done. Debug mode logs the full body of every metric, which is both a volume and a confidentiality consideration on a busy node.
Upgrades
Install and upgrade are the same command:
curl -fsSL https://install.constellation.space/agent | \
sudo env CONSTELLATION_API_TOKEN="$CONSTELLATION_API_TOKEN" sh
Two properties matter when re-running it on a live node:
- The socket path is stable across upgrades. Publishers keep the same
/run/constellation-agent/telemetry.sock. - An existing node identity wins. The installer resolves
entity_idin this order —CONSTELLATION_ENTITY_ID, then the value already in/etc/constellation/agent.env, then/etc/machine-id, then the hostname. Recomputing it on every run would silently re-key an already-registered node the first time an operator forgot the env var, and its console asset would go stale with no error anywhere.
machine-id is preferred over hostname because hostnames are neither unique nor stable: a fleet cloned from one image commonly shares one, which would merge every node's health into a single topology entity.
The agent restarts as part of an upgrade. Long-lived publishers must reconnect — see connection reuse.
If Telegraf already exists on the host
The installer replaces telegraf.service's ExecStart with Constellation's own config, which silently stops any inputs or outputs an existing Telegraf was running for other purposes. It refuses to do this automatically: if it finds a Telegraf it did not install itself, or one whose version does not match the pin, it fails with instructions rather than take over unannounced.
CONSTELLATION_ALLOW_TELEGRAF_TAKEOVER=1 # adopt an existing installation
CONSTELLATION_ALLOW_TELEGRAF_VERSION_MISMATCH=1 # proceed against an unverified version
This only applies to a Telegraf the installer did not itself provision. Re-running the installer on a node it already manages is the ordinary upgrade path above and needs neither variable.
Credentials
The API token is written to a root-only file at install time:
/etc/constellation/agent.env file mode 0600, root-readable only
It holds CONSTELLATION_API_URL, CONSTELLATION_API_TOKEN, CONSTELLATION_ENTITY_ID, CONSTELLATION_AGENT_VERSION, and CONSTELLATION_ENDPOINT.
The socket location is written separately and is world-readable, because every publishing application needs to read it:
/etc/constellation/socket.env contains only CONSTELLATION_SOCKET_PATH
Keeping these in two files is what lets an application discover the socket without ever being able to read the credential.
To rotate the token, re-run the installer with the new value:
curl -fsSL https://install.constellation.space/agent | \
sudo env CONSTELLATION_API_TOKEN="$NEW_TOKEN" sh
The existing entity_id is preserved, so the node keeps its console identity.
Granting and revoking application access
Access is by membership in the constellation group:
sudo usermod -aG constellation constellation-publisher # grant
sudo gpasswd -d constellation-publisher constellation # revoke
Group changes do not affect a running process. The application needs a new login or a service restart before the change takes effect — this is the single most common cause of a Permission denied that "should" already be fixed.
The runtime directory is created by systemd-tmpfiles as mode 2770, owned telegraf:constellation, so it is group-traversable and the socket is group-writable. It is recreated correctly after a reboot.
Buffering
The agent buffers locally when the API is unreachable and drains when it returns.
| Setting | Default | Env var |
|---|---|---|
| Buffer strategy | disk | CONSTELLATION_BUFFER_STRATEGY |
| Flush interval | 1s | CONSTELLATION_FLUSH_INTERVAL |
| Metric buffer limit | 100,000 | agent config |
| Metric batch size | 500 | agent config |
Choosing a strategy is a real trade-off:
disksurvives an agent or node restart, but fsyncs per metric. That caps sustained ingest near 290 metrics/s on NVMe, and lower on eMMC or SD storage.memoryis far faster but loses at most oneflush_intervalof telemetry if the node dies.
On-disk buffered telemetry lives at:
/var/lib/constellation/buffer
Delivery latency is roughly flush_interval plus a fixed transit/ingest floor: measured ~0.3s at a 200ms flush interval and ~0.6s at the 1s default. Lower CONSTELLATION_FLUSH_INTERVAL for latency-sensitive fleets and raise it for high-volume ones; the cost is request rate per node. Both egress paths land within noise of each other at a given value.
Egress
CONSTELLATION_EGRESS=grpc # default
CONSTELLATION_EGRESS=http
The default installation downloads and runs a Constellation gRPC egress component (/usr/local/bin/telegraf-constellation-grpc) via Telegraf's outputs.execd. The component retries transient RPC failures with exponential backoff while holding the batch and blocking further reads from Telegraf. Permanent rejections are logged once and dropped; partial acceptance is logged and not retried because retrying would duplicate accepted records. The optional HTTP path keeps acknowledgement and retry inside Telegraf's own outputs.http — no custom binary, no compiled artifact, just a config file — at the cost of a larger payload than gRPC's typed encoding.
Describe the agent accurately when you document your own deployment: it uses Telegraf for local collection and buffering, with a Constellation egress component present by default. It is not "stock Telegraf with a config" unless HTTP egress is explicitly selected.
Install-time environment variables
| Variable | Default | Effect |
|---|---|---|
CONSTELLATION_API_TOKEN | — | Required. Data-plane credential. |
CONSTELLATION_API_URL | https://api.constellation.space | Platform endpoint. |
CONSTELLATION_ENTITY_ID | machine-id, then hostname | Node identity. An existing value wins. |
CONSTELLATION_EGRESS | grpc | grpc or http. |
CONSTELLATION_BUFFER_STRATEGY | disk | disk or memory. |
CONSTELLATION_FLUSH_INTERVAL | 1s | Collector flush cadence. |
CONSTELLATION_TELEGRAF_VERSION | 1.39.2 | Pinned collector version. |
CONSTELLATION_TELEGRAF_PACKAGE | — | Local .deb/.rpm for an air-gapped install; requires CONSTELLATION_TELEGRAF_SIGNATURE. |
CONSTELLATION_TELEGRAF_SIGNATURE | — | Local InfluxData .asc signature, required alongside CONSTELLATION_TELEGRAF_PACKAGE. |
CONSTELLATION_CLI_PACKAGE | — | Local constellation-agent CLI binary, air-gapped installs. |
CONSTELLATION_GRPC_PACKAGE | — | Local gRPC egress binary, air-gapped installs (needed by default unless CONSTELLATION_EGRESS=http). |
CONSTELLATION_INFLUXDATA_KEY | — | Local InfluxData signing key; otherwise fetched from repos.influxdata.com. |
CONSTELLATION_ALLOW_TELEGRAF_TAKEOVER | 0 | Set 1 to adopt a pre-existing Telegraf the installer did not provision. |
CONSTELLATION_ALLOW_TELEGRAF_VERSION_MISMATCH | 0 | Set 1 to proceed against an existing Telegraf whose version doesn't match the pin. |
CONSTELLATION_ARTIFACT_BASE | release URL for the agent version | Override artifact download base. |
CONSTELLATION_ENDPOINT | — | Optional explicit ingest endpoint. |
A fully offline install needs every artifact supplied locally — copying only the Telegraf package is not enough and will fail partway through. Each local override still has its checksum verified the same way a network fetch would.
Uninstall
Uninstall is a flag on the installer script, not a subcommand of the binary:
curl -fsSL https://install.constellation.space/agent | sudo sh -s -- --uninstall
This stops the unit and removes the Constellation configuration, the systemd drop-ins (including any left by debug on), the tmpfiles rule, /usr/local/bin/constellation-agent, the gRPC egress binary, and both env files. What happens to Telegraf itself depends on who provisioned it — see If Telegraf already exists on the host:
# if this installer provisioned Telegraf itself:
uninstalled (Telegraf package retained but disabled; --purge removes buffered telemetry)
# if Telegraf predated this installer:
restoring the host's pre-existing telegraf.service
uninstalled (Telegraf package and prior config retained; --purge removes buffered telemetry)
In both cases the Telegraf package itself is intentionally left installed, and buffered telemetry is intentionally left on disk. To remove those too:
curl -fsSL https://install.constellation.space/agent | sudo sh -s -- --uninstall --purge
--purge additionally deletes /var/lib/constellation/buffer and removes the now-empty /var/lib/constellation, /etc/constellation, and /run/constellation-agent directories. Any telemetry still queued at that point is destroyed, not delivered. Drain first if it matters.
Files the agent owns
| Path | Purpose |
|---|---|
/usr/local/bin/constellation-agent | The operator utility. |
/usr/local/bin/telegraf-constellation-grpc | gRPC egress component (gRPC egress only). |
/etc/constellation/agent.env | Credential and identity, file mode 0600. |
/etc/constellation/socket.env | Socket path, world-readable. |
/etc/telegraf/telegraf.d/constellation.conf | Collection and egress configuration. |
/etc/telegraf/telegraf.d/zz-constellation-debug.conf | Present only while debug mode is on. |
/etc/systemd/system/telegraf.service.d/constellation.conf | Unit drop-in binding the config and env files. |
/usr/lib/tmpfiles.d/constellation-agent.conf | Recreates the runtime directory after reboot. |
/run/constellation-agent/telemetry.sock | The ingest socket. |
/var/lib/constellation/buffer | On-disk telemetry buffer. |
Related
- Install — install the service and grant publisher access
- Send one metric — validate the local write path
- Verify it — prove end-to-end delivery
- Equipment contracts — the ACU and modem payloads a poller reads before it ever gets here, field by field
- Socket protocol — the publishing contract and its limits
- Troubleshooting — diagnosing a node that is not delivering