Files
supabase/apps/studio/components/interfaces/Observability/useServiceHealthMetrics.utils.ts
Jordi Enric 88ed2aad97 new home: refactor charts to use old sources (#42245)
- refactors new charts in homepage to use stable analytics endpoints
- changes are behind newHomepageUsageV2 flag

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Centralized per-service health metrics hook with per-service data,
loading/error states and refresh.

* **Improvements**
  * Time-series normalization into fixed buckets aligned to an end time.
* Updated UI: success-rate formatting, per-service loading/error
surfaced, refreshed click/refresh behavior; removed delta display.

* **Removals**
  * Legacy project-metrics query and mapping utilities removed.

* **Tests**
* Extensive unit tests added for date ranges, bucket normalization, and
health metric calculations; some obsolete tests removed.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-28 17:02:00 +00:00

104 lines
2.7 KiB
TypeScript

import dayjs from 'dayjs'
import type { LogsBarChartDatum } from '../HomeNew/ProjectUsage.metrics'
import {
computeSuccessAndNonSuccessRates,
sumErrors,
sumTotal,
sumWarnings,
} from '../HomeNew/ProjectUsage.metrics'
/**
* Calculates the date range for fetching service health metrics
* based on the selected interval
*/
export const calculateDateRange = (
interval: '1hr' | '1day' | '7day'
): { startDate: string; endDate: string } => {
const now = dayjs()
const end = now.toISOString()
let start: string
switch (interval) {
case '1hr':
start = now.subtract(1, 'hour').toISOString()
break
case '1day':
start = now.subtract(1, 'day').toISOString()
break
case '7day':
start = now.subtract(7, 'day').toISOString()
break
default:
start = now.subtract(1, 'hour').toISOString()
}
return { startDate: start, endDate: end }
}
type RawChartData = {
timestamp: string | number
ok_count?: number | null
warning_count?: number | null
error_count?: number | null
}
/**
* Transforms raw chart query results to LogsBarChartDatum format
*/
export const transformToBarChartData = (data: RawChartData[]): LogsBarChartDatum[] => {
return data.map((row) => ({
timestamp: typeof row.timestamp === 'string' ? row.timestamp : String(row.timestamp),
ok_count: row.ok_count || 0,
warning_count: row.warning_count || 0,
error_count: row.error_count || 0,
}))
}
/**
* Calculates health metrics from bar chart data
*/
export const calculateHealthMetrics = (eventChartData: LogsBarChartDatum[]) => {
const total = sumTotal(eventChartData)
const errorCount = sumErrors(eventChartData)
const warningCount = sumWarnings(eventChartData)
const okCount = total - errorCount - warningCount
const errorRate = total > 0 ? (errorCount / total) * 100 : 0
const { successRate } = computeSuccessAndNonSuccessRates(total, warningCount, errorCount)
return {
total,
errorRate,
successRate,
errorCount,
warningCount,
okCount,
}
}
/**
* Calculates aggregated metrics across all services
*/
export const calculateAggregatedMetrics = (
services: {
total: number
errorCount: number
warningCount: number
}[]
) => {
const totalRequests = services.reduce((sum, s) => sum + s.total, 0)
const totalErrors = services.reduce((sum, s) => sum + s.errorCount, 0)
const totalWarnings = services.reduce((sum, s) => sum + s.warningCount, 0)
const { successRate: overallSuccessRate, nonSuccessRate: overallErrorRate } =
computeSuccessAndNonSuccessRates(totalRequests, totalWarnings, totalErrors)
return {
totalRequests,
totalErrors,
totalWarnings,
overallErrorRate,
overallSuccessRate,
}
}