mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-06-14 04:17:00 +00:00
Update 1.2.2.1 beta
This commit is contained in:
@@ -31,6 +31,7 @@ export default async function SystemOverviewTabPage({
|
||||
const messages = (await getMessages({ locale })) as unknown as {
|
||||
docs: { monitor: { dashboard: { systemOverview: {
|
||||
topRow: { rows: TopRow[]; thresholdsItems: string[] }
|
||||
processes: { listItems: string[]; detailItems: string[] }
|
||||
bottom: { storageItems: string[] }
|
||||
refresh: { items: string[] }
|
||||
dataCollected: { rows: DataRow[] }
|
||||
@@ -40,6 +41,8 @@ export default async function SystemOverviewTabPage({
|
||||
const so = messages.docs.monitor.dashboard.systemOverview
|
||||
const topRows = so.topRow.rows
|
||||
const thresholdsItems = so.topRow.thresholdsItems
|
||||
const processListItems = so.processes.listItems
|
||||
const processDetailItems = so.processes.detailItems
|
||||
const storageItems = so.bottom.storageItems
|
||||
const refreshItems = so.refresh.items
|
||||
const dataRows = so.dataCollected.rows
|
||||
@@ -135,6 +138,58 @@ export default async function SystemOverviewTabPage({
|
||||
{t("topRow.sparklineBody")}
|
||||
</Callout>
|
||||
|
||||
<h2 className="text-2xl font-semibold mt-10 mb-4 text-gray-900">{t("processes.heading")}</h2>
|
||||
<p className="mb-4 text-gray-800 leading-relaxed">
|
||||
{t.rich("processes.intro", { code })}
|
||||
</p>
|
||||
|
||||
<h3 className="text-lg font-semibold mt-6 mb-2 text-gray-900">{t("processes.listTitle")}</h3>
|
||||
<ul className="list-disc pl-6 mb-4 text-gray-800 leading-relaxed space-y-1">
|
||||
{processListItems.map((_, idx) => (
|
||||
<li key={idx}>{t.rich(`processes.listItems.${idx}`, { strong })}</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<figure className="my-6">
|
||||
<img
|
||||
src="/monitor/system-overview-top-processes.png"
|
||||
alt={t("processes.captureListAlt")}
|
||||
className="rounded-lg border border-gray-200 shadow-sm w-full"
|
||||
/>
|
||||
<figcaption className="text-sm text-gray-500 mt-2 text-center italic">
|
||||
{t("processes.captureListCaption")}
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
<h3 className="text-lg font-semibold mt-6 mb-2 text-gray-900">{t("processes.detailTitle")}</h3>
|
||||
<p className="mb-4 text-gray-800 leading-relaxed">
|
||||
{t.rich("processes.detailIntro", { code })}
|
||||
</p>
|
||||
<ul className="list-disc pl-6 mb-4 text-gray-800 leading-relaxed space-y-1">
|
||||
{processDetailItems.map((_, idx) => (
|
||||
<li key={idx}>{t.rich(`processes.detailItems.${idx}`, { strong, code })}</li>
|
||||
))}
|
||||
</ul>
|
||||
<p className="mb-4 text-gray-800 leading-relaxed">
|
||||
{t.rich("processes.detailRefresh", { em, code })}
|
||||
</p>
|
||||
|
||||
<figure className="my-6">
|
||||
<img
|
||||
src="/monitor/system-overview-process-detail.png"
|
||||
alt={t("processes.captureDetailAlt")}
|
||||
className="rounded-lg border border-gray-200 shadow-sm w-full"
|
||||
/>
|
||||
<figcaption className="text-sm text-gray-500 mt-2 text-center italic">
|
||||
{t("processes.captureDetailCaption")}
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
<h3 className="text-lg font-semibold mt-6 mb-2 text-gray-900">{t("processes.sourceTitle")}</h3>
|
||||
<p className="mb-6 text-gray-800 leading-relaxed">
|
||||
{t.rich("processes.sourceBody", { code, em })}
|
||||
</p>
|
||||
|
||||
<h2 className="text-2xl font-semibold mt-10 mb-4 text-gray-900">{t("middle.heading")}</h2>
|
||||
<p className="mb-4 text-gray-800 leading-relaxed">
|
||||
{t.rich("middle.body1", { code, em })}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"title": "Before you start",
|
||||
"drivers": "<strong>Coral drivers already installed on the host</strong>. This script does not install them; it only configures passthrough to the container. Run <hostLink>Install Coral TPU on the Host</hostLink> first if you haven't.",
|
||||
"driversCheck": "ls /dev/apex_* 2>/dev/null ; lsusb | grep -E '1a6e:089a|18d1:9302'",
|
||||
"container": "<strong>An existing LXC container</strong>, ideally running a <strong>Debian / Ubuntu</strong>-based distro. The inside-container install uses <code>apt-get</code>; Alpine / Arch containers are not currently supported by this script.",
|
||||
"container": "<strong>An existing LXC container</strong>, ideally running a <strong>Debian / Ubuntu</strong>-based distro — the in-container runtime install uses <code>apt-get</code>. <strong>Non-Debian containers</strong> (Alpine, Arch, RHEL, SUSE…) are still supported in <strong>passthrough-only mode</strong>: the script detects the distro and offers a prompt to skip the <code>libedgetpu</code> APT install while still writing the device passthrough config — useful for app containers that bundle the runtime themselves (e.g. the Frigate Docker image).",
|
||||
"downtime": "<strong>Be OK with a brief downtime</strong> of the container. The script stops it to apply config changes, then starts it back up to install drivers inside. No host reboot needed."
|
||||
},
|
||||
"hostPrep": {
|
||||
@@ -70,8 +70,8 @@
|
||||
],
|
||||
"noIgpuTitle": "Why no iGPU drivers here?",
|
||||
"noIgpuBody": "Earlier versions of this script also installed Intel <code>va-driver-all</code>, <code>intel-opencl-icd</code> and friends so the same container could do Quick Sync video decode alongside Coral inference. That doubled-up responsibility caused confusing failures when the user only wanted Coral. The iGPU side is now the exclusive job of <lxcGpuLink>Add GPU to LXC</lxcGpuLink> — run it first if you also want hardware video decode in the container.",
|
||||
"debianTitle": "Debian / Ubuntu containers only",
|
||||
"debianBody": "The in-container install uses <code>apt-get</code> directly. Alpine, Arch or RHEL-based containers are not currently supported — the install step will fail and leave the LXC with the passthrough config but no drivers inside. For those distros, install the Coral runtime manually following Google's <coralLink>official guide</coralLink> after the LXC config step."
|
||||
"debianTitle": "Non-Debian containers — passthrough-only mode",
|
||||
"debianBody": "The in-container runtime install uses <code>apt-get</code>, which only ships on Debian/Ubuntu-family distros. On <strong>Alpine, Arch, RHEL or SUSE</strong> containers the script detects the distro via <code>/etc/os-release</code> and shows a confirmation prompt: <em>continue in passthrough-only mode</em> (writes the device config to <code>/etc/pve/lxc/<ctid>.conf</code> and skips the <code>libedgetpu</code> APT install) or <em>abort</em>. Passthrough-only is the right choice if the app container that will actually use Coral already bundles the runtime — the canonical example is the Frigate Docker image. Otherwise, follow Google's <coralLink>official guide</coralLink> to install <code>libedgetpu</code> manually after the script has written the LXC config."
|
||||
},
|
||||
"summary": {
|
||||
"title": "Summary",
|
||||
@@ -95,8 +95,8 @@
|
||||
"apexBody": "Host apex module isn't loaded. On the host: <code>lsmod | grep apex</code> — if empty, run <code>modprobe apex</code>, or reboot if you just installed Coral drivers. Once the host has <code>/dev/apex_0</code>, restart the container: <code>pct stop <ctid> && pct start <ctid></code>.",
|
||||
"replugTitle": "USB Coral disappears after replug in a different port",
|
||||
"replugBody": "This is exactly why the script mounts <code>/dev/bus/usb</code> instead of the <code>/dev/coral</code> symlink. If you're hitting this, check your LXC config has <code>lxc.mount.entry: /dev/bus/usb dev/bus/usb ...</code> and not a reference to <code>/dev/coral</code> directly. Old configs from earlier script versions may need updating — re-run the script on the same container and the config gets refreshed.",
|
||||
"alpineTitle": "In-container install fails on an Alpine container",
|
||||
"alpineBody": "The script uses <code>apt-get</code>, which Alpine doesn't have. The LXC passthrough config is still valid — just install the Coral runtime manually with <code>apk add</code> following Google's guide for Alpine, or use a Debian-based container if you don't need the smaller footprint.",
|
||||
"alpineTitle": "Alpine / Arch / RHEL / SUSE container — runtime not installed",
|
||||
"alpineBody": "If you chose <em>passthrough-only mode</em> when the script prompted, the LXC config is written and the Coral device is visible inside the container, but the <code>libedgetpu</code> runtime is not installed. That's by design: Google's APT repo only ships for Debian/Ubuntu. Install the runtime manually with your distro's package manager (Alpine: <code>apk add</code>; Arch: AUR; RHEL/SUSE: build from source) following Google's official guide, or run an app container that bundles the runtime — the Frigate Docker image is the canonical example: just expose the device with <code>--device /dev/apex_0:/dev/apex_0</code> (M.2) or the USB bind mount the script already wrote (USB).",
|
||||
"frigateTitle": "Frigate says 'Coral EdgeTPU detected but not available'",
|
||||
"frigateBody": "Almost always a permissions issue inside the container. Frigate runs as root by default; check the root user is in the <code>plugdev</code> group inside the container (for USB), and that the process can read <code>/dev/apex_0</code> (for M.2). <code>ls -l /dev/apex_0</code> from inside the container should show group <code>apex</code> — if not, add the GID alignment to <code>/etc/group</code> or switch the container to privileged mode.",
|
||||
"logsTitle": "Check both host and container logs",
|
||||
|
||||
@@ -53,6 +53,32 @@
|
||||
"sparklineTitle": "The sparkline is meaningful",
|
||||
"sparklineBody": "The temperature card draws a 5-minute trace under the value, with the line and gradient colour following the same Warning/Critical pair documented above. It's the fastest way to see whether the host is in a thermal climb without opening the detail modal."
|
||||
},
|
||||
"processes": {
|
||||
"heading": "Click-through: top processes by CPU / Memory",
|
||||
"intro": "The CPU Usage and Memory cards are clickable. Clicking either opens a sortable list of the top 25 processes — the CPU card sorts by <code>%CPU</code>, the Memory card sorts by resident memory (RSS). Both pull from <code>/api/processes?sort=cpu|mem&limit=25</code>, which runs a single <code>ps -eo pid,user,pcpu,pmem,rss,comm</code> per refresh.",
|
||||
"listTitle": "The list modal",
|
||||
"listItems": [
|
||||
"<strong>Auto-refresh</strong> — the list re-fetches every 5 s while the dialog is open. Closing the dialog stops all polling.",
|
||||
"<strong>Filter box</strong> — matches against command, user or PID without re-fetching from the server.",
|
||||
"<strong>Inline progress bar</strong> — the primary metric column draws a bar scaled to the largest value in the filtered list, so visual ranking is preserved even when no process is near 100 %.",
|
||||
"<strong>Mobile layout</strong> — under 640 px the PID and User columns drop out so Command, CPU % and Memory still fit without horizontal scroll."
|
||||
],
|
||||
"captureListAlt": "Top processes by Memory modal — table with PID, USER, COMMAND, CPU %, Memory columns sorted by RSS",
|
||||
"captureListCaption": "The Memory card opens the list sorted by RSS (indigo accent). The CPU card opens the same list sorted by %CPU (blue accent).",
|
||||
"detailTitle": "Per-process detail",
|
||||
"detailIntro": "Clicking any row in the list opens a second modal with the full live picture of that one process, served from <code>/api/processes/<pid></code>. Four sections:",
|
||||
"detailItems": [
|
||||
"<strong>Overview</strong> — state (<code>R</code>/<code>S</code>/<code>D</code>/<code>Z</code>/…), parent (<code>PPid</code> + parent <code>comm</code>), thread count, open FD count, user and group.",
|
||||
"<strong>Resources</strong> — CPU %, Memory %, Resident (RSS), Virtual size, Swap, I/O read and write bytes.",
|
||||
"<strong>Command</strong> — short name (<code>comm</code>), full command line, executable path and working directory.",
|
||||
"<strong>Lifetime</strong> — start timestamp and elapsed runtime."
|
||||
],
|
||||
"detailRefresh": "The detail modal refreshes every 3 s while open. If the process exits mid-modal the next refresh surfaces <em>Process exited</em> instead of stale data — expected for short-lived helpers like <code>pct exec</code> or backup subprocesses.",
|
||||
"captureDetailAlt": "Process detail modal — Overview, Resources, Command and Lifetime sections for a single PID",
|
||||
"captureDetailCaption": "Per-process detail modal opened from a list row. The accent colour matches the card that opened it (blue for CPU, indigo for Memory).",
|
||||
"sourceTitle": "Where the data comes from",
|
||||
"sourceBody": "<code>/api/processes/<pid></code> reads <code>/proc/<pid>/cmdline</code>, <code>/exe</code>, <code>/cwd</code>, <code>/status</code>, <code>/io</code> and <code>/fd</code> directly, and calls <code>ps -o lstart=,etime=,pcpu=,pmem= -p <pid></code> for the live fields the kernel doesn't expose in <code>/proc</code>. UID and GID are resolved to user / group names through Python's <code>pwd</code> / <code>grp</code> modules. Both endpoints are pure on-demand HTTP handlers — no daemon, no background sampling. Nothing runs on the server when the modal is closed."
|
||||
},
|
||||
"middle": {
|
||||
"heading": "Middle: node metrics charts",
|
||||
"body1": "Below the top row sits the <code>NodeMetricsCharts</code> component — historical CPU, memory and disk-I/O graphs sourced from Proxmox's own RRD store via <code>/api/node/metrics</code>. A timeframe selector switches between <em>1 hour / 24 hours / 7 days / 30 days / 1 year</em>; data resolution drops as the window grows so the chart stays smooth.",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"title": "Antes de empezar",
|
||||
"drivers": "<strong>Drivers de Coral ya instalados en el host</strong>. Este script no los instala; solo configura el passthrough al contenedor. Ejecuta <hostLink>Install Coral TPU on the Host</hostLink> primero si no lo has hecho.",
|
||||
"driversCheck": "ls /dev/apex_* 2>/dev/null ; lsusb | grep -E '1a6e:089a|18d1:9302'",
|
||||
"container": "<strong>Un contenedor LXC existente</strong>, idealmente con una distro basada en <strong>Debian / Ubuntu</strong>. La instalación dentro del contenedor usa <code>apt-get</code>; los contenedores Alpine / Arch no están soportados por este script actualmente.",
|
||||
"container": "<strong>Un contenedor LXC existente</strong>, idealmente con una distro basada en <strong>Debian / Ubuntu</strong> — la instalación del runtime dentro del contenedor usa <code>apt-get</code>. Los <strong>contenedores no-Debian</strong> (Alpine, Arch, RHEL, SUSE…) siguen estando soportados en <strong>modo passthrough-only</strong>: el script detecta la distro y ofrece un prompt para saltarse la instalación APT de <code>libedgetpu</code> mientras escribe la config de passthrough del dispositivo — útil para contenedores de aplicación que ya incluyen el runtime (p.ej. la imagen Docker de Frigate).",
|
||||
"downtime": "<strong>Asume una breve interrupción</strong> del contenedor. El script lo para para aplicar los cambios de config y lo arranca de nuevo para instalar los drivers dentro. No hace falta reiniciar el host."
|
||||
},
|
||||
"hostPrep": {
|
||||
@@ -70,8 +70,8 @@
|
||||
],
|
||||
"noIgpuTitle": "¿Por qué no hay drivers de iGPU aquí?",
|
||||
"noIgpuBody": "Versiones anteriores de este script también instalaban Intel <code>va-driver-all</code>, <code>intel-opencl-icd</code> y compañía para que el mismo contenedor pudiera hacer decode de vídeo Quick Sync junto a la inferencia de Coral. Esa doble responsabilidad causaba fallos confusos cuando el usuario solo quería Coral. El lado iGPU es ahora trabajo exclusivo de <lxcGpuLink>Añadir GPU a LXC</lxcGpuLink> — ejecútalo primero si también quieres decode de vídeo por hardware en el contenedor.",
|
||||
"debianTitle": "Solo contenedores Debian / Ubuntu",
|
||||
"debianBody": "La instalación dentro del contenedor usa <code>apt-get</code> directamente. Los contenedores Alpine, Arch o basados en RHEL no están soportados actualmente — el paso de instalación fallará y dejará el LXC con la config de passthrough pero sin drivers dentro. Para esas distros, instala el runtime de Coral manualmente siguiendo la <coralLink>guía oficial</coralLink> de Google después del paso de config del LXC."
|
||||
"debianTitle": "Contenedores no-Debian — modo passthrough-only",
|
||||
"debianBody": "La instalación del runtime dentro del contenedor usa <code>apt-get</code>, que solo viene con distros de la familia Debian/Ubuntu. En contenedores <strong>Alpine, Arch, RHEL o SUSE</strong> el script detecta la distro vía <code>/etc/os-release</code> y muestra un prompt de confirmación: <em>continuar en modo passthrough-only</em> (escribe la config del dispositivo en <code>/etc/pve/lxc/<ctid>.conf</code> y se salta la instalación APT de <code>libedgetpu</code>) o <em>cancelar</em>. Passthrough-only es la opción correcta si el contenedor de aplicación que va a usar Coral ya incluye el runtime — el ejemplo canónico es la imagen Docker de Frigate. Si no, sigue la <coralLink>guía oficial</coralLink> de Google para instalar <code>libedgetpu</code> manualmente después de que el script haya escrito la config del LXC."
|
||||
},
|
||||
"summary": {
|
||||
"title": "Resumen",
|
||||
@@ -95,8 +95,8 @@
|
||||
"apexBody": "El módulo apex del host no está cargado. En el host: <code>lsmod | grep apex</code> — si está vacío, ejecuta <code>modprobe apex</code>, o reinicia si acabas de instalar los drivers de Coral. Una vez el host tenga <code>/dev/apex_0</code>, reinicia el contenedor: <code>pct stop <ctid> && pct start <ctid></code>.",
|
||||
"replugTitle": "La Coral USB desaparece al reconectarla en otro puerto",
|
||||
"replugBody": "Justo por eso el script monta <code>/dev/bus/usb</code> en lugar del symlink <code>/dev/coral</code>. Si te pasa esto, comprueba que tu config del LXC tiene <code>lxc.mount.entry: /dev/bus/usb dev/bus/usb ...</code> y no una referencia directa a <code>/dev/coral</code>. Las configs viejas de versiones anteriores del script pueden necesitar actualizarse — vuelve a ejecutar el script sobre el mismo contenedor y la config se refresca.",
|
||||
"alpineTitle": "La instalación dentro del contenedor falla en un contenedor Alpine",
|
||||
"alpineBody": "El script usa <code>apt-get</code>, que Alpine no tiene. La config de passthrough del LXC sigue siendo válida — solo instala el runtime de Coral manualmente con <code>apk add</code> siguiendo la guía de Google para Alpine, o usa un contenedor basado en Debian si no necesitas la huella más pequeña.",
|
||||
"alpineTitle": "Contenedor Alpine / Arch / RHEL / SUSE — runtime no instalado",
|
||||
"alpineBody": "Si elegiste <em>modo passthrough-only</em> cuando el script lo preguntó, la config del LXC se escribió y el dispositivo Coral es visible dentro del contenedor, pero el runtime <code>libedgetpu</code> no está instalado. Es así por diseño: el repo APT de Google solo se publica para Debian/Ubuntu. Instala el runtime manualmente con el gestor de paquetes de tu distro (Alpine: <code>apk add</code>; Arch: AUR; RHEL/SUSE: compilar desde fuente) siguiendo la guía oficial de Google, o usa un contenedor de aplicación que incluya el runtime — la imagen Docker de Frigate es el ejemplo canónico: solo expone el dispositivo con <code>--device /dev/apex_0:/dev/apex_0</code> (M.2) o el bind mount USB que el script ya escribió (USB).",
|
||||
"frigateTitle": "Frigate dice 'Coral EdgeTPU detected but not available'",
|
||||
"frigateBody": "Casi siempre es un problema de permisos dentro del contenedor. Frigate corre como root por defecto; comprueba que el usuario root está en el grupo <code>plugdev</code> dentro del contenedor (para USB), y que el proceso puede leer <code>/dev/apex_0</code> (para M.2). <code>ls -l /dev/apex_0</code> desde dentro del contenedor debería mostrar el grupo <code>apex</code> — si no, añade el alineamiento de GID a <code>/etc/group</code> o cambia el contenedor a modo privilegiado.",
|
||||
"logsTitle": "Revisa los logs del host y del contenedor",
|
||||
|
||||
@@ -53,6 +53,32 @@
|
||||
"sparklineTitle": "El sparkline es significativo",
|
||||
"sparklineBody": "La tarjeta de temperatura dibuja una traza de 5 minutos bajo el valor, con la línea y el degradado siguiendo el mismo par Warning/Critical documentado arriba. Es la forma más rápida de ver si el host está en escalada térmica sin abrir la modal de detalle."
|
||||
},
|
||||
"processes": {
|
||||
"heading": "Acceso directo: top procesos por CPU / Memoria",
|
||||
"intro": "Las tarjetas CPU Usage y Memory son clicables. Al pulsar cualquiera de ellas se abre una lista ordenable con los 25 procesos top — la tarjeta de CPU ordena por <code>%CPU</code>, la de Memory ordena por memoria residente (RSS). Ambas tiran de <code>/api/processes?sort=cpu|mem&limit=25</code>, que ejecuta un único <code>ps -eo pid,user,pcpu,pmem,rss,comm</code> por refresco.",
|
||||
"listTitle": "La modal con la lista",
|
||||
"listItems": [
|
||||
"<strong>Auto-refresco</strong> — la lista vuelve a obtener datos cada 5 s mientras el diálogo está abierto. Al cerrar el diálogo se detiene todo el polling.",
|
||||
"<strong>Caja de filtro</strong> — busca por command, user o PID sin volver a pedir datos al servidor.",
|
||||
"<strong>Barra de progreso en línea</strong> — la columna de la métrica primaria dibuja una barra escalada al mayor valor de la lista filtrada, para que el orden visual se mantenga aunque ningún proceso esté cerca del 100 %.",
|
||||
"<strong>Layout móvil</strong> — por debajo de 640 px las columnas PID y User desaparecen para que Command, CPU % y Memory sigan cabiendo sin scroll horizontal."
|
||||
],
|
||||
"captureListAlt": "Modal Top processes by Memory — tabla con columnas PID, USER, COMMAND, CPU %, Memory ordenada por RSS",
|
||||
"captureListCaption": "La tarjeta Memory abre la lista ordenada por RSS (acento índigo). La tarjeta CPU abre la misma lista ordenada por %CPU (acento azul).",
|
||||
"detailTitle": "Detalle por proceso",
|
||||
"detailIntro": "Al pulsar cualquier fila de la lista se abre una segunda modal con la foto en vivo completa de ese proceso, servida desde <code>/api/processes/<pid></code>. Cuatro secciones:",
|
||||
"detailItems": [
|
||||
"<strong>Overview</strong> — estado (<code>R</code>/<code>S</code>/<code>D</code>/<code>Z</code>/…), proceso padre (<code>PPid</code> + <code>comm</code> del padre), número de hilos, FDs abiertos, usuario y grupo.",
|
||||
"<strong>Resources</strong> — CPU %, Memoria %, Resident (RSS), Virtual size, Swap, bytes de I/O de lectura y escritura.",
|
||||
"<strong>Command</strong> — nombre corto (<code>comm</code>), línea de comandos completa, ruta del ejecutable y directorio de trabajo.",
|
||||
"<strong>Lifetime</strong> — timestamp de arranque y tiempo transcurrido en ejecución."
|
||||
],
|
||||
"detailRefresh": "La modal de detalle se refresca cada 3 s mientras está abierta. Si el proceso termina con la modal abierta, el siguiente refresco muestra <em>Process exited</em> en vez de datos obsoletos — esperable para procesos efímeros como <code>pct exec</code> o subprocesos de backup.",
|
||||
"captureDetailAlt": "Modal de detalle de proceso — secciones Overview, Resources, Command y Lifetime para un único PID",
|
||||
"captureDetailCaption": "Modal de detalle por proceso abierta desde una fila de la lista. El color de acento sigue al de la tarjeta que la abrió (azul para CPU, índigo para Memory).",
|
||||
"sourceTitle": "De dónde salen los datos",
|
||||
"sourceBody": "<code>/api/processes/<pid></code> lee directamente <code>/proc/<pid>/cmdline</code>, <code>/exe</code>, <code>/cwd</code>, <code>/status</code>, <code>/io</code> y <code>/fd</code>, y llama a <code>ps -o lstart=,etime=,pcpu=,pmem= -p <pid></code> para los campos en vivo que el kernel no expone en <code>/proc</code>. UID y GID se resuelven a nombre de usuario / grupo con los módulos <code>pwd</code> / <code>grp</code> de Python. Ambos endpoints son handlers HTTP puros bajo demanda — sin daemon, sin sampling en background. No corre nada en el servidor mientras la modal esté cerrada."
|
||||
},
|
||||
"middle": {
|
||||
"heading": "Medio: gráficas de métricas del nodo",
|
||||
"body1": "Bajo la fila superior se encuentra el componente <code>NodeMetricsCharts</code> — gráficas históricas de CPU, memoria y E/S de disco tomadas del propio almacén RRD de Proxmox vía <code>/api/node/metrics</code>. Un selector de timeframe alterna entre <em>1 hora / 24 horas / 7 días / 30 días / 1 año</em>; la resolución de los datos baja a medida que crece la ventana para que la gráfica se mantenga fluida.",
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 436 KiB After Width: | Height: | Size: 500 KiB |
BIN
web/public/monitor/system-overview-process-detail.png
Normal file
BIN
web/public/monitor/system-overview-process-detail.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 176 KiB |
BIN
web/public/monitor/system-overview-top-processes.png
Normal file
BIN
web/public/monitor/system-overview-top-processes.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 201 KiB |
Reference in New Issue
Block a user