summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlya Mashchenko <ilya@netdata.cloud>2024-05-21 22:28:19 +0300
committerGitHub <noreply@github.com>2024-05-21 22:28:19 +0300
commite54b6164dd9f9c897e99ed17f802f014275f7578 (patch)
tree271532099ba8869049b5233ef1e952e694b952e8
parent1b61aa9d215613c4c284fbfd5ddfb323d9fe4beb (diff)
go.d systemdunits add "skip_transient" (#17725)
-rw-r--r--src/go/collectors/go.d.plugin/modules/systemdunits/client.go1
-rw-r--r--src/go/collectors/go.d.plugin/modules/systemdunits/collect_units.go36
-rw-r--r--src/go/collectors/go.d.plugin/modules/systemdunits/config_schema.json10
-rw-r--r--src/go/collectors/go.d.plugin/modules/systemdunits/metadata.yaml4
-rw-r--r--src/go/collectors/go.d.plugin/modules/systemdunits/systemdunits.go8
-rw-r--r--src/go/collectors/go.d.plugin/modules/systemdunits/systemdunits_test.go50
-rw-r--r--src/go/collectors/go.d.plugin/modules/systemdunits/testdata/config.json1
-rw-r--r--src/go/collectors/go.d.plugin/modules/systemdunits/testdata/config.yaml1
8 files changed, 109 insertions, 2 deletions
diff --git a/src/go/collectors/go.d.plugin/modules/systemdunits/client.go b/src/go/collectors/go.d.plugin/modules/systemdunits/client.go
index b1152865f4..e6363d1329 100644
--- a/src/go/collectors/go.d.plugin/modules/systemdunits/client.go
+++ b/src/go/collectors/go.d.plugin/modules/systemdunits/client.go
@@ -17,6 +17,7 @@ type systemdClient interface {
type systemdConnection interface {
Close()
GetManagerProperty(string) (string, error)
+ GetUnitPropertyContext(ctx context.Context, unit string, propertyName string) (*dbus.Property, error)
ListUnitsContext(ctx context.Context) ([]dbus.UnitStatus, error)
ListUnitsByPatternsContext(ctx context.Context, states []string, patterns []string) ([]dbus.UnitStatus, error)
ListUnitFilesByPatternsContext(ctx context.Context, states []string, patterns []string) ([]dbus.UnitFile, error)
diff --git a/src/go/collectors/go.d.plugin/modules/systemdunits/collect_units.go b/src/go/collectors/go.d.plugin/modules/systemdunits/collect_units.go
index 4cfc89d604..0cf97af03f 100644
--- a/src/go/collectors/go.d.plugin/modules/systemdunits/collect_units.go
+++ b/src/go/collectors/go.d.plugin/modules/systemdunits/collect_units.go
@@ -14,6 +14,8 @@ import (
"github.com/coreos/go-systemd/v22/dbus"
)
+const transientProperty = "Transient"
+
const (
// https://www.freedesktop.org/software/systemd/man/systemd.html
unitStateActive = "active"
@@ -55,6 +57,20 @@ func (s *SystemdUnits) collectUnits(mx map[string]int64, conn systemdConnection)
seen[unit.Name] = true
+ if s.SkipTransient {
+ if _, ok := s.unitTransient[unit.Name]; !ok {
+ prop, err := s.getUnitTransientProperty(conn, unit.Name)
+ if err != nil {
+ return err
+ }
+ prop = strings.Trim(prop, "\"")
+ s.unitTransient[unit.Name] = prop == "true"
+ }
+ if s.unitTransient[unit.Name] {
+ continue
+ }
+ }
+
if !s.seenUnits[unit.Name] {
s.seenUnits[unit.Name] = true
s.addUnitCharts(name, typ)
@@ -75,6 +91,12 @@ func (s *SystemdUnits) collectUnits(mx map[string]int64, conn systemdConnection)
}
}
+ for k := range s.unitTransient {
+ if !seen[k] {
+ delete(s.unitTransient, k)
+ }
+ }
+
return nil
}
@@ -130,6 +152,20 @@ func (s *SystemdUnits) getLoadedUnitsByPatterns(conn systemdConnection) ([]dbus.
return loaded, nil
}
+func (s *SystemdUnits) getUnitTransientProperty(conn systemdConnection, unit string) (string, error) {
+ ctx, cancel := context.WithTimeout(context.Background(), s.Timeout.Duration())
+ defer cancel()
+
+ s.Debugf("calling function 'GetUnitProperty' for unit '%s'", unit)
+
+ prop, err := conn.GetUnitPropertyContext(ctx, unit, transientProperty)
+ if err != nil {
+ return "", fmt.Errorf("error on GetUnitProperty: %v", err)
+ }
+
+ return prop.Value.String(), nil
+}
+
func extractUnitNameType(name string) (string, string, bool) {
idx := strings.LastIndexByte(name, '.')
if idx <= 0 {
diff --git a/src/go/collectors/go.d.plugin/modules/systemdunits/config_schema.json b/src/go/collectors/go.d.plugin/modules/systemdunits/config_schema.json
index c13cabc6ec..016e984ced 100644
--- a/src/go/collectors/go.d.plugin/modules/systemdunits/config_schema.json
+++ b/src/go/collectors/go.d.plugin/modules/systemdunits/config_schema.json
@@ -18,6 +18,12 @@
"minimum": 0.5,
"default": 2
},
+ "skip_transient": {
+ "title": "Skip transient units",
+ "description": "If set, skip data collection for systemd transient units.",
+ "type": "boolean",
+ "default": false
+ },
"include": {
"title": "Include",
"description": "Configuration for monitoring specific systemd units. Include systemd units whose names match any of the specified [patterns](https://golang.org/pkg/path/filepath/#Match).",
@@ -86,6 +92,7 @@
"fields": [
"update_every",
"timeout",
+ "skip_transient",
"include"
]
},
@@ -102,6 +109,9 @@
"timeout": {
"ui:help": "Accepts decimals for precise control (e.g., type 1.5 for 1.5 seconds)."
},
+ "skip_transient": {
+ "ui:help": "A systemd transient unit is a temporary unit created on-the-fly, typically used for ad-hoc tasks or testing purposes. They are created using the `systemd-run` command, which allows you to specify unit properties directly on the command line."
+ },
"include": {
"ui:listFlavour": "list"
},
diff --git a/src/go/collectors/go.d.plugin/modules/systemdunits/metadata.yaml b/src/go/collectors/go.d.plugin/modules/systemdunits/metadata.yaml
index 6ca804fb30..791e58400f 100644
--- a/src/go/collectors/go.d.plugin/modules/systemdunits/metadata.yaml
+++ b/src/go/collectors/go.d.plugin/modules/systemdunits/metadata.yaml
@@ -77,6 +77,10 @@ modules:
- pattern1
- pattern2
```
+ - name: skip_transient
+ description: If set, skip data collection for systemd transient units.
+ default_value: "false"
+ required: false
- name: collect_unit_files
description: If set to true, collect the state of installed unit files. Enabling this may increase system overhead.
default_value: "false"
diff --git a/src/go/collectors/go.d.plugin/modules/systemdunits/systemdunits.go b/src/go/collectors/go.d.plugin/modules/systemdunits/systemdunits.go
index c39a5fc5bb..c5bebfdc71 100644
--- a/src/go/collectors/go.d.plugin/modules/systemdunits/systemdunits.go
+++ b/src/go/collectors/go.d.plugin/modules/systemdunits/systemdunits.go
@@ -36,6 +36,7 @@ func New() *SystemdUnits {
Config: Config{
Timeout: web.Duration(time.Second * 2),
Include: []string{"*.service"},
+ SkipTransient: false,
CollectUnitFiles: false,
IncludeUnitFiles: []string{"*.service"},
CollectUnitFilesEvery: web.Duration(time.Minute * 5),
@@ -43,6 +44,7 @@ func New() *SystemdUnits {
charts: &module.Charts{},
client: newSystemdDBusClient(),
seenUnits: make(map[string]bool),
+ unitTransient: make(map[string]bool),
seenUnitFiles: make(map[string]bool),
}
}
@@ -51,6 +53,7 @@ type Config struct {
UpdateEvery int `yaml:"update_every,omitempty" json:"update_every"`
Timeout web.Duration `yaml:"timeout,omitempty" json:"timeout"`
Include []string `yaml:"include,omitempty" json:"include"`
+ SkipTransient bool `yaml:"skip_transient" json:"skip_transient"`
CollectUnitFiles bool `yaml:"collect_unit_files,omitempty" json:"collect_unit_files"`
IncludeUnitFiles []string `yaml:"include_unit_files,omitempty" json:"include_unit_files"`
CollectUnitFilesEvery web.Duration `yaml:"collect_unit_files_every,omitempty" json:"collect_unit_files_every"`
@@ -65,8 +68,9 @@ type SystemdUnits struct {
systemdVersion int
- seenUnits map[string]bool
- unitSr matcher.Matcher
+ seenUnits map[string]bool
+ unitTransient map[string]bool
+ unitSr matcher.Matcher
lastListUnitFilesTime time.Time
cachedUnitFiles []dbus.UnitFile
diff --git a/src/go/collectors/go.d.plugin/modules/systemdunits/systemdunits_test.go b/src/go/collectors/go.d.plugin/modules/systemdunits/systemdunits_test.go
index fa9326b03f..89c0a92dda 100644
--- a/src/go/collectors/go.d.plugin/modules/systemdunits/systemdunits_test.go
+++ b/src/go/collectors/go.d.plugin/modules/systemdunits/systemdunits_test.go
@@ -12,6 +12,7 @@ import (
"os"
"path/filepath"
"slices"
+ "strings"
"testing"
"github.com/netdata/netdata/go/go.d.plugin/agent/module"
@@ -384,6 +385,37 @@ func TestSystemdUnits_Collect(t *testing.T) {
"unit_var-lib-nfs-rpc_pipefs_mount_state_inactive": 1,
},
},
+ "success v230+ on collecting all unit type with skip transient": {
+ prepare: func() *SystemdUnits {
+ systemd := New()
+ systemd.Include = []string{"*"}
+ systemd.SkipTransient = true
+ systemd.client = prepareOKClient(230)
+ return systemd
+ },
+ wantCollected: map[string]int64{
+ "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 v230- on collecting all unit types": {
prepare: func() *SystemdUnits {
systemd := New()
@@ -946,6 +978,24 @@ func (m *mockConn) GetManagerProperty(prop string) (string, error) {
return fmt.Sprintf("%d.6-1-manjaro", m.version), nil
}
+func (m *mockConn) GetUnitPropertyContext(_ context.Context, unit string, propertyName string) (*dbus.Property, error) {
+ if propertyName != transientProperty {
+ return nil, fmt.Errorf("'GetUnitProperty' unkown property name: %s", propertyName)
+ }
+
+ var prop dbus.Property
+
+ if strings.HasSuffix(unit, ".service") {
+ prop = dbus.PropDescription("false")
+ } else {
+ prop = dbus.PropDescription("true")
+ }
+
+ prop.Name = propertyName
+
+ return &prop, nil
+}
+
func (m *mockConn) ListUnitsContext(_ context.Context) ([]dbus.UnitStatus, error) {
if m.errOnListUnits {
return nil, errors.New("'ListUnits' call error")
diff --git a/src/go/collectors/go.d.plugin/modules/systemdunits/testdata/config.json b/src/go/collectors/go.d.plugin/modules/systemdunits/testdata/config.json
index ac1f53fb6b..1ab5b47ead 100644
--- a/src/go/collectors/go.d.plugin/modules/systemdunits/testdata/config.json
+++ b/src/go/collectors/go.d.plugin/modules/systemdunits/testdata/config.json
@@ -4,6 +4,7 @@
"include": [
"ok"
],
+ "skip_transient": true,
"collect_unit_files": true,
"collect_unit_files_every": 123.123,
"include_unit_files": [
diff --git a/src/go/collectors/go.d.plugin/modules/systemdunits/testdata/config.yaml b/src/go/collectors/go.d.plugin/modules/systemdunits/testdata/config.yaml
index dfed52c3f8..d1894aea14 100644
--- a/src/go/collectors/go.d.plugin/modules/systemdunits/testdata/config.yaml
+++ b/src/go/collectors/go.d.plugin/modules/systemdunits/testdata/config.yaml
@@ -2,6 +2,7 @@ update_every: 123
timeout: 123.123
include:
- ok
+skip_transient: true
collect_unit_files: true
collect_unit_files_every: 123.123
include_unit_files: