@@ -12,12 +12,14 @@ import {
1212 DockerContainerStorageStats ,
1313 DockerCreateContainerOptions ,
1414 DockerCredentials ,
15+ DockerHostConfig ,
1516 DockerIdentityToken ,
1617 DockerImage ,
1718 DockerImageManifestSummary ,
1819 DockerOCIDescriptor ,
1920 DockerOCIPlatform ,
2021} from './types' ;
22+ import os from 'os' ;
2123
2224export function encodeCreateContainerOptions ( image : string , options ?: DockerCreateContainerOptions ) : string {
2325 const body : any = { } ;
@@ -553,21 +555,40 @@ export function decodeDockerContainerNetworkStats(json: any | undefined): Docker
553555 } ;
554556}
555557
556- export function decodeDockerContainerStats ( json : any | undefined ) : DockerContainerStats | undefined {
558+ export function decodeDockerContainerStats (
559+ json : any | undefined ,
560+ hostConfig ?: DockerHostConfig ,
561+ ) : DockerContainerStats | undefined {
557562 if ( ! json ) return undefined ;
558563
559564 const cpuStats = decodeDockerContainerCpuStats ( json . cpu_stats ) ;
560565 const preStats = decodeDockerContainerCpuStats ( json . precpu_stats ) ;
561566 const memoryStats = decodeDockerContainerMemoryStats ( json . memory_stats ) ;
562567
568+ const hostCpuCoreCount = os . cpus ( ) . length ;
569+ const hostMemoryTotal = os . totalmem ( ) ;
570+
563571 const cpuCoreCount = Math . max ( cpuStats ?. cpuUsage ?. perCpuUsage ?. length || 0 , cpuStats ?. onlineCpus || 0 ) ;
564572 const cpuDelta = Math . max ( 0 , ( cpuStats ?. cpuUsage ?. totalUsage || 0 ) - ( preStats ?. cpuUsage ?. totalUsage || 0 ) ) ;
565573 const memoryTotal = memoryStats ?. total ;
566574 const memoryUsed = memoryStats ?. usage ? Math . max ( 0 , memoryStats ?. usage - ( memoryStats ?. stats . cache || 0 ) ) : undefined ;
567575 const systemCpuDelta = Math . max ( 0 , ( cpuStats ?. systemCpuUsage || 0 ) - ( preStats ?. systemCpuUsage || 0 ) ) ;
568576
569- const cpuUtilization = systemCpuDelta > 0 ? ( cpuDelta / systemCpuDelta ) * Math . max ( 1 , cpuCoreCount ) : 0 ;
570- const memoryUtilization = memoryTotal && memoryUsed ? memoryUsed / memoryTotal : undefined ;
577+ let containerCpuLimit = hostCpuCoreCount ; // default no limit
578+ if ( hostConfig ?. nanoCpus && hostConfig ?. cpuPeriod ) {
579+ containerCpuLimit = hostConfig . nanoCpus / 1e9 ;
580+ } else if ( hostConfig ?. cpuQuota && hostConfig ?. cpuPeriod ) {
581+ containerCpuLimit = hostConfig . cpuQuota / hostConfig . cpuPeriod ;
582+ } else if ( hostConfig ?. cpuCount ) {
583+ containerCpuLimit = hostConfig . cpuCount ;
584+ } else if ( hostConfig ?. cpuPercent ) {
585+ containerCpuLimit = ( hostConfig . cpuPercent / 100.0 ) * hostCpuCoreCount ;
586+ }
587+
588+ const cpuUtilizationHost = systemCpuDelta > 0 ? cpuDelta / systemCpuDelta : 0 ;
589+ const cpuUtilizationLimits = hostConfig ? ( cpuUtilizationHost * containerCpuLimit ) / hostCpuCoreCount : undefined ;
590+ const memoryUtilizationHost = memoryUsed !== undefined && hostMemoryTotal ? memoryUsed / hostMemoryTotal : undefined ;
591+ const memoryUtilizationLimits = memoryUsed !== undefined && memoryTotal ? memoryUsed / memoryTotal : undefined ;
571592 const networkStats : { [ networkInterface : string ] : DockerContainerNetworkStats } = { } ;
572593
573594 for ( const [ networkInterface , stats ] of Object . entries < any > ( json . networks || { } ) ) {
@@ -606,11 +627,17 @@ export function decodeDockerContainerStats(json: any | undefined): DockerContain
606627 containerId : json . id || '' ,
607628 cpuCoreCount,
608629 cpuStats,
609- cpuUtilization,
630+ cpuUtilization : {
631+ host : cpuUtilizationHost ,
632+ limits : cpuUtilizationLimits ,
633+ } ,
610634 memoryStats : memoryStats ! ,
611635 memoryTotal,
612636 memoryUsed,
613- memoryUtilization,
637+ memoryUtilization : {
638+ host : memoryUtilizationHost ,
639+ limits : memoryUtilizationLimits ,
640+ } ,
614641 name : json . name ,
615642 networkStats : json . networks ? networkStats : undefined ,
616643 pidCount : json . pids_stats
0 commit comments