]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - config/qos/RRD-func.pl
Update:
[people/pmueller/ipfire-2.x.git] / config / qos / RRD-func.pl
diff --git a/config/qos/RRD-func.pl b/config/qos/RRD-func.pl
new file mode 100644 (file)
index 0000000..4642f13
--- /dev/null
@@ -0,0 +1,197 @@
+
+##########################################
+##
+## DESCRIPTION
+##
+##   RRD function for tc-graph.
+##   Which is part of the ADSL-optimizer.
+##
+## REQUIRES
+##
+##
+## AUTHOR
+##   Jesper Dangaard Brouer <hawk@diku.dk>, d.15/4-2004
+##
+## CHANGELOG
+##   2004-04-15:  Initial version.
+##
+## $Id: RRD-func.pl,v 1.10 2004/05/27 17:02:12 hawk Exp $
+##########################################
+
+use RRDs;
+
+if (not defined $rrd_datadir) {
+    our $rrd_datadir = "/var/spool/rrdqueues/";
+}
+
+if (not defined $STEP) {
+    my $STEP=10;
+}
+
+my $heartbeat=$STEP*2;
+
+# Update script samples every 10 seconds.
+#  24*60*60  = 86400 seconds (== one day) 
+#   8640 *10 = 86400 seconds (== one day)
+#   8640 * 5days = 43200 seconds with 10 sec samples
+#
+my @rrd_data_sources = 
+    ("-s", $STEP,
+     "DS:bytes:COUNTER:$heartbeat:0:U",
+     "DS:bits:COUNTER:$heartbeat:0:U",
+     "DS:pkts:COUNTER:$heartbeat:0:U",
+     "DS:dropped:COUNTER:$heartbeat:0:U",
+     "DS:overlimits:COUNTER:$heartbeat:0:U",
+     "DS:lended:COUNTER:$heartbeat:0:U",
+     "DS:borrowed:COUNTER:$heartbeat:0:U",
+     "DS:giants:COUNTER:$heartbeat:0:U",
+     "DS:backlog:GAUGE:$heartbeat:0:U",
+     "RRA:AVERAGE:0.5:1:43200",
+     "RRA:AVERAGE:0.5:7:8640",
+     "RRA:AVERAGE:0.5:31:8640",
+     "RRA:AVERAGE:0.5:372:8640",
+     "RRA:MAX:0.5:7:8640",
+     "RRA:MAX:0.5:31:8640",
+     "RRA:MAX:0.5:372:8640"
+     );
+
+
+sub get_filename_rrd($) {
+    my $class_device = "$_[0]";
+    my $filename = "${rrd_datadir}class_${class_device}.rrd";
+    return $filename;
+}
+
+sub create_rrdfile($) {
+    my $class_device = "$_[0]";
+    my $filename = get_filename_rrd($class_device);
+    RRDs::create $filename, @rrd_data_sources;
+    my $ERROR = RRDs::error;
+    if ($ERROR) {
+       my $timestamp = time;
+       die "$timestamp: ERROR - Unable to create RRDfile \"$filename\": $ERROR\n";
+    }
+}
+
+sub format_class_data($) {
+    my $class = $_[0];
+    my ($rrd_template, $rrd_data);
+    my (@array_template, @array_data);
+    #print "Ref:". ref($class) ."\n";
+
+    # Select and correct undef values and key
+    while ( (my $key, my $value) = each %{$class}) {
+       # Skip timestamps
+       if ( ($key eq "last_update") ||
+            ($key eq "file_update") ||
+            ($key =~ /hfsc_/ )) {next}
+
+       push @array_template, $key; 
+
+       if ( (not defined $value) ||
+            ("$value" eq "") ) { 
+           $value = "U";
+       }
+       push @array_data, $value; 
+    }
+    
+    # Makes a RRD suitable input format
+    $rrd_template = join(":",@array_template);
+    $rrd_data     = join(":",@array_data);
+
+    return ($rrd_template, $rrd_data);
+}
+
+sub update_rrds {
+
+    my $res=0;
+
+    my @test = keys %classes_data;
+    if ( $#test <= 0) {
+       print  time, " [update_rrds] WARNING: classes_data empty!\n";
+       return "classes_data empty";
+    }
+
+    # Find the class_device (keys) in %classes_data
+    for my $class_device ( keys %classes_data ) {
+
+       if ("last_update" eq "$class_device") {next}
+
+       # Verify file exist (else create it) 
+       my $filename = get_filename_rrd($class_device);
+       if ( ! -f $filename ) {
+           print "Creating RRDfile: $filename\n";
+           create_rrdfile($class_device);
+       }
+       #print "$class_device\n";
+
+       # Make a RRD suitable input format
+       my ($rrd_template, $rrd_data) = format_class_data($classes_data{$class_device});
+       #print "rrd_template: $rrd_template\n";
+       #print "rrd_data: $rrd_data\n";
+
+
+       # WHAT ABOUT:
+       # $classes_data{$device}{last_update} ????
+       my ($tmp, $device) = split /_/, $class_device;
+       #print "device: $device $classes_data{last_update}{$device} \n";
+       if ( (exists $classes_data{last_update}{$device}) ) {
+           if ((($classes_data{$class_device}{last_update} + $heartbeat) < 
+                $classes_data{last_update}{$device})) {
+               print "WARNING: the class $class_device was";
+               print "not updated in lastrun + heartbeat...\n";
+               print "Assuming $class_device is removed,";
+               print " thus deleteing from hash table.";
+#          # ??? MAYBE DELETE THE OLD HASH ???
+               $res="Deleting class $class_device";
+               for my $key ( keys %{ $classes_data{$class_device} } ) {
+                   delete( $classes_data{$class_device}{$key});
+                   print " Deleting key: $key from: $class_device \n";
+               }
+               delete $classes_data{$class_device};
+               next;
+           }
+       }
+
+       # Verifies that it is new data, 
+       #  and not old data which already have been updated
+       # FIXME
+#      print "$0 FIXME update_rrds \n";
+       if ( exists $classes_data{$class_device}{file_update} ) {
+           if (($classes_data{$class_device}{file_update} >= 
+                $classes_data{$class_device}{last_update})) {
+               print "Warning ($class_device):";
+               print " data already updated... old data or deleted class?\n";
+               $res="Old data or deleted class";
+               # ??? MAYBE DELETE THE OLD HASH ???
+               next;
+           }
+       }
+
+
+       # Update the RRD file
+       my $update_time = $classes_data{$class_device}{last_update};
+#      print "Updates: $filename time:$update_time\n";
+#      print " --template=$rrd_template\n";
+#      print " $update_time:$rrd_data\n";
+       
+#      `rrdtool update $filename --template=$rrd_template $update_time:$rrd_data`;
+       RRDs::update ($filename, "--template=$rrd_template", 
+                     "N:$rrd_data");
+
+       my $ERROR = RRDs::error;
+       if ($ERROR) {
+           my $timestamp = time;
+           print "$timestamp: WARNING - ";
+           print "Unable to update RRDfile \"$filename\": $ERROR\n";       
+           $res="Unable to update RRDfile \"$filename\"";
+       } else {
+           $classes_data{$class_device}{file_update} = time;
+       }
+    }
+    return $res;
+}
+
+
+return 1;
+