http://qs1969.pair.com?node_id=303290

Nitrox has asked for the wisdom of the Perl Monks concerning the following question:

I've written an application that monitors the health of numerous servers and now I need to expand the "alerting" routine.

I'm trying to find the best way to store "windows of time" in a string (or an array of strings) (which is stored in a database and relates to the pager group that is responsible for that particular server). For example, "if server Foo fails and its currently Monday-Friday, 9:00-17:00 then page Group1".

The format that Swatch uses in it's config for the "when" option looked hopeful but only supports one "window". Here's an example: when=range_of_days:range_of_hours So if I wanted to be paged any time of the day on Saturday or Sunday the syntax would be: 7-1:1-24.

That works great for simplex windows but I already need to account for situations like:

If Foo fails: AND its Mon-Sat (any hour) OR its Sun !6-8 (any hour except between 6-8am) THEN page Group3
I also thought about utilizing the crontab syntax, so I went and read through the docs for many of the Schedule::Cron::* modules. Unfortunately I didn't see "the one" that I have envisioned in my head. I'd like to pass a crontab style string to the module and have it simply return true if the passed string would currently trigger an event.

Has anyone done any projects similar to this?

-Nitrox

Replies are listed 'Best First'.
Re: Representing windows of time in a string
by Limbic~Region (Chancellor) on Oct 30, 2003 at 17:03 UTC
    Nitrox,
    As I mentioned in the CB, The Panther has a section on using bitmap vectors to determine scheduling conflicts. It is just a matter of logically AND-ing the two bitmaps.

    Each hour in the week would be one bit. You would be storing a 21 byte bitmap vector. If the bit is set, then there is a problem if the event happens at this hour. The task then is to design a way to parse your range and localtime() into the bitmap vector.

    The following is very basic, but it gives you a fully functional framework. Expand it as you see fit.

    I hope this helps - L~R

      L~R, thanks for the full framework! I was headed down the same path and manipulated the examples from the Panther to work with 24 hours per day:
      #!/usr/bin/perl -w use strict; my %base_hours = ( sun => 0, mon => 24, tue => 48, wed => 72 , thu => +96, fri => 120, sat => 144 ); my $vector = interval_parse("Sat 9-17, Sun 9-17"); my $bits = unpack("b*", $vector); print $bits, "\n"; sub interval_parse { my ($interval_sequence) = @_; my ($time_range) = ""; foreach my $day_hours (split /,/, $interval_sequence) { my ($day, $from, $to) = ($day_hours =~ /([A-Za-z]+).*(\d+)-(\d+ +)/); my $base = $base_hours{lc $day}; $from += $base; $to += $base; for (my $i = $from; $i < $to; $i++) { vec($time_range, $i, 1) = 1; } } return($time_range); }
      Thanks for the pointer!

      -Nitrox

Re: Representing windows of time in a string
by simonm (Vicar) on Oct 30, 2003 at 16:50 UTC

    Strictly speaking, crontab schedules define "points" in time when the specific actions are triggered, whereas it seems you need a broader "range" or "set" of time spans.

    It might be overkill, but I think you should be able to accomplish this with the DateTime modules.

    For example, take a look at DateTime::Event::ICal... Using the ICal format, you could express your rules as:

    my $incident = DateTime->from_epoch( time() ); # your data here my $ok_down = DateTime::Event::ICal->recur( byday=>["su"], byhour=>[ +6, 7] ); unless ( $ok_down->contains( $incident ) { # notify }
Re: Representing windows of time in a string
by davido (Cardinal) on Oct 30, 2003 at 17:11 UTC
    Advanced Perl Programming, otherwise known as the Panther book from O'Reilly & Assoc. has a discussion that you would probably find beneficial. Chapter two, section three:

    Consider that there are only 24 * 7 = 168 hours in a week, the entire week's schedule can be represented by a bitmap vector of 21 bytes (168 / 8) .... The other cool thing is that you can obtain time conflicts by logically AND-ing two bitmaps.

    The implementation example provided in the book uses vec to construct the bitmaps, and logical 'and' to check for overlaps.

    Hope this helps...


    Dave


    "If I had my life to live over again, I'd be a plumber." -- Albert Einstein