Monitor and manage system processes with detailed process information
Learn how to work with system processes using gopsutil. This example shows you how to list processes, get detailed process information, and monitor resource usage.
Create a function to retrieve detailed process information:
main.go
func getProcessInfo(p *process.Process) (*ProcessInfo, error) { info := &ProcessInfo{PID: p.Pid} // Get process name name, err := p.Name() if err != nil { return nil, err } info.Name = name // Get process status status, err := p.Status() if err == nil && len(status) > 0 { info.Status = status[0] } // Get CPU percentage (requires a measurement interval) cpuPercent, err := p.CPUPercent() if err == nil { info.CPUPercent = cpuPercent } // Get memory percentage memPercent, err := p.MemoryPercent() if err == nil { info.MemPercent = memPercent } // Get memory info in MB memInfo, err := p.MemoryInfo() if err == nil { info.MemoryMB = memInfo.RSS / 1024 / 1024 } // Get number of threads numThreads, err := p.NumThreads() if err == nil { info.NumThreads = numThreads } // Get creation time createTime, err := p.CreateTime() if err == nil { t := time.Unix(createTime/1000, 0) info.CreateTime = t.Format("2006-01-02 15:04:05") } return info, nil}
Process methods may return errors if the process terminates or if you lack permissions.
Always check errors and handle them gracefully.
4
List all running processes
Create a function to list all processes:
main.go
func listAllProcesses() error { // Get all process PIDs pids, err := process.Pids() if err != nil { return fmt.Errorf("error getting process list: %w", err) } fmt.Printf("\nFound %d running processes\n\n", len(pids)) var processes []*ProcessInfo // Get information for each process for _, pid := range pids { p, err := process.NewProcess(pid) if err != nil { continue // Process may have terminated } info, err := getProcessInfo(p) if err != nil { continue // Skip processes we can't access } processes = append(processes, info) } // Sort by CPU usage (descending) sort.Slice(processes, func(i, j int) bool { return processes[i].CPUPercent > processes[j].CPUPercent }) // Display top 20 processes by CPU usage fmt.Println("Top 20 Processes by CPU Usage:") fmt.Println(strings.Repeat("=", 120)) for i, info := range processes { if i >= 20 { break } fmt.Println(info) } return nil}
5
Find processes by name
Add a function to search for processes:
main.go
func findProcessByName(searchName string) error { pids, err := process.Pids() if err != nil { return fmt.Errorf("error getting process list: %w", err) } fmt.Printf("\nSearching for processes matching '%s'...\n\n", searchName) found := false for _, pid := range pids { p, err := process.NewProcess(pid) if err != nil { continue } name, err := p.Name() if err != nil { continue } // Case-insensitive search if strings.Contains(strings.ToLower(name), strings.ToLower(searchName)) { info, err := getProcessInfo(p) if err != nil { continue } fmt.Println(info) found = true } } if !found { fmt.Printf("No processes found matching '%s'\n", searchName) } return nil}
6
Get detailed process information
Create a function to show comprehensive process details:
Some process information (like I/O counters and connections) may only be
available on certain platforms or require elevated privileges.
7
Monitor a process continuously
Add a function to monitor a process over time:
main.go
func monitorProcess(pid int32, duration time.Duration) error { p, err := process.NewProcess(pid) if err != nil { return fmt.Errorf("error getting process: %w", err) } name, _ := p.Name() fmt.Printf("\nMonitoring process %d (%s) for %s...\n\n", pid, name, duration) fmt.Println("Time | CPU % | Memory % | Memory MB | Threads") fmt.Println(strings.Repeat("-", 60)) ticker := time.NewTicker(2 * time.Second) defer ticker.Stop() timeout := time.After(duration) for { select { case <-timeout: fmt.Println("\nMonitoring complete.") return nil case t := <-ticker.C: // Check if process still exists isRunning, err := p.IsRunning() if err != nil || !isRunning { fmt.Println("\nProcess terminated.") return nil } info, err := getProcessInfo(p) if err != nil { continue } fmt.Printf("%s | %5.2f | %7.2f | %9d | %7d\n", t.Format("15:04:05"), info.CPUPercent, info.MemPercent, info.MemoryMB, info.NumThreads, ) } }}
8
Create the main function with CLI
Add a simple command-line interface:
main.go
func main() { if len(os.Args) < 2 { printUsage() return } command := os.Args[1] switch command { case "list": if err := listAllProcesses(); err != nil { fmt.Printf("Error: %v\n", err) } case "find": if len(os.Args) < 3 { fmt.Println("Usage: go run main.go find <process-name>") return } if err := findProcessByName(os.Args[2]); err != nil { fmt.Printf("Error: %v\n", err) } case "details": if len(os.Args) < 3 { fmt.Println("Usage: go run main.go details <pid>") return } var pid int32 if _, err := fmt.Sscanf(os.Args[2], "%d", &pid); err != nil { fmt.Printf("Invalid PID: %v\n", err) return } if err := showProcessDetails(pid); err != nil { fmt.Printf("Error: %v\n", err) } case "monitor": if len(os.Args) < 3 { fmt.Println("Usage: go run main.go monitor <pid>") return } var pid int32 if _, err := fmt.Sscanf(os.Args[2], "%d", &pid); err != nil { fmt.Printf("Invalid PID: %v\n", err) return } if err := monitorProcess(pid, 30*time.Second); err != nil { fmt.Printf("Error: %v\n", err) } default: printUsage() }}func printUsage() { fmt.Println("Process Monitor") fmt.Println("===============") fmt.Println("\nUsage:") fmt.Println(" go run main.go list - List top processes by CPU") fmt.Println(" go run main.go find <name> - Find processes by name") fmt.Println(" go run main.go details <pid> - Show detailed process info") fmt.Println(" go run main.go monitor <pid> - Monitor process for 30s")}
9
Test the application
Run the different commands:
# List top processesgo run main.go list# Find processes by namego run main.go find chrome# Show details for a specific PIDgo run main.go details 1234# Monitor a processgo run main.go monitor 1234
Use process.NewProcess(pid) to get a process handle. Always check if the process exists.
Resource Monitoring
Methods like CPUPercent() and MemoryPercent() provide real-time usage data.
Process Hierarchy
Use Ppid() to get parent process ID and track process relationships.
Error Handling
Processes can terminate anytime. Always handle errors gracefully.
Some process operations require elevated privileges (root/administrator).
If you get permission errors, try running your program with sudo or as administrator.