atc0005 / go-nagios

Shared Golang package for Nagios plugins
MIT License
8 stars 3 forks source link

Preformatted ServiceOutput string subjected to another (failed) formatting operation #58

Closed atc0005 closed 3 years ago

atc0005 commented 3 years ago

While working on a new Nagios plugin, I used %% literally in a fmt.Sprintf call that assigned the output to the ServiceOutput field. This was processed by (*ExitState).ReturnCheckResults() here:

https://github.com/atc0005/go-nagios/blob/1252557596a5f20c66f4494a94097b82b6f732b9/nagios.go#L164-L174

which causes the fmt.Printf function to attempt a replacement of what it found as a sole % placeholder value. This fails because I'm attempting to use the %% formatting characters to indicate a literal % character.

Example of what it should look like when emitted:

OK: 14 vCPUs allocated (70.0%); 6 more remaining from 20 allowed (evaluated 5 VMs, 1 Resource Pools)

What is emitted instead:

OK: 14 vCPUs allocated (70.0%!)(MISSING); 6 more remaining from 20 allowed (evaluated 5 VMs, 1 Resource Pools)
atc0005 commented 3 years ago

I modified my vendored copy of this package like so:

index 08b5ea0..72f2b4d 100644
--- a/vendor/github.com/atc0005/go-nagios/nagios.go
+++ b/vendor/github.com/atc0005/go-nagios/nagios.go
@@ -170,7 +170,7 @@ func (es *ExitState) ReturnCheckResults() {

        // One-line output used as the summary or short explanation for the
        // specific Nagios state that we are returning.
-       fmt.Printf(es.ServiceOutput)
+       fmt.Print(es.ServiceOutput)

        if es.LongServiceOutput != "" || es.LastError != nil {

This seems to work as expected by (presumably) forcing the existing preformatted string to be emitted as-is. Since we're not attempting any further formatting with this one step, we should be good to just emit the string as-is.

The "Detailed Info" content is handled by a fmt.Printf call, but that call explicitly uses a %v formatting verb, which I think is another attempt to print "as-is". That call does not appear to need any changes.

This change also seems to work as an alternative to replacing the fmt.Printf call with one to fmt.Print:

index 08b5ea0..ed4ce13 100644
--- a/vendor/github.com/atc0005/go-nagios/nagios.go
+++ b/vendor/github.com/atc0005/go-nagios/nagios.go
@@ -170,7 +170,7 @@ func (es *ExitState) ReturnCheckResults() {

        // One-line output used as the summary or short explanation for the
        // specific Nagios state that we are returning.
-       fmt.Printf(es.ServiceOutput)
+       fmt.Printf("%v", es.ServiceOutput)

        if es.LongServiceOutput != "" || es.LastError != nil {

I expect that this provides a clear distinction to the formatting "engine" what is a formatting verb and what is literal text.