Skip to content

Commit

Permalink
feat: add api endpoints to get current load
Browse files Browse the repository at this point in the history
  • Loading branch information
MauriceNino committed Jun 27, 2022
1 parent 463d0fa commit 48ab081
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 22 deletions.
40 changes: 39 additions & 1 deletion apps/api/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@ import * as express from 'express';
import { readFileSync } from 'fs';
import * as http from 'http';
import * as path from 'path';
import { Subscription } from 'rxjs';
import {
debounceTime,
lastValueFrom,
Observable,
Subscription,
take,
timeout,
} from 'rxjs';
import { Server } from 'socket.io';
import { CONFIG } from './config';
import { getDynamicServerInfo } from './dynamic-info';
Expand Down Expand Up @@ -68,6 +75,37 @@ server.listen(CONFIG.port, async () => {
await loadStaticServerInfo();
const obs = getDynamicServerInfo();

// Allow integrations
if (!CONFIG.disable_integrations) {
const getCurrentValue = async <T>(
subj: Observable<T>
): Promise<T | undefined> => {
try {
return await lastValueFrom(
subj.pipe(debounceTime(0), timeout(20), take(1))
);
} catch (e) {
return undefined;
}
};

app.get('/load/cpu', async (_, res) => {
res.send(await getCurrentValue(obs.cpu));
});
app.get('/load/ram', async (_, res) => {
res.send({ load: await getCurrentValue(obs.ram) });
});
app.get('/load/storage', async (_, res) => {
res.send(await getCurrentValue(obs.storage));
});
app.get('/load/network', async (_, res) => {
res.send(await getCurrentValue(obs.network));
});
app.get('/load/gpu', async (_, res) => {
res.send(await getCurrentValue(obs.gpu));
});
}

// Send current system status
io.on('connection', socket => {
const subscriptions: Subscription[] = [];
Expand Down
72 changes: 60 additions & 12 deletions apps/docs/docs/integration/api-preview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,19 @@ export const ApiPreview = () => {
const baseUrl = `${protocol}://${url}`;
const info = getDataFromUrl(baseUrl + '/info');
const config = getDataFromUrl(baseUrl + '/config');
const cpuLoad = getDataFromUrl(baseUrl + '/load/cpu');
const storageLoad = getDataFromUrl(baseUrl + '/load/storage');
const ramLoad = getDataFromUrl(baseUrl + '/load/ram');
const networkLoad = getDataFromUrl(baseUrl + '/load/network');
const gpuLoad = getDataFromUrl(baseUrl + '/load/gpu');

const formatOutput = data => {
return !data.loading
? !data.error
? JSON.stringify(data.data, null, 2)
: data.error.message ?? 'Error'
: 'Loading ...';
};

return (
<MantineProvider
Expand Down Expand Up @@ -106,23 +119,58 @@ export const ApiPreview = () => {
<h3>Info</h3>
<CodeBlock className={`language-http`}>{`${baseUrl}/info`}</CodeBlock>

<CodeBlock className={`language-json`}>
{!info.loading
? !info.error
? JSON.stringify(info.data, null, 2)
: info.error.message ?? 'Error'
: 'Loading ...'}
</CodeBlock>
<CodeBlock className={`language-json`}>{formatOutput(info)}</CodeBlock>

<h3>Config</h3>
<CodeBlock className={`language-http`}>{`${baseUrl}/config`}</CodeBlock>

<CodeBlock className={`language-json`}>
{!config.loading
? !config.error
? JSON.stringify(config.data, null, 2)
: config.error.message ?? 'Error'
: 'Loading ...'}
{formatOutput(config)}
</CodeBlock>

<h3>CPU Load</h3>
<CodeBlock
className={`language-http`}
>{`${baseUrl}/load/cpu`}</CodeBlock>

<CodeBlock className={`language-json`}>
{formatOutput(cpuLoad)}
</CodeBlock>

<h3>Storage Load</h3>
<CodeBlock
className={`language-http`}
>{`${baseUrl}/load/storage`}</CodeBlock>

<CodeBlock className={`language-json`}>
{formatOutput(storageLoad)}
</CodeBlock>

<h3>RAM Load</h3>
<CodeBlock
className={`language-http`}
>{`${baseUrl}/load/ram`}</CodeBlock>

<CodeBlock className={`language-json`}>
{formatOutput(ramLoad)}
</CodeBlock>

<h3>Network Load</h3>
<CodeBlock
className={`language-http`}
>{`${baseUrl}/load/network`}</CodeBlock>

<CodeBlock className={`language-json`}>
{formatOutput(networkLoad)}
</CodeBlock>

<h3>GPU Load</h3>
<CodeBlock
className={`language-http`}
>{`${baseUrl}/load/gpu`}</CodeBlock>

<CodeBlock className={`language-json`}>
{formatOutput(gpuLoad)}
</CodeBlock>
</div>
</MantineProvider>
Expand Down
14 changes: 14 additions & 0 deletions apps/docs/docs/integration/api.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,20 @@ or if multi-view for the storage widget is enabled at `config.enable_storage_spl

- Example: `https://<YOUR_SERVER_URL>/config`

### `/load`

Has multiple sub-routes, each returning the current load of the given type.

- `/load/cpu`
- `/load/storage`
- `/load/ram`
- `/load/network`
- `/load/gpu`

<br />

- Example: `https://<YOUR_SERVER_URL>/load/cpu`

## URL Preview

import { ApiPreview } from './api-preview';
Expand Down
16 changes: 7 additions & 9 deletions apps/view/src/utils/calculations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@ export const toCommas = (num: number, commas = 1): number => {
};

export const bpsPrettyPrint = (bits: number) => {
if (bits > 1000 * 1000 * 1000) {
return `${(bits / 1000 / 1000 / 1000).toFixed(1)} Gb/s`;
} else if (bits > 1000 * 1000) {
return `${(bits / 1000 / 1000).toFixed(1)} Mb/s`;
} else if (bits > 1000) {
return `${(bits / 1000).toFixed(1)} Kb/s`;
} else {
return `${bits.toFixed(1)} b/s`;
}
return bits > 1000 * 1000 * 1000
? `${(bits / 1000 / 1000 / 1000).toFixed(1)} Gb/s`
: bits > 1000 * 1000
? `${(bits / 1000 / 1000).toFixed(1)} Mb/s`
: bits > 1000
? `${(bits / 1000).toFixed(1)} Kb/s`
: `${bits.toFixed(1)} b/s`;
};

export const bytePrettyPrint = (byte: number): string => {
Expand Down

0 comments on commit 48ab081

Please sign in to comment.