]> git.ipfire.org Git - ipfire-2.x.git/blob - config/qos/RRD-func.pl
4642f1333fb83242f9df35d840ba1dea002310b8
[ipfire-2.x.git] / config / qos / RRD-func.pl
1
2 ##########################################
3 ##
4 ## DESCRIPTION
5 ##
6 ## RRD function for tc-graph.
7 ## Which is part of the ADSL-optimizer.
8 ##
9 ## REQUIRES
10 ##
11 ##
12 ## AUTHOR
13 ## Jesper Dangaard Brouer <hawk@diku.dk>, d.15/4-2004
14 ##
15 ## CHANGELOG
16 ## 2004-04-15: Initial version.
17 ##
18 ## $Id: RRD-func.pl,v 1.10 2004/05/27 17:02:12 hawk Exp $
19 ##########################################
20
21 use RRDs;
22
23 if (not defined $rrd_datadir) {
24 our $rrd_datadir = "/var/spool/rrdqueues/";
25 }
26
27 if (not defined $STEP) {
28 my $STEP=10;
29 }
30
31 my $heartbeat=$STEP*2;
32
33 # Update script samples every 10 seconds.
34 # 24*60*60 = 86400 seconds (== one day)
35 # 8640 *10 = 86400 seconds (== one day)
36 # 8640 * 5days = 43200 seconds with 10 sec samples
37 #
38 my @rrd_data_sources =
39 ("-s", $STEP,
40 "DS:bytes:COUNTER:$heartbeat:0:U",
41 "DS:bits:COUNTER:$heartbeat:0:U",
42 "DS:pkts:COUNTER:$heartbeat:0:U",
43 "DS:dropped:COUNTER:$heartbeat:0:U",
44 "DS:overlimits:COUNTER:$heartbeat:0:U",
45 "DS:lended:COUNTER:$heartbeat:0:U",
46 "DS:borrowed:COUNTER:$heartbeat:0:U",
47 "DS:giants:COUNTER:$heartbeat:0:U",
48 "DS:backlog:GAUGE:$heartbeat:0:U",
49 "RRA:AVERAGE:0.5:1:43200",
50 "RRA:AVERAGE:0.5:7:8640",
51 "RRA:AVERAGE:0.5:31:8640",
52 "RRA:AVERAGE:0.5:372:8640",
53 "RRA:MAX:0.5:7:8640",
54 "RRA:MAX:0.5:31:8640",
55 "RRA:MAX:0.5:372:8640"
56 );
57
58
59 sub get_filename_rrd($) {
60 my $class_device = "$_[0]";
61 my $filename = "${rrd_datadir}class_${class_device}.rrd";
62 return $filename;
63 }
64
65 sub create_rrdfile($) {
66 my $class_device = "$_[0]";
67 my $filename = get_filename_rrd($class_device);
68 RRDs::create $filename, @rrd_data_sources;
69 my $ERROR = RRDs::error;
70 if ($ERROR) {
71 my $timestamp = time;
72 die "$timestamp: ERROR - Unable to create RRDfile \"$filename\": $ERROR\n";
73 }
74 }
75
76 sub format_class_data($) {
77 my $class = $_[0];
78 my ($rrd_template, $rrd_data);
79 my (@array_template, @array_data);
80 #print "Ref:". ref($class) ."\n";
81
82 # Select and correct undef values and key
83 while ( (my $key, my $value) = each %{$class}) {
84 # Skip timestamps
85 if ( ($key eq "last_update") ||
86 ($key eq "file_update") ||
87 ($key =~ /hfsc_/ )) {next}
88
89 push @array_template, $key;
90
91 if ( (not defined $value) ||
92 ("$value" eq "") ) {
93 $value = "U";
94 }
95 push @array_data, $value;
96 }
97
98 # Makes a RRD suitable input format
99 $rrd_template = join(":",@array_template);
100 $rrd_data = join(":",@array_data);
101
102 return ($rrd_template, $rrd_data);
103 }
104
105 sub update_rrds {
106
107 my $res=0;
108
109 my @test = keys %classes_data;
110 if ( $#test <= 0) {
111 print time, " [update_rrds] WARNING: classes_data empty!\n";
112 return "classes_data empty";
113 }
114
115 # Find the class_device (keys) in %classes_data
116 for my $class_device ( keys %classes_data ) {
117
118 if ("last_update" eq "$class_device") {next}
119
120 # Verify file exist (else create it)
121 my $filename = get_filename_rrd($class_device);
122 if ( ! -f $filename ) {
123 print "Creating RRDfile: $filename\n";
124 create_rrdfile($class_device);
125 }
126 #print "$class_device\n";
127
128 # Make a RRD suitable input format
129 my ($rrd_template, $rrd_data) = format_class_data($classes_data{$class_device});
130 #print "rrd_template: $rrd_template\n";
131 #print "rrd_data: $rrd_data\n";
132
133
134 # WHAT ABOUT:
135 # $classes_data{$device}{last_update} ????
136 my ($tmp, $device) = split /_/, $class_device;
137 #print "device: $device $classes_data{last_update}{$device} \n";
138 if ( (exists $classes_data{last_update}{$device}) ) {
139 if ((($classes_data{$class_device}{last_update} + $heartbeat) <
140 $classes_data{last_update}{$device})) {
141 print "WARNING: the class $class_device was";
142 print "not updated in lastrun + heartbeat...\n";
143 print "Assuming $class_device is removed,";
144 print " thus deleteing from hash table.";
145 # # ??? MAYBE DELETE THE OLD HASH ???
146 $res="Deleting class $class_device";
147 for my $key ( keys %{ $classes_data{$class_device} } ) {
148 delete( $classes_data{$class_device}{$key});
149 print " Deleting key: $key from: $class_device \n";
150 }
151 delete $classes_data{$class_device};
152 next;
153 }
154 }
155
156 # Verifies that it is new data,
157 # and not old data which already have been updated
158 # FIXME
159 # print "$0 FIXME update_rrds \n";
160 if ( exists $classes_data{$class_device}{file_update} ) {
161 if (($classes_data{$class_device}{file_update} >=
162 $classes_data{$class_device}{last_update})) {
163 print "Warning ($class_device):";
164 print " data already updated... old data or deleted class?\n";
165 $res="Old data or deleted class";
166 # ??? MAYBE DELETE THE OLD HASH ???
167 next;
168 }
169 }
170
171
172 # Update the RRD file
173 my $update_time = $classes_data{$class_device}{last_update};
174 # print "Updates: $filename time:$update_time\n";
175 # print " --template=$rrd_template\n";
176 # print " $update_time:$rrd_data\n";
177
178 # `rrdtool update $filename --template=$rrd_template $update_time:$rrd_data`;
179 RRDs::update ($filename, "--template=$rrd_template",
180 "N:$rrd_data");
181
182 my $ERROR = RRDs::error;
183 if ($ERROR) {
184 my $timestamp = time;
185 print "$timestamp: WARNING - ";
186 print "Unable to update RRDfile \"$filename\": $ERROR\n";
187 $res="Unable to update RRDfile \"$filename\"";
188 } else {
189 $classes_data{$class_device}{file_update} = time;
190 }
191 }
192 return $res;
193 }
194
195
196 return 1;
197