3 # collectd - contrib/cussh.pl
4 # Copyright (C) 2007-2008 Sebastian Harl
6 # This program is free software; you can redistribute it and/or modify it
7 # under the terms of the GNU General Public License as published by the
8 # Free Software Foundation; only version 2 of the License is applicable.
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # General Public License for more details.
15 # You should have received a copy of the GNU General Public License along
16 # with this program; if not, write to the Free Software Foundation, Inc.,
17 # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 # Sebastian Harl <sh at tokkee.org>
25 cussh - collectd UNIX socket shell
29 B<cussh> [I<E<lt>pathE<gt>>]
33 B<collectd>'s unixsock plugin allows external programs to access the values it
34 has collected or received and to submit own values. This is a little
35 interactive frontend for this plugin.
41 =item I<E<lt>pathE<gt>>
43 The path to the UNIX socket provided by collectd's unixsock plugin. (Default:
44 F</var/run/collectd-unixsock>)
53 use Collectd::Unixsock();
56 my $path = $ARGV[0] || "/var/run/collectd-unixsock";
57 my $sock = Collectd::Unixsock->new($path);
65 PUTNOTIF => \&putnotif,
69 print STDERR "Unable to connect to $path!\n";
73 print "cussh version 0.2, Copyright (C) 2007-2008 Sebastian Harl\n"
74 . "cussh comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
75 . "and you are welcome to redistribute it under certain conditions.\n"
76 . "See the GNU General Public License 2 for more details.\n\n";
86 last if ($line =~ m/^quit$/i);
88 my ($cmd) = $line =~ m/^(\w+)\s*/;
95 if (defined $cmds->{$cmd}) {
99 print STDERR "ERROR: Unknown command $cmd!\n";
103 if (! $f->($sock, $line)) {
104 print STDERR "ERROR: Command failed!\n";
114 my $line = shift || return;
115 my $line_ptr = $line;
118 my $token_pattern = qr/[^"\s]+|"[^"]+"/;
120 while (my ($token) = $line_ptr =~ m/^($token_pattern)\s+/) {
125 if ($line_ptr =~ m/^$token_pattern$/) {
126 push @line, $line_ptr;
129 my ($token) = split m/ /, $line_ptr, 1;
130 print STDERR "Failed to parse line: $line\n";
131 print STDERR "Parse error near token \"$token\".\n";
135 foreach my $l (@line) {
136 if ($l =~ m/^"(.*)"$/) {
144 my $string = shift || return;
146 my ($h, $p, $pi, $t, $ti) =
147 $string =~ m#^([^/]+)/([^/-]+)(?:-([^/]+))?/([^/-]+)(?:-([^/]+))?\s*#;
150 return if ((! $h) || (! $p) || (! $t));
154 ($id{'host'}, $id{'plugin'}, $id{'type'}) = ($h, $p, $t);
156 $id{'plugin_instance'} = $pi if defined ($pi);
157 $id{'type_instance'} = $ti if defined ($ti);
162 my $ident = shift || return;
166 $string = $ident->{'host'} . "/" . $ident->{'plugin'};
168 if (defined $ident->{'plugin_instance'}) {
169 $string .= "-" . $ident->{'plugin_instance'};
172 $string .= "/" . $ident->{'type'};
174 if (defined $ident->{'type_instance'}) {
175 $string .= "-" . $ident->{'type_instance'};
198 See the embedded Perldoc documentation for details. To do that, run:
204 =item B<PUTVAL> I<Identifier> I<Valuelist>
209 my $sock = shift || return;
210 my $line = shift || return;
212 my @line = tokenize($line);
221 if (scalar(@line) < 2) {
222 print STDERR "Synopsis: PUTVAL <id> <value0> [<value1> ...]" . $/;
226 $id = getid($line[0]);
229 print STDERR "Invalid id \"$line[0]\"." . $/;
233 my ($time, @values) = split m/:/, $line;
234 $ret = $sock->putval(%$id, time => $time, values => \@values);
237 print STDERR "socket error: " . $sock->{'error'} . $/;
242 =item B<GETVAL> I<Identifier>
247 my $sock = shift || return;
248 my $line = shift || return;
250 my @line = tokenize($line);
259 if (scalar(@line) < 1) {
260 print STDERR "Synopsis: GETVAL <id>" . $/;
264 $id = getid($line[0]);
267 print STDERR "Invalid id \"$line[0]\"." . $/;
271 $vals = $sock->getval(%$id);
274 print STDERR "socket error: " . $sock->{'error'} . $/;
278 foreach my $key (keys %$vals) {
279 print "\t$key: $vals->{$key}\n";
284 =item B<FLUSH> [B<timeout>=I<$timeout>] [B<plugin>=I<$plugin>[ ...]]
289 my $sock = shift || return;
292 my @line = tokenize($line);
297 $res = $sock->flush();
302 foreach my $i (@line) {
303 my ($option, $value) = $i =~ m/^([^=]+)=(.+)$/;
304 next if (! ($option && $value));
306 if ($option eq "plugin") {
307 push @{$args{"plugins"}}, $value;
309 elsif ($option eq "timeout") {
310 $args{"timeout"} = $value;
312 elsif ($option eq "identifier") {
313 my $id = getid (\$value);
316 print STDERR "Not a valid identifier: \"$value\"\n";
319 push @{$args{"identifier"}}, $id;
322 print STDERR "Invalid option \"$option\".\n";
327 $res = $sock->flush(%args);
331 print STDERR "socket error: " . $sock->{'error'} . $/;
341 my $sock = shift || return;
347 print STDERR "Synopsis: LISTVAL" . $/;
351 @res = $sock->listval();
354 print STDERR "socket error: " . $sock->{'error'} . $/;
358 foreach my $ident (@res) {
359 print $ident->{'time'} . " " . putid($ident) . $/;
364 =item B<PUTNOTIF> [[B<severity>=I<$severity>] [B<message>=I<$message>] [ ...]]
369 my $sock = shift || return;
370 my $line = shift || return;
372 my @line = tokenize($line);
377 foreach my $i (@line) {
378 my ($key, $val) = split m/=/, $i, 2;
380 $values{$key} = $val;
383 $values{'message'} = defined($values{'message'})
384 ? ($values{'message'} . ' ' . $key)
388 $values{'time'} ||= time();
390 $ret = $sock->putnotif(%values);
392 print STDERR "socket error: " . $sock->{'error'} . $/;
399 These commands follow the exact same syntax as described in
400 L<collectd-unixsock(5)>.
404 L<collectd(1)>, L<collectd-unisock(5)>
408 Written by Sebastian Harl E<lt>sh@tokkee.orgE<gt>.
410 B<collectd> has been written by Florian Forster and others.
414 Copyright (C) 2007 Sebastian Harl.
416 This program is free software; you can redistribute it and/or modify it under
417 the terms of the GNU General Public License as published by the Free Software
418 Foundation; only version 2 of the License is applicable.
422 # vim: set sw=4 ts=4 tw=78 noexpandtab :