diff --git a/modules/systemdunits/README.md b/modules/systemdunits/README.md index be424b36b..999cb96f8 100644 --- a/modules/systemdunits/README.md +++ b/modules/systemdunits/README.md @@ -7,11 +7,13 @@ sidebar_label: "Systemd units" # Systemd units state monitoring with Netdata -[`Systemd`](https://www.freedesktop.org/wiki/Software/systemd/) is a suite of basic building blocks for a Linux system. +[Systemd](https://www.freedesktop.org/wiki/Software/systemd/) is a suite of basic building blocks for a Linux system. -This module monitors `Systemd` units state. +This module monitors Systemd units state. -- Works only on linux systems. +## Requirements + +- Works only on Linux systems. - Disabled by default. Should be explicitly enabled in the `go.d.conf`: ```yaml @@ -20,31 +22,26 @@ modules: systemdunits: yes ``` -## Charts - -It produces the following charts: - -- Service Unit State in `state` -- Socket Unit State in `state` -- Target Unit State in `state` -- Path Unit State in `state` -- Device Unit State in `state` -- Mount Unit State in `state` -- Automount Unit State in `state` -- Swap Unit State in `state` -- Timer Unit State in `state` -- Scope Unit State in `state` -- Slice Unit State in `state` - -## Unit states - -| Code | Name | Meaning | -|------|----------------|--------------------------------------------------------------------------------------------------------------------------------------| -| 1 | `active` | started, bound, plugged in, ..., depending on the unit type | -| 2 | `inactive` | stopped, unbound, unplugged, ..., depending on the unit type | -| 3 | `activating` | in the process of being activated | -| 4 | `deactivating` | in the process of being deactivated | -| 5 | `failed` | the service failed in some way (process returned error code on exit, or crashed, an operation timed out, or after too many restarts) | +## Metrics + +The unit types and states description can be found in +the [official documentation](https://www.freedesktop.org/software/systemd/man/systemd.html#Concepts). + +All metrics have "systemd." prefix. + +| Metric | Scope | Dimensions | Units | +|----------------------|:-----:|:--------------------------------------------------:|:-----:| +| service_unit_state | unit | active, inactive, activating, deactivating, failed | state | +| socket_unit_state | unit | active, inactive, activating, deactivating, failed | state | +| target_unit_state | unit | active, inactive, activating, deactivating, failed | state | +| path_unit_state | unit | active, inactive, activating, deactivating, failed | state | +| device_unit_state | unit | active, inactive, activating, deactivating, failed | state | +| mount_unit_state | unit | active, inactive, activating, deactivating, failed | state | +| automount_unit_state | unit | active, inactive, activating, deactivating, failed | state | +| swap_unit_state | unit | active, inactive, activating, deactivating, failed | state | +| timer_unit_state | unit | active, inactive, activating, deactivating, failed | state | +| scope_unit_state | unit | active, inactive, activating, deactivating, failed | state | +| slice_unit_state | unit | active, inactive, activating, deactivating, failed | state | ## Configuration diff --git a/modules/systemdunits/charts.go b/modules/systemdunits/charts.go index 59de4875a..23a1bf75e 100644 --- a/modules/systemdunits/charts.go +++ b/modules/systemdunits/charts.go @@ -6,86 +6,71 @@ package systemdunits import ( + "fmt" + "github.com/netdata/go.d.plugin/agent/module" + + "golang.org/x/text/cases" + "golang.org/x/text/language" ) -// systemd unit types: https://www.freedesktop.org/software/systemd/man/systemd.html -var charts = module.Charts{ - { - ID: "service_unit_state", - Title: "Service Unit State (1: active, 2: inactive, 3: activating, 4: deactivating, 5: failed)", - Units: "state", - Fam: "service", - Ctx: "systemd.service_units_state", - }, - { - ID: "socket_unit_state", - Title: "Socket Unit State (1: active, 2: inactive, 3: activating, 4: deactivating, 5: failed)", - Units: "state", - Fam: "socket", - Ctx: "systemd.socket_unit_state", - }, - { - ID: "target_unit_state", - Title: "Target Unit State (1: active, 2: inactive, 3: activating, 4: deactivating, 5: failed)", - Units: "state", - Fam: "target", - Ctx: "systemd.target_unit_state", - }, - { - ID: "path_unit_state", - Title: "Path Unit State (1: active, 2: inactive, 3: activating, 4: deactivating, 5: failed)", - Units: "state", - Fam: "path", - Ctx: "systemd.path_unit_state", - }, - { - ID: "device_unit_state", - Title: "Device Unit State (1: active, 2: inactive, 3: activating, 4: deactivating, 5: failed)", - Units: "state", - Fam: "device", - Ctx: "systemd.device_unit_state", - }, - { - ID: "mount_unit_state", - Title: "Mount Unit State (1: active, 2: inactive, 3: activating, 4: deactivating, 5: failed)", - Units: "state", - Fam: "mount", - Ctx: "systemd.mount_unit_state", - }, - { - ID: "automount_unit_state", - Title: "Automount Unit State (1: active, 2: inactive, 3: activating, 4: deactivating, 5: failed)", - Units: "state", - Fam: "automount", - Ctx: "systemd.automount_unit_state", - }, - { - ID: "swap_unit_state", - Title: "Swap Unit State (1: active, 2: inactive, 3: activating, 4: deactivating, 5: failed)", - Units: "state", - Fam: "swap", - Ctx: "systemd.swap_unit_state", - }, - { - ID: "timer_unit_state", - Title: "Timer Unit State (1: active, 2: inactive, 3: activating, 4: deactivating, 5: failed)", - Units: "state", - Fam: "timer", - Ctx: "systemd.timer_unit_state", - }, - { - ID: "scope_unit_state", - Title: "Scope Unit State (1: active, 2: inactive, 3: activating, 4: deactivating, 5: failed)", - Units: "state", - Fam: "scope", - Ctx: "systemd.scope_unit_state", - }, - { - ID: "slice_unit_state", - Title: "Slice Unit State (1: active, 2: inactive, 3: activating, 4: deactivating, 5: failed)", - Units: "state", - Fam: "slice", - Ctx: "systemd.slice_unit_state", - }, +const ( + prioServiceUnitState = module.Priority + iota + prioSocketUnitState + prioTargetUnitState + prioPathUnitState + prioDeviceUnitState + prioMountUnitState + prioAutomountUnitState + prioSwapUnitState + prioTimerUnitState + prioScopeUnitState + prioSliceUnitState +) + +var prioMap = map[string]int{ + unitTypeService: prioServiceUnitState, + unitTypeSocket: prioSocketUnitState, + unitTypeTarget: prioTargetUnitState, + unitTypePath: prioPathUnitState, + unitTypeDevice: prioDeviceUnitState, + unitTypeMount: prioMountUnitState, + unitTypeAutomount: prioAutomountUnitState, + unitTypeSwap: prioSwapUnitState, + unitTypeTimer: prioTimerUnitState, + unitTypeScope: prioScopeUnitState, + unitTypeSlice: prioSliceUnitState, +} + +func newTypedUnitStateChartTmpl(name, typ string) *module.Chart { + chart := module.Chart{ + ID: fmt.Sprintf("unit_%s_%s_state", name, typ), + Title: fmt.Sprintf("%s Unit State", cases.Title(language.English, cases.Compact).String(typ)), + Units: "state", + Fam: fmt.Sprintf("%s units", typ), + Ctx: fmt.Sprintf("systemd.%s_unit_state", typ), + Priority: prioMap[typ], + Labels: []module.Label{ + {Key: "unit_name", Value: name}, + }, + Dims: module.Dims{ + {Name: unitStateActive}, + {Name: unitStateInactive}, + {Name: unitStateActivating}, + {Name: unitStateDeactivating}, + {Name: unitStateFailed}, + }, + } + for _, d := range chart.Dims { + d.ID = fmt.Sprintf("unit_%s_%s_state_%s", name, typ, d.Name) + } + return &chart +} + +func (s *SystemdUnits) addUnitToCharts(name, typ string) { + chart := newTypedUnitStateChartTmpl(name, typ) + + if err := s.Charts().Add(chart); err != nil { + s.Warning(err) + } } diff --git a/modules/systemdunits/collect.go b/modules/systemdunits/collect.go index 3679c2658..2843a4230 100644 --- a/modules/systemdunits/collect.go +++ b/modules/systemdunits/collect.go @@ -12,11 +12,41 @@ import ( "strconv" "strings" - "github.com/netdata/go.d.plugin/agent/module" - "github.com/coreos/go-systemd/v22/dbus" ) +const ( + // https://www.freedesktop.org/software/systemd/man/systemd.html + unitStateActive = "active" + unitStateInactive = "inactive" + unitStateActivating = "activating" + unitStateDeactivating = "deactivating" + unitStateFailed = "failed" + + // https://www.freedesktop.org/software/systemd/man/systemd.html + unitTypeService = "service" + unitTypeSocket = "socket" + unitTypeTarget = "target" + unitTypePath = "path" + unitTypeDevice = "device" + unitTypeMount = "mount" + unitTypeAutomount = "automount" + unitTypeSwap = "swap" + unitTypeTimer = "timer" + unitTypeScope = "scope" + unitTypeSlice = "slice" +) + +var ( + unitStates = []string{ + unitStateActive, + unitStateActivating, + unitStateFailed, + unitStateInactive, + unitStateDeactivating, + } +) + func (s *SystemdUnits) collect() (map[string]int64, error) { conn, err := s.getConnection() if err != nil { @@ -48,19 +78,28 @@ func (s *SystemdUnits) collect() (map[string]int64, error) { return nil, nil } - collected := make(map[string]int64) - s.collectUnitsStates(collected, units) - return collected, nil + mx := make(map[string]int64) + s.collectUnitsStates(mx, units) + + return mx, nil } -func (s *SystemdUnits) collectUnitsStates(collected map[string]int64, units []dbus.UnitStatus) { +func (s *SystemdUnits) collectUnitsStates(mx map[string]int64, units []dbus.UnitStatus) { for _, unit := range units { - name := cleanUnitName(unit.Name) - if !s.collectedUnits[name] { - s.collectedUnits[name] = true - s.addUnitToCharts(name) + name, typ := extractUnitNameType(cleanUnitName(unit.Name)) + if name == "" || typ == "" { + continue + } + + if !s.units[unit.Name] { + s.units[unit.Name] = true + s.addUnitToCharts(name, typ) } - collected[name] = convertUnitState(unit.ActiveState) + + for _, s := range unitStates { + mx[fmt.Sprintf("unit_%s_%s_state_%s", name, typ, s)] = 0 + } + mx[fmt.Sprintf("unit_%s_%s_state_%s", name, typ, unit.ActiveState)] = 1 } } @@ -124,8 +163,8 @@ func (s *SystemdUnits) getLoadedUnits(conn systemdConnection) ([]dbus.UnitStatus loaded = append(loaded, unit) } } - s.Debugf("got total/loaded %d/%d units", len(units), len(loaded)) + return loaded, nil } @@ -134,11 +173,8 @@ func (s *SystemdUnits) getLoadedUnitsByPatterns(conn systemdConnection) ([]dbus. defer cancel() s.Debugf("calling function 'ListUnitsByPatterns'") - units, err := conn.ListUnitsByPatternsContext( - ctx, - []string{"active", "activating", "failed", "inactive", "deactivating"}, - s.Include, - ) + + units, err := conn.ListUnitsByPatternsContext(ctx, unitStates, s.Include) if err != nil { return nil, fmt.Errorf("error on ListUnitsByPatterns: %v", err) } @@ -149,60 +185,17 @@ func (s *SystemdUnits) getLoadedUnitsByPatterns(conn systemdConnection) ([]dbus. loaded = append(loaded, unit) } } - s.Debugf("got total/loaded %d/%d units", len(units), len(loaded)) - return loaded, nil -} - -func (s *SystemdUnits) addUnitToCharts(name string) { - typ := extractUnitType(name) - if typ == "" { - s.Warningf("add dimension (unit '%s'): can't extract unit type", name) - return - } - - id := fmt.Sprintf("%s_unit_state", typ) - chart := s.Charts().Get(id) - if chart == nil { - s.Warningf("add dimension (unit '%s'): can't find '%s' chart", name, id) - return - } - dim := &module.Dim{ - ID: name, - Name: name[:len(name)-len(typ)-1], // name.type => name - } - if err := chart.AddDim(dim); err != nil { - s.Warningf("add dimension (unit '%s'): %v", name, err) - } - chart.MarkNotCreated() + return loaded, nil } -func extractUnitType(name string) string { - // name.type => type +func extractUnitNameType(name string) (string, string) { idx := strings.LastIndexByte(name, '.') if idx <= 0 { - return "" - } - return name[idx+1:] -} - -func convertUnitState(state string) int64 { - // https://www.freedesktop.org/software/systemd/man/systemd.html - switch state { - case "active": - return 1 - case "inactive": - return 2 - case "activating": - return 3 - case "deactivating": - return 4 - case "failed": - return 5 - default: - return -1 + return "", "" } + return name[:idx], name[idx+1:] } func cleanUnitName(name string) string { diff --git a/modules/systemdunits/init.go b/modules/systemdunits/init.go index ba82358f3..d079443b1 100644 --- a/modules/systemdunits/init.go +++ b/modules/systemdunits/init.go @@ -9,18 +9,17 @@ import ( "errors" "strings" - "github.com/netdata/go.d.plugin/agent/module" "github.com/netdata/go.d.plugin/pkg/matcher" ) -func (s SystemdUnits) validateConfig() error { +func (s *SystemdUnits) validateConfig() error { if len(s.Include) == 0 { return errors.New("'include' option not set") } return nil } -func (s SystemdUnits) initSelector() (matcher.Matcher, error) { +func (s *SystemdUnits) initSelector() (matcher.Matcher, error) { if len(s.Include) == 0 { return matcher.TRUE(), nil } @@ -28,7 +27,3 @@ func (s SystemdUnits) initSelector() (matcher.Matcher, error) { expr := strings.Join(s.Include, " ") return matcher.NewSimplePatternsMatcher(expr) } - -func (s SystemdUnits) initCharts() (*module.Charts, error) { - return charts.Copy(), nil -} diff --git a/modules/systemdunits/systemdunits.go b/modules/systemdunits/systemdunits.go index 90fccc4d4..d28b9baed 100644 --- a/modules/systemdunits/systemdunits.go +++ b/modules/systemdunits/systemdunits.go @@ -32,8 +32,9 @@ func New() *SystemdUnits { Timeout: web.Duration{Duration: time.Second * 2}, }, - client: newSystemdDBusClient(), - collectedUnits: make(map[string]bool), + charts: &module.Charts{}, + client: newSystemdDBusClient(), + units: make(map[string]bool), } } @@ -50,7 +51,7 @@ type SystemdUnits struct { conn systemdConnection systemdVersion int - collectedUnits map[string]bool + units map[string]bool sr matcher.Matcher charts *module.Charts @@ -70,13 +71,6 @@ func (s *SystemdUnits) Init() bool { } s.sr = sr - cs, err := s.initCharts() - if err != nil { - s.Errorf("init charts: %v", err) - return false - } - s.charts = cs - s.Debugf("unit names patterns: %v", s.Include) s.Debugf("timeout: %s", s.Timeout) return true diff --git a/modules/systemdunits/systemdunits_test.go b/modules/systemdunits/systemdunits_test.go index 3a937d163..baa9ed46a 100644 --- a/modules/systemdunits/systemdunits_test.go +++ b/modules/systemdunits/systemdunits_test.go @@ -161,47 +161,211 @@ func TestSystemdUnits_Collect(t *testing.T) { return systemd }, wantCollected: map[string]int64{ - "dbus.socket": 1, - "dev-disk-by-uuid-DE44-CEE0.device": 1, - "dev-nvme0n1.device": 1, - "docker.socket": 1, - "getty-pre.target": 2, - "init.scope": 1, - "logrotate.timer": 1, - "lvm2-lvmetad.socket": 1, - "lvm2-lvmpolld.socket": 1, - "man-db.timer": 1, - "org.cups.cupsd.path": 1, - "pamac-cleancache.timer": 1, - "pamac-mirrorlist.timer": 1, - "proc-sys-fs-binfmt_misc.automount": 1, - "remote-fs-pre.target": 2, - "rpc_pipefs.target": 2, - "run-user-1000-gvfs.mount": 1, - "run-user-1000.mount": 1, - "session-1.scope": 1, - "session-2.scope": 1, - "session-3.scope": 1, - "session-6.scope": 1, - "shadow.timer": 1, - "sound.target": 1, - "sys-devices-virtual-net-loopback1.device": 1, - "sys-module-fuse.device": 1, - "sysinit.target": 1, - "system-getty.slice": 1, - "system-netctl.slice": 1, - "system-systemd-fsck.slice": 1, - "system.slice": 1, - "systemd-ask-password-console.path": 1, - "systemd-ask-password-wall.path": 1, - "systemd-ask-password-wall.service": 2, - "systemd-fsck-root.service": 2, - "systemd-udevd-kernel.socket": 1, - "tmp.mount": 1, - "user-runtime-dir@1000.service": 1, - "user.slice": 1, - "user@1000.service": 1, - "var-lib-nfs-rpc_pipefs.mount": 2, + "unit_dbus_socket_state_activating": 0, + "unit_dbus_socket_state_active": 1, + "unit_dbus_socket_state_deactivating": 0, + "unit_dbus_socket_state_failed": 0, + "unit_dbus_socket_state_inactive": 0, + "unit_dev-disk-by-uuid-DE44-CEE0_device_state_activating": 0, + "unit_dev-disk-by-uuid-DE44-CEE0_device_state_active": 1, + "unit_dev-disk-by-uuid-DE44-CEE0_device_state_deactivating": 0, + "unit_dev-disk-by-uuid-DE44-CEE0_device_state_failed": 0, + "unit_dev-disk-by-uuid-DE44-CEE0_device_state_inactive": 0, + "unit_dev-nvme0n1_device_state_activating": 0, + "unit_dev-nvme0n1_device_state_active": 1, + "unit_dev-nvme0n1_device_state_deactivating": 0, + "unit_dev-nvme0n1_device_state_failed": 0, + "unit_dev-nvme0n1_device_state_inactive": 0, + "unit_docker_socket_state_activating": 0, + "unit_docker_socket_state_active": 1, + "unit_docker_socket_state_deactivating": 0, + "unit_docker_socket_state_failed": 0, + "unit_docker_socket_state_inactive": 0, + "unit_getty-pre_target_state_activating": 0, + "unit_getty-pre_target_state_active": 0, + "unit_getty-pre_target_state_deactivating": 0, + "unit_getty-pre_target_state_failed": 0, + "unit_getty-pre_target_state_inactive": 1, + "unit_init_scope_state_activating": 0, + "unit_init_scope_state_active": 1, + "unit_init_scope_state_deactivating": 0, + "unit_init_scope_state_failed": 0, + "unit_init_scope_state_inactive": 0, + "unit_logrotate_timer_state_activating": 0, + "unit_logrotate_timer_state_active": 1, + "unit_logrotate_timer_state_deactivating": 0, + "unit_logrotate_timer_state_failed": 0, + "unit_logrotate_timer_state_inactive": 0, + "unit_lvm2-lvmetad_socket_state_activating": 0, + "unit_lvm2-lvmetad_socket_state_active": 1, + "unit_lvm2-lvmetad_socket_state_deactivating": 0, + "unit_lvm2-lvmetad_socket_state_failed": 0, + "unit_lvm2-lvmetad_socket_state_inactive": 0, + "unit_lvm2-lvmpolld_socket_state_activating": 0, + "unit_lvm2-lvmpolld_socket_state_active": 1, + "unit_lvm2-lvmpolld_socket_state_deactivating": 0, + "unit_lvm2-lvmpolld_socket_state_failed": 0, + "unit_lvm2-lvmpolld_socket_state_inactive": 0, + "unit_man-db_timer_state_activating": 0, + "unit_man-db_timer_state_active": 1, + "unit_man-db_timer_state_deactivating": 0, + "unit_man-db_timer_state_failed": 0, + "unit_man-db_timer_state_inactive": 0, + "unit_org.cups.cupsd_path_state_activating": 0, + "unit_org.cups.cupsd_path_state_active": 1, + "unit_org.cups.cupsd_path_state_deactivating": 0, + "unit_org.cups.cupsd_path_state_failed": 0, + "unit_org.cups.cupsd_path_state_inactive": 0, + "unit_pamac-cleancache_timer_state_activating": 0, + "unit_pamac-cleancache_timer_state_active": 1, + "unit_pamac-cleancache_timer_state_deactivating": 0, + "unit_pamac-cleancache_timer_state_failed": 0, + "unit_pamac-cleancache_timer_state_inactive": 0, + "unit_pamac-mirrorlist_timer_state_activating": 0, + "unit_pamac-mirrorlist_timer_state_active": 1, + "unit_pamac-mirrorlist_timer_state_deactivating": 0, + "unit_pamac-mirrorlist_timer_state_failed": 0, + "unit_pamac-mirrorlist_timer_state_inactive": 0, + "unit_proc-sys-fs-binfmt_misc_automount_state_activating": 0, + "unit_proc-sys-fs-binfmt_misc_automount_state_active": 1, + "unit_proc-sys-fs-binfmt_misc_automount_state_deactivating": 0, + "unit_proc-sys-fs-binfmt_misc_automount_state_failed": 0, + "unit_proc-sys-fs-binfmt_misc_automount_state_inactive": 0, + "unit_remote-fs-pre_target_state_activating": 0, + "unit_remote-fs-pre_target_state_active": 0, + "unit_remote-fs-pre_target_state_deactivating": 0, + "unit_remote-fs-pre_target_state_failed": 0, + "unit_remote-fs-pre_target_state_inactive": 1, + "unit_rpc_pipefs_target_state_activating": 0, + "unit_rpc_pipefs_target_state_active": 0, + "unit_rpc_pipefs_target_state_deactivating": 0, + "unit_rpc_pipefs_target_state_failed": 0, + "unit_rpc_pipefs_target_state_inactive": 1, + "unit_run-user-1000-gvfs_mount_state_activating": 0, + "unit_run-user-1000-gvfs_mount_state_active": 1, + "unit_run-user-1000-gvfs_mount_state_deactivating": 0, + "unit_run-user-1000-gvfs_mount_state_failed": 0, + "unit_run-user-1000-gvfs_mount_state_inactive": 0, + "unit_run-user-1000_mount_state_activating": 0, + "unit_run-user-1000_mount_state_active": 1, + "unit_run-user-1000_mount_state_deactivating": 0, + "unit_run-user-1000_mount_state_failed": 0, + "unit_run-user-1000_mount_state_inactive": 0, + "unit_session-1_scope_state_activating": 0, + "unit_session-1_scope_state_active": 1, + "unit_session-1_scope_state_deactivating": 0, + "unit_session-1_scope_state_failed": 0, + "unit_session-1_scope_state_inactive": 0, + "unit_session-2_scope_state_activating": 0, + "unit_session-2_scope_state_active": 1, + "unit_session-2_scope_state_deactivating": 0, + "unit_session-2_scope_state_failed": 0, + "unit_session-2_scope_state_inactive": 0, + "unit_session-3_scope_state_activating": 0, + "unit_session-3_scope_state_active": 1, + "unit_session-3_scope_state_deactivating": 0, + "unit_session-3_scope_state_failed": 0, + "unit_session-3_scope_state_inactive": 0, + "unit_session-6_scope_state_activating": 0, + "unit_session-6_scope_state_active": 1, + "unit_session-6_scope_state_deactivating": 0, + "unit_session-6_scope_state_failed": 0, + "unit_session-6_scope_state_inactive": 0, + "unit_shadow_timer_state_activating": 0, + "unit_shadow_timer_state_active": 1, + "unit_shadow_timer_state_deactivating": 0, + "unit_shadow_timer_state_failed": 0, + "unit_shadow_timer_state_inactive": 0, + "unit_sound_target_state_activating": 0, + "unit_sound_target_state_active": 1, + "unit_sound_target_state_deactivating": 0, + "unit_sound_target_state_failed": 0, + "unit_sound_target_state_inactive": 0, + "unit_sys-devices-virtual-net-loopback1_device_state_activating": 0, + "unit_sys-devices-virtual-net-loopback1_device_state_active": 1, + "unit_sys-devices-virtual-net-loopback1_device_state_deactivating": 0, + "unit_sys-devices-virtual-net-loopback1_device_state_failed": 0, + "unit_sys-devices-virtual-net-loopback1_device_state_inactive": 0, + "unit_sys-module-fuse_device_state_activating": 0, + "unit_sys-module-fuse_device_state_active": 1, + "unit_sys-module-fuse_device_state_deactivating": 0, + "unit_sys-module-fuse_device_state_failed": 0, + "unit_sys-module-fuse_device_state_inactive": 0, + "unit_sysinit_target_state_activating": 0, + "unit_sysinit_target_state_active": 1, + "unit_sysinit_target_state_deactivating": 0, + "unit_sysinit_target_state_failed": 0, + "unit_sysinit_target_state_inactive": 0, + "unit_system-getty_slice_state_activating": 0, + "unit_system-getty_slice_state_active": 1, + "unit_system-getty_slice_state_deactivating": 0, + "unit_system-getty_slice_state_failed": 0, + "unit_system-getty_slice_state_inactive": 0, + "unit_system-netctl_slice_state_activating": 0, + "unit_system-netctl_slice_state_active": 1, + "unit_system-netctl_slice_state_deactivating": 0, + "unit_system-netctl_slice_state_failed": 0, + "unit_system-netctl_slice_state_inactive": 0, + "unit_system-systemd-fsck_slice_state_activating": 0, + "unit_system-systemd-fsck_slice_state_active": 1, + "unit_system-systemd-fsck_slice_state_deactivating": 0, + "unit_system-systemd-fsck_slice_state_failed": 0, + "unit_system-systemd-fsck_slice_state_inactive": 0, + "unit_system_slice_state_activating": 0, + "unit_system_slice_state_active": 1, + "unit_system_slice_state_deactivating": 0, + "unit_system_slice_state_failed": 0, + "unit_system_slice_state_inactive": 0, + "unit_systemd-ask-password-console_path_state_activating": 0, + "unit_systemd-ask-password-console_path_state_active": 1, + "unit_systemd-ask-password-console_path_state_deactivating": 0, + "unit_systemd-ask-password-console_path_state_failed": 0, + "unit_systemd-ask-password-console_path_state_inactive": 0, + "unit_systemd-ask-password-wall_path_state_activating": 0, + "unit_systemd-ask-password-wall_path_state_active": 1, + "unit_systemd-ask-password-wall_path_state_deactivating": 0, + "unit_systemd-ask-password-wall_path_state_failed": 0, + "unit_systemd-ask-password-wall_path_state_inactive": 0, + "unit_systemd-ask-password-wall_service_state_activating": 0, + "unit_systemd-ask-password-wall_service_state_active": 0, + "unit_systemd-ask-password-wall_service_state_deactivating": 0, + "unit_systemd-ask-password-wall_service_state_failed": 0, + "unit_systemd-ask-password-wall_service_state_inactive": 1, + "unit_systemd-fsck-root_service_state_activating": 0, + "unit_systemd-fsck-root_service_state_active": 0, + "unit_systemd-fsck-root_service_state_deactivating": 0, + "unit_systemd-fsck-root_service_state_failed": 0, + "unit_systemd-fsck-root_service_state_inactive": 1, + "unit_systemd-udevd-kernel_socket_state_activating": 0, + "unit_systemd-udevd-kernel_socket_state_active": 1, + "unit_systemd-udevd-kernel_socket_state_deactivating": 0, + "unit_systemd-udevd-kernel_socket_state_failed": 0, + "unit_systemd-udevd-kernel_socket_state_inactive": 0, + "unit_tmp_mount_state_activating": 0, + "unit_tmp_mount_state_active": 1, + "unit_tmp_mount_state_deactivating": 0, + "unit_tmp_mount_state_failed": 0, + "unit_tmp_mount_state_inactive": 0, + "unit_user-runtime-dir@1000_service_state_activating": 0, + "unit_user-runtime-dir@1000_service_state_active": 1, + "unit_user-runtime-dir@1000_service_state_deactivating": 0, + "unit_user-runtime-dir@1000_service_state_failed": 0, + "unit_user-runtime-dir@1000_service_state_inactive": 0, + "unit_user@1000_service_state_activating": 0, + "unit_user@1000_service_state_active": 1, + "unit_user@1000_service_state_deactivating": 0, + "unit_user@1000_service_state_failed": 0, + "unit_user@1000_service_state_inactive": 0, + "unit_user_slice_state_activating": 0, + "unit_user_slice_state_active": 1, + "unit_user_slice_state_deactivating": 0, + "unit_user_slice_state_failed": 0, + "unit_user_slice_state_inactive": 0, + "unit_var-lib-nfs-rpc_pipefs_mount_state_activating": 0, + "unit_var-lib-nfs-rpc_pipefs_mount_state_active": 0, + "unit_var-lib-nfs-rpc_pipefs_mount_state_deactivating": 0, + "unit_var-lib-nfs-rpc_pipefs_mount_state_failed": 0, + "unit_var-lib-nfs-rpc_pipefs_mount_state_inactive": 1, }, }, "success on systemd v230- on collecting all unit types": { @@ -212,47 +376,211 @@ func TestSystemdUnits_Collect(t *testing.T) { return systemd }, wantCollected: map[string]int64{ - "dbus.socket": 1, - "dev-disk-by-uuid-DE44-CEE0.device": 1, - "dev-nvme0n1.device": 1, - "docker.socket": 1, - "getty-pre.target": 2, - "init.scope": 1, - "logrotate.timer": 1, - "lvm2-lvmetad.socket": 1, - "lvm2-lvmpolld.socket": 1, - "man-db.timer": 1, - "org.cups.cupsd.path": 1, - "pamac-cleancache.timer": 1, - "pamac-mirrorlist.timer": 1, - "proc-sys-fs-binfmt_misc.automount": 1, - "remote-fs-pre.target": 2, - "rpc_pipefs.target": 2, - "run-user-1000-gvfs.mount": 1, - "run-user-1000.mount": 1, - "session-1.scope": 1, - "session-2.scope": 1, - "session-3.scope": 1, - "session-6.scope": 1, - "shadow.timer": 1, - "sound.target": 1, - "sys-devices-virtual-net-loopback1.device": 1, - "sys-module-fuse.device": 1, - "sysinit.target": 1, - "system-getty.slice": 1, - "system-netctl.slice": 1, - "system-systemd-fsck.slice": 1, - "system.slice": 1, - "systemd-ask-password-console.path": 1, - "systemd-ask-password-wall.path": 1, - "systemd-ask-password-wall.service": 2, - "systemd-fsck-root.service": 2, - "systemd-udevd-kernel.socket": 1, - "tmp.mount": 1, - "user-runtime-dir@1000.service": 1, - "user.slice": 1, - "user@1000.service": 1, - "var-lib-nfs-rpc_pipefs.mount": 2, + "unit_dbus_socket_state_activating": 0, + "unit_dbus_socket_state_active": 1, + "unit_dbus_socket_state_deactivating": 0, + "unit_dbus_socket_state_failed": 0, + "unit_dbus_socket_state_inactive": 0, + "unit_dev-disk-by-uuid-DE44-CEE0_device_state_activating": 0, + "unit_dev-disk-by-uuid-DE44-CEE0_device_state_active": 1, + "unit_dev-disk-by-uuid-DE44-CEE0_device_state_deactivating": 0, + "unit_dev-disk-by-uuid-DE44-CEE0_device_state_failed": 0, + "unit_dev-disk-by-uuid-DE44-CEE0_device_state_inactive": 0, + "unit_dev-nvme0n1_device_state_activating": 0, + "unit_dev-nvme0n1_device_state_active": 1, + "unit_dev-nvme0n1_device_state_deactivating": 0, + "unit_dev-nvme0n1_device_state_failed": 0, + "unit_dev-nvme0n1_device_state_inactive": 0, + "unit_docker_socket_state_activating": 0, + "unit_docker_socket_state_active": 1, + "unit_docker_socket_state_deactivating": 0, + "unit_docker_socket_state_failed": 0, + "unit_docker_socket_state_inactive": 0, + "unit_getty-pre_target_state_activating": 0, + "unit_getty-pre_target_state_active": 0, + "unit_getty-pre_target_state_deactivating": 0, + "unit_getty-pre_target_state_failed": 0, + "unit_getty-pre_target_state_inactive": 1, + "unit_init_scope_state_activating": 0, + "unit_init_scope_state_active": 1, + "unit_init_scope_state_deactivating": 0, + "unit_init_scope_state_failed": 0, + "unit_init_scope_state_inactive": 0, + "unit_logrotate_timer_state_activating": 0, + "unit_logrotate_timer_state_active": 1, + "unit_logrotate_timer_state_deactivating": 0, + "unit_logrotate_timer_state_failed": 0, + "unit_logrotate_timer_state_inactive": 0, + "unit_lvm2-lvmetad_socket_state_activating": 0, + "unit_lvm2-lvmetad_socket_state_active": 1, + "unit_lvm2-lvmetad_socket_state_deactivating": 0, + "unit_lvm2-lvmetad_socket_state_failed": 0, + "unit_lvm2-lvmetad_socket_state_inactive": 0, + "unit_lvm2-lvmpolld_socket_state_activating": 0, + "unit_lvm2-lvmpolld_socket_state_active": 1, + "unit_lvm2-lvmpolld_socket_state_deactivating": 0, + "unit_lvm2-lvmpolld_socket_state_failed": 0, + "unit_lvm2-lvmpolld_socket_state_inactive": 0, + "unit_man-db_timer_state_activating": 0, + "unit_man-db_timer_state_active": 1, + "unit_man-db_timer_state_deactivating": 0, + "unit_man-db_timer_state_failed": 0, + "unit_man-db_timer_state_inactive": 0, + "unit_org.cups.cupsd_path_state_activating": 0, + "unit_org.cups.cupsd_path_state_active": 1, + "unit_org.cups.cupsd_path_state_deactivating": 0, + "unit_org.cups.cupsd_path_state_failed": 0, + "unit_org.cups.cupsd_path_state_inactive": 0, + "unit_pamac-cleancache_timer_state_activating": 0, + "unit_pamac-cleancache_timer_state_active": 1, + "unit_pamac-cleancache_timer_state_deactivating": 0, + "unit_pamac-cleancache_timer_state_failed": 0, + "unit_pamac-cleancache_timer_state_inactive": 0, + "unit_pamac-mirrorlist_timer_state_activating": 0, + "unit_pamac-mirrorlist_timer_state_active": 1, + "unit_pamac-mirrorlist_timer_state_deactivating": 0, + "unit_pamac-mirrorlist_timer_state_failed": 0, + "unit_pamac-mirrorlist_timer_state_inactive": 0, + "unit_proc-sys-fs-binfmt_misc_automount_state_activating": 0, + "unit_proc-sys-fs-binfmt_misc_automount_state_active": 1, + "unit_proc-sys-fs-binfmt_misc_automount_state_deactivating": 0, + "unit_proc-sys-fs-binfmt_misc_automount_state_failed": 0, + "unit_proc-sys-fs-binfmt_misc_automount_state_inactive": 0, + "unit_remote-fs-pre_target_state_activating": 0, + "unit_remote-fs-pre_target_state_active": 0, + "unit_remote-fs-pre_target_state_deactivating": 0, + "unit_remote-fs-pre_target_state_failed": 0, + "unit_remote-fs-pre_target_state_inactive": 1, + "unit_rpc_pipefs_target_state_activating": 0, + "unit_rpc_pipefs_target_state_active": 0, + "unit_rpc_pipefs_target_state_deactivating": 0, + "unit_rpc_pipefs_target_state_failed": 0, + "unit_rpc_pipefs_target_state_inactive": 1, + "unit_run-user-1000-gvfs_mount_state_activating": 0, + "unit_run-user-1000-gvfs_mount_state_active": 1, + "unit_run-user-1000-gvfs_mount_state_deactivating": 0, + "unit_run-user-1000-gvfs_mount_state_failed": 0, + "unit_run-user-1000-gvfs_mount_state_inactive": 0, + "unit_run-user-1000_mount_state_activating": 0, + "unit_run-user-1000_mount_state_active": 1, + "unit_run-user-1000_mount_state_deactivating": 0, + "unit_run-user-1000_mount_state_failed": 0, + "unit_run-user-1000_mount_state_inactive": 0, + "unit_session-1_scope_state_activating": 0, + "unit_session-1_scope_state_active": 1, + "unit_session-1_scope_state_deactivating": 0, + "unit_session-1_scope_state_failed": 0, + "unit_session-1_scope_state_inactive": 0, + "unit_session-2_scope_state_activating": 0, + "unit_session-2_scope_state_active": 1, + "unit_session-2_scope_state_deactivating": 0, + "unit_session-2_scope_state_failed": 0, + "unit_session-2_scope_state_inactive": 0, + "unit_session-3_scope_state_activating": 0, + "unit_session-3_scope_state_active": 1, + "unit_session-3_scope_state_deactivating": 0, + "unit_session-3_scope_state_failed": 0, + "unit_session-3_scope_state_inactive": 0, + "unit_session-6_scope_state_activating": 0, + "unit_session-6_scope_state_active": 1, + "unit_session-6_scope_state_deactivating": 0, + "unit_session-6_scope_state_failed": 0, + "unit_session-6_scope_state_inactive": 0, + "unit_shadow_timer_state_activating": 0, + "unit_shadow_timer_state_active": 1, + "unit_shadow_timer_state_deactivating": 0, + "unit_shadow_timer_state_failed": 0, + "unit_shadow_timer_state_inactive": 0, + "unit_sound_target_state_activating": 0, + "unit_sound_target_state_active": 1, + "unit_sound_target_state_deactivating": 0, + "unit_sound_target_state_failed": 0, + "unit_sound_target_state_inactive": 0, + "unit_sys-devices-virtual-net-loopback1_device_state_activating": 0, + "unit_sys-devices-virtual-net-loopback1_device_state_active": 1, + "unit_sys-devices-virtual-net-loopback1_device_state_deactivating": 0, + "unit_sys-devices-virtual-net-loopback1_device_state_failed": 0, + "unit_sys-devices-virtual-net-loopback1_device_state_inactive": 0, + "unit_sys-module-fuse_device_state_activating": 0, + "unit_sys-module-fuse_device_state_active": 1, + "unit_sys-module-fuse_device_state_deactivating": 0, + "unit_sys-module-fuse_device_state_failed": 0, + "unit_sys-module-fuse_device_state_inactive": 0, + "unit_sysinit_target_state_activating": 0, + "unit_sysinit_target_state_active": 1, + "unit_sysinit_target_state_deactivating": 0, + "unit_sysinit_target_state_failed": 0, + "unit_sysinit_target_state_inactive": 0, + "unit_system-getty_slice_state_activating": 0, + "unit_system-getty_slice_state_active": 1, + "unit_system-getty_slice_state_deactivating": 0, + "unit_system-getty_slice_state_failed": 0, + "unit_system-getty_slice_state_inactive": 0, + "unit_system-netctl_slice_state_activating": 0, + "unit_system-netctl_slice_state_active": 1, + "unit_system-netctl_slice_state_deactivating": 0, + "unit_system-netctl_slice_state_failed": 0, + "unit_system-netctl_slice_state_inactive": 0, + "unit_system-systemd-fsck_slice_state_activating": 0, + "unit_system-systemd-fsck_slice_state_active": 1, + "unit_system-systemd-fsck_slice_state_deactivating": 0, + "unit_system-systemd-fsck_slice_state_failed": 0, + "unit_system-systemd-fsck_slice_state_inactive": 0, + "unit_system_slice_state_activating": 0, + "unit_system_slice_state_active": 1, + "unit_system_slice_state_deactivating": 0, + "unit_system_slice_state_failed": 0, + "unit_system_slice_state_inactive": 0, + "unit_systemd-ask-password-console_path_state_activating": 0, + "unit_systemd-ask-password-console_path_state_active": 1, + "unit_systemd-ask-password-console_path_state_deactivating": 0, + "unit_systemd-ask-password-console_path_state_failed": 0, + "unit_systemd-ask-password-console_path_state_inactive": 0, + "unit_systemd-ask-password-wall_path_state_activating": 0, + "unit_systemd-ask-password-wall_path_state_active": 1, + "unit_systemd-ask-password-wall_path_state_deactivating": 0, + "unit_systemd-ask-password-wall_path_state_failed": 0, + "unit_systemd-ask-password-wall_path_state_inactive": 0, + "unit_systemd-ask-password-wall_service_state_activating": 0, + "unit_systemd-ask-password-wall_service_state_active": 0, + "unit_systemd-ask-password-wall_service_state_deactivating": 0, + "unit_systemd-ask-password-wall_service_state_failed": 0, + "unit_systemd-ask-password-wall_service_state_inactive": 1, + "unit_systemd-fsck-root_service_state_activating": 0, + "unit_systemd-fsck-root_service_state_active": 0, + "unit_systemd-fsck-root_service_state_deactivating": 0, + "unit_systemd-fsck-root_service_state_failed": 0, + "unit_systemd-fsck-root_service_state_inactive": 1, + "unit_systemd-udevd-kernel_socket_state_activating": 0, + "unit_systemd-udevd-kernel_socket_state_active": 1, + "unit_systemd-udevd-kernel_socket_state_deactivating": 0, + "unit_systemd-udevd-kernel_socket_state_failed": 0, + "unit_systemd-udevd-kernel_socket_state_inactive": 0, + "unit_tmp_mount_state_activating": 0, + "unit_tmp_mount_state_active": 1, + "unit_tmp_mount_state_deactivating": 0, + "unit_tmp_mount_state_failed": 0, + "unit_tmp_mount_state_inactive": 0, + "unit_user-runtime-dir@1000_service_state_activating": 0, + "unit_user-runtime-dir@1000_service_state_active": 1, + "unit_user-runtime-dir@1000_service_state_deactivating": 0, + "unit_user-runtime-dir@1000_service_state_failed": 0, + "unit_user-runtime-dir@1000_service_state_inactive": 0, + "unit_user@1000_service_state_activating": 0, + "unit_user@1000_service_state_active": 1, + "unit_user@1000_service_state_deactivating": 0, + "unit_user@1000_service_state_failed": 0, + "unit_user@1000_service_state_inactive": 0, + "unit_user_slice_state_activating": 0, + "unit_user_slice_state_active": 1, + "unit_user_slice_state_deactivating": 0, + "unit_user_slice_state_failed": 0, + "unit_user_slice_state_inactive": 0, + "unit_var-lib-nfs-rpc_pipefs_mount_state_activating": 0, + "unit_var-lib-nfs-rpc_pipefs_mount_state_active": 0, + "unit_var-lib-nfs-rpc_pipefs_mount_state_deactivating": 0, + "unit_var-lib-nfs-rpc_pipefs_mount_state_failed": 0, + "unit_var-lib-nfs-rpc_pipefs_mount_state_inactive": 1, }, }, "success on systemd v230+ on collecting only 'service' unit type": { @@ -263,10 +591,26 @@ func TestSystemdUnits_Collect(t *testing.T) { return systemd }, wantCollected: map[string]int64{ - "systemd-ask-password-wall.service": 2, - "systemd-fsck-root.service": 2, - "user-runtime-dir@1000.service": 1, - "user@1000.service": 1, + "unit_systemd-ask-password-wall_service_state_activating": 0, + "unit_systemd-ask-password-wall_service_state_active": 0, + "unit_systemd-ask-password-wall_service_state_deactivating": 0, + "unit_systemd-ask-password-wall_service_state_failed": 0, + "unit_systemd-ask-password-wall_service_state_inactive": 1, + "unit_systemd-fsck-root_service_state_activating": 0, + "unit_systemd-fsck-root_service_state_active": 0, + "unit_systemd-fsck-root_service_state_deactivating": 0, + "unit_systemd-fsck-root_service_state_failed": 0, + "unit_systemd-fsck-root_service_state_inactive": 1, + "unit_user-runtime-dir@1000_service_state_activating": 0, + "unit_user-runtime-dir@1000_service_state_active": 1, + "unit_user-runtime-dir@1000_service_state_deactivating": 0, + "unit_user-runtime-dir@1000_service_state_failed": 0, + "unit_user-runtime-dir@1000_service_state_inactive": 0, + "unit_user@1000_service_state_activating": 0, + "unit_user@1000_service_state_active": 1, + "unit_user@1000_service_state_deactivating": 0, + "unit_user@1000_service_state_failed": 0, + "unit_user@1000_service_state_inactive": 0, }, }, "success on systemd v230- on collecting only 'service' unit type": { @@ -277,10 +621,26 @@ func TestSystemdUnits_Collect(t *testing.T) { return systemd }, wantCollected: map[string]int64{ - "systemd-ask-password-wall.service": 2, - "systemd-fsck-root.service": 2, - "user-runtime-dir@1000.service": 1, - "user@1000.service": 1, + "unit_systemd-ask-password-wall_service_state_activating": 0, + "unit_systemd-ask-password-wall_service_state_active": 0, + "unit_systemd-ask-password-wall_service_state_deactivating": 0, + "unit_systemd-ask-password-wall_service_state_failed": 0, + "unit_systemd-ask-password-wall_service_state_inactive": 1, + "unit_systemd-fsck-root_service_state_activating": 0, + "unit_systemd-fsck-root_service_state_active": 0, + "unit_systemd-fsck-root_service_state_deactivating": 0, + "unit_systemd-fsck-root_service_state_failed": 0, + "unit_systemd-fsck-root_service_state_inactive": 1, + "unit_user-runtime-dir@1000_service_state_activating": 0, + "unit_user-runtime-dir@1000_service_state_active": 1, + "unit_user-runtime-dir@1000_service_state_deactivating": 0, + "unit_user-runtime-dir@1000_service_state_failed": 0, + "unit_user-runtime-dir@1000_service_state_inactive": 0, + "unit_user@1000_service_state_activating": 0, + "unit_user@1000_service_state_active": 1, + "unit_user@1000_service_state_deactivating": 0, + "unit_user@1000_service_state_failed": 0, + "unit_user@1000_service_state_inactive": 0, }, }, "fails when all unites are filtered": { @@ -430,7 +790,7 @@ func (m *mockConn) Close() { m.closeCalled = true } -func (m mockConn) GetManagerProperty(prop string) (string, error) { +func (m *mockConn) GetManagerProperty(prop string) (string, error) { if m.errOnGetManagerProperty { return "", errors.New("'GetManagerProperty' call error") } @@ -440,7 +800,7 @@ func (m mockConn) GetManagerProperty(prop string) (string, error) { return fmt.Sprintf("%d.6-1-manjaro", m.version), nil } -func (m mockConn) ListUnitsContext(_ context.Context) ([]dbus.UnitStatus, error) { +func (m *mockConn) ListUnitsContext(_ context.Context) ([]dbus.UnitStatus, error) { if m.errOnListUnits { return nil, errors.New("'ListUnits' call error") } @@ -450,7 +810,7 @@ func (m mockConn) ListUnitsContext(_ context.Context) ([]dbus.UnitStatus, error) return append([]dbus.UnitStatus{}, m.units...), nil } -func (m mockConn) ListUnitsByPatternsContext(_ context.Context, _ []string, ps []string) ([]dbus.UnitStatus, error) { +func (m *mockConn) ListUnitsByPatternsContext(_ context.Context, _ []string, ps []string) ([]dbus.UnitStatus, error) { if m.errOnListUnits { return nil, errors.New("'ListUnitsByPatterns' call error") }