From efa35a5b4de58bfea91baca729c10f026a1724af Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Thu, 13 Mar 2008 12:33:50 +0100 Subject: [PATCH] contrib/rrd_filter.px: Added a scale and shift filter. --- contrib/rrd_filter.px | 201 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 179 insertions(+), 22 deletions(-) diff --git a/contrib/rrd_filter.px b/contrib/rrd_filter.px index a212de5a..6a827831 100755 --- a/contrib/rrd_filter.px +++ b/contrib/rrd_filter.px @@ -48,6 +48,11 @@ our $NewRRAs = []; our $Step = 0; +our $Scale = 1.0; +our $Shift = 0.0; + +our $Debug = 0; + =head1 OPTIONS The following options can be passed on the command line: @@ -100,6 +105,15 @@ Inserts a new RRA in the generated RRD file. This is done B the step has been adjusted, take that into account when specifying I and I. For an explanation of the format please see L. +=item B<--scale> I + +Scales the values by the factor I, i.Ee. all values are +multiplied by I. + +=item B<--shift> I + +Shifts all values by I, i.Ee. I is added to all values. + =back =cut @@ -127,7 +141,9 @@ GetOptions ("infile|i=s" => \$InFile, exit (1); } push (@$NewRRAs, {cf => $cf, xff => $xff, steps => $steps, rows => $rows}); - } + }, + 'scale=f' => \$Scale, + 'shift=f' => \$Shift ) or exit (1); if (!$InFile || !$OutFile) @@ -174,6 +190,7 @@ sub handle_line_dsmap $ds_index = []; for (my $i = 0; $i < @$InDS; $i++) { + print STDOUT "DS map $i: $InDS->[$i] -> $OutDS->[$i]\n" if ($Debug); $ds_index->[$i] = -1; } } @@ -203,6 +220,14 @@ sub handle_line_dsmap $out_cache->[$current_index] .= $line; } + elsif ($line =~ m#\s*([^\s>]+)\s*#i) + { + $out_cache->[$current_index] .= "\t\t NaN \n"; + } + elsif ($line =~ m#\s*([^\s>]+)\s*#i) + { + $out_cache->[$current_index] .= "\t\t NaN \n"; + } elsif ($line =~ m##) { $out_cache->[$current_index] .= $line; @@ -247,6 +272,10 @@ sub handle_line_dsmap $current_index++; $out_cache->[$current_index] .= $line; } + elsif ($line =~ m#\s*([^\s>]+)\s*#i) + { + $out_cache->[$current_index] .= "\t\t\t NaN \n"; + } elsif ($line =~ m##) { # Print out all the DS definitions we need @@ -349,6 +378,11 @@ sub handle_line_step return; } + if ($Debug && !defined ($step_factor_up)) + { + print STDOUT "New step: $Step\n"; + } + $step_factor_up ||= 0; $step_factor_down ||= 0; @@ -441,6 +475,12 @@ sub handle_line_add_rra { my $rra = $NewRRAs->[$i]; my $temp; + + if ($Debug) + { + print STDOUT "Adding RRA: CF = $rra->{'cf'}, xff = $rra->{'xff'}, steps = $rra->{'steps'}, rows = $rra->{'rows'}, num_ds = $num_ds\n"; + } + $post->("\t\n", "\t\t $rra->{'cf'} \n", "\t\t $rra->{'steps'} \n", @@ -465,16 +505,53 @@ sub handle_line_add_rra { $post->($temp); } - $post->("\t\t\n"); + $post->("\t\t\n", "\t\n"); } + + $add_rra_done = 1; } $post->($line); }} # handle_line_add_rra # +# The _scale/shift_ handler +# +sub calculate_scale_shift +{ + my $value = shift; + my $tag = shift; + my $scale = shift; + my $shift = shift; + + if (lc ("$value") eq 'nan') + { + $value = 'NaN'; + return ("<$tag> NaN "); + } + + $value = ($scale * (0.0 + $value)) + $shift; + return (sprintf ("<%s> %1.10e ", $tag, $value, $tag)); +} + +sub handle_line_scale_shift +{ + my $line = shift; + my $index = shift; + + if (($Scale != 1.0) || ($Shift != 0.0)) + { + $line =~ s#<(min|max|last_ds|value|primary_value|secondary_value|v)>\s*([^\s<]+)\s*]+>#calculate_scale_shift ($2, $1, $Scale, $Shift)#eg; + } + + post_line ($line, $index + 1); +} + +# # The _output_ handler # +# This filter is unfinished! +# { my $fh; sub set_output @@ -482,6 +559,79 @@ sub set_output $fh = shift; } +{ +my $previous_values; +my $previous_differences; +my $pdp_per_row; +sub handle_line_peak_detect +{ + my $line = shift; + my $index = shift; + + if (!$previous_values) + { + $previous_values = []; + $previous_differences = []; + } + + if ($line =~ m##i) + { + $previous_values = []; + $previous_differences = []; + print STDERR "==============================================================================\n"; + } + elsif ($line =~ m#\s*([1-9][0-9]*)\s*#) + { + $pdp_per_row = int ($1); + print STDERR "pdp_per_row = $pdp_per_row;\n"; + } + elsif ($line =~ m##) + { + my @values = (); + while ($line =~ m#\s*([^\s>]+)\s*#ig) + { + if ($1 eq 'NaN') + { + push (@values, undef); + } + else + { + push (@values, 0.0 + $1); + } + } + + for (my $i = 0; $i < @values; $i++) + { + if (!defined ($values[$i])) + { + $previous_values->[$i] = undef; + } + elsif (!defined ($previous_values->[$i])) + { + $previous_values->[$i] = $values[$i]; + } + elsif (!defined ($previous_differences->[$i])) + { + $previous_differences->[$i] = abs ($previous_values->[$i] - $values[$i]); + } + else + { + my $divisor = ($previous_differences->[$i] < 1.0) ? 1.0 : $previous_differences->[$i]; + my $difference = abs ($previous_values->[$i] - $values[$i]); + my $change = $pdp_per_row * $difference / $divisor; + if (($divisor > 10.0) && ($change > 10e5)) + { + print STDERR "i = $i; average difference = " . $previous_differences->[$i]. "; current difference = " . $difference. "; change = $change;\n"; + } + $previous_values->[$i] = $values[$i]; + $previous_differences->[$i] = (0.95 * $previous_differences->[$i]) + (0.05 * $difference); + } + } + } + + post_line ($line, $index + 1); +}} # handle_line_peak_detect + sub handle_line_output { my $line = shift; @@ -530,32 +680,39 @@ sub post_line sub handle_fh { - my $in_fh = shift; - my $out_fh = shift; + my $in_fh = shift; + my $out_fh = shift; - set_output ($out_fh); + set_output ($out_fh); - if (@$InDS) - { - add_handler (\&handle_line_dsmap); - } + if (@$InDS) + { + add_handler (\&handle_line_dsmap); + } - if ($Step) - { - add_handler (\&handle_line_step); - } + if ($Step) + { + add_handler (\&handle_line_step); + } - if (@$NewRRAs) - { - add_handler (\&handle_line_add_rra); - } + if (($Scale != 1.0) || ($Shift != 0.0)) + { + add_handler (\&handle_line_scale_shift); + } - add_handler (\&handle_line_output); + #add_handler (\&handle_line_peak_detect); - while (my $line = <$in_fh>) - { - post_line ($line, 0); - } + if (@$NewRRAs) + { + add_handler (\&handle_line_add_rra); + } + + add_handler (\&handle_line_output); + + while (my $line = <$in_fh>) + { + post_line ($line, 0); + } } # handle_fh sub main -- 2.11.0