feat(services): enhance service health management with IP health tracking
quality / commitlint (push) Skipped
CD / update-wiki (push) Successful in 6s
quality / changes (push) Successful in 5s
quality / docker-check (push) Skipped
quality / web (push) Successful in 55s
quality / api (push) Successful in 41s
CD / quality (push) Successful in 1m45s
CD / publish (push) Successful in 1m33s

- Introduced IP health tracking in service views, allowing for detailed monitoring of individual IP statuses and latencies.
- Updated the service configuration to include an `ip_health` array, providing structured health data for each IP.
- Enhanced the `attachServiceHealth` function to aggregate IP health data alongside overall service health.
- Modified relevant components to display IP health information, improving visibility and user experience in service management interfaces.

This commit significantly improves the health monitoring capabilities of services, enabling better insights into the status of individual IPs associated with each service.
This commit is contained in:
Denozordec
2026-08-19 14:57:19 +07:00
parent 4ca948292d
commit 4224db8eb3
15 changed files with 346 additions and 157 deletions
+58 -1
View File
@@ -132,6 +132,7 @@ interface ServiceView$1 {
domains: ServiceDomainBindingView[];
health_status: IpHealthState;
health_latency_ms: number | null;
ip_health: ServiceIpHealth$1[];
}
interface SyncJob {
id: string;
@@ -192,6 +193,11 @@ interface IpHealthStatus {
last_checked_at: string | null;
last_error: string | null;
}
interface ServiceIpHealth$1 {
ip: string;
status: IpHealthState;
latency_ms: number | null;
}
interface ServiceNode {
id: number;
service_id: number;
@@ -372,6 +378,17 @@ declare const ipHealthStatusSchema: z.ZodObject<{
last_checked_at: z.ZodNullable<z.ZodString>;
last_error: z.ZodNullable<z.ZodString>;
}, z.core.$strip>;
declare const serviceIpHealthSchema: z.ZodObject<{
ip: z.ZodString;
status: z.ZodEnum<{
unknown: "unknown";
up: "up";
down: "down";
degraded: "degraded";
}>;
latency_ms: z.ZodNullable<z.ZodNumber>;
}, z.core.$strip>;
type ServiceIpHealth = z.infer<typeof serviceIpHealthSchema>;
declare const groupSchema: z.ZodObject<{
id: z.ZodNumber;
name: z.ZodString;
@@ -619,6 +636,16 @@ declare const serviceViewSchema: z.ZodObject<{
degraded: "degraded";
}>>;
health_latency_ms: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
ip_health: z.ZodDefault<z.ZodArray<z.ZodObject<{
ip: z.ZodString;
status: z.ZodEnum<{
unknown: "unknown";
up: "up";
down: "down";
degraded: "degraded";
}>;
latency_ms: z.ZodNullable<z.ZodNumber>;
}, z.core.$strip>>>;
}, z.core.$strip>;
declare const serviceGroupViewSchema: z.ZodObject<{
id: z.ZodNumber;
@@ -752,6 +779,16 @@ declare const serviceGroupViewSchema: z.ZodObject<{
degraded: "degraded";
}>>;
health_latency_ms: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
ip_health: z.ZodDefault<z.ZodArray<z.ZodObject<{
ip: z.ZodString;
status: z.ZodEnum<{
unknown: "unknown";
up: "up";
down: "down";
degraded: "degraded";
}>;
latency_ms: z.ZodNullable<z.ZodNumber>;
}, z.core.$strip>>>;
}, z.core.$strip>>>;
health_status: z.ZodDefault<z.ZodEnum<{
unknown: "unknown";
@@ -894,6 +931,16 @@ declare const serviceGroupsResponseSchema: z.ZodObject<{
degraded: "degraded";
}>>;
health_latency_ms: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
ip_health: z.ZodDefault<z.ZodArray<z.ZodObject<{
ip: z.ZodString;
status: z.ZodEnum<{
unknown: "unknown";
up: "up";
down: "down";
degraded: "degraded";
}>;
latency_ms: z.ZodNullable<z.ZodNumber>;
}, z.core.$strip>>>;
}, z.core.$strip>>>;
health_status: z.ZodDefault<z.ZodEnum<{
unknown: "unknown";
@@ -1002,6 +1049,16 @@ declare const serviceGroupsResponseSchema: z.ZodObject<{
degraded: "degraded";
}>>;
health_latency_ms: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
ip_health: z.ZodDefault<z.ZodArray<z.ZodObject<{
ip: z.ZodString;
status: z.ZodEnum<{
unknown: "unknown";
up: "up";
down: "down";
degraded: "degraded";
}>;
latency_ms: z.ZodNullable<z.ZodNumber>;
}, z.core.$strip>>>;
}, z.core.$strip>>>;
}, z.core.$strip>;
declare const domainSchema: z.ZodObject<{
@@ -1835,4 +1892,4 @@ declare const ingestAuditEventSchema: z.ZodObject<{
}, z.core.$strip>;
type IngestAuditEvent = z.infer<typeof ingestAuditEventSchema>;
export { AUDIT_SEVERITIES, AUDIT_SOURCE_APPS, AUDIT_TARGET_TYPES, type AppSettingsPatch, type AppSwitcherConfig, type AppSwitcherEntry, type AuditListQuery, type AuditLogEntry, type AuditSeverity, type AuditSourceApp, type AuditTargetType, type BulkUpdateDomainsInput, CERT_ERROR, CERT_EXPIRED, CERT_MONITORING_VALUES, CERT_MONITOR_AUTO, CERT_MONITOR_REQUIRED, CERT_MONITOR_SKIPPED, CERT_OK, CERT_UNKNOWN, CERT_WARNING, type CertMonitoring, type Certificate, type CfDnsRecord, type CfHealthCheck, type CfZone, type CfdmBindingSyncItem, type ChangeDomainInput, type ChangeIpInput, type CreateDnsRecordInput, type CreateDnsRecordPayload, type CreateDomainInput, type CreateDomainMonitorInput, type CreateGroupInput, type CreateOriginHealthCheckInput, type CreateServiceBindingInput, type CreateServiceGroupInput, type CreateServiceInput, type CreateServiceNodeInput, type CreateServiceWithConfigInput, type CreateSubdomainInput, type DnsRecord, type Domain, type DomainEnvironment, type DomainListItem, type DomainMonitor, type DomainMonitorResult, type DomainMonitorType, type Group, type GroupWithStats, type HealthCheckConfig, type HealthCheckProvider, type HealthCheckScope, type HealthCheckTarget, type HealthCheckType, type HealthStatusQuery, type IngestAuditEvent, type IpHealthState, type IpHealthStatus, type JwtClaims, type LbMode, type LoginInput, type LoginRequest, type LoginResponse, type NodeHealthState, type NotificationLog, type OriginHealthCheck, type OriginHealthCheckRecord, type ParsedFqdn, type PatchDnsRecordPayload, type ReorderServicesInput, SYNC_CONFLICT, SYNC_ERROR, SYNC_PENDING_DELETE, SYNC_PENDING_PUSH, SYNC_SYNCED, type Service, type ServiceBinding, type ServiceBindingView, type ServiceDomainBinding, type ServiceDomainBindingView, type ServiceGroup, type ServiceGroupView, type ServiceGroupsResponse, type ServiceNode, type ServiceNodeRecord, type ServiceOverview, type ServiceView, type Subdomain, type SubdomainRecord, type SyncJob, type ToggleEnabledInput, type UpdateDomainInput, type UpdateServiceConfigInput, type UpdateServiceGroupInput, type UpdateServiceNodeInput, type UpdateSubdomainInput, ValidationError, type VpsTrackerEvent, appSettingsPatchSchema, appSwitcherConfigSchema, appSwitcherEntrySchema, appSwitcherIconSchema, auditListQuerySchema, auditLogEntrySchema, auditSeveritySchema, auditSourceAppSchema, auditTargetTypeSchema, bindingToFqdn, bulkUpdateDomainsSchema, certMonitoringSchema, certStatusFromExpiry, certificateSchema, cfdmBindingSyncItemSchema, cfdmSyncBindingsBodySchema, changeDomainSchema, changeIpSchema, createDnsRecordSchema, createDomainMonitorSchema, createDomainSchema, createGroupSchema, createOriginHealthCheckSchema, createServiceBindingSchema, createServiceGroupSchema, createServiceNodeSchema, createServiceSchema, createServiceWithConfigSchema, createSubdomainSchema, dnsNameToSubdomainLabel, dnsRecordNamesMatch, dnsRecordSchema, domainEnvironmentSchema, domainListItemSchema, domainMonitorResultSchema, domainMonitorSchema, domainMonitorTypeSchema, domainSchema, fqdnToDisplay, groupSchema, groupWithStatsSchema, healthCheckConfigSchema, healthCheckProviderSchema, healthCheckScopeSchema, healthCheckTypeSchema, healthStatusQuerySchema, ingestAuditEventSchema, ipHealthStateSchema, ipHealthStatusSchema, isIpLiteral, isValidIpv4, lbModeSchema, loginSchema, nodeHealthStateSchema, normalizeDnsRecordName, notificationLogSchema, originHealthCheckSchema, parseFqdn, reorderServicesSchema, serviceBindingSchema, serviceDomainBindingSchema, serviceGroupSchema, serviceGroupTypeSchema, serviceGroupViewSchema, serviceGroupsResponseSchema, serviceNodeSchema, serviceSchema, serviceViewSchema, shouldMonitorService, subdomainLabelToFqdn, subdomainSchema, toggleEnabledSchema, updateDomainGroupSchema, updateDomainSchema, updateServiceConfigSchema, updateServiceGroupSchema, updateServiceNodeSchema, updateSubdomainSchema, validateDnsRecord, vpsTrackerEventSchema };
export { AUDIT_SEVERITIES, AUDIT_SOURCE_APPS, AUDIT_TARGET_TYPES, type AppSettingsPatch, type AppSwitcherConfig, type AppSwitcherEntry, type AuditListQuery, type AuditLogEntry, type AuditSeverity, type AuditSourceApp, type AuditTargetType, type BulkUpdateDomainsInput, CERT_ERROR, CERT_EXPIRED, CERT_MONITORING_VALUES, CERT_MONITOR_AUTO, CERT_MONITOR_REQUIRED, CERT_MONITOR_SKIPPED, CERT_OK, CERT_UNKNOWN, CERT_WARNING, type CertMonitoring, type Certificate, type CfDnsRecord, type CfHealthCheck, type CfZone, type CfdmBindingSyncItem, type ChangeDomainInput, type ChangeIpInput, type CreateDnsRecordInput, type CreateDnsRecordPayload, type CreateDomainInput, type CreateDomainMonitorInput, type CreateGroupInput, type CreateOriginHealthCheckInput, type CreateServiceBindingInput, type CreateServiceGroupInput, type CreateServiceInput, type CreateServiceNodeInput, type CreateServiceWithConfigInput, type CreateSubdomainInput, type DnsRecord, type Domain, type DomainEnvironment, type DomainListItem, type DomainMonitor, type DomainMonitorResult, type DomainMonitorType, type Group, type GroupWithStats, type HealthCheckConfig, type HealthCheckProvider, type HealthCheckScope, type HealthCheckTarget, type HealthCheckType, type HealthStatusQuery, type IngestAuditEvent, type IpHealthState, type IpHealthStatus, type JwtClaims, type LbMode, type LoginInput, type LoginRequest, type LoginResponse, type NodeHealthState, type NotificationLog, type OriginHealthCheck, type OriginHealthCheckRecord, type ParsedFqdn, type PatchDnsRecordPayload, type ReorderServicesInput, SYNC_CONFLICT, SYNC_ERROR, SYNC_PENDING_DELETE, SYNC_PENDING_PUSH, SYNC_SYNCED, type Service, type ServiceBinding, type ServiceBindingView, type ServiceDomainBinding, type ServiceDomainBindingView, type ServiceGroup, type ServiceGroupView, type ServiceGroupsResponse, type ServiceIpHealth, type ServiceNode, type ServiceNodeRecord, type ServiceOverview, type ServiceView, type Subdomain, type SubdomainRecord, type SyncJob, type ToggleEnabledInput, type UpdateDomainInput, type UpdateServiceConfigInput, type UpdateServiceGroupInput, type UpdateServiceNodeInput, type UpdateSubdomainInput, ValidationError, type VpsTrackerEvent, appSettingsPatchSchema, appSwitcherConfigSchema, appSwitcherEntrySchema, appSwitcherIconSchema, auditListQuerySchema, auditLogEntrySchema, auditSeveritySchema, auditSourceAppSchema, auditTargetTypeSchema, bindingToFqdn, bulkUpdateDomainsSchema, certMonitoringSchema, certStatusFromExpiry, certificateSchema, cfdmBindingSyncItemSchema, cfdmSyncBindingsBodySchema, changeDomainSchema, changeIpSchema, createDnsRecordSchema, createDomainMonitorSchema, createDomainSchema, createGroupSchema, createOriginHealthCheckSchema, createServiceBindingSchema, createServiceGroupSchema, createServiceNodeSchema, createServiceSchema, createServiceWithConfigSchema, createSubdomainSchema, dnsNameToSubdomainLabel, dnsRecordNamesMatch, dnsRecordSchema, domainEnvironmentSchema, domainListItemSchema, domainMonitorResultSchema, domainMonitorSchema, domainMonitorTypeSchema, domainSchema, fqdnToDisplay, groupSchema, groupWithStatsSchema, healthCheckConfigSchema, healthCheckProviderSchema, healthCheckScopeSchema, healthCheckTypeSchema, healthStatusQuerySchema, ingestAuditEventSchema, ipHealthStateSchema, ipHealthStatusSchema, isIpLiteral, isValidIpv4, lbModeSchema, loginSchema, nodeHealthStateSchema, normalizeDnsRecordName, notificationLogSchema, originHealthCheckSchema, parseFqdn, reorderServicesSchema, serviceBindingSchema, serviceDomainBindingSchema, serviceGroupSchema, serviceGroupTypeSchema, serviceGroupViewSchema, serviceGroupsResponseSchema, serviceIpHealthSchema, serviceNodeSchema, serviceSchema, serviceViewSchema, shouldMonitorService, subdomainLabelToFqdn, subdomainSchema, toggleEnabledSchema, updateDomainGroupSchema, updateDomainSchema, updateServiceConfigSchema, updateServiceGroupSchema, updateServiceNodeSchema, updateSubdomainSchema, validateDnsRecord, vpsTrackerEventSchema };
+8 -1
View File
@@ -192,6 +192,11 @@ var ipHealthStatusSchema = z.object({
last_checked_at: z.string().nullable(),
last_error: z.string().nullable()
});
var serviceIpHealthSchema = z.object({
ip: z.string(),
status: ipHealthStateSchema,
latency_ms: z.number().nullable()
});
var groupSchema = z.object({
id: z.number(),
name: z.string(),
@@ -277,7 +282,8 @@ var serviceViewSchema = serviceSchema.extend({
ips: z.array(z.string()).default([]),
domains: z.array(serviceDomainBindingSchema).default([]),
health_status: ipHealthStateSchema.default("unknown"),
health_latency_ms: z.number().nullable().default(null)
health_latency_ms: z.number().nullable().default(null),
ip_health: z.array(serviceIpHealthSchema).default([])
});
var serviceGroupViewSchema = serviceGroupSchema.extend({
services: z.array(serviceViewSchema).default([]),
@@ -843,6 +849,7 @@ export {
serviceGroupTypeSchema,
serviceGroupViewSchema,
serviceGroupsResponseSchema,
serviceIpHealthSchema,
serviceNodeSchema,
serviceSchema,
serviceViewSchema,
+9
View File
@@ -49,6 +49,14 @@ export const ipHealthStatusSchema = z.object({
export type IpHealthStatus = z.infer<typeof ipHealthStatusSchema>
export const serviceIpHealthSchema = z.object({
ip: z.string(),
status: ipHealthStateSchema,
latency_ms: z.number().nullable(),
})
export type ServiceIpHealth = z.infer<typeof serviceIpHealthSchema>
export const groupSchema = z.object({
id: z.number(),
name: z.string(),
@@ -150,6 +158,7 @@ export const serviceViewSchema = serviceSchema.extend({
domains: z.array(serviceDomainBindingSchema).default([]),
health_status: ipHealthStateSchema.default('unknown'),
health_latency_ms: z.number().nullable().default(null),
ip_health: z.array(serviceIpHealthSchema).default([]),
})
export const serviceGroupViewSchema = serviceGroupSchema.extend({
+7
View File
@@ -196,6 +196,7 @@ export interface ServiceView {
domains: ServiceDomainBindingView[];
health_status: IpHealthState;
health_latency_ms: number | null;
ip_health: ServiceIpHealth[];
}
export interface GroupWithStats extends Group {
@@ -293,6 +294,12 @@ export interface IpHealthStatus {
last_error: string | null;
}
export interface ServiceIpHealth {
ip: string;
status: IpHealthState;
latency_ms: number | null;
}
export interface ServiceNode {
id: number;
service_id: number;