feat(inputs.systemd_units): Support user scoped units (#15458)
This commit is contained in:
parent
32a5b44d7b
commit
4a9eba6abd
|
|
@ -31,6 +31,10 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
|
|||
## automount, swap, timer, path, slice and scope
|
||||
# unittype = "service"
|
||||
|
||||
## Collect system or user scoped units
|
||||
## ex: scope = "user"
|
||||
# scope = "system"
|
||||
|
||||
## Collect also units not loaded by systemd, i.e. disabled or static units
|
||||
## Enabling this feature might introduce significant load when used with
|
||||
## unspecific patterns (such as '*') as systemd will need to load all
|
||||
|
|
@ -69,6 +73,7 @@ These metrics are available in both modes:
|
|||
- load (string, load state)
|
||||
- active (string, active state)
|
||||
- sub (string, sub state)
|
||||
- user (string, username only for user scope)
|
||||
- fields:
|
||||
- load_code (int, see below)
|
||||
- active_code (int, see below)
|
||||
|
|
@ -198,15 +203,15 @@ were removed, tables are hex aligned to keep some space for future values
|
|||
### Output in non-detailed mode
|
||||
|
||||
```text
|
||||
systemd_units,host=host1.example.com,name=dbus.service,load=loaded,active=active,sub=running load_code=0i,active_code=0i,sub_code=0i 1533730725000000000
|
||||
systemd_units,host=host1.example.com,name=networking.service,load=loaded,active=failed,sub=failed load_code=0i,active_code=3i,sub_code=12i 1533730725000000000
|
||||
systemd_units,host=host1.example.com,name=ssh.service,load=loaded,active=active,sub=running load_code=0i,active_code=0i,sub_code=0i 1533730725000000000
|
||||
systemd_units,host=host1.example.com,name=dbus.service,load=loaded,active=active,sub=running,user=telegraf load_code=0i,active_code=0i,sub_code=0i 1533730725000000000
|
||||
systemd_units,host=host1.example.com,name=networking.service,load=loaded,active=failed,sub=failed,user=telegraf load_code=0i,active_code=3i,sub_code=12i 1533730725000000000
|
||||
systemd_units,host=host1.example.com,name=ssh.service,load=loaded,active=active,sub=running,user=telegraf load_code=0i,active_code=0i,sub_code=0i 1533730725000000000
|
||||
```
|
||||
|
||||
### Output in detailed mode
|
||||
|
||||
```text
|
||||
systemd_units,active=active,host=host1.example.com,load=loaded,name=dbus.service,sub=running,preset=disabled,state=static active_code=0i,load_code=0i,mem_avail=6470856704i,mem_current=2691072i,mem_peak=3895296i,pid=481i,restarts=0i,status_errno=0i,sub_code=0i,swap_current=794624i,swap_peak=884736i 1533730725000000000
|
||||
systemd_units,active=inactive,host=host1.example.com,load=not-found,name=networking.service,sub=dead active_code=2i,load_code=2i,pid=0i,restarts=0i,status_errno=0i,sub_code=1i 1533730725000000000
|
||||
systemd_units,active=active,host=host1.example.com,load=loaded,name=pcscd.service,sub=running,preset=disabled,state=indirect active_code=0i,load_code=0i,mem_avail=6370541568i,mem_current=512000i,mem_peak=4399104i,pid=1673i,restarts=0i,status_errno=0i,sub_code=0i,swap_current=3149824i,swap_peak=3149824i 1533730725000000000
|
||||
systemd_units,active=active,host=host1.example.com,load=loaded,name=dbus.service,sub=running,preset=disabled,state=static,user=telegraf active_code=0i,load_code=0i,mem_avail=6470856704i,mem_current=2691072i,mem_peak=3895296i,pid=481i,restarts=0i,status_errno=0i,sub_code=0i,swap_current=794624i,swap_peak=884736i 1533730725000000000
|
||||
systemd_units,active=inactive,host=host1.example.com,load=not-found,name=networking.service,sub=dead,user=telegraf active_code=2i,load_code=2i,pid=0i,restarts=0i,status_errno=0i,sub_code=1i 1533730725000000000
|
||||
systemd_units,active=active,host=host1.example.com,load=loaded,name=pcscd.service,sub=running,preset=disabled,state=indirect,user=telegraf active_code=0i,load_code=0i,mem_avail=6370541568i,mem_current=512000i,mem_peak=4399104i,pid=1673i,restarts=0i,status_errno=0i,sub_code=0i,swap_current=3149824i,swap_peak=3149824i 1533730725000000000
|
||||
```
|
||||
|
|
|
|||
|
|
@ -12,6 +12,10 @@
|
|||
## automount, swap, timer, path, slice and scope
|
||||
# unittype = "service"
|
||||
|
||||
## Collect system or user scoped units
|
||||
## ex: scope = "user"
|
||||
# scope = "system"
|
||||
|
||||
## Collect also units not loaded by systemd, i.e. disabled or static units
|
||||
## Enabling this feature might introduce significant load when used with
|
||||
## unspecific patterns (such as '*') as systemd will need to load all
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ var sampleConfig string
|
|||
type SystemdUnits struct {
|
||||
Pattern string `toml:"pattern"`
|
||||
UnitType string `toml:"unittype"`
|
||||
Scope string `toml:"scope"`
|
||||
Details bool `toml:"details"`
|
||||
CollectDisabled bool `toml:"collect_disabled_units"`
|
||||
Timeout config.Duration `toml:"timeout"`
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"os/user"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
|
@ -131,6 +132,8 @@ type archParams struct {
|
|||
pattern []string
|
||||
filter filter.Filter
|
||||
unitTypeDBus string
|
||||
scope string
|
||||
user string
|
||||
}
|
||||
|
||||
func (s *SystemdUnits) Init() error {
|
||||
|
|
@ -158,15 +161,38 @@ func (s *SystemdUnits) Init() error {
|
|||
}
|
||||
s.filter = f
|
||||
|
||||
switch s.Scope {
|
||||
case "", "system":
|
||||
s.scope = "system"
|
||||
case "user":
|
||||
u, err := user.Current()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to determine user: %w", err)
|
||||
}
|
||||
|
||||
s.scope = "user"
|
||||
s.user = u.Username
|
||||
default:
|
||||
return fmt.Errorf("invalid 'scope' %q", s.Scope)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SystemdUnits) Start(telegraf.Accumulator) error {
|
||||
ctx := context.Background()
|
||||
client, err := dbus.NewSystemConnectionContext(ctx)
|
||||
|
||||
var client *dbus.Conn
|
||||
var err error
|
||||
if s.scope == "user" {
|
||||
client, err = dbus.NewUserConnectionContext(ctx)
|
||||
} else {
|
||||
client, err = dbus.NewSystemConnectionContext(ctx)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.client = client
|
||||
|
||||
return nil
|
||||
|
|
@ -321,6 +347,9 @@ func (s *SystemdUnits) Gather(acc telegraf.Accumulator) error {
|
|||
"active": state.ActiveState,
|
||||
"sub": state.SubState,
|
||||
}
|
||||
if s.scope == "user" {
|
||||
tags["user"] = s.user
|
||||
}
|
||||
|
||||
fields := map[string]interface{}{
|
||||
"load_code": load,
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"os/user"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
|
@ -38,6 +39,50 @@ func TestDefaultPattern(t *testing.T) {
|
|||
require.Equal(t, "*", plugin.Pattern)
|
||||
}
|
||||
|
||||
func TestDefaultScope(t *testing.T) {
|
||||
u, err := user.Current()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
scope string
|
||||
expectedScope string
|
||||
expectedUser string
|
||||
}{
|
||||
{
|
||||
name: "default scope",
|
||||
scope: "",
|
||||
expectedScope: "system",
|
||||
expectedUser: "",
|
||||
},
|
||||
{
|
||||
name: "system scope",
|
||||
scope: "system",
|
||||
expectedScope: "system",
|
||||
expectedUser: "",
|
||||
},
|
||||
{
|
||||
name: "user scope",
|
||||
scope: "user",
|
||||
expectedScope: "user",
|
||||
expectedUser: u.Username,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
plugin := &SystemdUnits{
|
||||
Scope: tt.scope,
|
||||
}
|
||||
require.NoError(t, plugin.Init())
|
||||
require.Equal(t, tt.expectedScope, plugin.scope)
|
||||
require.Equal(t, tt.expectedUser, plugin.user)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestListFiles(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
|
|
|||
Loading…
Reference in New Issue