From bd3cb73d6daaa846edecad35d8376d9e8a6a482e Mon Sep 17 00:00:00 2001 From: Alexander Mattoni <5110855+mattoni@users.noreply.github.com> Date: Tue, 16 Jun 2026 17:11:42 +0000 Subject: [PATCH] add new telemetry types --- .gitignore | 6 +- .../servers/telemetry/ServerTelemetryCpu.yml | 13 + .../telemetry/ServerTelemetryMemory.yml | 272 ++++++++++++++++++ .../telemetry/ServerTelemetryProcessor.yml | 51 ++++ .../telemetry/ServerTelemetrySnapshot.yml | 21 ++ package-lock.json | 26 +- platform/api.yml | 6 + .../servers/telemetry/stream.yml | 48 ++++ 8 files changed, 423 insertions(+), 20 deletions(-) create mode 100644 components/schemas/infrastructure/servers/telemetry/ServerTelemetryCpu.yml create mode 100644 components/schemas/infrastructure/servers/telemetry/ServerTelemetryMemory.yml create mode 100644 components/schemas/infrastructure/servers/telemetry/ServerTelemetryProcessor.yml create mode 100644 components/schemas/infrastructure/servers/telemetry/ServerTelemetrySnapshot.yml create mode 100644 platform/paths/infrastructure/servers/telemetry/stream.yml diff --git a/.gitignore b/.gitignore index 83bb89bd..f8edd8d0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ dist/ node_modules -.turbo \ No newline at end of file +.turbo + +.resources +.postman +postman/ \ No newline at end of file diff --git a/components/schemas/infrastructure/servers/telemetry/ServerTelemetryCpu.yml b/components/schemas/infrastructure/servers/telemetry/ServerTelemetryCpu.yml new file mode 100644 index 00000000..a1271327 --- /dev/null +++ b/components/schemas/infrastructure/servers/telemetry/ServerTelemetryCpu.yml @@ -0,0 +1,13 @@ +type: object +title: ServerTelemetryCpu +description: CPU telemetry for the server. +required: + - processors +properties: + processors: + type: + - array + - "null" + description: Per-processor telemetry for each logical processor on the server. Null if processor information is unavailable. + items: + $ref: ./ServerTelemetryProcessor.yml diff --git a/components/schemas/infrastructure/servers/telemetry/ServerTelemetryMemory.yml b/components/schemas/infrastructure/servers/telemetry/ServerTelemetryMemory.yml new file mode 100644 index 00000000..596de7f7 --- /dev/null +++ b/components/schemas/infrastructure/servers/telemetry/ServerTelemetryMemory.yml @@ -0,0 +1,272 @@ +type: object +title: ServerTelemetryMemory +description: >- + Memory telemetry for the server, mirroring the kernel's /proc/meminfo. Unless + noted otherwise, all values are reported in kibibytes (kB). The huge_pages_* + fields are page counts rather than sizes. +required: + - mem_total + - mem_free + - mem_available + - buffers + - cached + - swap_cached + - active + - inactive + - active_anon + - inactive_anon + - active_file + - inactive_file + - unevictable + - mlocked + - swap_total + - swap_free + - dirty + - write_back + - anon_pages + - mapped + - shmem + - slab + - s_reclaimable + - s_unclaim + - kernel_stack + - page_tables + - nfs_unstable + - bounce + - writeback_tmp + - commit_limit + - committed_as + - vmalloc_total + - vmalloc_used + - vmalloc_chunk + - hardware_corrupted + - anon_huge_pages + - huge_pages_total + - huge_pages_free + - huge_pages_rsvd + - huge_pages_surp + - hugepagesize + - direct_map_4k + - direct_map_2M + - direct_map_1G +properties: + mem_total: + type: integer + format: int64 + minimum: 0 + description: Total usable RAM (physical memory minus reserved bytes and the kernel binary), in kB. + mem_free: + type: integer + format: int64 + minimum: 0 + description: Amount of physical RAM left completely unused, in kB. + mem_available: + type: integer + format: int64 + minimum: 0 + description: Estimate of memory available for starting new applications without swapping, in kB. + buffers: + type: integer + format: int64 + minimum: 0 + description: Temporary storage for raw disk blocks, in kB. + cached: + type: integer + format: int64 + minimum: 0 + description: Page cache for files read from disk, excluding swap cache, in kB. + swap_cached: + type: integer + format: int64 + minimum: 0 + description: Memory that was swapped out and has been swapped back in but is still also present in the swap file, in kB. + active: + type: integer + format: int64 + minimum: 0 + description: Memory used more recently and usually not reclaimed unless necessary, in kB. + inactive: + type: integer + format: int64 + minimum: 0 + description: Memory used less recently and more eligible for reclaim, in kB. + active_anon: + type: integer + format: int64 + minimum: 0 + description: Anonymous (non-file-backed) memory on the active list, in kB. + inactive_anon: + type: integer + format: int64 + minimum: 0 + description: Anonymous (non-file-backed) memory on the inactive list, in kB. + active_file: + type: integer + format: int64 + minimum: 0 + description: File-backed memory on the active list, in kB. + inactive_file: + type: integer + format: int64 + minimum: 0 + description: File-backed memory on the inactive list, in kB. + unevictable: + type: integer + format: int64 + minimum: 0 + description: Memory that cannot be reclaimed, such as mlocked pages and ramfs, in kB. + mlocked: + type: integer + format: int64 + minimum: 0 + description: Memory locked into RAM with mlock() and therefore unswappable, in kB. + swap_total: + type: integer + format: int64 + minimum: 0 + description: Total amount of swap space available, in kB. + swap_free: + type: integer + format: int64 + minimum: 0 + description: Amount of swap space currently unused, in kB. + dirty: + type: integer + format: int64 + minimum: 0 + description: Memory waiting to be written back to disk, in kB. + write_back: + type: integer + format: int64 + minimum: 0 + description: Memory actively being written back to disk, in kB. + anon_pages: + type: integer + format: int64 + minimum: 0 + description: Non-file-backed pages mapped into user-space page tables, in kB. + mapped: + type: integer + format: int64 + minimum: 0 + description: Files that have been mapped into memory, such as libraries, in kB. + shmem: + type: integer + format: int64 + minimum: 0 + description: Memory used by shared memory (shmem) and tmpfs, in kB. + slab: + type: integer + format: int64 + minimum: 0 + description: In-kernel data structure cache, in kB. + s_reclaimable: + type: integer + format: int64 + minimum: 0 + description: Portion of Slab that can be reclaimed under memory pressure, in kB. + s_unclaim: + type: integer + format: int64 + minimum: 0 + description: Portion of Slab that cannot be reclaimed under memory pressure, in kB. + kernel_stack: + type: integer + format: int64 + minimum: 0 + description: Memory used by the kernel stacks of all tasks, in kB. + page_tables: + type: integer + format: int64 + minimum: 0 + description: Memory used by page tables, in kB. + nfs_unstable: + type: integer + format: int64 + minimum: 0 + description: NFS pages sent to the server but not yet committed to stable storage, in kB. Reported as 0 on modern kernels. + bounce: + type: integer + format: int64 + minimum: 0 + description: Memory used for block-device bounce buffers, in kB. + writeback_tmp: + type: integer + format: int64 + minimum: 0 + description: Memory used by FUSE for temporary writeback buffers, in kB. + commit_limit: + type: integer + format: int64 + minimum: 0 + description: Total amount of memory currently available to be allocated, based on the overcommit ratio, in kB. + committed_as: + type: integer + format: int64 + minimum: 0 + description: Total amount of memory presently allocated across the system, in kB. + vmalloc_total: + type: integer + format: int64 + minimum: 0 + description: Total size of the vmalloc memory area, in kB. + vmalloc_used: + type: integer + format: int64 + minimum: 0 + description: Amount of the vmalloc area currently in use, in kB. + vmalloc_chunk: + type: integer + format: int64 + minimum: 0 + description: Largest contiguous free block of the vmalloc area, in kB. + hardware_corrupted: + type: integer + format: int64 + minimum: 0 + description: Amount of memory flagged as corrupted by the hardware, in kB. + anon_huge_pages: + type: integer + format: int64 + minimum: 0 + description: Anonymous memory backed by transparent huge pages, in kB. + huge_pages_total: + type: integer + format: int64 + minimum: 0 + description: Total number of huge pages in the pool (a count, not a size). + huge_pages_free: + type: integer + format: int64 + minimum: 0 + description: Number of huge pages in the pool that are not yet allocated (a count, not a size). + huge_pages_rsvd: + type: integer + format: int64 + minimum: 0 + description: Number of huge pages reserved for allocation but not yet allocated (a count, not a size). + huge_pages_surp: + type: integer + format: int64 + minimum: 0 + description: Number of surplus huge pages above the configured base pool size (a count, not a size). + hugepagesize: + type: integer + format: int64 + minimum: 0 + description: Size of a single huge page, in kB. + direct_map_4k: + type: integer + format: int64 + minimum: 0 + description: Amount of memory mapped into the kernel address space using 4 kB pages, in kB. + direct_map_2M: + type: integer + format: int64 + minimum: 0 + description: Amount of memory mapped into the kernel address space using 2 MB pages, in kB. + direct_map_1G: + type: integer + format: int64 + minimum: 0 + description: Amount of memory mapped into the kernel address space using 1 GB pages, in kB. diff --git a/components/schemas/infrastructure/servers/telemetry/ServerTelemetryProcessor.yml b/components/schemas/infrastructure/servers/telemetry/ServerTelemetryProcessor.yml new file mode 100644 index 00000000..85b8bedd --- /dev/null +++ b/components/schemas/infrastructure/servers/telemetry/ServerTelemetryProcessor.yml @@ -0,0 +1,51 @@ +type: object +title: ServerTelemetryProcessor +description: Telemetry for a single logical processor on the server, as reported by the kernel via /proc/cpuinfo. +required: + - id + - vendor_id + - model + - model_name + - flags + - cores + - mhz + - physical_id + - core_id +properties: + id: + type: integer + format: int64 + description: The logical processor index (the "processor" entry in /proc/cpuinfo). + vendor_id: + type: string + description: The CPU vendor identifier string, e.g. "GenuineIntel" or "AuthenticAMD". + model: + type: integer + format: int64 + description: The numeric CPU model identifier within the vendor's family. + model_name: + type: string + description: The human-readable CPU model name, e.g. "Intel(R) Xeon(R) CPU E5-2690 v4 @ 2.60GHz". + flags: + type: + - array + - "null" + description: The CPU feature flags reported for this processor (e.g. fpu, sse, avx). Null if not reported. + items: + type: string + cores: + type: integer + format: int64 + description: The number of physical cores in the package this processor belongs to. + mhz: + type: number + format: double + description: The current clock speed of this processor, in MHz. + physical_id: + type: integer + format: int64 + description: The identifier of the physical package (socket) this processor belongs to. + core_id: + type: integer + format: int64 + description: The identifier of the core within the physical package. diff --git a/components/schemas/infrastructure/servers/telemetry/ServerTelemetrySnapshot.yml b/components/schemas/infrastructure/servers/telemetry/ServerTelemetrySnapshot.yml new file mode 100644 index 00000000..1807b8ef --- /dev/null +++ b/components/schemas/infrastructure/servers/telemetry/ServerTelemetrySnapshot.yml @@ -0,0 +1,21 @@ +type: object +title: ServerTelemetrySnapshot +description: A single frame of server telemetry, pushed over the server telemetry websocket. +required: + - generated + - cpu + - memory +properties: + generated: + $ref: "../../../DateTime.yml" + description: The timestamp at which this telemetry snapshot was generated. + cpu: + description: CPU telemetry for this snapshot. Null when CPU telemetry is unavailable. + oneOf: + - $ref: ./ServerTelemetryCpu.yml + - type: "null" + memory: + description: Memory telemetry for this snapshot. Null when memory telemetry is unavailable. + oneOf: + - $ref: ./ServerTelemetryMemory.yml + - type: "null" diff --git a/package-lock.json b/package-lock.json index b8c53929..d82adf99 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,11 +9,11 @@ "version": "1.0.0", "license": "Apache-2.0", "devDependencies": { - "@apidevtools/json-schema-ref-parser": "^11.5.4", + "@apidevtools/json-schema-ref-parser": "11.5.4", "@redocly/cli": "2.14.3", - "@types/node": "^20.12.7", - "@types/yamljs": "^0.2.34", - "yamljs": "^0.3.0" + "@types/node": "20.12.7", + "@types/yamljs": "0.2.34", + "yamljs": "0.3.0" } }, "node_modules/@apidevtools/json-schema-ref-parser": { @@ -271,7 +271,6 @@ "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", "dev": true, "license": "Apache-2.0", - "peer": true, "engines": { "node": ">=8.0.0" } @@ -808,7 +807,6 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -1692,7 +1690,6 @@ "integrity": "sha512-UczzB+0nnwGotYSgllfARAqWCJ5e/skuV2K/l+Zyck/H6pJIhLXuBnz+6vn2i211o7DtbE78HQtsYEKICHGI+g==", "dev": true, "license": "MIT", - "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/mobx" @@ -2174,7 +2171,6 @@ "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -2185,7 +2181,6 @@ "integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -2667,7 +2662,6 @@ "integrity": "sha512-1v/e3Dl1BknC37cXMhwGomhO8AkYmN41CqyX9xhUDxry1ns3BFQy2lLDRQXJRdVVWB9OHemv/53xaStimvWyuA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@emotion/is-prop-valid": "1.2.2", "@emotion/unitless": "0.8.1", @@ -3218,8 +3212,7 @@ "version": "1.9.0", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", - "dev": true, - "peer": true + "dev": true }, "@opentelemetry/api-logs": { "version": "0.202.0", @@ -3608,7 +3601,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, - "peer": true, "requires": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -4229,8 +4221,7 @@ "version": "6.15.0", "resolved": "https://registry.npmjs.org/mobx/-/mobx-6.15.0.tgz", "integrity": "sha512-UczzB+0nnwGotYSgllfARAqWCJ5e/skuV2K/l+Zyck/H6pJIhLXuBnz+6vn2i211o7DtbE78HQtsYEKICHGI+g==", - "dev": true, - "peer": true + "dev": true }, "mobx-react": { "version": "9.2.0", @@ -4536,15 +4527,13 @@ "version": "19.2.3", "resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz", "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==", - "dev": true, - "peer": true + "dev": true }, "react-dom": { "version": "19.2.3", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz", "integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==", "dev": true, - "peer": true, "requires": { "scheduler": "^0.27.0" } @@ -4886,7 +4875,6 @@ "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.19.tgz", "integrity": "sha512-1v/e3Dl1BknC37cXMhwGomhO8AkYmN41CqyX9xhUDxry1ns3BFQy2lLDRQXJRdVVWB9OHemv/53xaStimvWyuA==", "dev": true, - "peer": true, "requires": { "@emotion/is-prop-valid": "1.2.2", "@emotion/unitless": "0.8.1", diff --git a/platform/api.yml b/platform/api.yml index 07a16c33..330a2493 100644 --- a/platform/api.yml +++ b/platform/api.yml @@ -644,6 +644,8 @@ paths: $ref: "./paths/infrastructure/servers/server.yml" "/v1/infrastructure/servers/{serverId}/telemetry": $ref: "./paths/infrastructure/servers/telemetry.yml" + "/v1/infrastructure/servers/{serverId}/telemetry/stream": + $ref: "./paths/infrastructure/servers/telemetry/stream.yml" "/v1/infrastructure/servers/{serverId}/instances": $ref: "./paths/infrastructure/servers/instances.yml" "/v1/infrastructure/servers/{serverId}/tasks": @@ -784,6 +786,10 @@ components: in: header type: apiKey description: Defines the scope of the request to a specific Hub. + schemas: + # This is a webhook only type for now, but we want it included in the output. + ServerTelemetrySnapshot: + $ref: ../components/schemas/infrastructure/servers/telemetry/ServerTelemetrySnapshot.yml webhooks: environmentMetricsPush: diff --git a/platform/paths/infrastructure/servers/telemetry/stream.yml b/platform/paths/infrastructure/servers/telemetry/stream.yml new file mode 100644 index 00000000..fc49ae18 --- /dev/null +++ b/platform/paths/infrastructure/servers/telemetry/stream.yml @@ -0,0 +1,48 @@ +# Component file +get: + operationId: "getServerTelemetryStreamAuth" + summary: Server Telemetry Stream Authorization + description: | + Retrieves an access token and URL to open a websocket to for streaming server telemetry live. + This connects directly to the server and streams telemetry in real time, with a new snapshot + pushed approximately every 5 seconds. + + Open a WebSocket to the returned `address`, passing the token as the `token` query parameter + (e.g. `wss://
?token=