-
-
Notifications
You must be signed in to change notification settings - Fork 1k
feat: OTEL metrics pipeline for task workers #3061
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
c1c03c4
c186ee6
b3895ba
8498803
b4407c7
23893de
56b196e
bf178b2
2964cf6
6b7b235
304fec6
82a6a23
aa450a6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -35,6 +35,7 @@ import { useCopy } from "~/hooks/useCopy"; | |
| import { useOrganization } from "~/hooks/useOrganizations"; | ||
| import { useProject } from "~/hooks/useProject"; | ||
| import { cn } from "~/utils/cn"; | ||
| import { formatBytes, formatDecimalBytes, formatQuantity } from "~/utils/columnFormat"; | ||
| import { formatCurrencyAccurate, formatNumber } from "~/utils/numberFormatter"; | ||
| import { v3ProjectPath, v3RunPathFromFriendlyId } from "~/utils/pathBuilder"; | ||
| import { Paragraph } from "../primitives/Paragraph"; | ||
|
|
@@ -64,9 +65,10 @@ function getFormattedValue(value: unknown, column: OutputColumnMetadata): string | |
| if (value === null) return "NULL"; | ||
| if (value === undefined) return ""; | ||
|
|
||
| // Handle custom render types | ||
| if (column.customRenderType) { | ||
| switch (column.customRenderType) { | ||
| // Handle format hints (from prettyFormat() or auto-populated from customRenderType) | ||
| const formatType = column.format ?? column.customRenderType; | ||
| if (formatType) { | ||
| switch (formatType) { | ||
| case "duration": | ||
| if (typeof value === "number") { | ||
| return formatDurationMilliseconds(value, { style: "short" }); | ||
|
|
@@ -93,6 +95,26 @@ function getFormattedValue(value: unknown, column: OutputColumnMetadata): string | |
| return value; | ||
| } | ||
| break; | ||
| case "bytes": | ||
| if (typeof value === "number") { | ||
| return formatBytes(value); | ||
| } | ||
| break; | ||
| case "decimalBytes": | ||
| if (typeof value === "number") { | ||
| return formatDecimalBytes(value); | ||
| } | ||
| break; | ||
| case "percent": | ||
| if (typeof value === "number") { | ||
| return `${value.toFixed(2)}%`; | ||
| } | ||
| break; | ||
| case "quantity": | ||
| if (typeof value === "number") { | ||
| return formatQuantity(value); | ||
| } | ||
| break; | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -220,6 +242,21 @@ function getDisplayLength(value: unknown, column: OutputColumnMetadata): number | |
| if (value === null) return 4; // "NULL" | ||
| if (value === undefined) return 9; // "UNDEFINED" | ||
|
|
||
| // Handle format hint types - estimate their rendered width | ||
| const fmt = column.format; | ||
| if (fmt === "bytes" || fmt === "decimalBytes") { | ||
| // e.g., "1.50 GiB" or "256.00 MB" | ||
| return 12; | ||
| } | ||
| if (fmt === "percent") { | ||
| // e.g., "45.23%" | ||
| return 8; | ||
| } | ||
| if (fmt === "quantity") { | ||
| // e.g., "1.50M" | ||
| return 8; | ||
| } | ||
|
|
||
| // Handle custom render types - estimate their rendered width | ||
| if (column.customRenderType) { | ||
| switch (column.customRenderType) { | ||
|
|
@@ -392,6 +429,10 @@ function isRightAlignedColumn(column: OutputColumnMetadata): boolean { | |
| ) { | ||
| return true; | ||
| } | ||
| const fmt = column.format; | ||
| if (fmt === "bytes" || fmt === "decimalBytes" || fmt === "percent" || fmt === "quantity") { | ||
| return true; | ||
| } | ||
| return isNumericType(column.type); | ||
| } | ||
|
|
||
|
|
@@ -474,6 +515,32 @@ function CellValue({ | |
| return <pre className="text-text-dimmed">UNDEFINED</pre>; | ||
| } | ||
|
|
||
| // Check format hint for new format types (from prettyFormat()) | ||
| if (column.format && !column.customRenderType) { | ||
| switch (column.format) { | ||
| case "bytes": | ||
| if (typeof value === "number") { | ||
| return <span className="tabular-nums">{formatBytes(value)}</span>; | ||
| } | ||
| break; | ||
| case "decimalBytes": | ||
| if (typeof value === "number") { | ||
| return <span className="tabular-nums">{formatDecimalBytes(value)}</span>; | ||
| } | ||
| break; | ||
| case "percent": | ||
| if (typeof value === "number") { | ||
| return <span className="tabular-nums">{value.toFixed(2)}%</span>; | ||
| } | ||
| break; | ||
| case "quantity": | ||
| if (typeof value === "number") { | ||
| return <span className="tabular-nums">{formatQuantity(value)}</span>; | ||
| } | ||
| break; | ||
| } | ||
| } | ||
|
Comment on lines
+518
to
+542
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. prettyFormat hints are skipped when customRenderType exists (and duration/cost formats are ignored). Suggested change- if (column.format && !column.customRenderType) {
+ if (column.format) {
switch (column.format) {
case "bytes":
if (typeof value === "number") {
return <span className="tabular-nums">{formatBytes(value)}</span>;
}
break;
case "decimalBytes":
if (typeof value === "number") {
return <span className="tabular-nums">{formatDecimalBytes(value)}</span>;
}
break;
case "percent":
if (typeof value === "number") {
return <span className="tabular-nums">{value.toFixed(2)}%</span>;
}
break;
case "quantity":
if (typeof value === "number") {
return <span className="tabular-nums">{formatQuantity(value)}</span>;
}
break;
+ case "duration":
+ if (typeof value === "number") {
+ return (
+ <span className="tabular-nums">
+ {formatDurationMilliseconds(value, { style: "short" })}
+ </span>
+ );
+ }
+ break;
+ case "durationSeconds":
+ if (typeof value === "number") {
+ return (
+ <span className="tabular-nums">
+ {formatDurationMilliseconds(value * 1000, { style: "short" })}
+ </span>
+ );
+ }
+ break;
+ case "costInDollars":
+ if (typeof value === "number") {
+ return <span className="tabular-nums">{formatCurrencyAccurate(value)}</span>;
+ }
+ break;
+ case "cost":
+ if (typeof value === "number") {
+ return <span className="tabular-nums">{formatCurrencyAccurate(value / 100)}</span>;
+ }
+ break;
}
}🤖 Prompt for AI Agents |
||
|
|
||
| // First check customRenderType for special rendering | ||
| if (column.customRenderType) { | ||
| switch (column.customRenderType) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Edge case:
maxValcould be-Infinitywhen the formatter is invoked with bytes format.If
maxValremains-Infinity(e.g., all values arenull/non-numeric), thenMath.abs(maxVal || 1)evaluates toMath.abs(-Infinity)=Infinitybecause-Infinityis truthy. This makesiclamp to the last unit index, so a non-zero value would be formatted as e.g."0.0 TiB"instead of"0 B". In practice, the early returns at lines 977–983 prevent rendering an empty chart, so this is unlikely to trigger. But a small guard would make the formatter more robust.Proposed defensive fix
return (value: number): string => { if (value === 0) return "0 B"; // Use consistent unit for all ticks based on max value + const refValue = isFinite(maxVal) ? Math.abs(maxVal) : Math.abs(value); const i = Math.min( - Math.floor(Math.log(Math.abs(maxVal || 1)) / Math.log(divisor)), + Math.floor(Math.log(refValue || 1) / Math.log(divisor)), units.length - 1 );🤖 Prompt for AI Agents