X-Git-Url: https://git.octo.it/?p=collectd.git;a=blobdiff_plain;f=contrib%2Fcussh.pl;h=ae758d17b14e1600188f57386572a339c6e338f0;hp=6da2856d0d8b307387788da48aff2da58cf6353d;hb=de407dd4e036f73e9bd4658af9d71f504fc11109;hpb=d22aee658210cbfa44caa39f302aa9331d4eab82 diff --git a/contrib/cussh.pl b/contrib/cussh.pl index 6da2856d..ae758d17 100755 --- a/contrib/cussh.pl +++ b/contrib/cussh.pl @@ -1,7 +1,7 @@ #!/usr/bin/perl # # collectd - contrib/cussh.pl -# Copyright (C) 2007-2008 Sebastian Harl +# Copyright (C) 2007-2009 Sebastian Harl # # 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 @@ -57,10 +57,13 @@ use Collectd::Unixsock(); my $sock = Collectd::Unixsock->new($path); my $cmds = { + HELP => \&cmd_help, PUTVAL => \&putval, GETVAL => \&getval, + GETTHRESHOLD => \&getthreshold, FLUSH => \&flush, LISTVAL => \&listval, + PUTNOTIF => \&putnotif, }; if (! $sock) { @@ -108,13 +111,42 @@ use Collectd::Unixsock(); exit 0; } +sub tokenize { + my $line = shift || return; + my $line_ptr = $line; + my @line = (); + + my $token_pattern = qr/[^"\s]+|"[^"]+"/; + + while (my ($token) = $line_ptr =~ m/^($token_pattern)\s+/) { + $line_ptr = $'; + push @line, $token; + } + + if ($line_ptr =~ m/^$token_pattern$/) { + push @line, $line_ptr; + } + else { + my ($token) = split m/ /, $line_ptr, 1; + print STDERR "Failed to parse line: $line\n"; + print STDERR "Parse error near token \"$token\".\n"; + return; + } + + foreach my $l (@line) { + if ($l =~ m/^"(.*)"$/) { + $l = $1; + } + } + return @line; +} + sub getid { my $string = shift || return; - print $$string . $/; my ($h, $p, $pi, $t, $ti) = - $$string =~ m/^(\w+)\/(\w+)(?:-(\w+))?\/(\w+)(?:-(\w+))?\s*/; - $$string = $'; + $string =~ m#^([^/]+)/([^/-]+)(?:-([^/]+))?/([^/-]+)(?:-([^/]+))?\s*#; + $string = $'; return if ((! $h) || (! $p) || (! $t)); @@ -122,8 +154,8 @@ sub getid { ($id{'host'}, $id{'plugin'}, $id{'type'}) = ($h, $p, $t); - $id{'plugin_instance'} = $pi if ($pi); - $id{'type_instance'} = $ti if ($ti); + $id{'plugin_instance'} = $pi if defined ($pi); + $id{'type_instance'} = $ti if defined ($ti); return \%id; } @@ -150,7 +182,74 @@ sub putid { =over 4 -=item B I +=item B + +=cut + +sub cmd_help { + my $sock = shift; + my $line = shift || ''; + + my @line = tokenize($line); + my $cmd = shift (@line); + + my %text = ( + help => < < [ ...] + +Submits a value to the daemon. +HELP + getval => < + +Retrieves the current value or values from the daemon. +HELP + flush => <] [timeout=] [identifier=] [...] + +Sends a FLUSH command to the daemon. +HELP + listval => < < [...] message= + +Sends a notifications message to the daemon. +HELP + ); + + if (!$cmd) + { + $cmd = 'help'; + } + if (!exists ($text{$cmd})) + { + print STDOUT "Unknown command: " . uc ($cmd) . "\n\n"; + $cmd = 'help'; + } + + print STDOUT $text{$cmd}; + + return 1; +} # cmd_help + +=item B I I =cut @@ -158,18 +257,37 @@ sub putval { my $sock = shift || return; my $line = shift || return; - my $id = getid(\$line); + my @line = tokenize($line); + + my $id; + my $ret; + + if (! @line) { + return; + } + + if (scalar(@line) < 2) { + print STDERR "Synopsis: PUTVAL [ ...]" . $/; + return; + } + + $id = getid($line[0]); if (! $id) { - print STDERR $sock->{'error'} . $/; + print STDERR "Invalid id \"$line[0]\"." . $/; return; } my ($time, @values) = split m/:/, $line; - return $sock->putval(%$id, time => $time, values => \@values); + $ret = $sock->putval(%$id, time => $time, values => \@values); + + if (! $ret) { + print STDERR "socket error: " . $sock->{'error'} . $/; + } + return $ret; } -=item B I I +=item B I =cut @@ -177,17 +295,73 @@ sub getval { my $sock = shift || return; my $line = shift || return; - my $id = getid(\$line); + my @line = tokenize($line); + + my $id; + my $vals; + + if (! @line) { + return; + } + + if (scalar(@line) < 1) { + print STDERR "Synopsis: GETVAL " . $/; + return; + } + + $id = getid($line[0]); + + if (! $id) { + print STDERR "Invalid id \"$line[0]\"." . $/; + return; + } + + $vals = $sock->getval(%$id); + + if (! $vals) { + print STDERR "socket error: " . $sock->{'error'} . $/; + return; + } + + foreach my $key (keys %$vals) { + print "\t$key: $vals->{$key}\n"; + } + return 1; +} + +=item B I + +=cut + +sub getthreshold { + my $sock = shift || return; + my $line = shift || return; + + my @line = tokenize($line); + + my $id; + my $vals; + + if (! @line) { + return; + } + + if (scalar(@line) < 1) { + print STDERR "Synopsis: GETTHRESHOLD " . $/; + return; + } + + $id = getid($line[0]); if (! $id) { - print STDERR $sock->{'error'} . $/; + print STDERR "Invalid id \"$line[0]\"." . $/; return; } - my $vals = $sock->getval(%$id); + $vals = $sock->getthreshold(%$id); if (! $vals) { - print STDERR $sock->{'error'} . $/; + print STDERR "socket error: " . $sock->{'error'} . $/; return; } @@ -205,6 +379,8 @@ sub flush { my $sock = shift || return; my $line = shift; + my @line = tokenize($line); + my $res; if (! $line) { @@ -213,7 +389,7 @@ sub flush { else { my %args = (); - foreach my $i (split m/ /, $line) { + foreach my $i (@line) { my ($option, $value) = $i =~ m/^([^=]+)=(.+)$/; next if (! ($option && $value)); @@ -223,6 +399,15 @@ sub flush { elsif ($option eq "timeout") { $args{"timeout"} = $value; } + elsif ($option eq "identifier") { + my $id = getid ($value); + if (!$id) + { + print STDERR "Not a valid identifier: \"$value\"\n"; + next; + } + push @{$args{"identifier"}}, $id; + } else { print STDERR "Invalid option \"$option\".\n"; return; @@ -233,10 +418,9 @@ sub flush { } if (! $res) { - print STDERR $sock->{'error'} . $/; - return; + print STDERR "socket error: " . $sock->{'error'} . $/; } - return 1; + return $res; } =item B @@ -245,13 +429,19 @@ sub flush { sub listval { my $sock = shift || return; + my $line = shift; my @res; + if ($line ne "") { + print STDERR "Synopsis: LISTVAL" . $/; + return; + } + @res = $sock->listval(); if (! @res) { - print STDERR $sock->{'error'} . $/; + print STDERR "socket error: " . $sock->{'error'} . $/; return; } @@ -261,6 +451,39 @@ sub listval { return 1; } +=item B [[B=I<$severity>] [B=I<$message>] [ ...]] + +=cut + +sub putnotif { + my $sock = shift || return; + my $line = shift || return; + + my @line = tokenize($line); + + my $ret; + + my (%values) = (); + foreach my $i (@line) { + my ($key, $val) = split m/=/, $i, 2; + if ($key && $val) { + $values{$key} = $val; + } + else { + $values{'message'} = defined($values{'message'}) + ? ($values{'message'} . ' ' . $key) + : $key; + } + } + $values{'time'} ||= time(); + + $ret = $sock->putnotif(%values); + if (! $ret) { + print STDERR "socket error: " . $sock->{'error'} . $/; + } + return $ret; +} + =back These commands follow the exact same syntax as described in