Skip to content

Commit

Permalink
Merge pull request #30 from NETWAYS/error_on_non_existing_pressure
Browse files Browse the repository at this point in the history
Enhanced error checking and more elaborate error message  for psi and netdev
  • Loading branch information
RincewindsHat authored Mar 18, 2024
2 parents e8ff1a2 + 4761058 commit 87638b3
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 14 deletions.
6 changes: 6 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ issues:
- gocognit
- maintidx
- gocyclo
- path: 'cmd/psi.go'
linters:
- funlen
- gocognit
- gocyclo
- maintidx
- path: 'internal/sensors/sensors.go'
linters:
- funlen
Expand Down
40 changes: 32 additions & 8 deletions cmd/psi.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package cmd

import (
"errors"
"fmt"
"os"

"github.com/NETWAYS/check_system_basics/internal/common/thresholds"
"github.com/NETWAYS/check_system_basics/internal/psi"
Expand Down Expand Up @@ -232,14 +234,22 @@ func init() {
psiFs.BoolVar(&config.IncludeIO, "include-io", false, "Include IO values explicitly (by default all are included)")
}

//nolint:funlen,gocognit,gocyclo
func checkPsiCPUPressure(config *psiConfig) result.PartialResult {
var cpuCheck result.PartialResult
_ = cpuCheck.SetDefaultState(check.OK)

psiCPU, err := psi.ReadCPUPressure()
if err != nil {
if errors.Is(err, os.ErrNotExist) {
_ = cpuCheck.SetState(check.Unknown)
cpuCheck.Output = "CPU pressure file not found. Perhaps the PSI interface is not active on this system? It might be necessary to change the kernel config"

return cpuCheck
}

check.ExitError(err)
}

var cpuCheck result.PartialResult
cpuCheck.Perfdata = *psiCPU.Perfdata()
_ = cpuCheck.SetState(check.OK)

Expand Down Expand Up @@ -358,15 +368,22 @@ func checkPsiCPUPressure(config *psiConfig) result.PartialResult {
return cpuCheck
}

//nolint:funlen,gocognit
func checkPsiIoPressure(config *psiConfig) result.PartialResult {
var ioCheck result.PartialResult
_ = ioCheck.SetDefaultState(check.OK)

psiIo, err := psi.ReadIoPressure()
if err != nil {
if errors.Is(err, os.ErrNotExist) {
_ = ioCheck.SetState(check.Unknown)
ioCheck.Output = "IO pressure file not found. Perhaps the PSI interface is not active on this system? It might be necessary to change the kernel config"

return ioCheck
}

check.ExitError(err)
}

var ioCheck result.PartialResult
_ = ioCheck.SetState(check.OK)
ioCheck.Perfdata = *psiIo.Perfdata()

//nolint:nestif
Expand Down Expand Up @@ -479,15 +496,22 @@ func checkPsiIoPressure(config *psiConfig) result.PartialResult {
return ioCheck
}

//nolint:funlen,gocognit
func checkPsiMemoryPressure(config *psiConfig) result.PartialResult {
var memoryCheck result.PartialResult
_ = memoryCheck.SetDefaultState(check.OK)

psiMemory, err := psi.ReadMemoryPressure()
if err != nil {
if errors.Is(err, os.ErrNotExist) {
_ = memoryCheck.SetState(check.Unknown)
memoryCheck.Output = "IO pressure file not found. Perhaps the PSI interface is not active on this system? It might be necessary to change the kernel config"

return memoryCheck
}

check.ExitError(err)
}

var memoryCheck result.PartialResult
_ = memoryCheck.SetState(check.OK)
memoryCheck.Perfdata = *psiMemory.Perfdata()

//nolint:nestif
Expand Down
34 changes: 28 additions & 6 deletions internal/netdev/netdev.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package netdev

import (
"os"
"path"
"strconv"
"strings"

Expand All @@ -18,6 +19,10 @@ const (
Unknown = 4
)

const (
netDevicePath = "/sys/class/net"
)

func TranslateIfaceState(state uint) string {
switch state {
case Up:
Expand Down Expand Up @@ -140,7 +145,7 @@ func GetAllInterfaces() ([]IfaceData, error) {
}

func listInterfaces() ([]string, error) {
file, err := os.Open("/sys/class/net")
file, err := os.Open(netDevicePath)
if err != nil {
return []string{}, err
}
Expand All @@ -150,7 +155,24 @@ func listInterfaces() ([]string, error) {
return []string{}, err
}

return devices, nil
result := make([]string, 0, len(devices))

for idx := range devices {
fileInfo, err := os.Stat(path.Join(netDevicePath, devices[idx]))
if err != nil {
// Could not stat file there, not sure if this can be handled usefully. Just die for now.
return []string{}, err
}

// Filter here, to get only entries which end in a directory (the entries itself are mostly symlinks)
// Despite of what man 5 sysfs says, not all the files represent network interfaces, but might also
// be normal files (at least a "bonding_masters" file was found on a system with bonded interfaces)
if fileInfo.Mode().IsDir() {
result = append(result, devices[idx])
}
}

return result, nil
}

// getInterfaceState receives the name of an interfaces and returns
Expand All @@ -159,9 +181,9 @@ func listInterfaces() ([]string, error) {
// @result = 2 => Interface is down
// @result = 3 => Interface is unknown or state of the interface is unknown for some reason
func getInterfaceState(data *IfaceData) error {
basePath := "/sys/class/net/" + data.Name
basePath := path.Join(netDevicePath, data.Name)

bytes, err := os.ReadFile(basePath + "/operstate")
bytes, err := os.ReadFile(path.Join(basePath, "operstate"))
if err != nil {
return err
}
Expand All @@ -188,12 +210,12 @@ func getInterfaceState(data *IfaceData) error {
// Get interfaces statistics
// @result: ifaceStats, err
func getInfacesStatistics(data *IfaceData) error {
basePath := "/sys/class/net/" + data.Name + "/statistics"
basePath := path.Join(netDevicePath, data.Name, "statistics")

var val uint64

for idx, stat := range GetIfaceStatNames() {
numberBytes, err := os.ReadFile(basePath + "/" + stat)
numberBytes, err := os.ReadFile(path.Join(basePath, stat))

if err != nil {
return err
Expand Down

0 comments on commit 87638b3

Please sign in to comment.