admin/monitoring: show ram
Massimo Melina committed
Aug 25, 2024 at 10:16 UTC
6317965b6adba84419616f1c4d2fc1efcf76f043
4 files changed
+10
-8
admin/src/MonitorPage.ts
+7
-5
@@ -17,6 +17,7 @@ import { agentIcons } from './LogsPage'
17
import { state, useSnapState } from './state'
18
import { useBlockIp } from './useBlockIp'
19
import { alertDialog, confirmDialog } from './dialog'
20
+import { useInterval } from 'usehooks-ts'
21
22
export default function MonitorPage() {
23
return h(Fragment, {},
@@ -26,13 +27,13 @@ export default function MonitorPage() {
27
}
28
29
function MoreInfo() {
29
- const { data: status, element } = useApiEx('get_status')
30
+ const { data: status, element, reload } = useApiEx('get_status')
31
+ useInterval(reload, 10_000) // status hardly change, but it can
32
const { data: connections } = useApiEvents('get_connection_stats')
31
- if (status && connections)
32
- Object.assign(status, connections)
33
const [allInfo, setAllInfo] = useState(false)
34
const md = useBreakpoint('md')
35
const sm = useBreakpoint('sm')
36
+ const xl = useBreakpoint('xl')
37
const formatDuration = createDurationFormatter({ maxTokens: 2, skipZeroes: true })
38
return element || h(Box, { display: 'flex', flexWrap: 'wrap', gap: { xs: .5, md: 1 }, mb: { xs: 1, sm: 2 } },
39
(allInfo || md) && pair('started', {
@@ -52,7 +53,8 @@ function MoreInfo() {
53
(allInfo || sm) && pair('ips', { label: "IPs", title: () => "Currently connected" }),
54
(md || allInfo && md || status?.http?.error) && pair('http', { label: "HTTP", render: port }),
55
(md || allInfo && md || status?.https?.error) && pair('https', { label: "HTTPS", render: port }),
55
- !md && h(IconBtn, {
56
+ (xl || allInfo) && pair('ram', { label: "RAM", render: formatBytes }),
57
+ !xl && h(IconBtn, {
58
size: 'small',
59
icon: allInfo ? ChevronLeft : ChevronRight,
60
title: "Show more",
@@ -71,7 +73,7 @@ function MoreInfo() {
73
}
74
75
function pair(k: string, { label, minWidth, render, title, onDelete }: PairOptions={}) {
74
- let v = _.get(status, k)
76
+ let v = _.get(connections, k) ?? _.get(status, k)
77
if (v === undefined)
78
return null
79
let color: Color = undefined
admin/src/api.ts
+1
-1
@@ -32,7 +32,7 @@ export function useApiEx<T=any>(...args: Parameters<typeof useApi>) {
32
!args[0] ? null
33
: res.error ? h(Alert, { severity: 'error' }, xlate(String(res.error), ERRORS),
34
h(IconBtn, { icon: Refresh, title: "Reload", onClick: res.reload, sx: { m:'-10px 0 -8px 16px' } }) )
35
- : res.loading || res.data === undefined ? spinner()
35
+ : res.data === undefined ? spinner()
36
: null,
37
Object.values(res))
38
}
shared/api.ts
+1
-2
@@ -89,13 +89,12 @@ export function useApi<T=any>(cmd: string | Falsy, params?: object, options: Api
89
const dataRef = useRef<any>()
90
useEffect(() => {
91
loadingRef.current?.abort()
92
- setData(undefined)
92
setError(undefined)
93
let aborted = false
94
let req: undefined | ReturnType<typeof apiCall>
95
const wholePromise = wait(0) // postpone a bit, so that if it is aborted immediately, it is never really fired (happens mostly in dev mode)
96
.then(() => !cmd || aborted ? undefined : req = apiCall<T>(cmd, params, options))
98
- .then(res => aborted || setData(dataRef.current = res as any), err => {
97
+ .then(res => aborted || setData(dataRef.current = res as any) || setError(undefined), err => {
98
if (aborted) return
99
setError(err)
100
setData(dataRef.current = undefined)
src/adminApis.ts
+1
@@ -128,6 +128,7 @@ export const adminApis = {
128
autoCheckUpdateResult: autoCheckUpdateResult.get(), // in this form, we get the same type of the serialized json
129
alerts: alerts.get(),
130
proxyDetected: getProxyDetected(),
131
+ ram: process.memoryUsage.rss(),
132
frpDetected: localhostAdmin.get() && !getProxyDetected()
133
&& getConnections().every(isLocalHost)
134
&& await frpDebounced(),