Skip to main content
The Users() function returns a list of all currently logged-in users on the system, including their terminal, remote host, and login time.

Function Signature

func Users() ([]UserStat, error)
func UsersWithContext(ctx context.Context) ([]UserStat, error)

Return Value

Returns a slice of UserStat structs, where each struct contains:
User
string
Username of the logged-in user
Terminal
string
Terminal or TTY the user is logged in on (e.g., “tty1”, “pts/0”)
Host
string
Hostname or IP address if the user is logged in remotely, empty for local logins
Started
int
Login time as Unix timestamp (seconds since epoch)

UserStat Structure

type UserStat struct {
    User     string `json:"user"`
    Terminal string `json:"terminal"`
    Host     string `json:"host"`
    Started  int    `json:"started"`
}

Usage Examples

List All Logged-in Users

package main

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

func main() {
    users, err := host.Users()
    if err != nil {
        panic(err)
    }
    
    fmt.Printf("Currently logged-in users: %d\n\n", len(users))
    
    for _, user := range users {
        fmt.Printf("User: %s\n", user.User)
        fmt.Printf("  Terminal: %s\n", user.Terminal)
        fmt.Printf("  Host: %s\n", user.Host)
        fmt.Printf("  Started: %d\n\n", user.Started)
    }
}

Format Login Times

package main

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

func main() {
    users, err := host.Users()
    if err != nil {
        panic(err)
    }
    
    for _, user := range users {
        loginTime := time.Unix(int64(user.Started), 0)
        duration := time.Since(loginTime)
        
        fmt.Printf("%s on %s (logged in %v ago)\n", 
            user.User, 
            user.Terminal, 
            duration.Round(time.Minute))
    }
}

Detect Remote Users

package main

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

func main() {
    users, err := host.Users()
    if err != nil {
        panic(err)
    }
    
    var localUsers, remoteUsers []host.UserStat
    
    for _, user := range users {
        if user.Host == "" {
            localUsers = append(localUsers, user)
        } else {
            remoteUsers = append(remoteUsers, user)
        }
    }
    
    fmt.Printf("Local users: %d\n", len(localUsers))
    fmt.Printf("Remote users: %d\n", len(remoteUsers))
    
    if len(remoteUsers) > 0 {
        fmt.Println("\nRemote connections:")
        for _, user := range remoteUsers {
            fmt.Printf("  %s from %s\n", user.User, user.Host)
        }
    }
}

With Context

package main

import (
    "context"
    "fmt"
    "time"
    "github.com/shirou/gopsutil/v4/host"
)

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    
    users, err := host.UsersWithContext(ctx)
    if err != nil {
        panic(err)
    }
    
    fmt.Printf("Found %d users\n", len(users))
}

JSON Output

package main

import (
    "encoding/json"
    "fmt"
    "github.com/shirou/gopsutil/v4/host"
)

func main() {
    users, err := host.Users()
    if err != nil {
        panic(err)
    }
    
    // Pretty print JSON
    data, err := json.MarshalIndent(users, "", "  ")
    if err != nil {
        panic(err)
    }
    
    fmt.Println(string(data))
}

Security Monitoring

package main

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

func monitorLogins() {
    knownUsers := make(map[string]bool)
    
    // Initialize with current users
    users, _ := host.Users()
    for _, user := range users {
        key := fmt.Sprintf("%s@%s", user.User, user.Terminal)
        knownUsers[key] = true
    }
    
    ticker := time.NewTicker(10 * time.Second)
    defer ticker.Stop()
    
    for range ticker.C {
        users, err := host.Users()
        if err != nil {
            continue
        }
        
        currentUsers := make(map[string]bool)
        
        for _, user := range users {
            key := fmt.Sprintf("%s@%s", user.User, user.Terminal)
            currentUsers[key] = true
            
            // New login detected
            if !knownUsers[key] {
                fmt.Printf("New login: %s on %s", user.User, user.Terminal)
                if user.Host != "" {
                    fmt.Printf(" from %s", user.Host)
                }
                fmt.Println()
            }
        }
        
        // Check for logouts
        for key := range knownUsers {
            if !currentUsers[key] {
                fmt.Printf("User logged out: %s\n", key)
            }
        }
        
        knownUsers = currentUsers
    }
}

Count Unique Users

package main

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

func main() {
    users, err := host.Users()
    if err != nil {
        panic(err)
    }
    
    uniqueUsers := make(map[string]int)
    
    for _, user := range users {
        uniqueUsers[user.User]++
    }
    
    fmt.Printf("Total sessions: %d\n", len(users))
    fmt.Printf("Unique users: %d\n\n", len(uniqueUsers))
    
    for username, count := range uniqueUsers {
        fmt.Printf("%s: %d session(s)\n", username, count)
    }
}

Platform Implementation

Reads from /var/run/utmp or uses getutent() system call

Error Handling

The function may return errors when:
  • Unable to access user database files (permission issues)
  • System calls fail
  • Context deadline exceeded
On some systems, the function may require elevated privileges to read user session information.

Info()

Get comprehensive host information

Host Overview

Back to host package overview

Build docs developers (and LLMs) love