Nagios - SQL Backup check

Der Sinn hinter diesem Check ist, dass es zwar toll ist, dass man aus einem Wartungsplan eines Microsoft SQL- Servers heraus eine eMail versenden kann, die den Beendigungsstatus des Maintenance Plans berichtet- aber auch diese Mail muss erst jemand lesen.

So entstand die Idee, den Status durch Nagios auslesen zu lassen. Im konkreten Fall geht es um einen Wartungsplan, der ein Backup aller Datenbanken auf ein NFS- Share schiebt, von wo aus sie dann durch EMC Networker gesichert werden.

Das Funtionsprinzip hinter den folgenden Konfigurationen und Scripten ist:

- der SQL Server arbeitet einen Wartungsplan ab
- als letzter Schritt im Wartungsplan wird ein T-SQL Script ausgeführt, das eine Textdatei mit dem aktuellen Zeitstempel schreibt
- das Nagios- System greift per NRPE auf ein NSClient++ Modul auf dem Datenbankserver zu
- ein Powershell- Script, das durch NSClient++ ausgeführt wird, liest die Textdatei aus und vergleicht sie mit den Grenzwerten, die von Nagios übergeben werden. Die beiden Grenzwerte sind das Alter der letzten Datensicherung in Stunden, warning und critical
- Nagios wertet den Rückgabewert aus und stellt das Ergebnis in der bekannten Optik dar

Zuerst wird im Maintenance Plan des Microsoft SQL Servers im letzten Schritt, der den erfolgreichen Abschluß abbildet, folgender T-SQLCode eingefügt:

T-SQL Code für den Microsoft SQL Server

declare @tgt varchar(128)
declare @uts varchar(16)
declare @output varchar(128)
select @uts = DATEDIFF(s, '1970-01-01 00:00:00', SYSUTCDATETIME() )
set @tgt = 'D:\SQL_Data\backup.status'
set @output = 'echo ' + @uts + ' > ' + @tgt
exec master..xp_cmdshell @output


Der nächste Schritt ist das Erstellen des Powershell- Scripts d:\sql_data\check_backupstatus.ps1.
Dieses Script wird später durch den NSClient++ aufgerufen und bildet die eigentliche Intelligenz ab.

Powershell- Checkscript

# args: path, warnhours, crithours
If ($Args.count -lt 3) {
  write-output "UNKNOWN: Too few parameters!"
  exit 3
}

If ($Args[1] -eq "$" -Or $Args[2] -eq "$") {
  write-output "UNKNOWN: Warning and critical must be set!"
  exit 3
}

If (!$Args[0] -Or !$Args[1] -Or !$Args[2]) {
  write-output "UNKNOWN: Three arguments needed!"
  exit 3
}

Function Convert-FromUnixdate ($UnixDate) {
   [timezone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').`
   AddSeconds($UnixDate))
}

$arg_file = $Args[0]
$arg_warn_hours = $Args[1]
$arg_crit_hours = $Args[2]

If (![System.IO.File]::Exists($arg_file)) {
  write-output "UNKNOWN: File $arg_file does not exist!"
  exit 3
}

If ($arg_warn_hours -ge $arg_crit_hours) {
  write-output "UNKNOWN: Warning can't be bigger than critical"
  exit 3
}

$tsfile = Get-Content $arg_file
$nicefile = Convert-FromUnixDate $tsfile

$tsnow = [int][double]::Parse($(Get-Date -date (Get-Date).ToUniversalTime()-uformat %s))
# DEBUG $nicetime = Convert-FromUnixDate $tsnow
# DEBUG write-output "NOW $tsnow - $nicetime"

$tswarnlimit = [int]$tsfile + [int]($arg_warn_hours * 3600)
$tscritlimit = [int]$tsfile + [int]($arg_crit_hours * 3600)

