-
Notifications
You must be signed in to change notification settings - Fork 1
/
nagios.go
105 lines (96 loc) · 2.58 KB
/
nagios.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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package nagios
import (
"fmt"
"github.com/kballard/go-shellquote"
"os"
"os/exec"
"strconv"
"strings"
"syscall"
"time"
)
var (
Debug bool
buildtime string
)
type NagiosResult struct {
ExitCode int
Text string
Perfdata string
Multiline []string
}
type ExecResult struct {
ReturnCode int
Output string
}
// Debugf is a helper function for debug logging if Debug is true
func Debugf(s string) {
if Debug != false {
fmt.Println("DEBUG " + fmt.Sprint(s))
}
}
// NagiosExit uses the NagiosResult struct to output Nagios plugin compatible output and exit codes
func NagiosExit(nr NagiosResult) {
text := nr.Text
exitCode := nr.ExitCode
switch {
case nr.ExitCode == 0:
text = "OK: " + nr.Text
exitCode = nr.ExitCode
case nr.ExitCode == 1:
text = "WARNING: " + nr.Text
exitCode = nr.ExitCode
case nr.ExitCode == 2:
text = "CRITICAL: " + nr.Text
exitCode = nr.ExitCode
case nr.ExitCode == 3:
text = "UNKNOWN: " + nr.Text
exitCode = nr.ExitCode
default:
text = "UNKNOWN: Exit code '" + string(nr.ExitCode) + "'undefined :" + nr.Text
exitCode = 3
}
if len(nr.Multiline) > 0 {
multiline := ""
for _, l := range nr.Multiline {
multiline = multiline + l + "\n"
}
fmt.Printf("%s|%s\n%s\n", text, nr.Perfdata, multiline)
} else {
fmt.Printf("%s|%s\n", text, nr.Perfdata)
}
os.Exit(exitCode)
}
// ExecuteCommand executes a shell command and provides the stdout and stderr output combined and the exit code.
// First arg is the command to execute as a simple string.
// Second arg is a timeout parameter as a int after which to kill the command and return.
// Third arg is a bool flag if the command is allowed to fail or not.
func ExecuteCommand(command string, timeout int, allowFail bool) ExecResult {
Debugf("Executing " + command)
parts := strings.SplitN(command, " ", 2)
cmd := parts[0]
cmdArgs := []string{}
if len(parts) > 1 {
args, err := shellquote.Split(parts[1])
if err != nil {
Debugf("executeCommand(): err: " + fmt.Sprint(err))
os.Exit(1)
} else {
cmdArgs = args
}
}
before := time.Now()
out, err := exec.Command(cmd, cmdArgs...).CombinedOutput()
duration := time.Since(before).Seconds()
er := ExecResult{0, string(out)}
if msg, ok := err.(*exec.ExitError); ok { // there is error code
er.ReturnCode = msg.Sys().(syscall.WaitStatus).ExitStatus()
}
Debugf("Executing " + command + " took " + strconv.FormatFloat(duration, 'f', 5, 64) + "s")
if err != nil && !allowFail {
fmt.Println("executeCommand(): command failed: "+command, err)
fmt.Println("executeCommand(): Output: " + string(out))
os.Exit(1)
}
return er
}