From 1631521321c3f8a5408ab911a89bf18675521492 Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Sat, 28 Oct 2023 16:01:11 +0800 Subject: [PATCH] feat: add monitor start or stop --- src/client/components/monitor/MonitorInfo.tsx | 76 ++++++++++++++++++- src/server/model/monitor/index.ts | 33 ++++---- src/server/trpc/routers/monitor.ts | 45 +++++++++++ 3 files changed, 136 insertions(+), 18 deletions(-) diff --git a/src/client/components/monitor/MonitorInfo.tsx b/src/client/components/monitor/MonitorInfo.tsx index 89f2fb9..f45034e 100644 --- a/src/client/components/monitor/MonitorInfo.tsx +++ b/src/client/components/monitor/MonitorInfo.tsx @@ -1,7 +1,11 @@ import { Button, Card, Select, Space, Spin } from 'antd'; import dayjs, { Dayjs } from 'dayjs'; import React, { useMemo, useState } from 'react'; -import { trpc } from '../../api/trpc'; +import { + defaultErrorHandler, + defaultSuccessHandler, + trpc, +} from '../../api/trpc'; import { useCurrentWorkspaceId } from '../../store/user'; import { Loading } from '../Loading'; import { getMonitorLink, getMonitorProvider } from '../modals/monitor/provider'; @@ -16,6 +20,7 @@ import { ColorTag } from '../ColorTag'; import { useNavigate } from 'react-router'; import { MonitorStatsBlock } from './MonitorStatsBlock'; import { MonitorEventList } from './MonitorEventList'; +import { useEvent } from '../../hooks/useEvent'; interface MonitorInfoProps { monitorId: string; @@ -34,6 +39,46 @@ export const MonitorInfo: React.FC = React.memo((props) => { workspaceId, monitorId, }); + const changeActiveMutation = trpc.monitor.changeActive.useMutation({ + onSuccess: defaultSuccessHandler, + onError: defaultErrorHandler, + }); + + const trpcUtils = trpc.useContext(); + + const handleStart = useEvent(async () => { + await changeActiveMutation.mutateAsync({ + workspaceId, + monitorId, + active: true, + }); + + trpcUtils.monitor.get.refetch({ + workspaceId, + monitorId, + }); + trpcUtils.monitor.events.refetch({ + workspaceId, + monitorId, + }); + }); + + const handleStop = useEvent(async () => { + await changeActiveMutation.mutateAsync({ + workspaceId, + monitorId, + active: false, + }); + + trpcUtils.monitor.get.refetch({ + workspaceId, + monitorId, + }); + trpcUtils.monitor.events.refetch({ + workspaceId, + monitorId, + }); + }); if (isInitialLoading) { return ; @@ -46,10 +91,17 @@ export const MonitorInfo: React.FC = React.memo((props) => { return (
- +
-
{monitorInfo.name}
+
+ {monitorInfo.name} + {monitorInfo.active === false && ( +
+ Stoped +
+ )} +
@@ -65,7 +117,7 @@ export const MonitorInfo: React.FC = React.memo((props) => {
-
+
+ + {monitorInfo.active ? ( + + ) : ( + + )}
diff --git a/src/server/model/monitor/index.ts b/src/server/model/monitor/index.ts index f5b5047..fccd347 100644 --- a/src/server/model/monitor/index.ts +++ b/src/server/model/monitor/index.ts @@ -108,6 +108,10 @@ class MonitorManager { console.log('All monitor has been begin.'); }); } + + getRunner(monitorId: string): MonitorRunner | undefined { + return this.monitorRunner[monitorId]; + } } /** @@ -154,13 +158,10 @@ class MonitorRunner { // check event update if (value < 0 && currentStatus === 'UP') { - await prisma.monitorEvent.create({ - data: { - message: `Monitor [${monitor.name}] has been down`, - monitorId: monitor.id, - type: 'DOWN', - }, - }); + await this.createEvent( + 'DOWN', + `Monitor [${monitor.name}] has been down` + ); await this.notify( `[${monitor.name}] 🔴 Down`, `[${monitor.name}] 🔴 Down\nTime: ${dayjs().format( @@ -168,13 +169,7 @@ class MonitorRunner { )}` ); } else if (value > 0 && currentStatus === 'DOWN') { - await prisma.monitorEvent.create({ - data: { - message: `Monitor [${monitor.name}] has been up`, - monitorId: monitor.id, - type: 'UP', - }, - }); + await this.createEvent('UP', `Monitor [${monitor.name}] has been up`); await this.notify( `[${monitor.name}] ✅ Up`, `[${monitor.name}] ✅ Up\nTime: ${dayjs().format( @@ -219,6 +214,16 @@ class MonitorRunner { this.startMonitor(); } + async createEvent(type: 'UP' | 'DOWN', message: string) { + return await prisma.monitorEvent.create({ + data: { + message, + monitorId: this.monitor.id, + type, + }, + }); + } + async notify(title: string, message: string) { const notifications = this.monitor.notifications; await Promise.all( diff --git a/src/server/trpc/routers/monitor.ts b/src/server/trpc/routers/monitor.ts index 53b51d0..fbc311e 100644 --- a/src/server/trpc/routers/monitor.ts +++ b/src/server/trpc/routers/monitor.ts @@ -161,6 +161,51 @@ export const monitorRouter = router({ }, }); }), + changeActive: workspaceOwnerProcedure + .meta( + buildMonitorOpenapi({ + method: 'PATCH', + path: '/{monitorId}/changeActive', + }) + ) + .input( + z.object({ + monitorId: z.string(), + active: z.boolean(), + }) + ) + .output(monitorInfoSchema) + .mutation(async ({ input, ctx }) => { + const { workspaceId, monitorId, active } = input; + + const monitor = await prisma.monitor.update({ + where: { + workspaceId, + id: monitorId, + }, + data: { + active, + }, + }); + const runner = monitorManager.getRunner(monitorId); + if (runner) { + if (active === true) { + runner.startMonitor(); + runner.createEvent( + 'UP', + `Monitor [${monitor.name}] has been manual start` + ); + } else { + runner.stopMonitor(); + runner.createEvent( + 'DOWN', + `Monitor [${monitor.name}] has been manual stop` + ); + } + } + + return monitor; + }), recentData: workspaceProcedure .meta( buildMonitorOpenapi({