github.com/netdata/go.d.plugin@v0.58.1/modules/logind/collect.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  //go:build linux
     4  // +build linux
     5  
     6  package logind
     7  
     8  import (
     9  	"strings"
    10  )
    11  
    12  func (l *Logind) collect() (map[string]int64, error) {
    13  	if l.conn == nil {
    14  		conn, err := l.newLogindConn(l.Config)
    15  		if err != nil {
    16  			return nil, err
    17  		}
    18  		l.conn = conn
    19  	}
    20  
    21  	mx := make(map[string]int64)
    22  
    23  	// https://www.freedesktop.org/wiki/Software/systemd/logind/ (Session Objects)
    24  	if err := l.collectSessions(mx); err != nil {
    25  		return nil, err
    26  	}
    27  	// https://www.freedesktop.org/wiki/Software/systemd/logind/ (User Objects)
    28  	if err := l.collectUsers(mx); err != nil {
    29  		return nil, err
    30  	}
    31  
    32  	return mx, nil
    33  }
    34  
    35  func (l *Logind) collectSessions(mx map[string]int64) error {
    36  	sessions, err := l.conn.ListSessions()
    37  	if err != nil {
    38  		return err
    39  	}
    40  
    41  	mx["sessions_remote"] = 0
    42  	mx["sessions_local"] = 0
    43  	mx["sessions_type_graphical"] = 0
    44  	mx["sessions_type_console"] = 0
    45  	mx["sessions_type_other"] = 0
    46  	mx["sessions_state_online"] = 0
    47  	mx["sessions_state_active"] = 0
    48  	mx["sessions_state_closing"] = 0
    49  
    50  	for _, session := range sessions {
    51  		props, err := l.conn.GetSessionProperties(session.Path)
    52  		if err != nil {
    53  			return err
    54  		}
    55  
    56  		if v, ok := props["Remote"]; ok && v.String() == "true" {
    57  			mx["sessions_remote"]++
    58  		} else {
    59  			mx["sessions_local"]++
    60  		}
    61  
    62  		if v, ok := props["Type"]; ok {
    63  			typ := strings.Trim(v.String(), "\"")
    64  			switch typ {
    65  			case "x11", "mir", "wayland":
    66  				mx["sessions_type_graphical"]++
    67  			case "tty":
    68  				mx["sessions_type_console"]++
    69  			case "unspecified":
    70  				mx["sessions_type_other"]++
    71  			default:
    72  				l.Debugf("unknown session type '%s' for session '%s/%s'", typ, session.User, session.ID)
    73  				mx["sessions_type_other"]++
    74  			}
    75  		}
    76  
    77  		if v, ok := props["State"]; ok {
    78  			state := strings.Trim(v.String(), "\"")
    79  			switch state {
    80  			case "online":
    81  				mx["sessions_state_online"]++
    82  			case "active":
    83  				mx["sessions_state_active"]++
    84  			case "closing":
    85  				mx["sessions_state_closing"]++
    86  			default:
    87  				l.Debugf("unknown session state '%s' for session '%s/%s'", state, session.User, session.ID)
    88  			}
    89  		}
    90  	}
    91  	return nil
    92  }
    93  
    94  func (l *Logind) collectUsers(mx map[string]int64) error {
    95  	users, err := l.conn.ListUsers()
    96  	if err != nil {
    97  		return err
    98  	}
    99  
   100  	// https://www.freedesktop.org/software/systemd/man/sd_uid_get_state.html
   101  	mx["users_state_offline"] = 0
   102  	mx["users_state_lingering"] = 0
   103  	mx["users_state_online"] = 0
   104  	mx["users_state_active"] = 0
   105  	mx["users_state_closing"] = 0
   106  
   107  	for _, user := range users {
   108  		v, err := l.conn.GetUserProperty(user.Path, "State")
   109  		if err != nil {
   110  			return err
   111  		}
   112  
   113  		state := strings.Trim(v.String(), "\"")
   114  		switch state {
   115  		case "offline":
   116  			mx["users_state_offline"]++
   117  		case "lingering":
   118  			mx["users_state_lingering"]++
   119  		case "online":
   120  			mx["users_state_online"]++
   121  		case "active":
   122  			mx["users_state_active"]++
   123  		case "closing":
   124  			mx["users_state_closing"]++
   125  		default:
   126  			l.Debugf("unknown user state '%s' for user '%s/%d'", state, user.Name, user.UID)
   127  		}
   128  	}
   129  	return nil
   130  }