Skip to main content

Overview

The Docker package provides detailed CPU and memory statistics by reading from the Linux cgroup filesystem. These functions work with both standard Docker cgroup layouts and systemd.slice configurations.
Statistics are read directly from /sys/fs/cgroup/ and do not require the Docker API.

CPU Statistics

CgroupCPU

Retrieves CPU statistics for a specific container from cgroups.
func CgroupCPU(containerID, base string) (*CgroupCPUStat, error)
func CgroupCPUWithContext(ctx context.Context, containerID, base string) (*CgroupCPUStat, error)

Parameters

  • containerID - Docker container ID (or empty string for all cgroups)
  • base - Base path for cgroup filesystem (empty string uses default)

Returns

type CgroupCPUStat struct {
    cpu.TimesStat
    Usage float64  // Total CPU usage in seconds
}
Inherits from cpu.TimesStat:
  • CPU - Container ID or “all”
  • User - CPU time in user mode (seconds)
  • System - CPU time in kernel mode (seconds)
  • Usage - Total CPU usage (seconds)

Example

import (
    "fmt"
    "log"
    "github.com/shirou/gopsutil/v4/docker"
)

func main() {
    containerID := "abc123def456..." // Full container ID
    
    stats, err := docker.CgroupCPU(containerID, "")
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Printf("Container: %s\n", stats.CPU)
    fmt.Printf("User CPU: %.2f seconds\n", stats.User)
    fmt.Printf("System CPU: %.2f seconds\n", stats.System)
    fmt.Printf("Total Usage: %.2f seconds\n", stats.Usage)
}

CgroupCPUUsage

Retrieves only the total CPU usage (more lightweight than full stats).
func CgroupCPUUsage(containerID, base string) (float64, error)
func CgroupCPUUsageWithContext(ctx context.Context, containerID, base string) (float64, error)

Example

usage, err := docker.CgroupCPUUsage(containerID, "")
if err != nil {
    log.Fatal(err)
}
fmt.Printf("CPU usage: %.2f seconds\n", usage)

CgroupCPUDocker

Convenience function that uses the default Docker cgroup path.
func CgroupCPUDocker(containerID string) (*CgroupCPUStat, error)
func CgroupCPUDockerWithContext(ctx context.Context, containerID string) (*CgroupCPUStat, error)
Equivalent to calling:
CgroupCPU(containerID, "/sys/fs/cgroup/cpuacct/docker")

Example

// Get running container IDs
ids, err := docker.GetDockerIDList()
if err != nil {
    log.Fatal(err)
}

// Monitor CPU for each container
for _, id := range ids {
    stats, err := docker.CgroupCPUDocker(id)
    if err != nil {
        log.Printf("Error getting stats for %s: %v", id[:12], err)
        continue
    }
    fmt.Printf("%s: %.2fs CPU\n", id[:12], stats.Usage)
}

CgroupCPUUsageDocker

Convenience function for getting just CPU usage with default Docker path.
func CgroupCPUUsageDocker(containerID string) (float64, error)
func CgroupCPUDockerUsageWithContext(ctx context.Context, containerID string) (float64, error)

Memory Statistics

CgroupMem

Retrieves detailed memory statistics for a container from cgroups.
func CgroupMem(containerID, base string) (*CgroupMemStat, error)
func CgroupMemWithContext(ctx context.Context, containerID, base string) (*CgroupMemStat, error)

Returns

type CgroupMemStat struct {
    ContainerID             string
    Cache                   uint64  // Page cache memory
    RSS                     uint64  // Resident set size
    RSSHuge                 uint64  // Anonymous huge pages
    MappedFile              uint64  // Memory-mapped files
    Pgpgin                  uint64  // Pages read from disk
    Pgpgout                 uint64  // Pages written to disk
    Pgfault                 uint64  // Page faults
    Pgmajfault              uint64  // Major page faults
    InactiveAnon            uint64  // Inactive anonymous memory
    ActiveAnon              uint64  // Active anonymous memory
    InactiveFile            uint64  // Inactive file cache
    ActiveFile              uint64  // Active file cache
    Unevictable             uint64  // Memory that cannot be evicted
    HierarchicalMemoryLimit uint64  // Memory limit for hierarchy
    TotalCache              uint64  // Total page cache (including descendants)
    TotalRSS                uint64  // Total RSS (including descendants)
    TotalRSSHuge            uint64  // Total huge pages
    TotalMappedFile         uint64  // Total mapped files
    TotalPgpgIn             uint64  // Total pages in
    TotalPgpgOut            uint64  // Total pages out
    TotalPgFault            uint64  // Total page faults
    TotalPgMajFault         uint64  // Total major page faults
    TotalInactiveAnon       uint64  // Total inactive anonymous
    TotalActiveAnon         uint64  // Total active anonymous
    TotalInactiveFile       uint64  // Total inactive file cache
    TotalActiveFile         uint64  // Total active file cache
    TotalUnevictable        uint64  // Total unevictable
    MemUsageInBytes         uint64  // Current memory usage
    MemMaxUsageInBytes      uint64  // Peak memory usage
    MemLimitInBytes         uint64  // Memory limit
    MemFailCnt              uint64  // Number of times limit was hit
}

