Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 9e895cf1cf
Fetching contributors…

Cannot retrieve contributors at this time

executable file 388 lines (336 sloc) 11.739 kb
#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long ('GetOptions');
use Data::Dumper ();
use File::Basename ('dirname');
our $InDir = '/var/lib/collectd';
our $OutDir = '/tmp/collectd-4';
our $Hostname = 'localhost';
# Types:
# +------------+----------------------+----+----+----+
# ! Subdir ! Type ! ti ! pi ! ex !
# +------------+----------------------+----+----+----+
# ! apache ! apache_bytes ! ! ! !
# ! apache ! apache_requests ! ! ! !
# ! apache ! apache_scoreboard ! x ! ! !
# ! battery ! charge ! ! x ! !
# ! apcups ! charge_percent ! ! ! !
# ! ! cpu ! x ! ! x !
# ! ! cpufreq ! x ! ! !
# ! battery ! current ! ! x ! !
# ! ntpd ! delay ! x ! ! !
# ! ! df ! x ! ! !
# ! ! disk ! x ! ! !
# ! dns ! dns_traffic ! ! ! !
# ! apple_se.. ! fanspeed ! x ! ! !
# ! mbmon ! fanspeed ! x ! ! !
# ! apcups ! frequency ! x ! ! !
# ! ntpd ! frequency_offset ! x ! ! !
# ! ! hddtemp ! x ! ! !
# ! interface ! if_errors ! ! x ! !
# ! interface ! if_packets ! ! x ! !
# ! ! lm_sensors ! ! ! !
# ! ! load ! ! ! !
# ! apcups ! load_percent ! ! ! !
# ! ! memory ! ! ! !
# ! ! multimeter ! ! ! !
# ! mysql ! mysql_commands ! x ! ! !
# ! mysql ! mysql_handler ! x ! ! !
# ! mysql ! mysql_qcache ! ! ! !
# ! mysql ! mysql_threads ! ! ! !
# ! ! nfs2_procedures ! x ! ! x !
# ! ! nfs3_procedures ! x ! ! x !
# ! dns ! opcode ! x ! ! !
# ! ! partition ! x ! ! !
# ! ! ping ! x ! ! !
# ! ! processes ! ! ! !
# ! processes ! ps_count ! x ! ! !
# ! processes ! ps_cputime ! x ! ! !
# ! processes ! ps_pagefaults ! x ! ! !
# ! processes ! ps_rss ! x ! ! !
# ! dns ! qtype ! x ! ! !
# ! dns ! rcode ! x ! ! !
# ! (*) ! sensors ! x ! ! !
# ! ! serial ! x ! ! !
# ! ! swap ! ! ! !
# ! ! tape ! x ! ! !
# ! apple_se.. ! temperature ! x ! ! !
# ! mbmon ! temperature ! x ! ! !
# ! ntpd ! time_dispersion ! x ! ! !
# ! ntpd ! time_offset ! x ! ! !
# ! apcups ! timeleft ! ! ! !
# ! ! traffic ! x ! ! ! ->rx,tx
# ! vserver ! traffic ! x ! x ! ! ->rx.tx
# ! ! users ! ! ! !
# ! apucups ! voltage ! x ! ! !
# ! battery ! voltage ! ! x ! !
# ! mbmon ! voltage ! x ! ! !
# ! vserver ! vs_memory ! ! x ! !
# ! vserver ! vs_processes ! ! x ! !
# ! vserver ! vs_threads ! ! x ! !
# ! ! wireless ! x ! ! !
# +------------+----------------------+----+----+----+
our %Subdirs =
(
apache => 0,
apcups => 0,
apple_sensors => 0,
battery => 1,
dns => 0,
interface => 1,
mbmon => 0,
mysql => 0,
ntpd => 0,
processes => 0,
sensors => 1,
vserver => 1
);
our %TypeTranslate =
(
cpu => sub { $_ = shift; $_->{'plugin_instance'} = $_->{'type_instance'}; $_->{'type_instance'} = undef; $_; },
hddtemp => sub { $_ = shift; $_->{'plugin'} = 'hddtemp'; $_->{'type'} = 'temperature'; $_->{'type_instance'} = $_->{'type_instance'}; $_; },
if_errors => sub { $_ = shift; $_->{'type_instance'} = $_->{'plugin_instance'}; $_->{'plugin_instance'} = undef; $_; },
if_packets => sub { $_ = shift; $_->{'type_instance'} = $_->{'plugin_instance'}; $_->{'plugin_instance'} = undef; $_; },
nfs2_procedures => sub { $_ = shift; @$_{qw(plugin plugin_instance type type_instance)} = ('nfs', 'v2' . $_->{'type_instance'}, 'nfs_procedure', undef); $_; },
nfs3_procedures => sub { $_ = shift; @$_{qw(plugin plugin_instance type type_instance)} = ('nfs', 'v3' . $_->{'type_instance'}, 'nfs_procedure', undef); $_; },
partition => sub { $_ = shift; $_->{'plugin'} = 'disk'; $_; },
processes => sub { $_ = shift; $_->{'type'} = 'ps_state'; $_; },
traffic => sub { $_ = shift; $_->{'plugin'} =~ s/^traffic$/interface/; @$_{qw(plugin_instance type)} = (undef, 'if_octets'); $_; }
);
our %TypeSplit =
(
cpu => { from => [qw(user nice syst idle wait)], to => 'value', type_instance => [qw(user nice system idle wait)] },
memory => { from => [qw(used free buffers cached)], to => 'value', type_instance => [qw(used free buffered cached)] },
nfs3_procedures => { from => [qw(null getattr lookup access readlink
read write create mkdir symlink mknod remove rmdir rename link
readdir readdirplus fsstat fsinfo pathconf commit)], to => 'value' },
nfs2_procedures => { from => [qw(create fsstat getattr link lookup
mkdir null read readdir readlink remove rename rmdir root
setattr symlink wrcache write)], to => 'value' },
processes => { from => [qw(running sleeping zombies stopped paging blocked)], to => 'value' },
swap => { from => [qw(cached free used resv)], to => 'value', type_instance => [qw(cached free used reserved)] }
);
our %TypeRename =
(
traffic => { from => [qw(incoming outgoing)], to => [qw(rx tx)] },
vs_processes => { from => [qw(total)], to => [qw(value)] },
);
GetOptions ("indir|i=s" => \$InDir,
"outdir|o=s" => \$OutDir,
"hostname=s" => \$Hostname) or exit_usage ();
die "No such directory: $InDir" if (!-d $InDir);
our @Files = ();
our %OutDirs = ();
@Files = find_files ();
for (@Files)
{
my $orig_filename = $_;
my $orig = parse_file ($orig_filename);
my $dest = translate_file ($orig);
my $dest_filename = get_filename ($dest);
my $dest_directory = dirname ($dest_filename);
if (!exists ($OutDirs{$dest_directory}))
{
print "[ -d '$OutDir/$dest_directory' ] || mkdir -p '$OutDir/$dest_directory'\n";
$OutDirs{$dest_directory} = 1;
}
if (($orig->{'type'} eq 'disk') || ($orig->{'type'} eq 'partition'))
{
special_disk ($orig_filename, $orig, $dest_filename, $dest);
}
elsif (exists ($TypeSplit{$orig->{'type'}}))
{
my $src_dses = $TypeSplit{$orig->{'type'}}->{'from'};
my $dst_ds = $TypeSplit{$orig->{'type'}}->{'to'};
my $type_instances = exists ($TypeSplit{$orig->{'type'}}->{'type_instance'})
? $TypeSplit{$orig->{'type'}}->{'type_instance'}
: $TypeSplit{$orig->{'type'}}->{'from'};
for (my $i = 0; $i < @$src_dses; $i++)
{
my $src_ds = $src_dses->[$i];
$dest->{'type_instance'} = $type_instances->[$i];
$dest_filename = get_filename ($dest);
print "./rrd_filter.px -i '$InDir/$orig_filename' -m '${src_ds}:${dst_ds}' -o '$OutDir/$dest_filename'\n";
}
}
else
{
print "cp '$InDir/$orig_filename' '$OutDir/$dest_filename'\n";
}
if (exists ($TypeRename{$orig->{'type'}}))
{
my $src_dses = $TypeRename{$orig->{'type'}}->{'from'};
my $dst_dses = $TypeRename{$orig->{'type'}}->{'to'};
print "rrdtool tune '$OutDir/$dest_filename'";
for (my $i = 0; $i < @$src_dses; $i++)
{
print " --data-source-rename "
. $src_dses->[$i] . ':' . $dst_dses->[$i];
}
print "\n";
}
}
exit (0);
sub translate_file
{
my $orig = shift;
my $dest = {};
%$dest = %$orig;
if (defined ($TypeTranslate{$orig->{'type'}}))
{
$TypeTranslate{$orig->{'type'}}->($dest);
}
return ($dest);
} # translate_file
sub get_filename
{
my $args = shift;
my $filename = $args->{'host'}
. '/' . $args->{'plugin'} . (defined ($args->{'plugin_instance'}) ? '-'.$args->{'plugin_instance'} : '')
. '/' . $args->{'type'} . (defined ($args->{'type_instance'}) ? '-'.$args->{'type_instance'} : '') . '.rrd';
return ($filename);
}
sub parse_file
{
my $fullname = shift;
my @parts = split ('/', $fullname);
my $filename;
my $host;
my $plugin;
my $plugin_instance;
my $type;
my $type_instance;
$filename = pop (@parts);
if ($filename =~ m/^([^-]+)(?:-(.*))?\.rrd$/)
{
$type = $1;
$type_instance = $2;
}
else
{
return;
}
if (@parts)
{
my $dirname = pop (@parts);
my $regex_str = join ('|', keys (%Subdirs));
if ($dirname =~ m/^($regex_str)(?:-(.*))?$/)
{
$plugin = $1;
$plugin_instance = $2;
}
else
{
push (@parts, $dirname);
}
}
if (!$plugin)
{
$plugin = $type;
}
if (@parts)
{
$host = pop (@parts);
}
else
{
$host = $Hostname;
}
return
({
host => $host,
plugin => $plugin,
plugin_instance => $plugin_instance,
type => $type,
type_instance => $type_instance
});
} # parse_file
sub find_files
{
my $reldir = @_ ? shift : '';
my $absdir = $InDir . ($reldir ? "/$reldir" : '');
my $dh;
my @files = ();
my @dirs = ();
opendir ($dh, $absdir) or die ("opendir ($absdir): $!");
while (my $file = readdir ($dh))
{
next if ($file =~ m/^\./);
next if (-l "$absdir/$file");
if (-d "$absdir/$file")
{
push (@dirs, ($reldir ? "$reldir/" : '') . $file);
}
elsif ($file =~ m/\.rrd$/)
{
push (@files, ($reldir ? "$reldir/" : '') . $file);
}
}
closedir ($dh);
for (my $i = 0; $i < @dirs; $i++)
{
push (@files, find_files ($dirs[$i]));
}
return (@files);
} # find_files
{my $cache;
sub _special_disk_instance
{
my $orig_instance = shift;
if (!defined ($cache))
{
my $fh;
open ($fh, "< /proc/diskstats") or die ("open (/proc/diststats): $!");
$cache = {};
while (my $line = <$fh>)
{
chomp ($line);
my @fields = split (' ', $line);
$cache->{$fields[0] . '-' . $fields[1]} = $fields[2];
}
close ($fh);
}
return (defined ($cache->{$orig_instance})
? $cache->{$orig_instance}
: $orig_instance);
}}
sub special_disk
{
my $orig_filename = shift;
my $orig = shift;
my $dest_filename = shift;
my $dest = shift;
my $dest_directory;
$dest->{'type_instance'} = undef;
$dest->{'plugin_instance'} = _special_disk_instance ($orig->{'type_instance'});
if ($dest->{'plugin_instance'} eq $orig->{'type_instance'})
{
print qq(echo "You may need to rename these files" >&2\n);
}
$dest->{'type'} = 'disk_merged';
$dest_filename = get_filename ($dest);
$dest_directory = dirname ($dest_filename);
if (!exists ($OutDirs{$dest_directory}))
{
print "[ -d '$OutDir/$dest_directory' ] || mkdir -p '$OutDir/$dest_directory'\n";
$OutDirs{$dest_directory} = 1;
}
print "./rrd_filter.px -i '$InDir/$orig_filename' -m 'rmerged:read' -m 'wmerged:write' -o '$OutDir/$dest_filename'\n";
$dest->{'type'} = 'disk_octets';
$dest_filename = get_filename ($dest);
print "./rrd_filter.px -i '$InDir/$orig_filename' -m 'rbytes:read' -m 'wbytes:write' -o '$OutDir/$dest_filename'\n";
$dest->{'type'} = 'disk_ops';
$dest_filename = get_filename ($dest);
print "./rrd_filter.px -i '$InDir/$orig_filename' -m 'rcount:read' -m 'wcount:write' -o '$OutDir/$dest_filename'\n";
$dest->{'type'} = 'disk_time';
$dest_filename = get_filename ($dest);
print "./rrd_filter.px -i '$InDir/$orig_filename' -m 'rtime:read' -m 'wtime:write' -o '$OutDir/$dest_filename'\n";
}
sub exit_usage
{
print <<EOF;
Usage: $0 [-i indir] [-o outdir] [--hostname myhostname]
EOF
exit (1);
}
Jump to Line
Something went wrong with that request. Please try again.