If ( $tscritlimit -le $tsnow ) {
  write-output "CRITICAL: Last backup finished at $nicefile"
  exit 2
}
ElseIf ( $tswarnlimit -le $tsnow ) {
  write-output "WARNING: Last backup finished at $nicefile"
  exit 1
}
Else {
  write-output "OK: Last backup finished at $nicefile"
  exit 0
}
Powershell- Checkscript

Nach der Installation des NSClient++ auf dem Datenbanksystem wird die Konfigurationsdatei nsclient.ini ähnlich zur folgenden angepasst. Wichtig sind hierbei vor allem folgende Parameter:

allow arguments=true
allow nasty characters=true

sowie der Aufruf des Check- Scripts
check_backupstatus = cmd /c echo d:\sql_data\check_backupstatus.ps1 "$ARG1$" $ARG2$ $ARG3$ ; exit($lastexitcode) | powershell.exe -command -

Die anderen Einstellungen, hier speziell die Zeile allowed_hosts, sind auf die jeweilige Umgebung anzupassen.
Nicht vergessen nach Änderungen der Konfiguration auch den Dienst neu zu starten! :-D

nsclient.ini

# If you want to fill this file with all avalible options run the following command:
#   nscp settings --generate --add-defaults --load-all
# If you want to activate a module and bring in all its options use:
#   nscp settings --activate-module <MODULE NAME> --add-defaults
# For details run: nscp settings --help


; Undocumented section
[/settings/default]

; Undocumented key
password = S1hD35Dqs3PxrR4A

; Undocumented key
allowed hosts = 127.0.0.1,172.16.0.47,::1


; Undocumented section
[/settings/NRPE/server]
allow arguments=true
allow nasty characters=true

; Undocumented key
verify mode = none

; Undocumented key
insecure = true


; Undocumented section
[/modules]

; Undocumented key
CheckExternalScripts = 1

; Undocumented key
CheckHelpers = 1

; Undocumented key
CheckEventLog = 1

; Undocumented key
CheckNSCP = 1

; Undocumented key
CheckDisk = 1

; Undocumented key
CheckSystem = 1

; Undocumented key
NRPEServer = 1

; rss
[/settings/external scripts]
allow arguments=true
allow nasty characters=true

[/settings/external scripts/scripts]
check_backupstatus = cmd /c echo d:\sql_data\check_backupstatus.ps1 "$ARG1$" $ARG2$ $ARG3$ ; exit($lastexitcode) | powershell.exe -command -


Im letzten Schritt muss der neue Check nun noch in Nagios selbst eingebunden werden. Die folgenden beiden Schnipsel stellen exemplarisch eine Kommando und eine Servicedefiniton dar.

Nagios Konfiguration

Kommandodefinition:
...
define command{
  command_name    check_nrpe
  command_line    $USER1$/check_nrpe -H $HOSTADDRESS$ -u -t 60 -c $ARG1$ -a $ARG2$
}
...

Checkdefinition:

...
define service{
  use                     generic-service-server
  host_name               datenbank.server
  service_description     Database Backup
  check_command           check_nrpe!check_backupstatus!d:\\sql_data\\backup.status 13 25
}
...

Die Parameter des check_command, bzw. des NRPE- Aufrufs  sind:
- Name des Checks, der auf dem Remote-System datenbank.server ausgeführt werden soll
- Pfad zur und Name der Statusdatei, die durch das T-SQL-Script geschrieben wird
- Status WARNING sobald die letzte Sicherung älter als 13 Stunden ist
- Status CRITICAL sobald die letzte Sicherung älter als 25 Stunden ist


Nach einem Reload der Nagios Konfiguration springt der Status auf UNKNOWN, da die Statusdatei erst beim nächsten Lauf des Maintenance- Plans erzeugt wird. Nach erfolgreicher Beendigung des Plans sollte der Status zeitnah auf OK springen und die Prüfung ist aktiv.

Wieder einige Mails weniger zu Lesen.