Skip to content

Commit

Permalink
Add support for Nagios Performance Data
Browse files Browse the repository at this point in the history
- Add `PerformanceData` type to represent a single, complete
  Performance Data entry

- Extend `ExitState` type to hold Performance Data entries

- Modify `ExitState.ReturnCheckResults()` method to process
  Performance Data entries if present

- Add `ExitState.AddPerfData()` method with optional flag
  to skip validation
  - intended to allow client code full control of validation

This is a first draft and has not undergone sufficient testing
to be considered stable.

Documentation updates have not been made yet to illustrate
use of the new functionality.

refs GH-81
  • Loading branch information
atc0005 committed Sep 14, 2021
1 parent 1dffb7e commit 1db1acf
Showing 1 changed file with 137 additions and 2 deletions.
139 changes: 137 additions & 2 deletions nagios.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,87 @@ type ServiceState struct {
ExitCode int
}

// PerformanceData represents the performance data generated by a Nagios
// plugin.
//
// Plugin performance data is external data specific to the plugin used to
// perform the host or service check. Plugin-specific data can include things
// like percent packet loss, free disk space, processor load, number of
// current users, etc. - basically any type of metric that the plugin is
// measuring when it executes.
//
// https://nagios-plugins.org/doc/guidelines.html
// https://assets.nagios.com/downloads/nagioscore/docs/nagioscore/3/en/perfdata.html
// https://assets.nagios.com/downloads/nagioscore/docs/nagioscore/3/en/pluginapi.html
type PerformanceData struct {

// Label is the single quoted text string used as a label for a specific
// performance data point. The label length is arbitrary, but ideally the
// first 19 characters are unique due to a limitation in RRD. There is
// also a limitation in the amount of data that NRPE returns to Nagios.
Label string

// Value is the data point associated with the performance data label.
//
// Value is in class [-0-9.] and must be the same UOM as Min and Max UOM.
// Value may be a literal "U" instead, this would indicate that the actual
// value couldn't be determined.
Value string

// UnitOfMeasurement is an optional unit of measurement (UOM). If
// provided, consists of a string of zero or more characters. Numbers,
// semicolons or quotes are not permitted.
//
// Examples:
//
// 1) no unit specified - assume a number (int or float) of things (eg,
// users, processes, load averages)
// 2) s - seconds (also us, ms)
// 3) % - percentage
// 4) B - bytes (also KB, MB, TB)
// 5) c - a continuous counter (such as bytes transmitted on an interface)
UnitOfMeasurement string

// Warn is in the range format (see the Section called Threshold and
// Ranges). Must be the same UOM as Crit. An empty string is permitted.
//
// https://nagios-plugins.org/doc/guidelines.html#THRESHOLDFORMAT
Warn string

// Crit is in the range format (see the Section called Threshold and
// Ranges). Must be the same UOM as Warn. An empty string is permitted.
//
// https://nagios-plugins.org/doc/guidelines.html#THRESHOLDFORMAT
Crit string

// Min is in class [-0-9.] and must be the same UOM as Value and Max. Min
// is not required if UOM=%. An empty string is permitted.
Min string

// Max is in class [-0-9.] and must be the same UOM as Value and Min. Max
// is not required if UOM=%. An empty string is permitted.
Max string
}

// Validate performs basic validation of PerformanceData. An error is returned
// for any validation failures.
func (pd PerformanceData) Validate() error {

// Validate fields
switch {
case pd.Label == "":
return fmt.Errorf("provided performance data missing required label")
case pd.Value == "":
return fmt.Errorf("provided performance data missing required value")

// TODO: Expand validation
// https://nagios-plugins.org/doc/guidelines.html
default:
return nil

}
}

// ExitCallBackFunc represents a function that is called as a final step
// before application termination so that branding information can be emitted
// for inclusion in the notification. This helps identify which specific
Expand Down Expand Up @@ -91,6 +172,10 @@ type ExitState struct {
// from the last service check.
LongServiceOutput string

// perfData is the collection of zero or more PerformanceData values
// generated by a Nagios plugin.
perfData []PerformanceData

// WarningThreshold is the value used to determine when the service check
// has crossed between an existing state into a WARNING state. This value
// is used for display purposes.
Expand Down Expand Up @@ -245,11 +330,61 @@ func (es *ExitState) ReturnCheckResults() {

}

// If set, call user-provided branding function just before exiting
// application
// If set, call user-provided branding function before emitting
// performance data and exiting application.
if es.BrandingCallback != nil {
fmt.Printf("%s%s%s", CheckOutputEOL, es.BrandingCallback(), CheckOutputEOL)
}

// Generate formatted performance data if provided.
if es.perfData != nil {

// Performance data must be separated from the text output
// (LongServiceOutput) via a pipe character.
fmt.Print("|")

for _, pd := range es.perfData {
fmt.Printf(
// expected format:
// 'label'=value[UOM];[warn];[crit];[min];[max]
// https://nagios-plugins.org/doc/guidelines.html
"'%s'=%s%s;%s;%s;%s;%s%s",
pd.Label,
pd.Value,
pd.UnitOfMeasurement,
pd.Warn,
pd.Crit,
pd.Min,
pd.Max,
CheckOutputEOL,
)
}
}

os.Exit(es.ExitStatusCode)
}

// AddPerfData appends provided performance data. Validation is skipped if
// requested, otherwise an error is returned if validation fails.
//
// Client code may wish to disable validation if performing this step
// directly.
func (es *ExitState) AddPerfData(skipValidate bool, pd ...PerformanceData) error {

if pd == nil {
return fmt.Errorf("no performance data provided")
}

for i := range pd {
if skipValidate {
if err := pd[i].Validate(); err != nil {
return err
}
}

es.perfData = append(es.perfData, pd[i])
}

return nil

}

0 comments on commit 1db1acf

Please sign in to comment.