stat.flexfs
stat.flexfs collects usage statistics from admin servers, stores them in its database, and, when SMTP is configured, sends periodic usage reports by email. In the monthly report email, customers billed by someone else, such as AWS Marketplace customers, are listed in a separate section per biller with its own total, are not included in the invoicing total, and their report files are placed in a billed-by-<biller> folder in the attached archive. Wherever a customer billed by someone else is named, on the dashboard and in reports, the biller follows the name, as in Acme (AWS). A biller’s section is omitted in months where its customers have no cost. It also manages license grants that are returned to admin servers as part of the stats relay flow.
Persistent Flags
Section titled “Persistent Flags”These flags apply to every subcommand. Flag names on every subcommand are matched case-insensitively and ignoring hyphens.
| Flag | Type | Default | Description | Visibility |
|---|---|---|---|---|
--reportErrors | bool | false | Report errors and panics to Paradigm4 | Public |
Subcommands
Section titled “Subcommands”| Subcommand | Description | Visibility |
|---|---|---|
completion | Generate a shell autocompletion script | Public |
deinit creds | Remove the credentials file | Public |
deinit systemd | Remove the systemd service unit | Public |
init creds | Initialize the credentials file | Public |
init systemd | Create and enable a systemd service unit | Public |
license | Print license information | Public |
start | Start the statistics server | Public |
version | Print the build version | Public |
deinit creds
Section titled “deinit creds”stat.flexfs deinit creds [flags]Removes the credentials file for the stat server. If the credentials file is referenced by a systemd unit, the command refuses unless --force is passed, in which case it removes the references too. deinit on its own does the same thing as deinit creds.
| Flag | Type | Default | Description | Visibility |
|---|---|---|---|---|
--credsFile | string | ~/.flexfs/stat/creds | Credentials file path | Public |
--force | bool | false | Remove creds even if referenced by systemd (removes references too) | Public |
deinit systemd
Section titled “deinit systemd”sudo stat.flexfs deinit systemdRemoves the systemd service unit (flexfs-stat.service) for the stat server. Requires root.
init creds
Section titled “init creds”stat.flexfs init creds [flags]Initializes a credentials file for the stat server with the marketplace API token and SMTP settings for usage reports. SMTP is optional: without --smtpAddr, no usage report email is sent. With --smtpAddr, --smtpFrom and --smtpTo are required, and --smtpUser requires --smtpPass; any other SMTP flag without --smtpAddr is refused. With nothing set, no file is written, and with --force an existing file is removed. init on its own does the same thing as init creds.
| Flag | Type | Default | Description | Visibility |
|---|---|---|---|---|
--credsFile | string | ~/.flexfs/stat/creds | Credentials file path | Public |
--force | bool | false | Overwrite existing credentials file | Public |
--marketplaceToken | string | "" | Marketplace API token, a UUID (prompts if omitted; empty = marketplace API disabled) | Public |
--smtpAddr | string | "" | SMTP server address (empty = no report email) | Public |
--smtpFrom | string | "" | SMTP from email address (required with --smtpAddr) | Public |
--smtpPass | string | "" | SMTP server password (prompts if omitted and a username is set) | Public |
--smtpTo | string | "" | SMTP to email addresses, comma-separated (required with --smtpAddr) | Public |
--smtpUser | string | "" | SMTP server username (required only for authenticated relays) | Public |
init systemd
Section titled “init systemd”sudo stat.flexfs init systemd [flags]Creates and enables a systemd service unit (flexfs-stat.service) for the stat server. Requires root. Optional: the server can also be run directly with start by any user. The service runs as root, so it uses root’s /root/.flexfs defaults, credentials included, unless --startFlags names other paths.
| Flag | Type | Default | Description | Visibility |
|---|---|---|---|---|
--force | bool | false | Overwrite existing systemd unit file | Public |
--now | bool | false | Start the service immediately after enabling | Public |
--startFlags | string | "" | Additional flags to pass to the start command | Public |
stat.flexfs start [flags]Starts the statistics server, binding the endpoint that admin servers relay usage to. It can start without a credentials file. SMTP values from the file or the internal override flags follow the same rules as init creds. Any user can run it, and ~ in the defaults is that user’s home folder. A non-root user needs a --bindAddr port above 1023.
| Flag | Type | Default | Description | Visibility |
|---|---|---|---|---|
--bindAddr | string | 0.0.0.0:443 | Address and port to bind | Public |
--credsFile | string | ~/.flexfs/stat/creds | Credentials file path | Public |
--dbFolder | string | ~/.flexfs/stat | Database folder path | Public |
--keyFolder | string | ~/.flexfs/license | Signing key folder path | Public |
--marketplaceToken | string | "" | Marketplace API token (overrides credentials file) | Internal |
--mockTime | bool | false | Simulate time as 5 minutes after last reported_at | Internal |
--noSSL | bool | false | Serve the stat endpoint over plain HTTP | Public |
--pprof | bool | false | Enable pprof profiler | Internal |
--pprofPort | int | 6067 | Pprof server port | Internal |
--smtpAddr | string | "" | SMTP server address (overrides credentials file) | Internal |
--smtpFrom | string | "" | SMTP from email address (overrides credentials file) | Internal |
--smtpPass | string | "" | SMTP server password (overrides credentials file) | Internal |
--smtpTo | string | "" | SMTP to email addresses (overrides credentials file) | Internal |
--smtpUser | string | "" | SMTP server username (overrides credentials file) | Internal |
--sqliteOpts | string | _journal=WAL&_cache_size=10240&_fk=true&_timeout=5000 | SQLite database connection options | Internal |
--sslCert | string | ~/.flexfs/ssl/cert | SSL certificate file path. A self-signed certificate and key are created if neither exists. | Public |
--sslKey | string | ~/.flexfs/ssl/key | SSL private key file path | Public |
--verbose, -v | bool | false | Enable verbose logging | Public |
Hourly statistics
Section titled “Hourly statistics”Metadata servers report volume statistics at the top of each hour, and admin servers relay them to the stat server. With each relay attempt, admin servers send a Report-Age header with the number of seconds since they received the report. The stat server subtracts that from its own clock, so reports delayed by relay retries or outages of up to 24 hours are recorded under the correct hour regardless of the reporting host’s clock. Reports without the header, or older than 24 hours, are filed by their arrival time instead. AWS Marketplace metering meters each hour about 2 hours after it ends, so it includes reports for that hour that arrive by then.
A report is filed under an hour if its time falls from 10 minutes before that hour until 50 minutes after it, so a report at 09:59:58 or 10:03:00 is recorded as the 10:00 report. A warning is logged when a report’s time is more than 2 minutes before the hour, which usually means the reporting host’s clock is fast.
Only one report per volume is recorded for each hour. A repeated report for the same hour, such as a retry, replaces the earlier one and is answered normally. A volume listed more than once in the same report is recorded once, from its last entry, and a warning is logged.
When SMTP is configured, the monthly report email is sent at 03:01 UTC on the 1st, after late reports for the previous month’s last hours have arrived.
Grants and suspended customers
Section titled “Grants and suspended customers”Admin servers post usage to POST /v1/stats and receive a license grant valid for up to 12 hours in return, signed with the private.pem in --keyFolder. If that file is missing or cannot be used, the statistics are still recorded and the request is answered with 204 and no grant. A customer can have grants suspended through the marketplace API. A suspended customer’s statistics are still recorded, but the request is answered with 403 and no grant, and the admin server discards its current grant, so the customer’s volumes become read-only. The Enterprise installer reports this as subscription is not active.
Usage report endpoint
Section titled “Usage report endpoint”GET /v1/reports generates and emails the monthly usage reports on demand. It only accepts requests made directly to the stat server from the same host (a loopback address with no X-Forwarded-For, X-Real-IP, or Forwarded header) and answers 403 otherwise. Without SMTP configured, it answers 503. When the stat server runs behind a reverse proxy on the same host, the proxy must set X-Real-IP or X-Forwarded-For on every request it forwards.
Marketplace API
Section titled “Marketplace API”Marketplace integration servers such as aws.flexfs use these endpoints to manage customers. They are enabled only when marketplaceToken is set, and every request must send Authorization: Bearer <marketplaceToken>. With no token configured, they answer 503. The grants, rate bins, and usage endpoints only act on customers created with a billed_by value, and answer 404 for any other customer, so the token cannot affect directly invoiced customers.
| Endpoint | Body | Response | Description |
|---|---|---|---|
POST /v1/customers | {"billed_by": "AWS", "id": "<uuid>", "name": "...", "rate_bins": {"0": 0.10}} | 201 {"id": "<license key>"}, or 200 if a customer with that id exists | Create a customer; name, billed_by (who bills the customer), and rate bin 0 are required, and rates must not be negative; id (a lowercase UUID) is optional and makes the request safe to repeat |
PUT /v1/customers/{id}/grants | {"suspended": true} | 204 | Suspend or resume license grants for a customer; suspended is required |
PUT /v1/customers/{id}/rate-bins | {"rate_bins": {"0": 0.10, "6": 0.05}} | 204 | Replace a customer’s rate bins; rate bin 0 is required and rates must not be negative; statistics already recorded keep the rates they were recorded with |
GET /v1/customers/{id}/usage?from=<unix>&to=<unix> | 200 [{"hour": 0, "hours_in_month": 744, "size_bins": {"0": 0}}] | Hourly bytes per size bin summed across volumes, and the number of hours in that hour’s month, for hours in [from, to); hours without statistics are omitted; the range is limited to 31 days |