mirror of
https://github.com/Sagit-chu/flvx.git
synced 2026-10-06 10:06:36 +08:00
feat(monitoring): add node/tunnel metrics, service monitors, and health checks
- Add NodeMetric/TunnelMetric/ServiceMonitor models and repository methods - Implement metrics ingestion service with per-minute bucket aggregation - Add health checker for node connectivity monitoring - Wire node metrics from WebSocket SystemInfo messages - Add tunnel metrics ingestion from flow upload endpoint - Create monitoring REST API endpoints for nodes, tunnels, services - Implement service monitor CRUD and execution (TCP/ICMP checks) - Add MonitorPermission for non-admin access control - Create frontend monitor page with node/tunnel/service views - Add tunnel metrics ingestion from agent flow reports - Include schema migration for tunnel_metric unique index - Fix tunnel entry port conflict validation to use transaction Entire-Checkpoint: 030821a7c8e3
This commit is contained in:
@@ -26,6 +26,16 @@ import type {
|
||||
SpeedLimitMutationPayload,
|
||||
UpdatePasswordPayload,
|
||||
BackupImportPayload,
|
||||
NodeMetricApiItem,
|
||||
TunnelMetricApiItem,
|
||||
ServiceMonitorApiItem,
|
||||
ServiceMonitorResultApiItem,
|
||||
ServiceMonitorLimitsApiData,
|
||||
ServiceMonitorMutationPayload,
|
||||
MonitorNodeApiItem,
|
||||
MonitorTunnelApiItem,
|
||||
MonitorPermissionApiItem,
|
||||
MonitorAccessApiData,
|
||||
} from "./types";
|
||||
|
||||
import axios from "axios";
|
||||
@@ -372,3 +382,85 @@ export const getAnnouncement = () =>
|
||||
Network.get<AnnouncementData>("/announcement/get");
|
||||
export const updateAnnouncement = (data: AnnouncementData) =>
|
||||
Network.post("/announcement/update", data);
|
||||
|
||||
export const getNodeMetrics = (
|
||||
nodeId: number,
|
||||
start?: number,
|
||||
end?: number,
|
||||
) => {
|
||||
const params: Record<string, string> = {};
|
||||
|
||||
if (start) params.start = String(start);
|
||||
if (end) params.end = String(end);
|
||||
|
||||
return Network.get<NodeMetricApiItem[]>(
|
||||
`/monitor/nodes/${nodeId}/metrics`,
|
||||
params,
|
||||
);
|
||||
};
|
||||
|
||||
export const getNodeMetricsLatest = (nodeId: number) =>
|
||||
Network.get<NodeMetricApiItem>(`/monitor/nodes/${nodeId}/metrics/latest`);
|
||||
|
||||
export const getTunnelMetrics = (
|
||||
tunnelId: number,
|
||||
start?: number,
|
||||
end?: number,
|
||||
) => {
|
||||
const params: Record<string, string> = {};
|
||||
|
||||
if (start) params.start = String(start);
|
||||
if (end) params.end = String(end);
|
||||
|
||||
return Network.get<TunnelMetricApiItem[]>(
|
||||
`/monitor/tunnels/${tunnelId}/metrics`,
|
||||
params,
|
||||
);
|
||||
};
|
||||
|
||||
export const getMonitorTunnels = () =>
|
||||
Network.get<MonitorTunnelApiItem[]>("/monitor/tunnels");
|
||||
|
||||
export const getServiceMonitorList = () =>
|
||||
Network.get<ServiceMonitorApiItem[]>("/monitor/services");
|
||||
|
||||
export const getServiceMonitorLimits = () =>
|
||||
Network.get<ServiceMonitorLimitsApiData>("/monitor/services/limits");
|
||||
|
||||
export const createServiceMonitor = (data: ServiceMonitorMutationPayload) =>
|
||||
Network.post<ServiceMonitorApiItem>("/monitor/services/create", data);
|
||||
|
||||
export const updateServiceMonitor = (data: ServiceMonitorMutationPayload) =>
|
||||
Network.post<ServiceMonitorApiItem>("/monitor/services/update", data);
|
||||
|
||||
export const deleteServiceMonitor = (id: number) =>
|
||||
Network.post("/monitor/services/delete", { id });
|
||||
|
||||
export const getServiceMonitorResults = (monitorId: number, limit = 100) =>
|
||||
Network.get<ServiceMonitorResultApiItem[]>(
|
||||
`/monitor/services/${monitorId}/results`,
|
||||
{ limit: String(limit) },
|
||||
);
|
||||
|
||||
export const getServiceMonitorLatestResults = () =>
|
||||
Network.get<ServiceMonitorResultApiItem[]>(
|
||||
"/monitor/services/latest-results",
|
||||
);
|
||||
|
||||
export const runServiceMonitor = (id: number) =>
|
||||
Network.post<ServiceMonitorResultApiItem>("/monitor/services/run", { id });
|
||||
|
||||
export const getMonitorNodes = () =>
|
||||
Network.get<MonitorNodeApiItem[]>("/monitor/nodes");
|
||||
|
||||
export const getMonitorAccess = () =>
|
||||
Network.get<MonitorAccessApiData>("/monitor/access");
|
||||
|
||||
export const getMonitorPermissionList = () =>
|
||||
Network.get<MonitorPermissionApiItem[]>("/monitor/permission/list");
|
||||
|
||||
export const assignMonitorPermission = (userId: number) =>
|
||||
Network.post("/monitor/permission/assign", { userId });
|
||||
|
||||
export const removeMonitorPermission = (userId: number) =>
|
||||
Network.post("/monitor/permission/remove", { userId });
|
||||
|
||||
Reference in New Issue
Block a user