diff options
Diffstat (limited to 'src/go/collectors/go.d.plugin')
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: |