Remove HTTP service check

Remove HTTP service check functionality as the React application is now frontend only.
This commit is contained in:
Tola Leng
2025-06-18 16:47:00 +08:00
parent 78674f758c
commit 94e2c0da77
5 changed files with 66 additions and 185 deletions
@@ -1,7 +1,7 @@
import { FormControl, FormField, FormItem, FormLabel } from "@/components/ui/form"; import { FormControl, FormField, FormItem, FormLabel } from "@/components/ui/form";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Globe } from "lucide-react"; import { Globe, Wifi, Server, Globe2 } from "lucide-react";
import { UseFormReturn } from "react-hook-form"; import { UseFormReturn } from "react-hook-form";
import { ServiceFormData } from "./types"; import { ServiceFormData } from "./types";
@@ -10,6 +10,21 @@ interface ServiceTypeFieldProps {
} }
export function ServiceTypeField({ form }: ServiceTypeFieldProps) { export function ServiceTypeField({ form }: ServiceTypeFieldProps) {
const getServiceIcon = (type: string) => {
switch (type) {
case "http":
return <Globe className="w-4 h-4" />;
case "ping":
return <Wifi className="w-4 h-4" />;
case "tcp":
return <Server className="w-4 h-4" />;
case "dns":
return <Globe2 className="w-4 h-4" />;
default:
return <Globe className="w-4 h-4" />;
}
};
return ( return (
<FormField <FormField
control={form.control} control={form.control}
@@ -24,13 +39,13 @@ export function ServiceTypeField({ form }: ServiceTypeFieldProps) {
> >
<SelectTrigger> <SelectTrigger>
<SelectValue> <SelectValue>
{field.value === "http" && ( {field.value && (
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Globe className="w-4 h-4" /> {getServiceIcon(field.value)}
<span>HTTP/S</span> <span>{field.value.toUpperCase()}</span>
</div> </div>
)} )}
{field.value !== "http" && "Select a service type"} {!field.value && "Select a service type"}
</SelectValue> </SelectValue>
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
@@ -41,13 +56,43 @@ export function ServiceTypeField({ form }: ServiceTypeFieldProps) {
<span>HTTP/S</span> <span>HTTP/S</span>
</div> </div>
<p className="text-xs text-muted-foreground mt-1"> <p className="text-xs text-muted-foreground mt-1">
Monitor websites and REST APIs with HTTP/HTTPS protocol Monitor websites and REST APIs with HTTP/HTTPS Protocol
</p>
</div>
</SelectItem>
<SelectItem value="ping">
<div className="flex flex-col">
<div className="flex items-center gap-2">
<Wifi className="w-4 h-4" />
<span>PING</span>
</div>
<p className="text-xs text-muted-foreground mt-1">
Monitor host availability with PING Protocol
</p>
</div>
</SelectItem>
<SelectItem value="tcp">
<div className="flex flex-col">
<div className="flex items-center gap-2">
<Server className="w-4 h-4" />
<span>TCP</span>
</div>
<p className="text-xs text-muted-foreground mt-1">
Monitor TCP port connectivity with TCP Protocol
</p>
</div>
</SelectItem>
<SelectItem value="dns">
<div className="flex flex-col">
<div className="flex items-center gap-2">
<Globe2 className="w-4 h-4" />
<span>DNS</span>
</div>
<p className="text-xs text-muted-foreground mt-1">
Monitor DNS resolution
</p> </p>
</div> </div>
</SelectItem> </SelectItem>
<SelectItem value="ping">PING</SelectItem>
<SelectItem value="tcp">TCP</SelectItem>
<SelectItem value="dns">DNS</SelectItem>
</SelectContent> </SelectContent>
</Select> </Select>
</FormControl> </FormControl>
@@ -1,6 +1,5 @@
import { monitoringIntervals } from './monitoringIntervals'; import { monitoringIntervals } from './monitoringIntervals';
import { checkHttpService } from './httpChecker';
import { import {
startMonitoringService, startMonitoringService,
pauseMonitoring, pauseMonitoring,
@@ -12,6 +11,5 @@ export const monitoringService = {
startMonitoringService, startMonitoringService,
pauseMonitoring, pauseMonitoring,
resumeMonitoring, resumeMonitoring,
checkHttpService,
startAllActiveServices startAllActiveServices
}; };
@@ -1,7 +1,6 @@
import { pb } from '@/lib/pocketbase'; import { pb } from '@/lib/pocketbase';
import { monitoringIntervals } from '../monitoringIntervals'; import { monitoringIntervals } from '../monitoringIntervals';
import { checkHttpService } from '../httpChecker';
/** /**
* Start monitoring for a specific service * Start monitoring for a specific service
@@ -30,34 +29,20 @@ export async function startMonitoringService(serviceId: string): Promise<void> {
status: "up", status: "up",
}); });
// Start with an immediate check // The actual service checking is now handled by the Go microservice
await checkHttpService(serviceId); // This frontend service just tracks the monitoring state
const intervalMs = (service.heartbeat_interval || 60) * 1000;
console.log(`Service ${service.name} monitoring delegated to backend service`);
// Then schedule regular checks based on the interval // Store a placeholder interval to track that this service is being monitored
const intervalMs = (service.heartbeat_interval || 60) * 1000; // Convert from seconds to milliseconds const intervalId = window.setInterval(() => {
console.log(`Setting check interval for ${service.name} to ${intervalMs}ms (${service.heartbeat_interval || 60} seconds)`); console.log(`Monitoring active for service ${service.name} (handled by backend)`);
// Store the interval ID so we can clear it later if needed
const intervalId = window.setInterval(async () => {
try {
// Check if service has been paused since scheduling
const currentService = await pb.collection('services').getOne(serviceId);
if (currentService.status === "paused") {
console.log(`Service ${serviceId} is now paused. Skipping scheduled check.`);
return;
}
console.log(`Running scheduled check for service ${service.name}`);
await checkHttpService(serviceId);
} catch (error) {
console.error(`Error in scheduled check for ${service.name}:`, error);
}
}, intervalMs); }, intervalMs);
// Store the interval ID for this service // Store the interval ID for this service
monitoringIntervals.set(serviceId, intervalId); monitoringIntervals.set(serviceId, intervalId);
console.log(`Monitoring scheduled for service ${serviceId} every ${service.heartbeat_interval || 60} seconds`); console.log(`Monitoring registered for service ${serviceId}`);
} catch (error) { } catch (error) {
console.error("Error starting service monitoring:", error); console.error("Error starting service monitoring:", error);
} }
@@ -57,148 +57,3 @@ export function formatCurrentTime(): string {
const now = new Date(); const now = new Date();
return now.toISOString(); return now.toISOString();
} }
/**
* Make an HTTP request to a service endpoint with retry logic
* Improved to better handle different response scenarios and detection issues
*/
export async function makeHttpRequest(url: string, maxRetries: number = 3): Promise<{ isUp: boolean; responseTime: number }> {
let retries = 0;
let isUp = false;
let responseTime = 0;
let lastError = null;
const startTime = performance.now();
try {
// Ensure URL has proper protocol
const targetUrl = ensureHttpsProtocol(url);
while (retries < maxRetries && !isUp) {
try {
// Use fetch API with a timeout to prevent long-hanging requests
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 second timeout
console.log(`Attempt ${retries + 1}/${maxRetries} checking ${targetUrl}`);
// IMPROVED APPROACH: Try multiple detection methods in sequence
// Method 1: Try HEAD request first as it's lightweight
try {
console.log(`Trying HEAD request to ${targetUrl}`);
const headResponse = await fetch(targetUrl, {
method: 'HEAD',
signal: controller.signal,
cache: 'no-cache',
headers: {
'Accept': '*/*',
'User-Agent': 'ServiceMonitor/1.0'
}
});
// If HEAD request succeeds with any status code, service is reachable
isUp = true;
console.log(`HEAD request successful with status ${headResponse.status}`);
} catch (headError) {
console.log(`HEAD request failed: ${headError.message}`);
lastError = headError;
// Method 2: Fall back to standard GET with proper error handling
try {
console.log(`Trying standard GET request to ${targetUrl}`);
const getResponse = await fetch(targetUrl, {
method: 'GET',
signal: controller.signal,
cache: 'no-cache',
headers: {
'Accept': '*/*',
'User-Agent': 'ServiceMonitor/1.0'
}
});
// If GET returns any response, consider the service up
isUp = true;
console.log(`GET request successful with status ${getResponse.status}`);
} catch (getError) {
console.log(`Standard GET request failed: ${getError.message}`);
lastError = getError;
// Method 3: Try with no-cors mode as a last resort
try {
console.log(`Trying no-cors GET request to ${targetUrl}`);
const noCorsResponse = await fetch(targetUrl, {
method: 'GET',
mode: 'no-cors', // This allows requests to succeed even if CORS is restricted
signal: controller.signal,
cache: 'no-cache'
});
// In no-cors mode, we can't read the response, but if we get here without an exception,
// the request succeeded and the service is likely up
isUp = true;
console.log(`No-cors GET request succeeded, assuming service is UP`);
} catch (corsError) {
console.log(`No-cors GET request also failed: ${corsError.message}`);
lastError = corsError;
isUp = false;
}
// Method 4: If all fetches fail but error is CORS-related, consider service up
if (!isUp && lastError &&
(lastError.message.includes('CORS') ||
lastError.message.includes('blocked') ||
lastError.message.includes('policy'))) {
console.log("CORS error detected, but this likely means the service is running.");
console.log("Setting service as UP despite CORS restriction.");
isUp = true;
}
}
}
clearTimeout(timeoutId);
responseTime = Math.round(performance.now() - startTime);
if (isUp) {
console.log(`Service is detected as UP after ${retries + 1} attempts, response time: ${responseTime}ms`);
break;
} else {
console.log(`All connection attempts failed for attempt ${retries + 1}`);
retries++;
// Add a short delay between retries
if (retries < maxRetries) {
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
} catch (error) {
console.error(`HTTP request attempt ${retries + 1} failed with error:`, error);
lastError = error;
retries++;
if (retries < maxRetries) {
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
}
} catch (error) {
console.error('Critical error in makeHttpRequest:', error);
isUp = false;
responseTime = Math.round(performance.now() - startTime);
lastError = error;
}
// Final check for status
if (!isUp && lastError) {
console.log("Final connection attempt failed with error:", lastError);
// Check for specific errors that might indicate the site is actually up
if (lastError.name === 'AbortError') {
console.log("Request timed out which may indicate a slow response rather than service down");
}
}
// Log the final result for debugging
console.log(`Final service check result - URL: ${url}, isUp: ${isUp}, responseTime: ${responseTime}ms, retries: ${retries}`);
return { isUp, responseTime };
}
@@ -1,4 +1,3 @@
import { pb } from '@/lib/pocketbase'; import { pb } from '@/lib/pocketbase';
import { Service, CreateServiceParams, UptimeData } from '@/types/service.types'; import { Service, CreateServiceParams, UptimeData } from '@/types/service.types';
import { monitoringService } from './monitoring'; import { monitoringService } from './monitoring';
@@ -144,7 +143,6 @@ export const serviceService = {
startMonitoringService: monitoringService.startMonitoringService, startMonitoringService: monitoringService.startMonitoringService,
pauseMonitoring: monitoringService.pauseMonitoring, pauseMonitoring: monitoringService.pauseMonitoring,
resumeMonitoring: monitoringService.resumeMonitoring, resumeMonitoring: monitoringService.resumeMonitoring,
checkHttpService: monitoringService.checkHttpService,
startAllActiveServices: monitoringService.startAllActiveServices, startAllActiveServices: monitoringService.startAllActiveServices,
// Re-export uptime functions // Re-export uptime functions