Add charts for db and storage egress

This commit is contained in:
Joshen Lim committed 2023-05-02 16:36:52 +08:00
1 parent b792c5afcb
commit 940dfc8a44
4 files changed
+221 -46

No files matched your search

@@ -1,24 +1,39 @@
import { useParams } from 'common'
import ShimmeringLoader from 'components/ui/ShimmeringLoader'
import { useInfraMonitoringQuery } from 'data/analytics/infra-monitoring-query'
import dayjs from 'dayjs'
import { DATE_FORMAT } from 'lib/constants'
import { useDailyStatsQuery } from 'data/analytics/daily-stats-query'
import { useProjectSubscriptionQuery } from 'data/subscriptions/project-subscription-query'
import { useProjectUsageQuery } from 'data/usage/project-usage-query'
import BarChart from './BarChart'
import { generateUsageData } from './Usage.utils'
import { Button } from 'ui'
import SparkBar from 'components/ui/SparkBar'
import { formatBytes } from 'lib/helpers'
const Bandwidth = () => {
const { ref } = useParams()
const { data: usage } = useProjectUsageQuery({ projectRef: ref })
const { data: subscription } = useProjectSubscriptionQuery({ projectRef: ref })
const { current_period_start, current_period_end } = subscription?.billing ?? {}
const startDate = new Date((current_period_start ?? 0) * 1000).toISOString()
const endDate = new Date((current_period_end ?? 0) * 1000).toISOString()
const currentDate = 1682669326710 / 1000
const startDate = dayjs.unix(currentDate).subtract(24, 'hour').format(DATE_FORMAT)
const endDate = dayjs.unix(currentDate).format(DATE_FORMAT)
const { data: ioBudgetData, isLoading: isLoadingIoBudgetData } = useInfraMonitoringQuery({
const { db_egress } = usage ?? {}
const dbEgressExcess = (db_egress?.usage ?? 0) - (db_egress?.limit ?? 0)
const { data: dbEgressData, isLoading: isLoadingDbEgressData } = useDailyStatsQuery({
projectRef: ref,
attribute: 'disk_io_budget',
attribute: 'total_rest_egress',
interval: '1d',
startDate,
endDate,
})
const { storage_egress } = usage ?? {}
const storageEgressExcess = (storage_egress?.usage ?? 0) - (storage_egress?.limit ?? 0)
const { data: storageEgressData, isLoading: isLoadingStorageEgressData } = useDailyStatsQuery({
projectRef: ref,
attribute: 'total_storage_egress',
interval: '1d',
startDate,
endDate,
interval: '1h',
})
return (
@@ -31,24 +46,57 @@ const Bandwidth = () => {
</div>
</div>
</div>
{/* DATABASE EGRESS - need to fix if no value yet (API will return period_start as 0 in first data point) */}
<div className="border-b">
<div className="1xl:px-28 mx-auto flex flex-col gap-10 px-5 lg:px-16 2xl:px-32 py-16">
<div className="grid grid-cols-12">
<div className="col-span-5">
<div className="sticky top-16">
<p className="text-base">IO Budget</p>
<p className="text-base">Database Egress</p>
<p className="text-sm text-scale-1000">Some description here</p>
</div>
</div>
<div className="col-span-7 space-y-6">
<div className="space-y-1">
<p>IO budget per day</p>
<p className="text-sm text-scale-1000">
Just FYI for now its a percentage for IO budget, which is different from what the
figma designs are (in minutes). We will need o11y or infra to help update this
</p>
<div className="space-y-2">
<div className="flex items-center justify-between">
<p className="text-sm">
Egress {subscription?.tier.key.toLowerCase()} quota usage
</p>
<Button type="default" size="tiny" onClick={() => {}}>
Upgrade project
</Button>
</div>
<SparkBar
type="horizontal"
barClass="bg-scale-1200"
value={db_egress?.usage ?? 0}
max={db_egress?.limit ?? 0}
/>
<div>
<div className="flex items-center justify-between border-b py-1">
<p className="text-xs text-scale-1000">
Included in {subscription?.tier.name.toLowerCase()}
</p>
<p className="text-xs">{formatBytes(db_egress?.limit ?? 0)}</p>
</div>
<div className="flex items-center justify-between border-b py-1">
<p className="text-xs text-scale-1000">Used</p>
<p className="text-xs">{formatBytes(db_egress?.usage ?? 0)}</p>
</div>
<div className="flex items-center justify-between py-1">
<p className="text-xs text-scale-1000">Extra volume used this month</p>
<p className="text-xs">
{dbEgressExcess < 0 ? formatBytes(0) : formatBytes(dbEgressExcess)}
</p>
</div>
</div>
</div>
{isLoadingIoBudgetData ? (
<div className="space-y-1">
<p>Database egress over time</p>
<p className="text-sm text-scale-1000">Some description here</p>
</div>
{isLoadingDbEgressData ? (
<div className="space-y-2">
<ShimmeringLoader />
<ShimmeringLoader className="w-3/4" />
@@ -56,16 +104,78 @@ const Bandwidth = () => {
</div>
) : (
<BarChart
attribute="disk_io_budget"
data={generateUsageData('disk_io_budget', 30)}
reference={{
value: 65,
label: 'FREE QUOTA',
x: 60,
y: 49,
width: 200,
height: 24,
}}
attribute="total_rest_egress"
data={dbEgressData?.data ?? []}
unit={undefined}
yDomain={[0, 100]}
/>
)}
</div>
</div>
</div>
</div>
{/* STORAGE EGRESS - need to fix if no value yet (API will return period_start as 0 in first data point) */}
<div className="border-b">
<div className="1xl:px-28 mx-auto flex flex-col gap-10 px-5 lg:px-16 2xl:px-32 py-16">
<div className="grid grid-cols-12">
<div className="col-span-5">
<div className="sticky top-16">
<p className="text-base">Storage Egress</p>
<p className="text-sm text-scale-1000">Some description here</p>
</div>
</div>
<div className="col-span-7 space-y-6">
<div className="space-y-2">
<div className="flex items-center justify-between">
<p className="text-sm">
Storage egress {subscription?.tier.key.toLowerCase()} quota usage
</p>
<Button type="default" size="tiny" onClick={() => {}}>
Upgrade project
</Button>
</div>
<SparkBar
type="horizontal"
barClass="bg-scale-1200"
value={storage_egress?.usage ?? 0}
max={storage_egress?.limit ?? 0}
/>
<div>
<div className="flex items-center justify-between border-b py-1">
<p className="text-xs text-scale-1000">
Included in {subscription?.tier.name.toLowerCase()}
</p>
<p className="text-xs">{formatBytes(storage_egress?.limit ?? 0)}</p>
</div>
<div className="flex items-center justify-between border-b py-1">
<p className="text-xs text-scale-1000">Used</p>
<p className="text-xs">{formatBytes(storage_egress?.usage ?? 0)}</p>
</div>
<div className="flex items-center justify-between py-1">
<p className="text-xs text-scale-1000">Extra volume used this month</p>
<p className="text-xs">
{storageEgressExcess < 0 ? formatBytes(0) : formatBytes(storageEgressExcess)}
</p>
</div>
</div>
</div>
<div className="space-y-1">
<p>Storage egress over time</p>
<p className="text-sm text-scale-1000">Some description here</p>
</div>
{isLoadingStorageEgressData ? (
<div className="space-y-2">
<ShimmeringLoader />
<ShimmeringLoader className="w-3/4" />
<ShimmeringLoader className="w-1/2" />
</div>
) : (
<BarChart
attribute="total_rest_egress"
data={storageEgressData?.data ?? []}
unit={undefined}
yDomain={[0, 100]}
/>
)}
</div>
@@ -2,8 +2,6 @@ import { useParams } from 'common'
import ShimmeringLoader from 'components/ui/ShimmeringLoader'
import { useInfraMonitoringQuery } from 'data/analytics/infra-monitoring-query'
import { useProjectSubscriptionQuery } from 'data/subscriptions/project-subscription-query'
import dayjs from 'dayjs'
import { DATE_FORMAT } from 'lib/constants'
import BarChart from './BarChart'
const Infrastructure = () => {
@@ -16,18 +14,26 @@ const Infrastructure = () => {
const { data: cpuUsageData, isLoading: isLoadingCpuUsageData } = useInfraMonitoringQuery({
projectRef: ref,
attribute: 'cpu_usage',
interval: '1d',
startDate,
endDate,
interval: '1d',
modifier: (x: number) => x * 100,
})
const { data: memoryUsageData, isLoading: isLoadingMemoryUsageData } = useInfraMonitoringQuery({
projectRef: ref,
attribute: 'ram_usage',
interval: '1d',
startDate,
endDate,
})
const { data: ioBudgetData, isLoading: isLoadingIoBudgetData } = useInfraMonitoringQuery({
projectRef: ref,
attribute: 'disk_io_budget',
interval: '1d',
startDate,
endDate,
})
return (
@@ -108,6 +114,40 @@ const Infrastructure = () => {
</div>
</div>
</div>
{/* DISK IO BUDGET */}
<div className="border-b">
<div className="1xl:px-28 mx-auto flex flex-col gap-10 px-5 lg:px-16 2xl:px-32 py-16">
<div className="grid grid-cols-12">
<div className="col-span-5">
<div className="sticky top-16">
<p className="text-base">IO Budget</p>
<p className="text-sm text-scale-1000">Some description here</p>
</div>
</div>
<div className="col-span-7 space-y-6">
<div className="space-y-1">
<p>Disk IO budget per day</p>
<p className="text-sm text-scale-1000">Some description here</p>
</div>
{isLoadingIoBudgetData ? (
<div className="space-y-2">
<ShimmeringLoader />
<ShimmeringLoader className="w-3/4" />
<ShimmeringLoader className="w-1/2" />
</div>
) : (
<BarChart
attribute="disk_io_budget"
data={ioBudgetData?.data ?? []}
unit={ioBudgetData?.format}
yDomain={[0, 100]}
/>
)}
</div>
</div>
</div>
</div>
</>
)
}
@@ -75,9 +75,9 @@ const Usage = () => {
</div>
<Infrastructure />
{/* <Bandwidth />
<SizeAndCounts />
<Activity /> */}
<Bandwidth />
{/* <SizeAndCounts /> */}
{/* <Activity /> */}
</>
)
}
+36 -11
View File
@@ -4,10 +4,11 @@ import { API_URL } from 'lib/constants'
import { useCallback } from 'react'
import { analyticsKeys } from './keys'
import { AnalyticsData } from './constants'
import dayjs from 'dayjs'
export type DailyStatsVariables = {
projectRef?: string
attribute?:
attribute:
| 'total_realtime_egress'
| 'total_realtime_requests'
| 'total_realtime_ingress'
@@ -50,17 +51,11 @@ export type DailyStatsVariables = {
endDate?: string
interval?: string
dateFormat?: string
modifier?: (x: number) => number
}
export async function getDailyStats(
{
projectRef,
attribute,
startDate,
endDate,
interval = '1d',
dateFormat = 'DD MMM',
}: DailyStatsVariables,
{ projectRef, attribute, startDate, endDate, interval = '1d' }: DailyStatsVariables,
signal?: AbortSignal
) {
if (!projectRef) throw new Error('Project ref is required')
@@ -82,14 +77,44 @@ export type DailyStatsData = Awaited<ReturnType<typeof getDailyStats>>
export type DailyStatsError = unknown
export const useDailyStatsQuery = <TData = DailyStatsData>(
{ projectRef, attribute, startDate, endDate, interval = '1d' }: DailyStatsVariables,
{
projectRef,
attribute,
startDate,
endDate,
interval = '1d',
dateFormat,
modifier,
}: DailyStatsVariables,
{ enabled = true, ...options }: UseQueryOptions<DailyStatsData, DailyStatsError, TData> = {}
) =>
useQuery<DailyStatsData, DailyStatsError, TData>(
analyticsKeys.dailyStats(projectRef, { attribute, startDate, endDate, interval }),
({ signal }) => getDailyStats({ projectRef, attribute, startDate, endDate, interval }, signal),
{
enabled: enabled && typeof projectRef !== 'undefined',
enabled:
enabled &&
typeof projectRef !== 'undefined' &&
typeof attribute !== 'undefined' &&
typeof startDate !== 'undefined' &&
typeof endDate !== 'undefined',
// @ts-ignore
select(data) {
return {
...data,
data: data.data.map((x) => {
return {
...x,
[attribute]:
modifier !== undefined ? modifier(Number(x[attribute])) : Number(x[attribute]),
period_start:
Number(x.period_start) > 0
? dayjs(x.period_start).format(dateFormat)
: x.period_start,
}
}),
}
},
...options,
}
)