Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions apps/web/src/components/settings/DiagnosticsSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip";
import { toastManager } from "../ui/toast";
import { ExpandableText } from "./ExpandableText";
import { ResourceTelemetryDiagnostics } from "./ResourceTelemetryDiagnostics";
import { formatCpuTime } from "./ResourceTelemetryDiagnostics.logic";
import { SettingsPageContainer, SettingsSection } from "./settingsLayout";
import { useAtomCommand } from "../../state/use-atom-command";
import { useSettingsScope } from "./SettingsScopeContext";
Expand Down Expand Up @@ -426,13 +427,6 @@ const RESOURCE_HISTORY_WINDOWS = [
{ label: "1h", windowMs: 60 * 60_000, bucketMs: 5 * 60_000 },
] as const;

function formatCpuTime(seconds: number): string {
if (seconds < 60) return `${seconds.toFixed(seconds >= 10 ? 1 : 2).replace(/\.0+$/, "")}s`;
const minutes = seconds / 60;
if (minutes < 60) return `${minutes.toFixed(minutes >= 10 ? 1 : 2).replace(/\.0+$/, "")}m`;
return `${(minutes / 60).toFixed(2).replace(/\.0+$/, "")}h`;
}

function formatShortProcessName(command: string): string {
const name = formatProcessName(command);
return name.length > 42 ? `${name.slice(0, 39)}...` : name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import { describe, expect, it } from "vite-plus/test";
import type { ResourceTelemetryProcess } from "@t3tools/contracts";
import * as DateTime from "effect/DateTime";

import { visibleResourceTelemetryProcesses } from "./ResourceTelemetryDiagnostics.logic";
import {
formatCpuTime,
visibleResourceTelemetryProcesses,
} from "./ResourceTelemetryDiagnostics.logic";

const process = (pid: number, ppid: number, depth: number): ResourceTelemetryProcess => ({
identity: { pid, startTimeMs: pid * 1_000 },
Expand Down Expand Up @@ -46,3 +49,14 @@ describe("visibleResourceTelemetryProcesses", () => {
]);
});
});

describe("formatCpuTime", () => {
it("switches units when rounding reaches the next unit", () => {
expect([59.94, 59.97, 3_599.7, 3_600].map((seconds) => formatCpuTime(seconds))).toEqual([
"59.9s",
"1m",
"1h",
"1h",
]);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,13 @@ export function resourceHistoryCpuScaleMax(
): number {
return Math.max(1, ...buckets.map((bucket) => bucket.avgCpuPercent));
}

export function formatCpuTime(seconds: number): string {
const format = (value: number) => value.toFixed(value >= 10 ? 1 : 2).replace(/\.0+$/, "");
// Pick the unit after rounding so 59.97 seconds never renders as "60s".
const shortSeconds = format(seconds);
if (Number(shortSeconds) < 60) return `${shortSeconds}s`;
const shortMinutes = format(seconds / 60);
if (Number(shortMinutes) < 60) return `${shortMinutes}m`;
return `${(seconds / 3_600).toFixed(2).replace(/\.0+$/, "")}h`;
}
17 changes: 6 additions & 11 deletions apps/web/src/components/settings/ResourceTelemetryDiagnostics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import { Toggle, ToggleGroup } from "../ui/toggle-group";
import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip";
import { toastManager } from "../ui/toast";
import {
formatCpuTime,
processIdentityKey,
resourceHistoryBarHeight,
resourceHistoryCpuScaleMax,
Expand All @@ -72,14 +73,6 @@ function formatRate(value: number): string {
return `${formatBytes(value)}/s`;
}

function formatCpuTime(valueMs: number): string {
const seconds = valueMs / 1_000;
if (seconds < 60) return `${seconds.toFixed(seconds >= 10 ? 1 : 2).replace(/\.0+$/, "")}s`;
const minutes = seconds / 60;
if (minutes < 60) return `${minutes.toFixed(minutes >= 10 ? 1 : 2).replace(/\.0+$/, "")}m`;
return `${(minutes / 60).toFixed(2).replace(/\.0+$/, "")}h`;
}

function formatDurationMicros(value: number): string {
if (value < 1_000) return `${Math.round(value)} µs`;
if (value < 1_000_000) return `${(value / 1_000).toFixed(2).replace(/\.0+$/, "")} ms`;
Expand Down Expand Up @@ -609,7 +602,7 @@ function ProcessTable({
{process.cpuPercent.toFixed(1)}%
</td>
<td className="px-3 py-2 text-right font-mono tabular-nums">
{formatCpuTime(process.cpuTimeMs)}
{formatCpuTime(process.cpuTimeMs / 1_000)}
</td>
<td className="px-3 py-2 text-right font-mono tabular-nums">
{formatBytes(process.residentBytes)}
Expand Down Expand Up @@ -715,7 +708,7 @@ function HistoryProcessTable({
{categoryLabel(process.category)}
</td>
<td className="px-3 py-2 text-right font-mono tabular-nums">
{formatCpuTime(process.cpuTimeMs)}
{formatCpuTime(process.cpuTimeMs / 1_000)}
</td>
<td className="px-3 py-2 text-right font-mono tabular-nums">
{process.maxCpuPercent.toFixed(1)}%
Expand Down Expand Up @@ -1013,7 +1006,9 @@ function ResourceTelemetryDiagnosticsBody({
icon={<CpuIcon className="size-3.5" />}
label="Current CPU"
value={allT3 ? `${allT3.currentCpuPercent.toFixed(1)}%` : "..."}
detail={allT3 ? `${formatCpuTime(allT3.cpuTimeMs)} observed CPU time` : undefined}
detail={
allT3 ? `${formatCpuTime(allT3.cpuTimeMs / 1_000)} observed CPU time` : undefined
}
/>
<IconStat
icon={<MemoryStickIcon className="size-3.5" />}
Expand Down
Loading