Wrap errors so that they can be unwrapped

This commit is contained in:
Holger Obermaier
2026-02-11 13:51:58 +01:00
parent ca95494a83
commit 6bfdd6ff17
9 changed files with 35 additions and 42 deletions

View File

@@ -55,7 +55,7 @@ func (m *CPUFreqCpuInfoCollector) Init(config json.RawMessage) error {
const cpuInfoFile = "/proc/cpuinfo" const cpuInfoFile = "/proc/cpuinfo"
file, err := os.Open(cpuInfoFile) file, err := os.Open(cpuInfoFile)
if err != nil { if err != nil {
return fmt.Errorf("failed to open file '%s': %v", cpuInfoFile, err) return fmt.Errorf("%s Init(): failed to open file '%s': %w", m.name, cpuInfoFile, err)
} }
// Collect topology information from file cpuinfo // Collect topology information from file cpuinfo
@@ -123,7 +123,7 @@ func (m *CPUFreqCpuInfoCollector) Init(config json.RawMessage) error {
// Check if at least one CPU with frequency information was detected // Check if at least one CPU with frequency information was detected
if len(m.topology) == 0 { if len(m.topology) == 0 {
return fmt.Errorf("no CPU frequency info found in %s", cpuInfoFile) return fmt.Errorf("%s Init(): no CPU frequency info found in %s", m.name, cpuInfoFile)
} }
m.init = true m.init = true

View File

@@ -76,7 +76,7 @@ func (m *CPUFreqCollector) Init(config json.RawMessage) error {
scalingCurFreqFile := filepath.Join("/sys/devices/system/cpu", fmt.Sprintf("cpu%d", c.CpuID), "cpufreq/scaling_cur_freq") scalingCurFreqFile := filepath.Join("/sys/devices/system/cpu", fmt.Sprintf("cpu%d", c.CpuID), "cpufreq/scaling_cur_freq")
err := unix.Access(scalingCurFreqFile, unix.R_OK) err := unix.Access(scalingCurFreqFile, unix.R_OK)
if err != nil { if err != nil {
return fmt.Errorf("unable to access file '%s': %v", scalingCurFreqFile, err) return fmt.Errorf("unable to access file '%s': %w", scalingCurFreqFile, err)
} }
m.topology = append(m.topology, m.topology = append(m.topology,

View File

@@ -14,7 +14,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"log"
"os/exec" "os/exec"
"os/user" "os/user"
"slices" "slices"
@@ -324,8 +323,7 @@ func (m *GpfsCollector) Init(config json.RawMessage) error {
if len(config) > 0 { if len(config) > 0 {
err := json.Unmarshal(config, &m.config) err := json.Unmarshal(config, &m.config)
if err != nil { if err != nil {
log.Print(err.Error()) return fmt.Errorf("%s Init(): failed to unmarshal JSON config: %w", m.name, err)
return err
} }
} }
m.meta = map[string]string{ m.meta = map[string]string{
@@ -366,7 +364,7 @@ func (m *GpfsCollector) Init(config json.RawMessage) error {
// when using sudo, the full path of mmpmon must be specified because // when using sudo, the full path of mmpmon must be specified because
// exec.LookPath will not work as mmpmon is not executable as user // exec.LookPath will not work as mmpmon is not executable as user
if m.config.Sudo && !strings.HasPrefix(m.config.Mmpmon, "/") { if m.config.Sudo && !strings.HasPrefix(m.config.Mmpmon, "/") {
return fmt.Errorf("when using sudo, mmpmon_path must be provided and an absolute path: %s", m.config.Mmpmon) return fmt.Errorf("%s Init(): when using sudo, mmpmon_path must be provided and an absolute path: %s", m.name, m.config.Mmpmon)
} }
// Check if mmpmon is in executable search path // Check if mmpmon is in executable search path
@@ -379,7 +377,7 @@ func (m *GpfsCollector) Init(config json.RawMessage) error {
p = m.config.Mmpmon p = m.config.Mmpmon
} else { } else {
cclog.ComponentError(m.name, fmt.Sprintf("failed to find mmpmon binary '%s': %v", m.config.Mmpmon, err)) cclog.ComponentError(m.name, fmt.Sprintf("failed to find mmpmon binary '%s': %v", m.config.Mmpmon, err))
return fmt.Errorf("failed to find mmpmon binary '%s': %v", m.config.Mmpmon, err) return fmt.Errorf("%s Init(): failed to find mmpmon binary '%s': %w", m.name, m.config.Mmpmon, err)
} }
} }
m.config.Mmpmon = p m.config.Mmpmon = p

View File

@@ -90,10 +90,10 @@ func (m *InfinibandCollector) Init(config json.RawMessage) error {
globPattern := filepath.Join(IB_BASEPATH, "*", "ports", "*") globPattern := filepath.Join(IB_BASEPATH, "*", "ports", "*")
ibDirs, err := filepath.Glob(globPattern) ibDirs, err := filepath.Glob(globPattern)
if err != nil { if err != nil {
return fmt.Errorf("unable to glob files with pattern %s: %v", globPattern, err) return fmt.Errorf("%s Init(): unable to glob files with pattern %s: %w", m.name, globPattern, err)
} }
if ibDirs == nil { if ibDirs == nil {
return fmt.Errorf("unable to find any directories with pattern %s", globPattern) return fmt.Errorf("%s Init(): unable to find any directories with pattern %s", m.name, globPattern)
} }
for _, path := range ibDirs { for _, path := range ibDirs {
@@ -157,7 +157,7 @@ func (m *InfinibandCollector) Init(config json.RawMessage) error {
for _, counter := range portCounterFiles { for _, counter := range portCounterFiles {
err := unix.Access(counter.path, unix.R_OK) err := unix.Access(counter.path, unix.R_OK)
if err != nil { if err != nil {
return fmt.Errorf("unable to access %s: %v", counter.path, err) return fmt.Errorf("%s Init(): unable to access %s: %w", m.name, counter.path, err)
} }
} }
@@ -177,7 +177,7 @@ func (m *InfinibandCollector) Init(config json.RawMessage) error {
} }
if len(m.info) == 0 { if len(m.info) == 0 {
return fmt.Errorf("found no IB devices") return fmt.Errorf("%s Init(): found no IB devices", m.name)
} }
m.init = true m.init = true

View File

@@ -217,7 +217,7 @@ func (m *LikwidCollector) Init(config json.RawMessage) error {
if len(config) > 0 { if len(config) > 0 {
err := json.Unmarshal(config, &m.config) err := json.Unmarshal(config, &m.config)
if err != nil { if err != nil {
return err return fmt.Errorf("%s Init(): failed to unmarshal JSON config: %w", m.name, err)
} }
} }
lib := dl.New(m.config.LibraryPath, LIKWID_LIB_DL_FLAGS) lib := dl.New(m.config.LibraryPath, LIKWID_LIB_DL_FLAGS)
@@ -226,13 +226,13 @@ func (m *LikwidCollector) Init(config json.RawMessage) error {
} }
err := lib.Open() err := lib.Open()
if err != nil { if err != nil {
return fmt.Errorf("error opening %s: %v", m.config.LibraryPath, err) return fmt.Errorf("error opening %s: %w", m.config.LibraryPath, err)
} }
if m.config.ForceOverwrite { if m.config.ForceOverwrite {
cclog.ComponentDebug(m.name, "Set LIKWID_FORCE=1") cclog.ComponentDebug(m.name, "Set LIKWID_FORCE=1")
if err := os.Setenv("LIKWID_FORCE", "1"); err != nil { if err := os.Setenv("LIKWID_FORCE", "1"); err != nil {
return fmt.Errorf("error setting environment variable LIKWID_FORCE=1: %v", err) return fmt.Errorf("error setting environment variable LIKWID_FORCE=1: %w", err)
} }
} }
if err := m.setup(); err != nil { if err := m.setup(); err != nil {
@@ -327,7 +327,7 @@ func (m *LikwidCollector) Init(config json.RawMessage) error {
p = m.config.DaemonPath p = m.config.DaemonPath
} }
if err := os.Setenv("PATH", p); err != nil { if err := os.Setenv("PATH", p); err != nil {
return fmt.Errorf("error setting environment variable PATH=%s: %v", p, err) return fmt.Errorf("error setting environment variable PATH=%s: %w", p, err)
} }
} }
C.HPMmode(1) C.HPMmode(1)
@@ -406,10 +406,10 @@ func (m *LikwidCollector) takeMeasurement(evidx int, evset LikwidEventsetConfig,
// Create the lock file if it does not exist // Create the lock file if it does not exist
file, createErr := os.Create(m.config.LockfilePath) file, createErr := os.Create(m.config.LockfilePath)
if createErr != nil { if createErr != nil {
return true, fmt.Errorf("failed to create lock file: %v", createErr) return true, fmt.Errorf("failed to create lock file: %w", createErr)
} }
if err := file.Close(); err != nil { if err := file.Close(); err != nil {
return true, fmt.Errorf("failed to close lock file: %v", err) return true, fmt.Errorf("failed to close lock file: %w", err)
} }
info, err = os.Stat(m.config.LockfilePath) // Recheck the file after creation info, err = os.Stat(m.config.LockfilePath) // Recheck the file after creation
} }

View File

@@ -10,7 +10,6 @@ package collectors
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"log"
"slices" "slices"
// "os" // "os"
@@ -49,7 +48,7 @@ func (m *nfsCollector) initStats() error {
// Wait for cmd end // Wait for cmd end
if err := cmd.Wait(); err != nil { if err := cmd.Wait(); err != nil {
return fmt.Errorf("initStats(): %w", err) return fmt.Errorf("%s initStats(): %w", m.name, err)
} }
buffer, err := cmd.Output() buffer, err := cmd.Output()
@@ -81,7 +80,7 @@ func (m *nfsCollector) updateStats() error {
// Wait for cmd end // Wait for cmd end
if err := cmd.Wait(); err != nil { if err := cmd.Wait(); err != nil {
return fmt.Errorf("updateStats(): %w", err) return fmt.Errorf("%s updateStats(): %w", m.name, err)
} }
buffer, err := cmd.Output() buffer, err := cmd.Output()
@@ -114,8 +113,7 @@ func (m *nfsCollector) MainInit(config json.RawMessage) error {
if len(config) > 0 { if len(config) > 0 {
err := json.Unmarshal(config, &m.config) err := json.Unmarshal(config, &m.config)
if err != nil { if err != nil {
log.Print(err.Error()) return fmt.Errorf("%s Init(): failed to unmarshal JSON config: %w", m.name, err)
return err
} }
} }
m.meta = map[string]string{ m.meta = map[string]string{
@@ -128,11 +126,11 @@ func (m *nfsCollector) MainInit(config json.RawMessage) error {
// Check if nfsstat is in executable search path // Check if nfsstat is in executable search path
_, err := exec.LookPath(m.config.Nfsstats) _, err := exec.LookPath(m.config.Nfsstats)
if err != nil { if err != nil {
return fmt.Errorf("NfsCollector.Init(): Failed to find nfsstat binary '%s': %v", m.config.Nfsstats, err) return fmt.Errorf("%s Init(): Failed to find nfsstat binary '%s': %w", m.name, m.config.Nfsstats, err)
} }
m.data = make(map[string]NfsCollectorData) m.data = make(map[string]NfsCollectorData)
if err := m.initStats(); err != nil { if err := m.initStats(); err != nil {
return fmt.Errorf("NfsCollector.Init(): %w", err) return fmt.Errorf("%s Init(): %w", m.name, err)
} }
m.init = true m.init = true
m.parallel = true m.parallel = true

View File

@@ -84,7 +84,7 @@ func (m *NUMAStatsCollector) Init(config json.RawMessage) error {
if len(config) > 0 { if len(config) > 0 {
err := json.Unmarshal(config, &m.config) err := json.Unmarshal(config, &m.config)
if err != nil { if err != nil {
return fmt.Errorf("unable to unmarshal numastat configuration: %s", err.Error()) return fmt.Errorf("%s Init(): unable to unmarshal numastat configuration: %w", m.name, err)
} }
} }
@@ -93,10 +93,10 @@ func (m *NUMAStatsCollector) Init(config json.RawMessage) error {
globPattern := base + "[0-9]*" globPattern := base + "[0-9]*"
dirs, err := filepath.Glob(globPattern) dirs, err := filepath.Glob(globPattern)
if err != nil { if err != nil {
return fmt.Errorf("unable to glob files with pattern '%s'", globPattern) return fmt.Errorf("%s Init(): unable to glob files with pattern '%s'", m.name, globPattern)
} }
if dirs == nil { if dirs == nil {
return fmt.Errorf("unable to find any files with pattern '%s'", globPattern) return fmt.Errorf("%s Init(): unable to find any files with pattern '%s'", m.name, globPattern)
} }
m.topology = make([]NUMAStatsCollectorTopolgy, 0, len(dirs)) m.topology = make([]NUMAStatsCollectorTopolgy, 0, len(dirs))
for _, dir := range dirs { for _, dir := range dirs {

View File

@@ -79,9 +79,10 @@ func ParseCPUs(cpuset string) ([]int, error) {
} }
func GetAllCPUs() ([]int, error) { func GetAllCPUs() ([]int, error) {
data, err := os.ReadFile("/sys/devices/system/cpu/online") cpuOnline := "/sys/devices/system/cpu/online"
data, err := os.ReadFile(cpuOnline)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to read /sys/devices/system/cpu/online: %v", err) return nil, fmt.Errorf("failed to read file \"%s\": %w", cpuOnline, err)
} }
return ParseCPUs(strings.TrimSpace(string(data))) return ParseCPUs(strings.TrimSpace(string(data)))
} }
@@ -114,8 +115,7 @@ func (m *SlurmCgroupCollector) Init(config json.RawMessage) error {
if len(config) > 0 { if len(config) > 0 {
err = json.Unmarshal(config, &m.config) err = json.Unmarshal(config, &m.config)
if err != nil { if err != nil {
cclog.ComponentError(m.name, "Error reading config:", err.Error()) return fmt.Errorf("%s Init(): Error reading JSON config: %w", m.name, err)
return err
} }
m.excludeMetrics = make(map[string]struct{}) m.excludeMetrics = make(map[string]struct{})
for _, metric := range m.config.ExcludeMetrics { for _, metric := range m.config.ExcludeMetrics {
@@ -130,19 +130,16 @@ func (m *SlurmCgroupCollector) Init(config json.RawMessage) error {
if !m.useSudo { if !m.useSudo {
user, err := user.Current() user, err := user.Current()
if err != nil { if err != nil {
cclog.ComponentError(m.name, "Failed to get current user:", err.Error()) return fmt.Errorf("%s Init(): Failed to get current user: %w", m.name, err)
return err
} }
if user.Uid != "0" { if user.Uid != "0" {
cclog.ComponentError(m.name, "Reading cgroup files requires root privileges (or enable use_sudo in config)") return fmt.Errorf("%s Init(): Reading cgroup files requires root privileges (or enable use_sudo in config)", m.name)
return fmt.Errorf("not root")
} }
} }
m.allCPUs, err = GetAllCPUs() m.allCPUs, err = GetAllCPUs()
if err != nil { if err != nil {
cclog.ComponentError(m.name, "Error reading online CPUs:", err.Error()) return fmt.Errorf("%s Init(): Error reading online CPUs: %w", m.name, err)
return err
} }
m.init = true m.init = true

View File

@@ -64,7 +64,7 @@ func (m *TempCollector) Init(config json.RawMessage) error {
if len(config) > 0 { if len(config) > 0 {
err := json.Unmarshal(config, &m.config) err := json.Unmarshal(config, &m.config)
if err != nil { if err != nil {
return err return fmt.Errorf("%s Init(): failed to unmarshal JSON config: %w", m.name, err)
} }
} }
@@ -80,10 +80,10 @@ func (m *TempCollector) Init(config json.RawMessage) error {
globPattern := filepath.Join("/sys/class/hwmon", "*", "temp*_input") globPattern := filepath.Join("/sys/class/hwmon", "*", "temp*_input")
inputFiles, err := filepath.Glob(globPattern) inputFiles, err := filepath.Glob(globPattern)
if err != nil { if err != nil {
return fmt.Errorf("unable to glob files with pattern '%s': %v", globPattern, err) return fmt.Errorf("%s Init(): unable to glob files with pattern '%s': %w", m.name, globPattern, err)
} }
if inputFiles == nil { if inputFiles == nil {
return fmt.Errorf("unable to find any files with pattern '%s'", globPattern) return fmt.Errorf("%s Init(): unable to find any files with pattern '%s'", m.name, globPattern)
} }
// Get sensor name for each temperature sensor file // Get sensor name for each temperature sensor file
@@ -172,7 +172,7 @@ func (m *TempCollector) Init(config json.RawMessage) error {
// Empty sensors map // Empty sensors map
if len(m.sensors) == 0 { if len(m.sensors) == 0 {
return fmt.Errorf("no temperature sensors found") return fmt.Errorf("%s Init(): no temperature sensors found", m.name)
} }
// Finished initialization // Finished initialization