mickem / nscp

NSClient++
http://nsclient.org
GNU General Public License v2.0
239 stars 94 forks source link

Powershell scripts: problem with perfdata #704

Closed parosio closed 3 years ago

parosio commented 3 years ago

Powershell script: problem with perfdata

Hello, I have a ps1 script that receive 3 params: a filename FN, a number N, a string S. Check last line of FN to search for S, and check the filetime is less than N minutes old. Depending on results, outputs a resultstring and exit with the corresponding code. Ex: "OK: file is less than N minutes old" 0.

I'd also want to pass back the lastline as perfdata.

The problem is each "token" of perfdata string is handled separately and sort of null-terminated: a string like "additional information here" becomes "'additional'=0 'information'=0 'here'=0".

Details follow:

from nsclient.ini:

[/settings/external scripts/wrappings]

; POWERSHELL WRAPPING - 
ps1 = cmd /c echo scripts\\%SCRIPT% %ARGS%; exit($lastexitcode) | powershell.exe -command -

[/settings/external scripts/wrapped scripts]
check_log_operation     = check_file_last_line.ps1 "f:\logpath\operation.log"   40  "END: Successfull"

from check_file_last_line.ps1:

if ($args.count -gt 0) { $theFile = $args[0] }
if ($args.count -gt 1) { $olderThan = $args[1] }
 . . .
$lastLine = gc $theFile | select -last 1

write-host ("OK: Last operation is less than ${olderThan} minutes old", "$lastLine" )  -Separator "|"
exit 0

Expected Behavior

I'd expect nscp to return to nagios the last line of file, as seen when running the script from the command line:

cmd /c echo .\check_file_last_line.ps1 "f:\logpath\operation.log" 40 "END: Successfull" | powershell.exe -command -
OK: Last operation is less than 40 minutes old|"---- check-operation END: Successfully stored <25> mails for folder(s) <operation> ---- "

Actual Behavior

Perfdata get messed up: each whitespace separated token is embedded within single quotes, and terminated by "=0 ":

from nscp test output:

D ext-script Command line: cmd /c echo scripts\\check_file_last_line.ps1 "f:\logpath\operation.log"  40  "END: Successfull"; exit($lastexitcode) | powershell.exe -command -
L        cli OK: OK: Last operation is less than 40 minutes old
L        cli  Performance data: '"----'=0 'check-operation'=0 'END:'=0 'Successfully'=0 'stored'=0 '<25>'=0 'mails'=0 'for'=0 'folder(s)'=0 '<operation>'=0 '----'=0 '"'=0

Details

Additional Details

NSClient++ log:

2020-10-28 10:26:39: debug:c:\source\master\modules\CheckExternalScripts\CheckExternalScripts.cpp:371: Command line: cmd /c echo scripts\\check_file_last_line.ps1 "f:\logpath\operation.log" 40 "END: Successfull"; exit($lastexitcode) | powershell.exe -command -
2020-10-28 10:26:41: info:c:\source\master\modules\CommandClient\CommandClient.cpp:44: OK: OK: Last operation is less than 40 minutes old
2020-10-28 10:26:41: info:c:\source\master\modules\CommandClient\CommandClient.cpp:44:  Performance data: '"----'=0 'check-operation'=0 'END:'=0 'Successfully'=0 'stored'=0 '<25>'=0 'mails'=0 'for'=0 'folder(s)'=0 '<operation>'=0 '----'=0 '"'=0
mintsoft commented 3 years ago

The behaviour is that anything after the | will be treated as perfdata; at which point nscp will try and parse it into the perfdata format (i..e name_of_thing=value_of_thing;; - http://docs.pnp4nagios.org/pnp-0.6/perfdata_format) and put it back together again. If you change from | to something else it should leave the output unmolested

parosio commented 3 years ago

Thank you @mintsoft, that explains it, and seems quite fair. Only I didn't expect nscp to try an interpretation of the output of a custom script.

In the example above, supposing I wanted nagios to receive 'mail_uploaded'=25ml as perfdata, what I should output from the ps script?

mintsoft commented 3 years ago

You should output something like:

write-host "Mail: everything is OK | mail_uploaded=25;;"