views:

838

answers:

5

I am writing a script to capture disk usage on a system (yes, I know there is software that can do this). For database reporting purposes, I want the interval between data points to be as equal as possible. For example, if I am polling disk usage every 10 minutes, I want every data point to be YYYY-MM-DD HH:[0-5]0:00. If I'm am polling every 5 minutes, it would be YYYY-MM-DD HH:[0-5][05]:00.

If I have a ksh script (or even a Perl script) to capture the disk usage, how can I let the script come active and wait for the next "Poll time" before taking a snapshot, and then sleep for the correct number of seconds until the next "Poll time". If I am polling every 5 minutes, and it is 11:42:00, then I want to sleep for 180 seconds so it will take a snapshot at 11:45:00 - and then sleep for 5 minutes so it will take another snapshot at 11:50:00.

I wrote a way that works if my poll time is every 10 minutes, but if I change the poll time to a different number, it doesn't work. I would like it to be flexible on the poll time.

I prefer to do this in shell script, but if it is way too much code, Perl would be fine too.

Any ideas on how to accomplish this?

Thanks in advance!

Brian

EDIT: Wow - I left out a pretty important part - that cron is disabled, so I will not be able to use cron for this task. I am very sorry to all the people who gave that as an answer, because yes, that is the perfect way to do what I wanted, if I could use cron.

I will be using our scheduler to kick off my script right before midnight every day, and I want the script to handle running at the exact "poll times", sleeping in between, and exiting at midnight.

Again, I'm very sorry for not clarifying on crontabs.

+6  A: 

cron will do the job.

http://en.wikipedia.org/wiki/Cron

Just configure it to run your ksh script at the times you need and you are done

Reginaldo
+1 for the answer since you were exactly right - however, I have clarified in my edit that I cannot use cron. Sorry for leaving that out in my question...
BrianH
You could create a simple java application that takes advantage of <a href="http://www.opensymphony.com/quartz/">Quartz</a>. Quartz has all the plumbing to achieve this. Also <a href="http://static.springframework.org/spring/docs/1.2.9/reference/scheduling.html">Spring</a> has some nice features to make the use of Quartz even easier.
Reginaldo
+2  A: 

If I were doing this, I would use the system scheduler (cron or something else) to schedule my program to run every 180 seconds.

EDIT: I might have misunderstood your request. Are you looking more for something along the following lines? (I suspect there is a bug or two here):

ANOTHER EDIT: Remove dependency on Time::Local (but now I suspect more bugs ;-)

#!/usr/bin/perl

use strict;
use warnings;

use POSIX qw( strftime );

my $mins = 5;

while ( 1 ) {
    my ($this_sec, $this_min) = (localtime)[0 .. 1];

    my $next_min = $mins * ( 1 + int( $this_min / $mins ) );
    my $to_sleep = 60 * int( $next_min - $this_min - 1 )
                 + 60 - $this_sec;

    warn strftime('%Y:%m:%d %H:%M:%S - ', localtime),
        "Sleeping '$to_sleep' seconds\n";

    sleep $to_sleep;
}

__END__
Sinan Ünür
+1 for the answer since you were exactly right - however, I have clarified in my edit that I cannot use cron. Sorry for leaving that out in my question...
BrianH
Yes - that is exactly what I was looking for! ksh would be preferred, but I think Perl is going to end up being the least amount of hassle. Thanks very much!
BrianH
@BrianH Well, the only thing that creates a dependency on Perl is the Time::Local module.
Sinan Ünür
@BrianH with the Time::Local dependency removed, it should be easy to translate this to a ksh script because the key part is just arithmetic. I would appreciate it if you could remember to mark the answer accepted if it did solve your problem.
Sinan Ünür
+1  A: 

Have it sleep for a very short time, <=1 sec, and check each time whether poll time has arrived. Incremental processor use will be negligible.

Edit: cron is fine if you know what interval you will use and don't intend to change frequently. But if you change intervals often, consider a continuously running script w/ short sleep time.

John Pirie
That is what I was doing, but this requires some kind of hard coding of the poll times, either in the program, a database, or config file. I guess I could write an algorithm to calculate all of the poll times for a 24 hour period, but there seems like there should be a better way...
BrianH
Then the question really is, What factors determine poll time, and under what circumstances would it change? If you want to transcend the dumb-process way of hard-coding, you'll have to define the logic.
John Pirie
+3  A: 

You might want to consider using cron. This is exactly what it was made for.

D.Shawley
+1 for the answer since you were exactly right - however, I have clarified in my edit that I cannot use cron. Sorry for leaving that out in my question...
BrianH
A: 

Depending on how fine grained your time resolution needs to be, there may be a need to write your script daemon style. Start it once, while(1) and do the logic inside the program (you can check every second until it's time to run again).

Perl's Time::HiRes allows very fine granularity if you need it.

Artem Russakovskii