@@ -25,24 +25,51 @@ export async function metrics(component: string, group: string | undefined, opts
2525// Customer-facing name for each internal billing dimension (the platform stores RAM as `ram`).
2626const DIMENSION_LABEL : Record < string , string > = { ram : 'memory' }
2727
28- // insta usage — usage across the 5 billing dimensions (cpu/memory/volume/egress/storage) we charge
29- // on, over a window. Shows the billed dimensions, not the raw provider (fly/neon) meters.
30- export async function usage ( opts : { from ?: string ; to ?: string ; json ?: boolean } ) : Promise < void > {
31- const api = await ApiClient . load ( )
32- const p = await requireProject ( )
33- const res = await api . request ( 'GET' , `/projects/${ p . projectId } /usage${ qs ( { from : opts . from , to : opts . to } ) } ` )
34- if ( opts . json ) return printJson ( res )
35- // Window defaults to the current billing cycle. `to` is the exclusive next-cycle start, so show
36- // the inclusive last day (to − 1 day) — e.g. an org created on the 5th reads "…-05 → …next-04".
28+ type Dim = { dimension : string ; quantity : number ; unit : string ; costUsd ?: number }
29+
30+ // Window line. Defaults to the current billing cycle; `to` is the exclusive next-cycle start, so
31+ // show the inclusive last day (to − 1 day) — e.g. an org created on the 5th reads "…-05 → …next-04".
32+ function cycleLine ( res : { from : number ; to : number } ) : string {
3733 const day = ( sec : number ) => new Date ( sec * 1000 ) . toISOString ( ) . slice ( 0 , 10 )
38- info ( `billing cycle ${ day ( res . from ) } → ${ day ( res . to - 86400 ) } ` )
39- if ( ! res . dimensions ?. length ) return info ( '(no usage recorded)' )
40- for ( const d of res . dimensions ) {
34+ return `billing cycle ${ day ( res . from ) } → ${ day ( res . to - 86400 ) } `
35+ }
36+
37+ function printDimensions ( dims : Dim [ ] ) : void {
38+ for ( const d of dims ) {
4139 const label = DIMENSION_LABEL [ d . dimension ] ?? d . dimension
4240 const cost = d . costUsd != null ? ` ($${ Number ( d . costUsd ) . toFixed ( 4 ) } )` : ''
4341 info ( `${ label } : ${ d . quantity } ${ d . unit } ${ cost } ` )
4442 }
45- info ( `total: $${ Number ( res . totalCostUsd ?? 0 ) . toFixed ( 4 ) } ` )
43+ }
44+
45+ // insta usage — usage across the 5 billing dimensions (cpu/memory/volume/egress/storage) for the
46+ // current billing cycle. Shows the whole ORG by default (with a per-project breakdown); pass --proj
47+ // [id] for a single project (the linked one, or a given id). Billed dimensions, not raw fly/neon meters.
48+ export async function usage ( opts : { from ?: string ; to ?: string ; json ?: boolean ; proj ?: string | boolean } ) : Promise < void > {
49+ const api = await ApiClient . load ( )
50+ const p = await requireProject ( )
51+
52+ if ( opts . proj !== undefined && opts . proj !== false ) {
53+ const projectId = typeof opts . proj === 'string' ? opts . proj : p . projectId
54+ const res = await api . request ( 'GET' , `/projects/${ projectId } /usage${ qs ( { from : opts . from , to : opts . to } ) } ` )
55+ if ( opts . json ) return printJson ( res )
56+ info ( cycleLine ( res ) )
57+ if ( ! res . dimensions ?. length ) return info ( '(no usage recorded)' )
58+ printDimensions ( res . dimensions )
59+ return info ( `total: $${ Number ( res . totalCostUsd ?? 0 ) . toFixed ( 4 ) } ` )
60+ }
61+
62+ // Default: the whole org (the linked project's org), with a per-project cost breakdown.
63+ const res = await api . request ( 'GET' , `/orgs/${ p . orgId } /usage${ qs ( { from : opts . from , to : opts . to } ) } ` )
64+ if ( opts . json ) return printJson ( res )
65+ info ( cycleLine ( res ) )
66+ if ( ! res . org ?. dimensions ?. length ) return info ( '(no usage recorded)' )
67+ printDimensions ( res . org . dimensions )
68+ info ( `total: $${ Number ( res . org . totalCostUsd ?? 0 ) . toFixed ( 4 ) } ` )
69+ if ( res . projects ?. length ) {
70+ info ( 'by project:' )
71+ for ( const pr of res . projects ) info ( ` ${ pr . name } : $${ Number ( pr . totalCostUsd ?? 0 ) . toFixed ( 4 ) } ` )
72+ }
4673}
4774
4875// insta logs <db|compute> [group]
0 commit comments