Skip to content

Commit

Permalink
More CPU metrics, though we mgiht need to rethink the long-term plan
Browse files Browse the repository at this point in the history
  • Loading branch information
charliepark committed Jan 30, 2025
1 parent 503a47e commit 1bd508d
Show file tree
Hide file tree
Showing 2 changed files with 216 additions and 82 deletions.
196 changes: 136 additions & 60 deletions app/pages/project/instances/instance/tabs/MetricsTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Copyright Oxide Computer Company
*/
import React, { useMemo, useState } from 'react'
import type { LoaderFunctionArgs } from 'react-router'
import { Link, type LoaderFunctionArgs } from 'react-router'

import { apiQueryClient, usePrefetchedApiQuery } from '@oxide/api'
import { Storage24Icon } from '@oxide/design-system/icons/react'
Expand All @@ -16,6 +16,7 @@ import { getInstanceSelector, useInstanceSelector } from '~/hooks/use-params'
import { EmptyMessage } from '~/ui/lib/EmptyMessage'
import { Listbox } from '~/ui/lib/Listbox'
import { TableEmptyBox } from '~/ui/lib/Table'
import { pb } from '~/util/path-builder'

import { OxqlMetric } from './MetricsTab/OxqlMetric'

Expand All @@ -26,10 +27,16 @@ import { OxqlMetric } from './MetricsTab/OxqlMetric'

export async function loader({ params }: LoaderFunctionArgs) {
const { project, instance } = getInstanceSelector(params)
await apiQueryClient.prefetchQuery('instanceDiskList', {
path: { instance },
query: { project },
})
await Promise.all([
apiQueryClient.prefetchQuery('instanceDiskList', {
path: { instance },
query: { project },
}),
apiQueryClient.prefetchQuery('instanceView', {
path: { instance },
query: { project },
}),
])
return null
}

Expand All @@ -40,6 +47,10 @@ export function Component() {
path: { instance },
query: { project },
})
const { data: instanceData } = usePrefetchedApiQuery('instanceView', {
path: { instance },
query: { project },
})
const disks = useMemo(() => data?.items || [], [data])

const { startTime, endTime, dateTimeRangePicker } = useDateTimeRangePicker({
Expand Down Expand Up @@ -72,67 +83,132 @@ export function Component() {
}

return (
<>
<div className="mb-4 flex justify-between">
<Listbox
className="w-64"
aria-label="Choose disk"
name="disk-name"
selected={diskName}
items={diskItems}
onChange={(val) => {
if (val) {
setDiskName(val)
setDiskId(disks.find((d) => d.name === val)?.id || '')
}
}}
/>
{dateTimeRangePicker}
<div className="flex gap-8">
<div className="flex w-[160px] flex-shrink-0 flex-col gap-2">
<Link to={pb.instanceMetrics({ project, instance })}>CPU</Link>
<Link to={pb.instanceMetrics({ project, instance })}>Utilization</Link>
<Link to={pb.instanceMetrics({ project, instance })}>Time</Link>
<Link to={pb.instanceMetrics({ project, instance })}>Disk</Link>
<Link to={pb.instanceMetrics({ project, instance })}>Network</Link>
</div>

<div className="mt-8 space-y-12">
{/* see the following link for the source of truth on what these mean
https://github.com/oxidecomputer/crucible/blob/258f162b/upstairs/src/stats.rs#L9-L50 */}

<div className="flex w-full space-x-4">
<OxqlMetric
{...commonProps}
title="Reads"
unit="Count"
metricName="virtual_disk:reads"
/>
<OxqlMetric
{...commonProps}
title="Read"
unit="Bytes"
metricName="virtual_disk:bytes_read"
<div className="flex-grow">
<div className="mb-4 flex justify-between">
<Listbox
className="w-64"
aria-label="Choose disk"
name="disk-name"
selected={diskName}
items={diskItems}
onChange={(val) => {
if (val) {
setDiskName(val)
setDiskId(disks.find((d) => d.name === val)?.id || '')
}
}}
/>
{dateTimeRangePicker}
</div>
<div className="mt-8 space-y-12">
{/* see the following link for the source of truth on what these mean
https://github.com/oxidecomputer/crucible/blob/258f162b/upstairs/src/stats.rs#L9-L50 */}

<div className="flex w-full space-x-4">
<OxqlMetric
{...commonProps}
title="Writes"
unit="Count"
metricName="virtual_disk:writes"
/>
<OxqlMetric
{...commonProps}
title="Write"
unit="Bytes"
metricName="virtual_disk:bytes_written"
/>
</div>
<div className="flex w-full space-x-4">
<OxqlMetric
{...commonProps}
title="Reads"
unit="Count"
metricName="virtual_disk:reads"
/>
<OxqlMetric
{...commonProps}
title="Read"
unit="Bytes"
metricName="virtual_disk:bytes_read"
/>
</div>

<div className="flex w-full space-x-4">
<OxqlMetric
{...commonProps}
title="Flushes"
unit="Count"
metricName="virtual_disk:flushes"
/>
<div className="flex w-full space-x-4">
<OxqlMetric
{...commonProps}
title="Writes"
unit="Count"
metricName="virtual_disk:writes"
/>
<OxqlMetric
{...commonProps}
title="Write"
unit="Bytes"
metricName="virtual_disk:bytes_written"
/>
</div>

<div className="flex w-full space-x-4">
<OxqlMetric
{...commonProps}
title="Flushes"
unit="Count"
metricName="virtual_disk:flushes"
/>
</div>

<div className="flex w-full space-x-4">
<OxqlMetric
startTime={startTime}
endTime={endTime}
title="CPU Utilization: Running"
unit="%"
metricName="virtual_machine:vcpu_usage"
state="run"
instanceId={instanceData.id}
join
/>
<OxqlMetric
startTime={startTime}
endTime={endTime}
title="CPU Utilization: Idling"
unit="%"
metricName="virtual_machine:vcpu_usage"
state="idle"
instanceId={instanceData.id}
join
/>
</div>

<div className="flex w-full space-x-4">
<OxqlMetric
startTime={startTime}
endTime={endTime}
title="CPU Utilization: Waiting"
unit="%"
metricName="virtual_machine:vcpu_usage"
state="waiting"
instanceId={instanceData.id}
join
/>
<OxqlMetric
startTime={startTime}
endTime={endTime}
title="CPU Utilization: Emulation"
unit="%"
metricName="virtual_machine:vcpu_usage"
state="emulation"
instanceId={instanceData.id}
join
/>
</div>
<div className="flex w-full space-x-4">
<OxqlMetric
startTime={startTime}
endTime={endTime}
title="CPU Utilization"
unit="%"
metricName="virtual_machine:vcpu_usage"
instanceId={instanceData.id}
join
/>
</div>
</div>
</div>
</>
</div>
)
}
Loading

0 comments on commit 1bd508d

Please sign in to comment.