Example

import (
    "fmt"
    "log"
    "github.com/shirou/gopsutil/v4/docker"
)

func main() {
    containerID := "abc123def456..." // Full container ID
    
    mem, err := docker.CgroupMem(containerID, "")
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Printf("Container: %s\n", mem.ContainerID)
    fmt.Printf("Current Usage: %d MB\n", mem.MemUsageInBytes/1024/1024)
    fmt.Printf("Peak Usage: %d MB\n", mem.MemMaxUsageInBytes/1024/1024)
    fmt.Printf("Memory Limit: %d MB\n", mem.MemLimitInBytes/1024/1024)
    fmt.Printf("RSS: %d MB\n", mem.RSS/1024/1024)
    fmt.Printf("Cache: %d MB\n", mem.Cache/1024/1024)
    fmt.Printf("Page Faults: %d\n", mem.Pgfault)
    fmt.Printf("Major Faults: %d\n", mem.Pgmajfault)
}

CgroupMemDocker

Convenience function that uses the default Docker cgroup path.
func CgroupMemDocker(containerID string) (*CgroupMemStat, error)
func CgroupMemDockerWithContext(ctx context.Context, containerID string) (*CgroupMemStat, error)
Equivalent to calling:
CgroupMem(containerID, "/sys/fs/cgroup/memory/docker")

Example: Complete Container Monitor

import (
    "fmt"
    "log"
    "time"
    "github.com/shirou/gopsutil/v4/docker"
)

func monitorContainer(containerID string) {
    ticker := time.NewTicker(5 * time.Second)
    defer ticker.Stop()
    
    for range ticker.C {
        // Get CPU stats
        cpu, err := docker.CgroupCPUDocker(containerID)
        if err != nil {
            log.Printf("CPU error: %v", err)
            continue
        }
        
        // Get memory stats
        mem, err := docker.CgroupMemDocker(containerID)
        if err != nil {
            log.Printf("Memory error: %v", err)
            continue
        }
        
        fmt.Printf("[%s] CPU: %.2fs | Memory: %dMB / %dMB\n",
            time.Now().Format("15:04:05"),
            cpu.Usage,
            mem.MemUsageInBytes/1024/1024,
            mem.MemLimitInBytes/1024/1024,
        )
    }
}

func main() {
    ids, err := docker.GetDockerIDList()
    if err != nil {
        log.Fatal(err)
    }
    
    if len(ids) == 0 {
        log.Fatal("No running containers found")
    }
    
    // Monitor first running container
    monitorContainer(ids[0])
}

Custom Cgroup Paths

Using systemd.slice

For containers managed by systemd, use a custom base path:
containerID := "abc123def456"
base := "/sys/fs/cgroup/cpuacct/system.slice"

// Systemd uses this format: docker-<id>.scope
stats, err := docker.CgroupCPU("docker-"+containerID+".scope", base)

Reading All Cgroups

Pass an empty containerID to read stats for the entire cgroup:
// Get stats for all containers combined
stats, err := docker.CgroupCPU("", "/sys/fs/cgroup/cpuacct/docker")
fmt.Printf("Total Docker CPU: %.2fs\n", stats.Usage)

Understanding the Metrics

  • User Time: CPU time spent executing user-space code
  • System Time: CPU time spent in kernel on behalf of the container
  • Usage: Total CPU time consumed (converted from nanoseconds)
These are cumulative values since container start.
  • RSS: Physical memory used by processes (excluding cache)
  • Cache: File cache memory that can be reclaimed
  • MemUsageInBytes: Current total memory usage
  • MemLimitInBytes: Container memory limit
  • MemFailCnt: How many times limit was exceeded
  • Pgfault: Minor page faults (resolved from memory)
  • Pgmajfault: Major page faults (required disk I/O)
High major fault counts indicate memory pressure or heavy I/O.

Implementation Notes

The package automatically handles different cgroup filesystem layouts:
  • Standard Docker: /sys/fs/cgroup/{subsystem}/docker/{id}/
  • Systemd: /sys/fs/cgroup/{subsystem}/system.slice/docker-{id}.scope/

File Locations

The package reads from these cgroup files: CPU:
  • cpuacct.stat - User and system time
  • cpuacct.usage - Total usage in nanoseconds
Memory:
  • memory.stat - Detailed memory breakdown
  • memory.usage_in_bytes - Current usage
  • memory.max_usage_in_bytes - Peak usage
  • memory.limit_in_bytes - Memory limit
  • memory.failcnt - Limit hit count

Build docs developers (and LLMs) love