Xaprb

Stay curious!

How to gather statistics at regular intervals

with 4 comments

I gather a lot of statistics such as performance data. Sometimes I have multiple things going on a system and I want to be able to align and compare the resulting data from multiple processes later. That means they need to be aligned on time intervals. Here is a naive way to gather stats at intervals:

while sleep 1; do gather-some-stats; done

There are two problems: each iteration will take longer than a second, so there will be drift; and the iterations will not be aligned exactly on the clock ticks, so the data isn’t as easy to correlate with other samples. This becomes a bigger problem when there are many such jobs gathering data at longer intervals such as 15 seconds or 5 minutes, where the lack of correlation between samples can be frustrating.

Here is what I’ve been doing recently. Is there a better way?

INTERVAL=1
while true; do
   sleep=$(date +%s.%N | awk "{print $INTERVAL - (\$1 % $INTERVAL)}")
   sleep $sleep
   gather-some-stats
done

Written by Baron Schwartz

March 18th, 2011 at 10:17 am

Posted in Coding,Sys Admin

4 Responses to 'How to gather statistics at regular intervals'

Subscribe to comments with RSS

  1. If you don’t care about the possibility of concurrent stats collection processes, you could simply fork the gather-some-stats call and sleep for $INTERVAL. You will perhaps still “drift” over the course of a week or so, but perhaps that’s acceptable.

    lamby

    18 Mar 11 at 10:32 am

  2. Baron,

    I usually use Perl and Time::HiRes for that. The following pattern should do what you want (for 1 second intervals here):

    use Time::HiRes qw( ualarm );

    $SIG{ALRM} = sub {};
    ualarm((1_000_000 – (gettimeofday)[1]), 1_000_000);
    while(1)
    {
    sleep;
    print “beep!\n”;
    }

    This will set up a repeating timer, starting at the edge of the next second, and repeating every 1 second after that. Unhooking SIGALRM from its default abort handler will just cause it to wake up from the indefinite “sleep” call.

    Regards,

    Jeremy

    Jeremy Cole

    18 Mar 11 at 10:50 am

  3. watch -n 1 gather-some-stats if you want the first behavior. expr or $(()) at least with bash allows easier math.

    Allan Wind

    18 Mar 11 at 11:31 am

  4. lamby, I found that even backgrounding (and sleep itself) causes enough drift to matter. Jeremy, yes that’s a good Perl-ism. I remember that we used that in mk-heartbeat originally, but ultimately had to move away from it because of various problems I don’t recall with sleep and alarms and signal handlers… it stops working reliably when things get more complex. Allan, bash doesn’t do floating-point math, only integer math.

    Xaprb

    18 Mar 11 at 12:59 pm

Leave a Reply