Translations of this page:

Ausnahmen in Timeperiods definieren

Intro

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.

Wie funktionierts?

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

Feiertage

In Deutschland gibt es feste Daten (Neujahr, 1.Mai, 1./2. Weihnachtstag etc. ) und Termine, die sich jedes Jahr verschieben (Ostern, Pfingsten etc.).

Fixe Tage

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
    }

Flexible Tage

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

Alternatives Perl-Skript

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__

Integration

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.

Fazit

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

nagios/tips/ausnahmen_in_timeperiods_definieren.txt · Zuletzt geändert: 2009/04/09 11:04 von ckpinguin
CC Attribution-Noncommercial-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0