gomonop/pkg/perfdata/perfdata.go

128 lines
2.8 KiB
Go
Raw Normal View History

// Package `perfdata` provides representations for a monitoring plugin's
// performance data.
package perfdata // import nocternity.net/gomonop/pkg/perfdata
import (
"strconv"
"strings"
"nocternity.net/gomonop/pkg/status"
)
// Performance data, including a label, units, a value, warning/critical
// ranges and min/max boundaries.
type PerfData struct {
Label string
units UnitOfMeasurement
bits perfDataBits
value string
warn, crit Range
min, max string
}
// Create performance data using the specified label and units.
func New(label string, units UnitOfMeasurement, value string) *PerfData {
if value != "" && !valueCheck.MatchString(value) {
panic("invalid value")
}
pdRange := &PerfData{}
pdRange.Label = label
pdRange.units = units
if value == "" {
pdRange.value = "U"
} else {
pdRange.value = value
}
return pdRange
}
// Set the warning range for the performance data record.
func (d *PerfData) SetWarn(r *Range) {
if r == nil {
d.bits &^= PDatWarn
} else {
d.warn = *r
d.bits |= PDatWarn
}
}
// Set the critical range for the performance data record.
func (d *PerfData) SetCrit(r *Range) {
if r == nil {
d.bits &^= PDatCrit
} else {
d.crit = *r
d.bits |= PDatCrit
}
}
// Set the performance data's minimal value.
func (d *PerfData) SetMin(min string) {
if !valueCheck.MatchString(min) {
panic("invalid value")
}
d.min = min
d.bits |= PDatMin
}
// Set the performance data's maximal value.
func (d *PerfData) SetMax(max string) {
if !valueCheck.MatchString(max) {
panic("invalid value")
}
d.max = max
d.bits |= PDatMax
}
// Check the performance data's value against its configured ranges.
func (d *PerfData) GetStatus() status.Status {
value, err := strconv.ParseFloat(d.value, 64)
if err != nil {
return status.StatusUnknown
}
if d.bits&PDatCrit != 0 && d.crit.Contains(value) {
return status.StatusCritical
}
if d.bits&PDatWarn != 0 && d.warn.Contains(value) {
return status.StatusWarning
}
return status.StatusOK
}
// Converts performance data to a string which may be read by the monitoring
// system.
func (d *PerfData) String() string {
var strBuilder strings.Builder
needsQuotes := strings.ContainsAny(d.Label, " '=\"")
if needsQuotes {
strBuilder.WriteRune('\'')
}
strBuilder.WriteString(strings.ReplaceAll(d.Label, "'", "''"))
if needsQuotes {
strBuilder.WriteRune('\'')
}
strBuilder.WriteRune('=')
strBuilder.WriteString(d.value)
strBuilder.WriteString(d.units.String())
strBuilder.WriteRune(';')
if d.bits&PDatWarn != 0 {
strBuilder.WriteString(d.warn.String())
}
strBuilder.WriteRune(';')
if d.bits&PDatCrit != 0 {
strBuilder.WriteString(d.crit.String())
}
strBuilder.WriteRune(';')
if d.bits&PDatMin != 0 {
strBuilder.WriteString(d.min)
}
strBuilder.WriteRune(';')
if d.bits&PDatMax != 0 {
strBuilder.WriteString(d.max)
}
return strBuilder.String()
}