Overview
Starting from v3.23.6, gopsutil supports passing configuration through Go’s context.Context. This allows you to:
Set custom paths for system directories
Control operation timeouts and cancellation
Pass configuration without global state
Maintain thread-safe, concurrent operations
Every function in gopsutil has a WithContext variant (e.g., VirtualMemory() and VirtualMemoryWithContext()).
Basic Context Usage
All WithContext functions accept a context.Context as their first parameter:
package main
import (
" context "
" fmt "
" github.com/shirou/gopsutil/v4/mem "
)
func main () {
ctx := context . Background ()
v , err := mem . VirtualMemoryWithContext ( ctx )
if err != nil {
panic ( err )
}
fmt . Printf ( "Total: %v , Used: %.2f%% \n " , v . Total , v . UsedPercent )
}
Configuring Paths via Context
Context-based path configuration is particularly useful in containerized environments where system directories may be mounted at non-standard locations.
You can override system directory paths by passing an EnvMap in the context:
Single Path Override
Multiple Path Overrides
Docker Container Example
import (
" context "
" github.com/shirou/gopsutil/v4/common "
" github.com/shirou/gopsutil/v4/mem "
)
ctx := context . WithValue (
context . Background (),
common . EnvKey ,
common . EnvMap {
common . HostProcEnvKey : "/myproc" ,
},
)
v , err := mem . VirtualMemoryWithContext ( ctx )
Available Environment Keys
The following environment keys can be configured via context:
Key Default Description HostProcEnvKey/procLinux proc filesystem HostSysEnvKey/sysLinux sys filesystem HostEtcEnvKey/etcSystem configuration directory HostVarEnvKey/varVariable data directory HostRunEnvKey/runRuntime data directory HostDevEnvKey/devDevice filesystem HostRootEnvKey/Root filesystem HostProcMountinfo(empty) Override for /proc/N/mountinfo
These keys are primarily used on Linux systems. On other platforms, they may have limited or no effect.
Priority Order
When resolving configuration values, gopsutil follows this priority order:
Context Values (Highest Priority)
Values set in context.Context via common.EnvMap take precedence over all other sources. ctx := context . WithValue ( context . Background (),
common . EnvKey ,
common . EnvMap { common . HostProcEnvKey : "/custom/proc" },
)
// Uses /custom/proc
Environment Variables
If not set in context, gopsutil checks environment variables like HOST_PROC. export HOST_PROC = / host / proc
# Uses /host/proc if not overridden by context
Default Values (Lowest Priority)
If neither context nor environment variables are set, gopsutil uses platform defaults. // Uses /proc on Linux by default
v , _ := mem . VirtualMemory ()
Timeout and Cancellation
Use Go’s context features to implement timeouts and cancellation:
Timeout Context
Manual Cancellation
Deadline Context
import (
" context "
" time "
" github.com/shirou/gopsutil/v4/process "
)
// Set a 5-second timeout
ctx , cancel := context . WithTimeout ( context . Background (), 5 * time . Second )
defer cancel ()
processes , err := process . ProcessesWithContext ( ctx )
if err != nil {
if ctx . Err () == context . DeadlineExceeded {
fmt . Println ( "Operation timed out" )
}
}
Practical Examples
Monitoring from Kubernetes Sidecar
package main
import (
" context "
" fmt "
" time "
" github.com/shirou/gopsutil/v4/common "
" github.com/shirou/gopsutil/v4/cpu "
" github.com/shirou/gopsutil/v4/mem "
)
func main () {
// Host system mounted at /host in the container
ctx := context . WithValue (
context . Background (),
common . EnvKey ,
common . EnvMap {
common . HostProcEnvKey : "/host/proc" ,
common . HostSysEnvKey : "/host/sys" ,
},
)
for {
// Get host CPU usage
cpuPercent , _ := cpu . PercentWithContext ( ctx , time . Second , false )
fmt . Printf ( "Host CPU: %.2f%% \n " , cpuPercent [ 0 ])
// Get host memory usage
memInfo , _ := mem . VirtualMemoryWithContext ( ctx )
fmt . Printf ( "Host Memory: %.2f%% \n " , memInfo . UsedPercent )
time . Sleep ( 10 * time . Second )
}
}
Testing with Custom Paths
package mypackage
import (
" context "
" testing "
" github.com/shirou/gopsutil/v4/common "
" github.com/shirou/gopsutil/v4/host "
)
func TestHostInfo ( t * testing . T ) {
// Use test fixtures
ctx := context . WithValue (
context . Background (),
common . EnvKey ,
common . EnvMap {
common . HostProcEnvKey : "./testdata/proc" ,
common . HostSysEnvKey : "./testdata/sys" ,
common . HostEtcEnvKey : "./testdata/etc" ,
},
)
info , err := host . InfoWithContext ( ctx )
if err != nil {
t . Fatalf ( "Failed to get host info: %v " , err )
}
// Assertions
if info . Platform != "ubuntu" {
t . Errorf ( "Expected ubuntu, got %s " , info . Platform )
}
}
Concurrent Operations with Shared Context
package main
import (
" context "
" fmt "
" sync "
" github.com/shirou/gopsutil/v4/cpu "
" github.com/shirou/gopsutil/v4/disk "
" github.com/shirou/gopsutil/v4/mem "
" github.com/shirou/gopsutil/v4/net "
)
type SystemStats struct {
CPU [] float64
Mem float64
Disk float64
Net uint64
}
func getSystemStats ( ctx context . Context ) ( * SystemStats , error ) {
var (
stats SystemStats
wg sync . WaitGroup
mu sync . Mutex
errs [] error
)
// CPU
wg . Add ( 1 )
go func () {
defer wg . Done ()
cpu , err := cpu . PercentWithContext ( ctx , 0 , true )
mu . Lock ()
defer mu . Unlock ()
if err != nil {
errs = append ( errs , err )
} else {
stats . CPU = cpu
}
}()
// Memory
wg . Add ( 1 )
go func () {
defer wg . Done ()
mem , err := mem . VirtualMemoryWithContext ( ctx )
mu . Lock ()
defer mu . Unlock ()
if err != nil {
errs = append ( errs , err )
} else {
stats . Mem = mem . UsedPercent
}
}()
// Disk
wg . Add ( 1 )
go func () {
defer wg . Done ()
disk , err := disk . UsageWithContext ( ctx , "/" )
mu . Lock ()
defer mu . Unlock ()
if err != nil {
errs = append ( errs , err )
} else {
stats . Disk = disk . UsedPercent
}
}()
// Network
wg . Add ( 1 )
go func () {
defer wg . Done ()
counters , err := net . IOCountersWithContext ( ctx , false )
mu . Lock ()
defer mu . Unlock ()
if err != nil {
errs = append ( errs , err )
} else if len ( counters ) > 0 {
stats . Net = counters [ 0 ]. BytesSent + counters [ 0 ]. BytesRecv
}
}()
wg . Wait ()
if len ( errs ) > 0 {
return nil , errs [ 0 ]
}
return & stats , nil
}
func main () {
ctx := context . Background ()
stats , err := getSystemStats ( ctx )
if err != nil {
panic ( err )
}
fmt . Printf ( "CPU: %v \n " , stats . CPU )
fmt . Printf ( "Memory: %.2f%% \n " , stats . Mem )
fmt . Printf ( "Disk: %.2f%% \n " , stats . Disk )
fmt . Printf ( "Network: %d bytes \n " , stats . Net )
}
Best Practices
Always Use WithContext Prefer WithContext variants for better control and testability, even if you’re just passing context.Background().
Reuse Contexts Create context once for a logical operation and pass it through your call stack rather than creating new contexts repeatedly.
Don't Store Contexts Never store contexts in structs. Pass them as function parameters according to Go conventions.
Cancel When Done Always call the cancel function returned by WithTimeout or WithCancel using defer to prevent context leaks.
Common Patterns
Wrapper Functions
type Monitor struct {
ctx context . Context
}
// Don't do this - storing context is an anti-pattern
// func NewMonitor(ctx context.Context) *Monitor {
// return &Monitor{ctx: ctx}
// }
// Instead, pass context to methods
func ( m * Monitor ) GetMemory ( ctx context . Context ) ( * mem . VirtualMemoryStat , error ) {
return mem . VirtualMemoryWithContext ( ctx )
}
Configuration Helper
func NewHostContext ( basePath string ) context . Context {
return context . WithValue (
context . Background (),
common . EnvKey ,
common . EnvMap {
common . HostProcEnvKey : filepath . Join ( basePath , "proc" ),
common . HostSysEnvKey : filepath . Join ( basePath , "sys" ),
common . HostEtcEnvKey : filepath . Join ( basePath , "etc" ),
common . HostVarEnvKey : filepath . Join ( basePath , "var" ),
common . HostRunEnvKey : filepath . Join ( basePath , "run" ),
common . HostDevEnvKey : filepath . Join ( basePath , "dev" ),
},
)
}
// Usage
ctx := NewHostContext ( "/hostfs" )
info , err := host . InfoWithContext ( ctx )
Next Steps
Environment Variables Learn about environment variable configuration
Caching Optimize performance with caching strategies
Quick Start Get started with basic gopsutil usage
API Reference Explore the complete API documentation