Auf der Nagios-Konferenz haben Hendrik und Jörg die Neuerungen des Nagios 3 vorgestellt. Dabei wurde eine Neuerung vorgestellt, die gerade für Betreiber einer Rufbereitschaft interessant ist: Der Ausschluss bestimmter Termine aus Timeperiods.
Nagios 3.x erlaubt es, z.B. Feiertage aus timeperiods auszuschliessen. Eine Standard-Timeperiod würde z.B. so aussehen:
define timeperiod{
timeperiod_name nonworkhours
alias Non-Work Hours
sunday 00:00-24:00 ; Every Sunday of every week
monday 00:00-09:00,17:00-24:00 ; Every Monday of every week
tuesday 00:00-09:00,17:00-24:00 ; Every Tuesday of every week
wednesday 00:00-09:00,17:00-24:00 ; Every Wednesday of every week
thursday 00:00-09:00,17:00-24:00 ; Every Thursday of every week
friday 00:00-09:00,17:00-24:00 ; Every Friday of every week
saturday 00:00-24:00 ; Every Saturday of every week
}
Diese Timeperiod lässt sich um spezifische Termine erweitern, die Nagios als Ausnahmen zu den regelmässigen Tagesintervallen behandelt. Sprich, jede Zeile, die kein „weekday“ (sunday-saturday) ist, ist eine Ausnahme. Dabei sind einige spezielle Formate vorgesehen, die die Definition bestimmter Zeitfenster erleichtert. Hierzu ein (sinnloses) Beispiel:
define timeperiod{
timeperiod_name nonworkhours
alias Non-Work Hours
sunday 00:00-24:00 ; Every Sunday of every week
[...]
saturday 00:00-24:00 ; Every Saturday of every week
1999-01-28 00:00-24:00 ; January 28th, 1999
february 10 00:00-24:00 ; February 10th of every year
monday 3-thursday 4 00:00-24:00 ; 3rd Monday to 4th Thursday of every month
day 1 - 15 00:00-24:00 ; 1st to 15th day of every month
day 20 - -1 00:00-24:00 ; 20th to the last day of every month
july 10 - 15 00:00-24:00 ; July 10th to July 15th of every year
2008-04-01 / 7 00:00-24:00 ; Every 7 days from April 1st, 2008 (continuing forever)
}
Mehr dazu: Siehe Nagios-Doku
In Deutschland gibt es feste Daten (Neujahr, 1.Mai, 1./2. Weihnachtstag etc. ) und Termine, die sich jedes Jahr verschieben (Ostern, Pfingsten etc.).
Die festen Termine wären relativ leicht als Timeperiod zu integrieren:
define timeperiod{
timeperiod_name fixed-holiday-nrw
alias Fixed german holiday dates for NRW.
january 01 00:00-24:00 ; Neujahr
may 01 00:00-24:00 ; Tag der Arbeit
october 03 00:00-24:00 ; Tag der deutschen Einheit
november 01 00:00-24:00 ; Allerheiligen
december 25 - 26 00:00-24:00 ; Weihnachten
register 0
}
So weit, so gut. Aber wie kommt man jetzt an die flexiblen Feiertage!? Es gibt im Web verschiedene Ansätze, diese Frage zu beantworten, z.B. auf dieser Seite.
Leichter und kleiner geht es aber mit dem Perl-Modul „Date::Holidays::DE“. Mit diesem Modul ist es möglich, sich die Feiertage zu einem bestimmten Jahr (und einem bestimmten Bundesland) ausgeben zu lassen.
Hier ein Beispiel zur Verwendung des Moduls:
#!/usr/bin/perl use Date::Holidays::DE qw(holidays); my $year = $ARGV[0]; my $feiertage_ref = holidays( WHERE => ['common', 'nw'], FORMAT => "%Y-%m-%d\t\t00:00-24:00\t\t;%#", WEEKENDS => 0, YEAR => $year); # ADD => ['heil', 'silv', 'mari']); my @feiertage = @$feiertage_ref; print "define timeperiod { timeperiod_name\t\tgerman-holidays alias\t\t\tGerman Holiday Dates register\t\t0\n"; foreach(@feiertage) { print "\t\t$_\n"; } print "}\n";
(Für eine weiterführende Dokumentation des Moduls kann man sich hier umschauen.)
Dieses Script nimmt als erstes Argument das Jahr entgegen, für das die Feiertage ausgegeben werden sollen.
Ein Aufruf mit './<scriptname>.pl 2007 ergibt folgenden Output:
define timeperiod {
timeperiod_name german-holidays
alias German Holiday Dates
register 0
2007-01-01 00:00-24:00 ;neuj
2007-04-06 00:00-24:00 ;karf
2007-04-09 00:00-24:00 ;ostm
2007-05-01 00:00-24:00 ;1mai
2007-05-17 00:00-24:00 ;himm
2007-05-28 00:00-24:00 ;pfim
2007-06-07 00:00-24:00 ;fron
2007-10-03 00:00-24:00 ;3okt
2007-11-01 00:00-24:00 ;alhe
2007-12-25 00:00-24:00 ;wei1
2007-12-26 00:00-24:00 ;wei2
}
Damit german-holidays als Vorlage (Template) verwendet werden kann, benötigt obige Definition noch folgenden Zusatz:
name german-holidays
Als Alternative kann auch das Perl-Skript von diesem Forums-Thread verwendet werden. Es verwendet im Gegensatz zum obigen Skript die Perl-Module use Date::Calendar::Profiles, Date::Calendar::Year und Date::Calc::Object.
Es kann eine Feiertagsliste für mehrere Jahre erzeugen und nimmt auch die gewünschten Zeiten als Argument. Ein Aufruf wie perl timeperiod_holidays.pl 2007 2008 DE-BY 00:00-24:00 [perl timeperiod_holidays.pl YEAR_START YEAR_END PROFILE TIMES] ergibt folgenden Output für das Profil „Bayern“ und für die Jahre 2007 bis 2008.:
define timeperiod{
timeperiod_name holidays
alias holidays for Date::Calendar-Profile DE-BY from 2007 to 2008
2007-01-01 00:00-24:00 ; (Mon) Neujahr
2007-04-06 00:00-24:00 ; (Fri) Karfreitag
2007-04-09 00:00-24:00 ; (Mon) Ostermontag
2007-05-01 00:00-24:00 ; (Tue) Tag der Arbeit
2007-05-17 00:00-24:00 ; (Thu) Christi Himmelfahrt
2007-05-28 00:00-24:00 ; (Mon) Pfingstmontag
2007-06-07 00:00-24:00 ; (Thu) Fronleichnam
2007-08-15 00:00-24:00 ; (Wed) Mariä Himmelfahrt
2007-10-03 00:00-24:00 ; (Wed) Tag der deutschen Einheit
2007-11-01 00:00-24:00 ; (Thu) Allerheiligen
2007-12-25 00:00-24:00 ; (Tue) 1. Weihnachtsfeiertag
2007-12-26 00:00-24:00 ; (Wed) 2. Weihnachtsfeiertag
2008-01-01 00:00-24:00 ; (Tue) Neujahr
2008-03-21 00:00-24:00 ; (Fri) Karfreitag
2008-03-24 00:00-24:00 ; (Mon) Ostermontag
2008-05-01 00:00-24:00 ; (Thu) Christi Himmelfahrt, Tag der Arbeit
2008-05-12 00:00-24:00 ; (Mon) Pfingstmontag
2008-05-22 00:00-24:00 ; (Thu) Fronleichnam
2008-08-15 00:00-24:00 ; (Fri) Mariä Himmelfahrt
2008-10-03 00:00-24:00 ; (Fri) Tag der deutschen Einheit
2008-12-25 00:00-24:00 ; (Thu) 1. Weihnachtsfeiertag
2008-12-26 00:00-24:00 ; (Fri) 2. Weihnachtsfeiertag
}
Die möglichen Profile können der Dokumentation zu Date::Calendar::Profiles auf CPAN entnommen werden.
Achtung: Samstage und Sonntage werden von dem Skript generell ignoriert, man muss diese also entsprechend in seinen timeperiods berücksichtigen. Grund für die Einschränkung ist, dass niedere Feiertage an einem Wochenende von dem Perl-Modul auch als volle Feiertage behandelt werden, was unschön ist und ohnehin meist Samstage und Sonntage mit Feiertagen gleichzubehandeln sind.
Hier noch das Skript:
#!/usr/bin/perl -w BEGIN { eval { require bytes; }; } use strict; use Date::Calendar::Profiles qw( $Profiles ); use Date::Calendar::Year; use Date::Calc::Object qw(:ALL); sub print_holidays { my($year_start) = shift_year(\@_); my($year_end) = shift_year(\@_); my($prof) = shift; my($times) = shift; my($j,$year_curr,$full,$half,$last,$i,$date,$year,$month,$day,@labels,$dow,$holiday); my $return; die "No such calendar profile '$prof'" unless (exists $Profiles->{$prof}); for ( $j = $year_start; $j <= $year_end; $j++ ) { $year_curr = Date::Calendar::Year->new( $j, $Profiles->{$prof} ); $full = $year_curr->vec_full(); $half = $year_curr->vec_half(); $last = $year_curr->val_days(); Language(1); Date::Calc->date_format(0); for ( $i = 0; $i < $last; $i++ ) { $date = $year_curr->index2date($i); @labels = $year_curr->labels($date); ($year,$month,$day) = $date->date(); if (@labels > 1) { $dow = substr(shift(@labels),0,3); # we skip saturdays and sundays! next if ( $dow eq "Sat" || $dow eq "Sun" ); # we only want "full" and "half" holidays! $holiday = $full->contains($i) ? "full" : $half->contains($i) ? "half" : ""; if ($holiday) { $return .= sprintf("\t%04d-%02d-%02d\t",$year,$month,$day) . "$times\t; ($dow) " . join(", ", @labels) . "\n"; } } } } return $return; } unless (@ARGV == 4) { die "Usage: perl timeperiod_holidays.pl YEAR_START YEAR_END PROFILE TIMES\n"; } my $timeperiod = "define timeperiod{\n\ttimeperiod_name\tholidays\n\talias\tholidays for Date::Calendar-Profile $ARGV[2] from $ARGV[0] to $ARGV[1]\n"; $timeperiod .= print_holidays( @ARGV ); $timeperiod .= "}"; print $timeperiod; __END__
Diese neue Timeperiod lässt sich jetzt einfach in bestehende Timeperiods integrieren:
define timeperiod{
timeperiod_name nonworkhours
alias Non-Work Hours
use german-holidays
sunday 00:00-24:00 ; Every Sunday of every week
monday 00:00-09:00,17:00-24:00 ; Every Monday of every week
tuesday 00:00-09:00,17:00-24:00 ; Every Tuesday of every week
wednesday 00:00-09:00,17:00-24:00 ; Every Wednesday of every week
thursday 00:00-09:00,17:00-24:00 ; Every Thursday of every week
friday 00:00-09:00,17:00-24:00 ; Every Friday of every week
saturday 00:00-24:00 ; Every Saturday of every week
}
Damit werden alle Feiertage aus der Timeperiod ausgeschlossen.
Nagios 3.0 bringt eine schöne neue Möglichkeit, auf Sonderfälle wie Feiertage oder auch regelmässige Wartungsfenster(…) zu reagieren und für diese Zeiten direkt in den Timeperiods Ausnahmen zu definieren.
Mithilfe eines jährlich laufenden Cron-Jobs lässt sich die Pflege der Feiertage automatisieren und so den Wartungsaufwand gering zu halten.
— localhost 2007/06/26 12:11