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