diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-20 11:38:19 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-20 11:38:19 +0300 |
| commit | 9310b54d439d4a1a8d4d337987aa63884df0af76 (patch) | |
| tree | c6fb38085891a04ce81672f977af316a2e96b2fd /internal/flags/sampling.go | |
| parent | 5fd613562e2aa2ab3aac3349f44db88330046c1c (diff) | |
feat: add syscall aggregate sampling infrastructure (task 17)
Diffstat (limited to 'internal/flags/sampling.go')
| -rw-r--r-- | internal/flags/sampling.go | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/internal/flags/sampling.go b/internal/flags/sampling.go new file mode 100644 index 0000000..19b4f9d --- /dev/null +++ b/internal/flags/sampling.go @@ -0,0 +1,88 @@ +package flags + +import ( + "fmt" + "strconv" + "strings" + + "ior/internal/types" +) + +func cloneFamilySamplingRates(in map[types.SyscallFamily]uint32) map[types.SyscallFamily]uint32 { + out := make(map[types.SyscallFamily]uint32, len(in)) + for family, rate := range in { + out[family] = rate + } + return out +} + +func cloneSyscallSamplingRates(in map[string]uint32) map[string]uint32 { + out := make(map[string]uint32, len(in)) + for syscall, rate := range in { + out[syscall] = rate + } + return out +} + +func parseFamilySamplingRates(raw string) (map[types.SyscallFamily]uint32, error) { + entries, err := parseSamplingEntries(raw) + if err != nil { + return nil, err + } + out := make(map[types.SyscallFamily]uint32, len(entries)) + for key, rate := range entries { + family, ok := types.ParseSyscallFamily(key) + if !ok { + return nil, fmt.Errorf("invalid syscall family in sampling map: %q", key) + } + out[family] = rate + } + return out, nil +} + +func parseSyscallSamplingRates(raw string) (map[string]uint32, error) { + entries, err := parseSamplingEntries(raw) + if err != nil { + return nil, err + } + out := make(map[string]uint32, len(entries)) + for syscall, rate := range entries { + syscall = strings.ToLower(strings.TrimSpace(syscall)) + if syscall == "" { + return nil, fmt.Errorf("invalid syscall sampling key %q", syscall) + } + if _, ok := types.EnterTraceIDByName(syscall); !ok { + return nil, fmt.Errorf("invalid syscall in sampling map: %q", syscall) + } + out[syscall] = rate + } + return out, nil +} + +func parseSamplingEntries(raw string) (map[string]uint32, error) { + out := make(map[string]uint32) + raw = strings.TrimSpace(raw) + if raw == "" { + return out, nil + } + for _, part := range strings.Split(raw, ",") { + part = strings.TrimSpace(part) + if part == "" { + continue + } + key, valueRaw, ok := strings.Cut(part, "=") + if !ok { + return nil, fmt.Errorf("invalid sampling entry %q: expected name=rate", part) + } + key = strings.TrimSpace(key) + if key == "" { + return nil, fmt.Errorf("invalid sampling entry %q: empty name", part) + } + rate, err := strconv.ParseUint(strings.TrimSpace(valueRaw), 10, 32) + if err != nil { + return nil, fmt.Errorf("invalid sampling rate for %q: %w", key, err) + } + out[key] = uint32(rate) + } + return out, nil +} |
