// 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() }