Here's another way...
We use Check_MK (which is nagios based) with a Check_MK agent installed on the VisualCron server....
We drop the PowerShell script below onto the VisualCron server to get executed by the agent (every 1 min in our case).
(we also tried a C# one, which executed quicker but it needed to be recompiled each time the API dll's changed - so we switched it to PowerShell)
This gives us the performance data to draw graphs of execution time and a nice at-a-glance view in the Check_MK UI
I'm sure you can make something similar for other Nagios clients (like NSClient++ or whatever) without too much difficulty.
When you install VisualCron you'll get some API documentation / samples in C:\Program Files (x86)\VisualCron\API (assuming you use default install directory).
# Load the VisualCron API Dlls
$VC = [Reflection.Assembly]::LoadFrom("C:\Program Files (x86)\VisualCron\VisualCron.dll");
$VCAPI = [Reflection.Assembly]::LoadFrom("C:\Program Files (x86)\VisualCron\VisualCronAPI.dll");
# Define Client & Server Objects
$Global:Client = New-Object -TypeName VisualCronAPI.Client
$Global:Server = New-Object -TypeName VisualCronAPI.Server
# Define Connection Object
$Conn = New-Object -TypeName VisualCronAPI.Connection
# Set Connection Values
$Conn.Address = 'localhost'
$Conn.UserName = 'api_user'
$Conn.PassWord = 'password'
$Conn.Port = 16444
$Conn.ConnectionType = 'Local'
# If connecting to localhost, check VisualCron Service is running (useful for cluster installations)
If ($Conn.Address -like 'localhost' -and -not (Get-Process VisualCronService -ErrorAction SilentlyContinue)) {
Write-Output "2 VisualCron ExecTime=0 Error: VisualCron service not running"
exit
}
# Try to Connect to the VisualCron Server
try {
$Global:Server = $Client.Connect($conn, $true);
}
catch {
Write-Output "2 VisualCron ExecTime=0 Error: Could Not Connect to VisualCron Server"
}
# Get the jobs
$jobs = $Global:Server.jobs.GetAll()
# Run through them and write out the status
foreach ($job in $jobs) {
# We only report on Active jobs:
if ($job.Stats.Active -eq $True) {
# Get the job name (and replace space with underscore)
$JobName = $job.name.Replace(" ","_")
# Check the last exit code and use this to set Check_MK status
if ($job.Stats.ExitCode -eq 0) {
$Status = 0
}
else {
$Status = 2
}
# Get the last execution time from the job, in seconds
$ExecutionTime = [timespan]::fromseconds($job.Stats.ExecutionTime)
# Get the date / time the job last ran
[datetime]$DateLastExecution = $job.Stats.DateLastExecution
# Make the output easier to read in the check_MK GUI
$RanAt = $DateLastExecution.ToShortTimeString()
$RanOn = $DateLastExecution.ToShortDateString()
$Today = $(Get-Date).ToShortDateString()
$Yesterday = $(Get-Date).AddDays(-1).ToShortDateString()
$TimeTaken = "Last execution time: $("{0:hh\:mm\:ss}" -f $Executiontime)"
$StartedAt = $DateLastExecution.TolongTimeString()
If ($job.Stats.Status -like '*Running*' ) {
$OutputMessage = "RUNNING (since $StartedAt)"
}
ElseIf ($RanOn -eq $Today) {
$OutputMessage = "Last ran Today at $RanAt ($TimeTaken)"
}
ElseIf ($RanOn -eq $Yesterday) {
$OutputMessage = "Last ran Yesterday at $RanAt ($TimeTaken)"
}
Else {
$OutputMessage = "Last ran on $RanOn at $RanAt ($TimeTaken)"
}
# Write the output:
Write-Output "${Status} VC_${JobName} ExecTime=$($ExecutionTime.TotalSeconds) $OutputMessage"
}
}