slack-bot/pkg/check/df.go

99 lines
2.4 KiB
Go

package check
import (
"fmt"
"go/slack-bot/pkg/notify"
"regexp"
"strconv"
"strings"
)
const dfMessage = "disk check"
//DfChecker df command implementation of AdvancedChecker
type DfChecker struct {
CliChecker
pourcentRegexMatcher *regexp.Regexp
}
type DfStdout []DfStdoutLine
type DfStdoutLine struct {
Filesystem,
Size,
Used,
Available string
PourcentUsed int
Mounted string
}
//DfParameter df check configuration
type DfParameter struct {
FileSystemName string `hcl:"fs_name"`
CriticalPourcent int `hcl:"critical"`
}
//NewDfChecker build new checker for df command
func NewDfChecker() *DfChecker {
return &DfChecker{
CliChecker: CliChecker{
alertingMessage: dfMessage,
command: []string{"sh", "-c", "df -P | grep -v 'auto_home'"},
},
pourcentRegexMatcher: regexp.MustCompile(`(?P<value>.*)%`),
}
}
//Parse df command stdout
func (dc *DfChecker) Parse(stdout string) interface{} {
var dfOut DfStdout
for _, line := range strings.Split(stdout, "\n")[1:] {
if strings.TrimSpace(line) == "" {
continue
}
var cleanedColumns []string
for _, col := range strings.Split(line, " ") {
if v := strings.TrimSpace(col); v != "" {
cleanedColumns = append(cleanedColumns, v)
}
}
valueIndex := dc.pourcentRegexMatcher.SubexpIndex("value")
log.Printf("df column : %+v\n", cleanedColumns)
v, err := strconv.Atoi(dc.pourcentRegexMatcher.FindStringSubmatch(cleanedColumns[4])[valueIndex])
if err != nil {
v = -1
}
// extract pourcent used from columns
dfOut = append(dfOut, DfStdoutLine{
Filesystem: cleanedColumns[0],
Size: cleanedColumns[1],
Used: cleanedColumns[2],
Available: cleanedColumns[3],
PourcentUsed: v,
Mounted: cleanedColumns[len(cleanedColumns)-1],
})
}
return dfOut
}
//FileSystemUsedCheck take dfStdout and check if filesystem is full over than criticalPourcent value
func (dc *DfChecker) FileSystemUsedCheck(dfOut DfStdout, param DfParameter) notify.Message {
message := notify.Message{
ShouldNotify: false,
}
for _, line := range dfOut {
if line.Filesystem == param.FileSystemName {
if line.PourcentUsed > param.CriticalPourcent {
text := fmt.Sprintf("%s : fs '%s' critial %d%%, used %d%% \n", dc.alertingMessage, line.Filesystem, param.CriticalPourcent, line.PourcentUsed)
message = notify.Message{
Content: text,
ShouldNotify: true,
}
}
}
}
return message
}