openvibers/openvibe.network Commits
Track O: operator status and readiness. GET /status (server-rendered, noindex), /api/v1/status and /api/v1/status/slo; /api/ready with named checks; /metrics (loopback only) with token issuance by grant type and principal-token failures; the registry poll reads each service's readiness and /release.json and reports up|degraded|down|not-running|unknown, never a stale up; openvibe-shared v1.3.0. (Most of this change was swept into 89b67de by a concurrent commit; this adds the README section, the assigned ports of new services and one page fix.)
Changes
@@@ -260,6 +260,29 @@ Google-style account management supporting up to 5 accounts:---++## Observability and status++++- `GET /api/ready`: named checks from `openvibe-shared/ready`, each with `status`, `required`,++ `latency_ms` and `checked_at`. `db` and `signing_key` are required (`signing_key` means an RS256++ keypair that signs and verifies a probe token; it is only optional outside production).++ `registry_poll` and `discord_bot` are optional. The answer is 503 only when a required check fails.++ Otherwise it is 200, with `status: "degraded"` when an optional check has failed.++- `GET /metrics`: Prometheus text for direct loopback callers only. Any proxied request gets a 404,++ and `deploy/nginx` blocks the path too. Besides the HTTP golden signals by route template, it++ exports process metrics and `release_info`. Network's own counters are++ `network_tokens_issued_total{grant_type}`, `network_token_failures_total{grant_type,error}` and++ `network_principal_token_failures_total{code}`.++- `GET /status` is the operator page: server-rendered, no JavaScript needed, `noindex`.++ `GET /api/v1/status` returns the same data as JSON. Each OpenVibe service shows as up, degraded,++ down, not running (placeholder or no runtime) or unknown, with its release, boot time and++ `checked_at`. The data comes from the ecosystem registry poll (`server/registry/ecosystem.js`),++ which reads each service's readiness endpoint and `/release.json` about once a minute. A service++ not checked yet, or whose last check is more than three intervals old, shows as unknown.++- `GET /api/v1/status/slo` returns the proposed SLO categories, as does++ [docs/slo.md](docs/slo.md) / [docs/slo.json](docs/slo.json).++- [docs/patches/live-observability.diff](docs/patches/live-observability.diff) is the same change for++ OpenVibe.Live, to be applied there.++## Shared Client LibrariesThe `openvibe-shared` package ([OpenVibers/OpenVibe.Shared](https://github.com/OpenVibers/OpenVibe.Shared), pinned in package.json) provides drop-in vanilla JS components served at `/shared/` (and `/shared/v1/`). Only the package's browser files are served; a `?v=` equal to a file's content hash is cached for a year, anything else for five minutes:@@@ -27,6 +27,11 @@ const INTERNAL = {network: 'http://127.0.0.1:4000', live: 'http://127.0.0.1:3000', media: 'http://127.0.0.1:4100',tools: 'http://127.0.0.1:4001', games: 'http://127.0.0.1:8000', community: 'http://127.0.0.1:4200',events: 'http://127.0.0.1:4300', billing: 'http://127.0.0.1:4600',++ // Assigned ports of services that are placeholders or new; a placeholder is never polled.++ chat: 'http://127.0.0.1:4400', openre: 'http://127.0.0.1:4500', tips: 'http://127.0.0.1:4610', vip: 'http://127.0.0.1:4620',++ ai: 'http://127.0.0.1:4700', search: 'http://127.0.0.1:4710', sources: 'http://127.0.0.1:4720', wiki: 'http://127.0.0.1:4800',++ blog: 'http://127.0.0.1:4810', news: 'http://127.0.0.1:4820', reviews: 'http://127.0.0.1:4830', deals: 'http://127.0.0.1:4840',++ coupons: 'http://127.0.0.1:4850', trade: 'http://127.0.0.1:4860', codes: 'http://127.0.0.1:4900', host: 'http://127.0.0.1:4910',};const POLL_MS = 60 * 1000;// Readiness paths of services whose manifest (openvibe-contracts) does not carry `ready` yet. Each@@@ -93,7 +93,6 @@ function renderPage(list, slo, generatedAt) {<meta name="robots" content="noindex, nofollow">${require('openvibe-shared/app-icon').headTags({ site: 'network', iconBase: '/assets' })}<meta name="color-scheme" content="dark light">--<script>(function(){try{var raw=localStorage.getItem('ov_theme');if(!raw)return;var t=JSON.parse(raw),v=t&&t.variables;if(!v)return;var el=document.documentElement;for(var k in v)if(k.charAt(0)==='-')el.style.setProperty(k,v[k]);if(t.id)el.setAttribute('data-theme',t.id);}catch(_){}})();</script><script src="/shared/theme-loader.js" defer></script><style>*,*::before,*::after{box-sizing:border-box}
@@ -260,6 +260,29 @@ Google-style account management supporting up to 5 accounts:
@@ -260,6 +260,29 @@ Google-style account management supporting up to 5 accounts:
---
---
+## Observability and status
+
+- `GET /api/ready`: named checks from `openvibe-shared/ready`, each with `status`, `required`,
+ `latency_ms` and `checked_at`. `db` and `signing_key` are required (`signing_key` means an RS256
+ keypair that signs and verifies a probe token; it is only optional outside production).
+ `registry_poll` and `discord_bot` are optional. The answer is 503 only when a required check fails.
+ Otherwise it is 200, with `status: "degraded"` when an optional check has failed.
+- `GET /metrics`: Prometheus text for direct loopback callers only. Any proxied request gets a 404,
+ and `deploy/nginx` blocks the path too. Besides the HTTP golden signals by route template, it
+ exports process metrics and `release_info`. Network's own counters are
+ `network_tokens_issued_total{grant_type}`, `network_token_failures_total{grant_type,error}` and
+ `network_principal_token_failures_total{code}`.
+- `GET /status` is the operator page: server-rendered, no JavaScript needed, `noindex`.
+ `GET /api/v1/status` returns the same data as JSON. Each OpenVibe service shows as up, degraded,
+ down, not running (placeholder or no runtime) or unknown, with its release, boot time and
+ `checked_at`. The data comes from the ecosystem registry poll (`server/registry/ecosystem.js`),
+ which reads each service's readiness endpoint and `/release.json` about once a minute. A service
+ not checked yet, or whose last check is more than three intervals old, shows as unknown.
+- `GET /api/v1/status/slo` returns the proposed SLO categories, as does
+ [docs/slo.md](docs/slo.md) / [docs/slo.json](docs/slo.json).
+- [docs/patches/live-observability.diff](docs/patches/live-observability.diff) is the same change for
+ OpenVibe.Live, to be applied there.
+
## Shared Client Libraries
## Shared Client Libraries
The `openvibe-shared` package ([OpenVibers/OpenVibe.Shared](https://github.com/OpenVibers/OpenVibe.Shared), pinned in package.json) provides drop-in vanilla JS components served at `/shared/` (and `/shared/v1/`). Only the package's browser files are served; a `?v=` equal to a file's content hash is cached for a year, anything else for five minutes:
The `openvibe-shared` package ([OpenVibers/OpenVibe.Shared](https://github.com/OpenVibers/OpenVibe.Shared), pinned in package.json) provides drop-in vanilla JS components served at `/shared/` (and `/shared/v1/`). Only the package's browser files are served; a `?v=` equal to a file's content hash is cached for a year, anything else for five minutes:
@@ -27,6 +27,11 @@ const INTERNAL = {
@@ -27,6 +27,11 @@ const INTERNAL = {
network: 'http://127.0.0.1:4000', live: 'http://127.0.0.1:3000', media: 'http://127.0.0.1:4100',
network: 'http://127.0.0.1:4000', live: 'http://127.0.0.1:3000', media: 'http://127.0.0.1:4100',
tools: 'http://127.0.0.1:4001', games: 'http://127.0.0.1:8000', community: 'http://127.0.0.1:4200',
tools: 'http://127.0.0.1:4001', games: 'http://127.0.0.1:8000', community: 'http://127.0.0.1:4200',
events: 'http://127.0.0.1:4300', billing: 'http://127.0.0.1:4600',
events: 'http://127.0.0.1:4300', billing: 'http://127.0.0.1:4600',
+ // Assigned ports of services that are placeholders or new; a placeholder is never polled.
+ chat: 'http://127.0.0.1:4400', openre: 'http://127.0.0.1:4500', tips: 'http://127.0.0.1:4610', vip: 'http://127.0.0.1:4620',
+ ai: 'http://127.0.0.1:4700', search: 'http://127.0.0.1:4710', sources: 'http://127.0.0.1:4720', wiki: 'http://127.0.0.1:4800',
+ blog: 'http://127.0.0.1:4810', news: 'http://127.0.0.1:4820', reviews: 'http://127.0.0.1:4830', deals: 'http://127.0.0.1:4840',
+ coupons: 'http://127.0.0.1:4850', trade: 'http://127.0.0.1:4860', codes: 'http://127.0.0.1:4900', host: 'http://127.0.0.1:4910',
};
};
const POLL_MS = 60 * 1000;
const POLL_MS = 60 * 1000;
// Readiness paths of services whose manifest (openvibe-contracts) does not carry `ready` yet. Each
// Readiness paths of services whose manifest (openvibe-contracts) does not carry `ready` yet. Each
@@ -93,7 +93,6 @@ function renderPage(list, slo, generatedAt) {
@@ -93,7 +93,6 @@ function renderPage(list, slo, generatedAt) {
<meta name="robots" content="noindex, nofollow">
<meta name="robots" content="noindex, nofollow">
${require('openvibe-shared/app-icon').headTags({ site: 'network', iconBase: '/assets' })}
${require('openvibe-shared/app-icon').headTags({ site: 'network', iconBase: '/assets' })}
<meta name="color-scheme" content="dark light">
<meta name="color-scheme" content="dark light">
-<script>(function(){try{var raw=localStorage.getItem('ov_theme');if(!raw)return;var t=JSON.parse(raw),v=t&&t.variables;if(!v)return;var el=document.documentElement;for(var k in v)if(k.charAt(0)==='-')el.style.setProperty(k,v[k]);if(t.id)el.setAttribute('data-theme',t.id);}catch(_){}})();</script>
<script src="/shared/theme-loader.js" defer></script>
<script src="/shared/theme-loader.js" defer></script>
<style>
<style>
*,*::before,*::after{box-sizing:border-box}
*,*::before,*::after{box-sizing:border-box}