[rrd-users] Re: Can you add more DS "Data Sources" to an already existing rrd database?
Jeff Rodriguez
jeff at unixisgod.com
Thu Dec 4 16:26:01 MET 2003
The script is a litte rough around the edges but the basic idea is:
rrdtool dump blah.rrd > blah.xml
./scriptname.pl blah.xml > blah2.xml
(asks you for some input)
rrdtool import blah2.xml blah2.rrd
#!/usr/bin/perl
# Copyright (C) 2003 Jeff Rodriguez
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
use warnings;
use strict;
# Get a file from the commandline if it applies
my $file = shift || undef;
# Predefine some variables
my $new_ds_def = undef;
my @current_ds_list = ();
my $new_ds_number = undef;
my %new_ds_values = ();
my $parsing_cdp_prep = 0;
my @cdp_prep_values = ();
my $parsing_ds = 0;
my $parsing_ds_num = 0;
my @ds_values = ();
# Define the $xml_input file handle reference
my $xml_input = undef;
if ( defined $file && -e $file )
{
open($xml_input,$file) or die "Could not open $file\n";
}
else
{
$xml_input = \*STDIN;
print STDERR "Paste your XML file here. ^D (unix) or ^Z (win32) to
end\n";
}
while ( my $xml_line = <$xml_input> )
{
print STDERR "Copyright (C) 2003 Jeff Rodriguez\n";
# Remove newlines
chomp $xml_line;
chop $xml_line if substr($xml_line, -1) eq "\r";
if ( $xml_line =~ /^\s+<ds>$/ )
{
$parsing_ds = 1;
}
if ( $parsing_ds == 1 )
{
$ds_values[$parsing_ds_num] .= "$xml_line\n";
}
if ( $xml_line =~ /^\s+<\/ds>$/ )
{
$parsing_ds = 0;
$parsing_ds_num++;
$ds_values[$parsing_ds_num] .= "$xml_line\n";
next;
}
# See if this is the name of a DS
$xml_line =~ /\s+<name> (.+?) <\/name>/;
if ( defined $1 )
{
if ( $#current_ds_list == -1 )
{
push(@current_ds_list, $1);
}
else
{
push(@current_ds_list, $1) if $1 ne $current_ds_list[-1];
}
}
# See if we're at the end of the DS definition list
if ( $xml_line =~ /Round Robin Archives/ )
{
# Well, we are ask where they want the DS
print STDERR "You currently have " . ($#current_ds_list + 1) . "
Data Source(s).\n";
print STDERR "Where do you want the new DS?\n";
print STDERR "1. Before '$current_ds_list[0]'.\n";
# List each DS
for (my $i = 2; $i <= ( $#current_ds_list + 2 ); $i++)
{
print STDERR "$i. After '$current_ds_list[$i - 2]'.\n";
}
# Get their choice from the command line
print STDERR "? ";
while ( !defined $new_ds_number )
{
my $number = <STDIN>;
chomp $number;
$number =~ /(\d+)/;
if ( defined $1 && $1 <= ( $#current_ds_list + 2 ) && $1 > 0 )
{
$new_ds_number = $1;
if ( $1 == 1 )
{
print STDERR "Your new Data Source will be before
'$current_ds_list[0]'.\n";
}
else
{
print STDERR "Your new Data Source will be after
'$current_ds_list[$1 - 2]'.\n";
}
}
else
{
print STDERR "Invalid entry. Enter a valid choice: ";
next;
}
}
# Get the new DS values
while ( keys %new_ds_values != 5 )
{
print STDERR "Enter the Data Source Definition for your new
DS\n";
print STDERR "DS:";
my $new_ds_definition = <STDIN>;
chomp $new_ds_definition;
$new_ds_definition =~
/^([a-zA-Z0-9_]{1,19}):(GAUGE|COUNTER|DERIVE|ABSOLUTE):(\d+?):(U|\d+?):(U|\d
+?)$/;
if ( defined $1 && defined $2 && defined $3 && defined $4 &&
defined $5 )
{
if ( grep(/^$1$/, @current_ds_list) )
{
print STDERR "The data source '$1' already exists!\n";
}
else
{
$new_ds_values{name} = $1;
$new_ds_values{type} = $2;
$new_ds_values{heartbeat} = $3;
if ( $4 eq "U" )
{
$new_ds_values{min} = "NaN";
}
else
{
$new_ds_values{min} = $4;
}
if ( $5 eq "U" )
{
$new_ds_values{max} = "NaN";
}
else
{
$new_ds_values{max} = $5;
}
}
}
else
{
next;
}
}
# Inject the new Data Source
splice(@ds_values, ($new_ds_number - 1), 0, <<EndDataSource
<ds>
<name> $new_ds_values{name} </name>
<type> $new_ds_values{type} </type>
<minimal_heartbeat> $new_ds_values{heartbeat}
</minimal_heartbeat>
<min> $new_ds_values{min} </min>
<max> $new_ds_values{max} </max>
<!-- PDP Status -->
<last_ds> UNKN </last_ds>
<value> 0.0000000000e+00 </value>
<unknown_sec> 0 </unknown_sec>
</ds>
EndDataSource
);
foreach my $ds_value (@ds_values)
{
print "$ds_value\n";
}
}
# If the new_ds_number is defined, we've finished parsing the data
sources and it's time to start adding
if ( defined $new_ds_number )
{
if ( $xml_line =~ /<\/cdp_prep>/ )
{
$parsing_cdp_prep = 0;
splice(@cdp_prep_values, ($new_ds_number - 1), 0, "
<ds><value> NaN </value> <unknown_datapoints> 0
</unknown_datapoints></ds>");
foreach my $cdp_prep_value (@cdp_prep_values)
{
print "$cdp_prep_value\n";
}
@cdp_prep_values = ();
}
# Test to see if we're parsig a cdp_prep
if ( $parsing_cdp_prep == 1 )
{
push(@cdp_prep_values, $xml_line);
}
# Test to see if this line is a <cdp_prep> line
if ( $xml_line =~ /<cdp_prep>/ )
{
$parsing_cdp_prep = 1;
print "$xml_line\n";
}
# This checks to see if xml_line is a database entry
if ( $xml_line =~ /^(.+?<row>)(.+?)(<\/row>.*)$/ )
{
my @datasources_in_entry = split(/<\/v>/, $2);
splice(@datasources_in_entry, ($new_ds_number - 1), 0, "<v> 0
");
my $new_line = join("</v>", @datasources_in_entry);
print "$1$new_line</v>$3\n";
}
else
{
print "$xml_line\n" unless $parsing_cdp_prep == 1;
}
}
else
{
print "$xml_line\n" unless $parsing_ds == 1;
}
}
--
Unsubscribe mailto:rrd-users-request at list.ee.ethz.ch?subject=unsubscribe
Help mailto:rrd-users-request at list.ee.ethz.ch?subject=help
Archive http://www.ee.ethz.ch/~slist/rrd-users
WebAdmin http://www.ee.ethz.ch/~slist/lsg2.cgi
More information about the rrd-users
mailing list