Skip to content

Commit 0493d19

Browse files
authored
Merge pull request #1 from nirjan-dev/multi-system
Multi system
2 parents c7c3cd4 + 3286cfe commit 0493d19

23 files changed

Lines changed: 421 additions & 184 deletions

agent/.env.example

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ REQUESTS_PER_MINUTE_UNIT=
33
MINUTE_UNIT=
44
SERVER_URL=
55
AGENT_TOKEN=
6-
PORT=
6+
PORT=
7+
NAME=

agent/main.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ const REQUESTS_PER_MINUTE_UNIT =
3535
const MINUTE_UNIT = Number(Deno.env.get("MINUTE_UNIT"));
3636
const AGENT_TOKEN = Deno.env.get("AGENT_TOKEN");
3737
const PORT = Number(Deno.env.get("PORT")) || 8000;
38+
const NAME = Deno.env.get("NAME") ?? 'no name configured'
3839
if (!AGENT_TOKEN) {
3940
throw new Error("No AGENT_TOKEN set in env variables. Exiting agent...");
4041
}
@@ -64,6 +65,7 @@ console.log(
6465
console.log(`SEND_REQUESTS: ${SEND_REQUESTS}`);
6566
console.log(`SERVER_URL: ${SERVER_URL}`);
6667
console.log(`PORT: ${PORT}`);
68+
console.log(`NAME: ${NAME}`)
6769

6870
async function getMemoryStats(): Promise<MemoryInfo> {
6971
const { total, available, active } = await mem();
@@ -196,6 +198,7 @@ async function getContainersInfo(): Promise<ContainerInfo[]> {
196198

197199
async function getMetrics(): Promise<Metrics> {
198200
return {
201+
name: NAME,
199202
timestamp: Date.now(),
200203
memory: await getMemoryStats(),
201204
battery: await getBatteryStats(),
@@ -292,10 +295,11 @@ setInterval(async () => {
292295
});
293296
const parsedResponse = await response.json();
294297
if (parsedResponse?.statusCode !== 201) {
295-
throw new Error(`Error sending metrics ` + parsedResponse?.statusMessage);
298+
throw new Error(`Error sending metrics ` + parsedResponse?.statusMessage + JSON.stringify(parsedResponse?.data, null, 2));
296299
}
297-
} catch (error) {
298-
console.error(error);
300+
} catch (error:unknown) {
301+
console.log(error)
302+
console.log('tried sending: ', JSON.stringify(metrics, null, 2))
299303
}
300304
}, requestIntervalMilliSeconds);
301305

@@ -311,7 +315,7 @@ async function handler(_req: Request): Promise<Response> {
311315
}
312316

313317
const ws = new CommandResponderWebsocketClient({
314-
url: `${SERVER_URL}/api/ws?type=server`,
318+
url: `${SERVER_URL}/api/ws?type=server&name=${NAME}`,
315319
});
316320

317321
ws.connect();

agent/schemas/schemas.zod.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { z } from "zod";
33

44
export const processInfoSchema = z.object({
55
app: z.string(),
6-
pid: z.number(),
6+
pid: z.number().nullable(),
77
cpuPercent: z.string(),
88
memoryPercent: z.string(),
99
});
@@ -60,6 +60,7 @@ export const networkInfoSchema = z.object({
6060

6161
export const metricsSchema = z.object({
6262
timestamp: z.number(),
63+
name: z.string(),
6364
memory: memoryInfoSchema,
6465
cpu: cpuInfoSchema,
6566
processes: z.array(processInfoSchema),

agent/servomon-agent-test

87.9 MB
Binary file not shown.

shared/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export interface ProcessInfo {
22
app: string;
3-
pid: number;
3+
pid: number | null;
44
cpuPercent: string;
55
memoryPercent: string;
66
}
@@ -57,6 +57,7 @@ export interface NetworkInfo {
5757

5858
export interface Metrics {
5959
timestamp: number;
60+
name: string;
6061
memory: MemoryInfo;
6162
cpu: CpuInfo;
6263
processes: ProcessInfo[];

web/components/SystemInfo.vue

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
<template>
22
<UCard>
33
<template #header><h2>System info</h2></template>
4+
<h2 class="flex justify-between items-center">
5+
Name
6+
<span class="text-lg font-bold text-primary">{{ name }} </span>
7+
</h2>
8+
49
<h2 class="flex justify-between items-center">
510
Updated at
611
<span class="text-lg font-bold text-primary">{{ updateTime }} </span>
@@ -16,6 +21,7 @@
1621

1722
<script setup lang="ts">
1823
const props = defineProps<{
24+
name: string | string[];
1925
timestamp?: number;
2026
systemInfo?: {
2127
os: string;

web/components/SystemOverview.vue

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<template>
2+
<UCard>
3+
<template #header
4+
><div class="flex justify-between">
5+
<span class="capitalize"> {{ name }}</span>
6+
<UButton :to="link">View Details</UButton>
7+
</div>
8+
</template>
9+
10+
<div>
11+
<h2
12+
v-for="(info, label) in rows"
13+
class="flex justify-between items-center"
14+
>
15+
{{ label }}
16+
<span class="text-lg font-bold">{{ info }} </span>
17+
</h2>
18+
</div>
19+
</UCard>
20+
</template>
21+
22+
<script lang="ts" setup>
23+
const props = defineProps<{
24+
name: string;
25+
link: string;
26+
metrics: {
27+
timestamp: number;
28+
memory: {
29+
usedPercentage: number;
30+
};
31+
cpu: {
32+
used: number;
33+
};
34+
containersInfo: unknown[];
35+
networkInfo: {
36+
downloadPerSecond: string;
37+
uploadPerSecond: string;
38+
};
39+
systemInfo: {
40+
os: string;
41+
device: string;
42+
};
43+
battery: {
44+
charge: number;
45+
};
46+
};
47+
}>();
48+
49+
const rows = computed(() => {
50+
return {
51+
"Last Update": new Date(props.metrics.timestamp).toLocaleString(),
52+
OS: props.metrics.systemInfo.os,
53+
Device: props.metrics.systemInfo.device,
54+
Battery: props.metrics.battery.charge,
55+
"Memory Used": `${props.metrics.memory.usedPercentage}%`,
56+
"CPU Used": `${props.metrics.cpu.used}%`,
57+
"Active Containers": `${props.metrics.containersInfo.length}`,
58+
"Download Speed": `${props.metrics.networkInfo.downloadPerSecond}`,
59+
"Upload Speed": `${props.metrics.networkInfo.uploadPerSecond}`,
60+
};
61+
});
62+
</script>
63+
64+
<style></style>

web/layouts/default.vue

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<template>
2+
<UContainer>
3+
<MetricsTitle />
4+
<slot />
5+
</UContainer>
6+
</template>
7+
8+
<script lang="ts" setup></script>
9+
10+
<style></style>

web/nuxt.config.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
// https://nuxt.com/docs/api/configuration/nuxt-config
22
export default defineNuxtConfig({
33
devtools: { enabled: true },
4+
alias: {
5+
"@global-shared/*": "../../shared/*",
6+
},
47
ssr: false,
58
nitro: {
69
storage: {
710
metrics: {
8-
driver: "memory",
11+
driver: "fs",
12+
base: "./data/metrics",
913
},
1014
pushSubs: {
1115
driver: "fs",
1216
base: "./data/pushSubs",
1317
},
18+
serverState: {
19+
driver: "fs",
20+
base: "./data/serverState",
21+
},
1422
},
1523
experimental: {
1624
tasks: true,

web/pages/index.vue

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<template>
2+
<div>
3+
<h1 class="lg:text-xl text-lg font-semi-bold">All available systems</h1>
4+
<div class="grid md:grid-cols-2 grid-cols-1 lg:grid-cols-3 gap-4 py-6">
5+
<div v-for="system in systems">
6+
<SystemOverview
7+
v-if="systemMetricsStreams[system]?.at(-1)"
8+
:name="system"
9+
:link="`/systems/${system}`"
10+
:metrics="systemMetricsStreams[system].at(-1)!"
11+
/>
12+
</div>
13+
</div>
14+
</div>
15+
</template>
16+
17+
<script lang="ts" setup>
18+
import type { Metrics } from "../../shared/types";
19+
20+
const systems = (await $fetch("/api/sytems")) ?? [];
21+
const systemMetricsStreams = reactive<Record<string, Metrics[]>>({});
22+
23+
function setupMetricsStream() {
24+
systems.forEach((system) => {
25+
const metricsStream = new EventSource("/api/metrics-stream?name=" + system);
26+
27+
metricsStream.onmessage = (event) => {
28+
const newMetrics = JSON.parse(event.data) as Metrics[];
29+
30+
systemMetricsStreams[system] = newMetrics;
31+
};
32+
});
33+
}
34+
35+
onMounted(() => {
36+
setupMetricsStream();
37+
});
38+
</script>
39+
40+
<style></style>

0 commit comments

Comments
 (0)