diff --git a/lib/grafana.ts b/lib/grafana.ts index 26ed093..5e6310a 100644 --- a/lib/grafana.ts +++ b/lib/grafana.ts @@ -3,7 +3,7 @@ import fetcher from '@/lib/fetcher' const GRAFANA_URL = process.env.GRAFANA_URL const GRAFANA_TOKEN = process.env.GRAFANA_TOKEN -export const getPiTemp = async () => { +export const getTemp = async () => { const response = await fetcher(GRAFANA_URL, { method: 'POST', headers: { @@ -19,7 +19,7 @@ export const getPiTemp = async () => { "type": "prometheus" }, "expr": "node_hwmon_temp_celsius", - "maxDataPoints": 612 + "maxDataPoints": 100 } ], "from": "now-5m", @@ -30,4 +30,70 @@ export const getPiTemp = async () => { return { temp: response.results.A.frames[0].data.values[1][15].toFixed(2) } +} + +export const getRootFsUsage = async () => { + const response = await fetcher(GRAFANA_URL, { + method: 'POST', + headers: { + Authorization: `Bearer ${GRAFANA_TOKEN}`, + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + "queries": [ + { + "datasource": { + "uid": "4f-R6jgRz", + "type": "prometheus" + }, + "expr": "100 - ((node_filesystem_avail_bytes{mountpoint='/',fstype!='rootfs'} * 100) / node_filesystem_size_bytes{mountpoint='/',fstype!='rootfs'})", + "maxDataPoints": 100 + } + ], + "from": "now-5m", + "to": "now" + }) + }) + + return { + usage: response.results.A.frames[0].data.values[1][15].toFixed(2) + } +} + +export const getUptime = async () => { + const response = await fetcher(GRAFANA_URL, { + method: 'POST', + headers: { + Authorization: `Bearer ${GRAFANA_TOKEN}`, + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + "queries": [ + { + "datasource": { + "uid": "4f-R6jgRz", + "type": "prometheus" + }, + "expr": "node_time_seconds - node_boot_time_seconds", + "maxDataPoints": 100 + } + ], + "from": "now-5m", + "to": "now" + }) + }) + + const seconds = response.results.A.frames[0].data.values[1][15] + const minutes = (seconds / 60).toFixed(2) + const hours = (seconds / 3_600).toFixed(2) + const weeks = (seconds / 604_800).toFixed(2) + + return { + seconds: (seconds).toFixed(2), + minutes, + hours, + weeks + } } \ No newline at end of file diff --git a/pages/api/grafana/rootfs.ts b/pages/api/grafana/rootfs.ts new file mode 100644 index 0000000..d622eb6 --- /dev/null +++ b/pages/api/grafana/rootfs.ts @@ -0,0 +1,8 @@ +import {NextApiRequest, NextApiResponse} from 'next' +import {getRootFsUsage} from '@/lib/grafana' + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + const response = await getRootFsUsage() + + return res.status(200).json(response) +} \ No newline at end of file diff --git a/pages/api/grafana/temp.ts b/pages/api/grafana/temp.ts index 5396be0..290a83d 100644 --- a/pages/api/grafana/temp.ts +++ b/pages/api/grafana/temp.ts @@ -1,8 +1,8 @@ import {NextApiRequest, NextApiResponse} from 'next' -import {getPiTemp} from '@/lib/grafana' +import {getTemp} from '@/lib/grafana' export default async function handler(req: NextApiRequest, res: NextApiResponse) { - const response = await getPiTemp() + const response = await getTemp() return res.status(200).json(response) } \ No newline at end of file diff --git a/pages/api/grafana/uptime.ts b/pages/api/grafana/uptime.ts new file mode 100644 index 0000000..8c70f7b --- /dev/null +++ b/pages/api/grafana/uptime.ts @@ -0,0 +1,8 @@ +import {NextApiRequest, NextApiResponse} from 'next' +import {getUptime} from '@/lib/grafana' + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + const response = await getUptime() + + return res.status(200).json(response) +} \ No newline at end of file diff --git a/pages/dashboard.tsx b/pages/dashboard.tsx index 85d05d9..3912c06 100644 --- a/pages/dashboard.tsx +++ b/pages/dashboard.tsx @@ -10,10 +10,14 @@ import {getDashboardData} from '@/lib/dashboard' import fetcher from '@/lib/fetcher' import type {MetricGroup} from '@/types' +const config = { + refreshInterval: 30000 +} + export default function Dashboard({metrics}: { metrics: MetricGroup }) { - const {data: tempData} = useSWR('api/grafana/temp', fetcher, { - refreshInterval: 30000 - }) + const {data: tempData} = useSWR('api/grafana/temp', fetcher, config) + const {data: rootFsData} = useSWR('api/grafana/rootfs', fetcher, config) + const {data: uptimeData} = useSWR('api/grafana/uptime', fetcher, config) return ( <> @@ -60,6 +64,22 @@ export default function Dashboard({metrics}: { metrics: MetricGroup }) { {tempData ? `${tempData.temp} ℃` : "—"} + +

+ Root FS usage +

+ + {rootFsData ? `${rootFsData.usage} %` : "—"} + +
+ +

+ Uptime minutes +

+ + {uptimeData ? `${numberFormat(uptimeData.minutes)}` : "—"} + +