Skip to content

Commit 2f3477a

Browse files
core: frontend: Add health_monitor
Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
1 parent 520ff81 commit 2f3477a

File tree

7 files changed

+457
-0
lines changed

7 files changed

+457
-0
lines changed

core/frontend/src/menus.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ const menus = [
5050
advanced: true,
5151
text: 'Visualize disk usage and delete files/folders.',
5252
},
53+
{
54+
title: 'Health Monitor',
55+
icon: 'mdi-heart-pulse',
56+
route: '/tools/health-monitor',
57+
advanced: false,
58+
text: 'Monitor system and vehicle health warnings.',
59+
},
5360
{
5461
title: 'Log Browser',
5562
icon: 'mdi-math-log',

core/frontend/src/router/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ const routes: Array<RouteConfig> = [
4848
name: 'Disk',
4949
component: defineAsyncComponent(() => import('../views/Disk.vue')),
5050
},
51+
{
52+
path: '/tools/health-monitor',
53+
name: 'Health Monitor',
54+
component: defineAsyncComponent(() => import('../views/HealthMonitor.vue')),
55+
},
5156
{
5257
path: '/tools/web-terminal',
5358
name: 'Terminal',
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import {
2+
Action, Module, Mutation, VuexModule, getModule,
3+
} from 'vuex-module-decorators'
4+
5+
import store from '@/store'
6+
import { HealthHistory, HealthSummary } from '@/types/health-monitor'
7+
import back_axios, { isBackendOffline } from '@/utils/api'
8+
9+
@Module({ dynamic: true, store, name: 'health_monitor' })
10+
class HealthMonitorStore extends VuexModule {
11+
API_URL = '/health-monitor/v1.0/health'
12+
13+
summary: HealthSummary | null = null
14+
15+
history: HealthHistory | null = null
16+
17+
loading = false
18+
19+
error: string | null = null
20+
21+
@Mutation
22+
setSummary(value: HealthSummary | null): void {
23+
this.summary = value
24+
}
25+
26+
@Mutation
27+
setHistory(value: HealthHistory | null): void {
28+
this.history = value
29+
}
30+
31+
@Mutation
32+
setLoading(value: boolean): void {
33+
this.loading = value
34+
}
35+
36+
@Mutation
37+
setError(message: string | null): void {
38+
this.error = message
39+
}
40+
41+
@Action
42+
async fetchSummary(): Promise<void> {
43+
this.setLoading(true)
44+
this.setError(null)
45+
46+
await back_axios({
47+
method: 'get',
48+
url: `${this.API_URL}/summary`,
49+
timeout: 10000,
50+
})
51+
.then((response) => {
52+
this.setSummary(response.data as HealthSummary)
53+
})
54+
.catch((error) => {
55+
this.setSummary(null)
56+
if (isBackendOffline(error)) {
57+
return
58+
}
59+
this.setError(`Failed to fetch health summary: ${error.message}`)
60+
})
61+
.finally(() => {
62+
this.setLoading(false)
63+
})
64+
}
65+
66+
@Action
67+
async fetchHistory(limit = 200): Promise<void> {
68+
await back_axios({
69+
method: 'get',
70+
url: `${this.API_URL}/history`,
71+
params: { limit },
72+
timeout: 10000,
73+
})
74+
.then((response) => {
75+
this.setHistory(response.data as HealthHistory)
76+
})
77+
.catch((error) => {
78+
this.setHistory(null)
79+
if (isBackendOffline(error)) {
80+
return
81+
}
82+
this.setError(`Failed to fetch health history: ${error.message}`)
83+
})
84+
}
85+
}
86+
87+
const health_monitor = getModule(HealthMonitorStore)
88+
89+
export { HealthMonitorStore }
90+
export default health_monitor

core/frontend/src/types/frontend_services.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,13 @@ export const kraken_service: Service = {
119119
version: '0.1.0',
120120
}
121121

122+
export const health_monitor_service: Service = {
123+
name: 'Health Monitor',
124+
description: 'Service to monitor system and vehicle health warnings.',
125+
company: 'Blue Robotics',
126+
version: '0.1.0',
127+
}
128+
122129
export const parameters_service: Service = {
123130
name: 'Parameters service',
124131
description: 'Service to manage vehicle Parameters',
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
export type HealthSeverity = 'info' | 'warn' | 'error' | 'critical'
2+
export type HealthSource = 'system' | 'vehicle' | 'extension' | 'network'
3+
export type HealthEventType = 'problem_detected' | 'problem_resolved' | 'problem_updated'
4+
5+
export interface HealthProblem {
6+
id: string
7+
severity: HealthSeverity
8+
title: string
9+
details: string
10+
source: HealthSource
11+
timestamp: number
12+
metadata?: Record<string, unknown>
13+
first_seen_ms?: number
14+
last_seen_ms?: number
15+
}
16+
17+
export interface HealthEvent extends HealthProblem {
18+
type: HealthEventType
19+
}
20+
21+
export interface HealthSummary {
22+
active: HealthProblem[]
23+
updated_at: number
24+
}
25+
26+
export interface HealthHistory {
27+
events: HealthEvent[]
28+
}

0 commit comments

Comments
 (0)