mirror of
https://github.com/screentinker/screentinker.git
synced 2026-08-14 14:23:14 -06:00
Three changes, all about the same failure: sharing appears to be on while nothing actually arrives. SEND ON OPT-IN. Turning sharing on now reports immediately instead of waiting for the next daily tick. Two reasons: the operator is standing right there, and "nothing has been sent" for the next 24h reads as broken at exactly the moment someone is checking whether it works. It also means an egress-filtered network fails HERE, where we can name the host to unblock, rather than silently tonight where nobody is watching. NAME THE FAILURE. Failed attempts are now recorded separately from successes, so Settings can say which address did not answer and why, instead of showing an empty "nothing sent yet". A blocked outbound connection is the normal failure on a self-hosted box and is otherwise completely invisible — the operator cannot tell a firewall from a broken feature. A later success clears the complaint, so a stale warning never outlives the problem it describes. Docs gained a section on it, and the UI states plainly that nothing needs opening inbound. OPERATOR COLLECTOR, ADDITIVE. TELEMETRY_EXTRA_ENDPOINT lets an operator post the same three fields to their own collector. The naming is the point. It replaces TELEMETRY_ENDPOINT, which was a true override — and an override is the wrong shape here, because a variable called "endpoint" that silently redirected the report someone agreed to SHARE would make the opt-in mean something other than what the UI says. Our address is hard-wired and not overridable; theirs is explicitly additional and named so it cannot be mistaken for a replacement. Settings lists every destination a report goes to. The operator collector is independent of the sharing switch, because it is their server posting to their host and our opt-in has no business gating it. So an operator who wants internal fleet numbers with nothing leaving for us sets it and leaves sharing off — supported on purpose, and tested. Destinations are attempted separately: one unreachable collector must not cost the other its report. 1662/1662 pass. Tests pin the properties that matter: an operator collector never replaces the shared report, sharing-off still sends nothing to us whatever else is configured, one dead destination does not stop the other, and a failure records the address actually tried.
113 lines
5 KiB
Markdown
113 lines
5 KiB
Markdown
# Install statistics
|
|
|
|
ScreenTinker can optionally report how many screens an install runs. It is **off until you turn it
|
|
on**, and this page documents the whole of it.
|
|
|
|
---
|
|
|
|
## What is sent
|
|
|
|
Three fields. This is the complete payload:
|
|
|
|
```json
|
|
{
|
|
"instance_id": "9f2c1b6e-4a17-4c8e-9d3b-27a5e0f81c44",
|
|
"version": "1.9.34",
|
|
"screen_count": 42
|
|
}
|
|
```
|
|
|
|
| Field | What it is |
|
|
|---|---|
|
|
| `instance_id` | A random UUID generated by your server on first use and kept in its own database. It carries no information about you — its only job is to let two reports from the same server be recognised as the same server, so a count is a count rather than a sum of duplicates. |
|
|
| `version` | The ScreenTinker version this server is running. |
|
|
| `screen_count` | How many displays have been paired with this server. |
|
|
|
|
## What is not sent
|
|
|
|
No hostnames, IP addresses or domains. No organization, workspace or user names. No email
|
|
addresses and no user count. No device names, locations or serial numbers. No content, filenames,
|
|
playlists or schedules. No logs and no configuration.
|
|
|
|
The request is sent over HTTPS, and the receiving service does not record the source address.
|
|
|
|
## Verifying that
|
|
|
|
Rather than take the above on trust:
|
|
|
|
- **In the product** — Settings → Install statistics shows the exact payload your server would
|
|
send, generated live from your own data, plus what it last actually sent and when.
|
|
- **In the source** — the payload is built in one function, `payload()` in
|
|
[`server/lib/telemetry.js`](../server/lib/telemetry.js). Every field that leaves your server
|
|
is in that object literal. `server/test/telemetry.test.js` fails if a field is added.
|
|
- **On the wire** — the destination is a single `POST`, overridable with `TELEMETRY_ENDPOINT`, so
|
|
you can point it at your own collector and read exactly what arrives.
|
|
|
|
## Turning it on or off
|
|
|
|
You are asked once, on the dashboard, if you are a platform administrator. Both answers are
|
|
remembered, so declining is permanent and you will not be asked again after an update.
|
|
|
|
To change your mind at any time: **Settings → Install statistics**.
|
|
|
|
Reports are sent 5 minutes after the server starts, then once a day while it keeps running.
|
|
Nothing is queued or retried — if your server is offline or the request fails, that attempt is
|
|
simply skipped.
|
|
|
|
## If your outbound traffic is filtered
|
|
|
|
Reports are an ordinary HTTPS `POST` from your server to:
|
|
|
|
```
|
|
https://stats.screentinker.com/api/telemetry/report
|
|
```
|
|
|
|
Many self-hosted servers sit on networks that block outbound connections by default. **If yours
|
|
does, that address has to be allowed or the reports never arrive** — sharing will appear to be on
|
|
while nothing reaches us.
|
|
|
|
You do not have to guess whether that is happening. Turning sharing on sends a report immediately,
|
|
so a blocked connection is reported there and then, and **Settings → Install statistics** names the
|
|
failure and the address to allow.
|
|
|
|
Nothing needs to be opened *inbound*. This is an outbound connection from your server only.
|
|
|
|
## Keeping your own copy
|
|
|
|
If you want these numbers for your own fleet, set `TELEMETRY_EXTRA_ENDPOINT` to your own collector.
|
|
Your server then posts the same three fields there as well.
|
|
|
|
Two things to be clear about, because the naming is deliberate:
|
|
|
|
- **It is additional, not a redirect.** Setting it does not stop the shared report going to
|
|
ScreenTinker — that is why it is called `EXTRA` rather than `ENDPOINT`. Settings lists every
|
|
destination a report goes to, so what is configured is always visible.
|
|
- **It is independent of the sharing switch.** Your collector receives reports whether sharing is
|
|
on or off, because that is your server posting to your host. **If you want your own statistics
|
|
and nothing sent to us, set it and leave sharing off** — that combination is supported on purpose.
|
|
|
|
Each destination is attempted separately, so one being unreachable never stops the other.
|
|
|
|
## Why we ask
|
|
|
|
ScreenTinker is self-hostable, so most installs are invisible to us by design, and that is how it
|
|
should stay. The cost is that we genuinely cannot answer "how many screens run this?" — a question
|
|
that matters for arguing the project is worth continuing to build, and for deciding which players
|
|
deserve the next round of work.
|
|
|
|
Sharing is a small, specific way to help with that. Declining is a completely reasonable answer and
|
|
changes nothing about how the product works.
|
|
|
|
> **A note on honesty.** Because sharing is opt-in, any total we publish is a **floor** — "at least
|
|
> N screens" — never an estimate of the whole install base. Instances that opt in are not a random
|
|
> sample of those that don't, so the number is not something to extrapolate from, and we won't.
|
|
|
|
## Running your own collector
|
|
|
|
Set `TELEMETRY_COLLECTOR=1` and this server accepts reports at `POST /api/telemetry/report`,
|
|
storing them in a `telemetry_reports` table keyed by `instance_id`. The endpoint is inert unless
|
|
that variable is set, so a normal install never exposes it.
|
|
|
|
Reports are upserted rather than appended — one row per install holding its latest report, not a
|
|
growing event log.
|