-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsubtree_oom.go
74 lines (65 loc) · 1.88 KB
/
subtree_oom.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package jasper
import (
"context"
"fmt"
"os/exec"
"strconv"
"strings"
)
type oomTrackerImpl struct {
WasOOMKilled bool `json:"was_oom_killed"`
Pids []int `json:"pids"`
}
// OOMTracker provides a tool for detecting if there have been OOM
// events on the system. The Clear operation may affect the state the
// system logs and the data reported will reflect the entire system,
// not simply processes managed by Jasper tools.
type OOMTracker interface {
Check(context.Context) error
Clear(context.Context) error
Report() (bool, []int)
}
// NewOOMTracker returns an implementation of the OOMTracker interface
// for the current platform.
func NewOOMTracker() OOMTracker { return &oomTrackerImpl{} }
func (o *oomTrackerImpl) Report() (bool, []int) { return o.WasOOMKilled, o.Pids }
func isSudo(ctx context.Context) (bool, error) {
if err := exec.CommandContext(ctx, "sudo", "-n", "date").Run(); err != nil {
switch err.(type) {
case *exec.ExitError:
return false, nil
default:
return false, fmt.Errorf("error executing sudo date: %w", err)
}
}
return true, nil
}
func dmesgContainsOOMKill(line string) bool {
return strings.Contains(line, "Out of memory") ||
strings.Contains(line, "Killed process") || strings.Contains(line, "OOM killer") ||
strings.Contains(line, "OOM-killer")
}
func getPidFromDmesg(line string) (int, bool) {
split := strings.Split(line, "Killed process")
if len(split) <= 1 {
return 0, false
}
newSplit := strings.Split(strings.TrimSpace(split[1]), " ")
pid, err := strconv.Atoi(newSplit[0])
if err != nil {
return 0, false
}
return pid, true
}
func getPidFromLog(line string) (int, bool) {
split := strings.Split(line, "pid")
if len(split) <= 1 {
return 0, false
}
newSplit := strings.Split(strings.TrimSpace(split[1]), " ")
pid, err := strconv.Atoi(newSplit[0])
if err != nil {
return 0, false
}
return pid, true
}