Skip to content

Commit

Permalink
check_service: use cgroup pids if no main pid available
Browse files Browse the repository at this point in the history
  • Loading branch information
sni committed May 2, 2024
1 parent 17ad339 commit f7da798
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 33 deletions.
1 change: 1 addition & 0 deletions Changes
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ next:
- update node exporter to 1.8.0
- add native aarch64 (arm64) packages for windows
- add support for extending default filter/warn/crit
- check_service: use cgroup pids if no main pid available
- fix missing scripts in inventory

0.23 Mon Apr 15 17:29:53 CEST 2024
Expand Down
70 changes: 43 additions & 27 deletions pkg/snclient/check_service_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package snclient
import (
"context"
"fmt"
"strings"
"time"

"pkg/convert"
Expand All @@ -17,35 +18,50 @@ func (l *CheckService) addProcMetrics(ctx context.Context, pidStr string, listEn
if pidStr == "" {
return nil
}
pid, err := convert.IntE(pidStr)
if err != nil {
return fmt.Errorf("pid is not a number: %s: %s", pidStr, err.Error())
}
if pid <= 0 {
return fmt.Errorf("pid is not a positive number: %s", pidStr)
}

proc, err := process.NewProcess(pid)
if err != nil {
log.Tracef("%s", fmt.Errorf("pid not found %d: %s", pid, err.Error()).Error())

return nil
}

cpuP, err := proc.CPUPercentWithContext(ctx)
if err == nil {
listEntry["cpu"] = fmt.Sprintf("%.1f", cpuP)
}

mem, _ := proc.MemoryInfoWithContext(ctx)
if mem != nil {
listEntry["rss"] = fmt.Sprintf("%d", mem.RSS)
listEntry["vms"] = fmt.Sprintf("%d", mem.VMS)
cpu := float64(0)
rss := uint64(0)
vms := uint64(0)
createTimeUnix := int64(0)
for _, pidStrEx := range strings.Split(pidStr, ",") {
pid, err := convert.IntE(pidStrEx)
if err != nil {
return fmt.Errorf("pid is not a number: %s: %s", pidStrEx, err.Error())
}
if pid <= 0 {
return fmt.Errorf("pid is not a positive number: %s", pidStrEx)
}

proc, err := process.NewProcess(pid)
if err != nil {
log.Tracef("%s", fmt.Errorf("pid not found %d: %s", pid, err.Error()).Error())

return nil
}

cpuP, err := proc.CPUPercentWithContext(ctx)
if err == nil {
cpu += cpuP
}

mem, _ := proc.MemoryInfoWithContext(ctx)
if mem != nil {
rss += mem.RSS
vms += mem.VMS
}

createTimeMillis, err := proc.CreateTimeWithContext(ctx)
if err == nil {
ctMillis := createTimeMillis / 1e3
if ctMillis < createTimeUnix {
createTimeUnix = ctMillis
}
}
}

createTimeMillis, err := proc.CreateTimeWithContext(ctx)
if err == nil {
createTimeUnix := createTimeMillis / 1e3
listEntry["cpu"] = fmt.Sprintf("%.1f", cpu)
listEntry["rss"] = fmt.Sprintf("%d", rss)
listEntry["vms"] = fmt.Sprintf("%d", vms)
if createTimeUnix > 0 {
listEntry["created"] = fmt.Sprintf("%d", createTimeUnix)
listEntry["age"] = fmt.Sprintf("%d", time.Now().Unix()-createTimeUnix)
}
Expand Down
20 changes: 14 additions & 6 deletions pkg/snclient/check_service_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ var (
reSvcDetails = regexp.MustCompile(`(?s)^.*?\.service(?:\s\-\s(.*?)|)\n.*Active:\s*([A-Za-z() :-]+)(?:\ssince|\n)`)
reSvcMainPid = regexp.MustCompile(`Main\sPID:\s(\d+)`)
reSvcPidMaster = regexp.MustCompile(`─(\d+).+\(master\)`)
reSvcPidCgroup = regexp.MustCompile(`[├─└]─\s*(\d+)\s+`)
reSvcPreset = regexp.MustCompile(`\s+preset:\s+(\w+)\)`)
reSvcTasks = regexp.MustCompile(`Tasks:\s*(\d+)`)
reSvcStatic = regexp.MustCompile(`;\sstatic\)`)
Expand Down Expand Up @@ -249,15 +250,22 @@ func (l *CheckService) parseSystemCtlStatus(name, output string) (listEntry map[
}

match = reSvcMainPid.FindStringSubmatch(output)
if len(match) < 1 {
if len(match) >= 1 {
listEntry["pid"] = match[1]
}
if listEntry["pid"] == "" {
match = reSvcPidMaster.FindStringSubmatch(output)
if len(match) < 1 {
listEntry["pid"] = ""
} else {
if len(match) >= 1 {
listEntry["pid"] = match[1]
}
} else {
listEntry["pid"] = match[1]
}
if listEntry["pid"] == "" {
matches := reSvcPidCgroup.FindAllStringSubmatch(output, -1)
pids := []string{}
for _, m := range matches {
pids = append(pids, m[1])
}
listEntry["pid"] = strings.Join(pids, ",")
}

match = reSvcTasks.FindStringSubmatch(output)
Expand Down

0 comments on commit f7da798

Please sign in to comment.