summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 04c92d7)
raw | patch | inline | side by side (parent: 04c92d7)
author | Matthias Bethke <matthias.bethke@financial.com> | |
Wed, 10 Sep 2014 17:34:50 +0000 (19:34 +0200) | ||
committer | Matthias Bethke <matthias.bethke@financial.com> | |
Wed, 10 Sep 2014 17:34:50 +0000 (19:34 +0200) |
Rationale:
A frequent use case for LISTVAL is to retrieve a list of resources for a certain
host or host group that is not known in advance, such as when the hosts have
different disks installed. Using the existing listval() method,
Collectd::Unixsock retrieves the entire list, parses each entry into a hash and
returns the list, only to have the caller throw away the vast majority of
entries immediately. listval_filter() allows the caller to pass any attribute
that can be passed to getval() and filters the list of resources retrieved from
the socket before parsing it, resulting in a large speedup.
The current implemntation has some code duplication, although listval() could be
implemented as a small wrapper around listval_filter() with just a few percent
speed penalty due to the extra dynamically built regexp.
A frequent use case for LISTVAL is to retrieve a list of resources for a certain
host or host group that is not known in advance, such as when the hosts have
different disks installed. Using the existing listval() method,
Collectd::Unixsock retrieves the entire list, parses each entry into a hash and
returns the list, only to have the caller throw away the vast majority of
entries immediately. listval_filter() allows the caller to pass any attribute
that can be passed to getval() and filters the list of resources retrieved from
the socket before parsing it, resulting in a large speedup.
The current implemntation has some code duplication, although listval() could be
implemented as a small wrapper around listval_filter() with just a few percent
speed penalty due to the extra dynamically built regexp.
bindings/perl/lib/Collectd/Unixsock.pm | patch | blob | history | |
bindings/perl/t/01_methods.t | patch | blob | history |
index f2e4fb0790c4e453ea325f4f4225637d4ac68600..5c6a5f9d24c74179b8c2e3a878619198398bdc73 100644 (file)
return;
} # putval
+=item I<$res> = I<$self>-E<gt>B<listval_filter> ( C<%identifier> )
+
+Queries a list of values from the daemon while restricting the results to
+certain hosts, plugins etc. The argument may be anything that passes for an
+identifier (cf. L<VALUE IDENTIFIERS>), although all fields are optional.
+The returned data is in the same format as from C<listval>.
+
+=cut
+
+sub listval_filter
+{
+ my $self = shift;
+ my %args = @_;
+ my @ret;
+ my $nresults;
+ my $fh = $self->{sock} or confess;
+
+ my $pattern =
+ (exists $args{host} ? "$args{host}" : '[^/]+') .
+ (exists $args{plugin} ? "/$args{plugin}" : '/[^/-]+') .
+ (exists $args{plugin_instance} ? "-$args{plugin_instance}" : '(?:-[^/]+)?') .
+ (exists $args{type} ? "/$args{type}" : '/[^/-]+') .
+ (exists $args{type_instance} ? "-$args{type_instance}" : '(?:-[^/]+)?');
+ $pattern = qr/^\d+ $pattern$/;
+
+ my $msg = $self->_socket_command('LISTVAL') or return;
+ ($nresults, $msg) = split / /, $msg, 2;
+
+ # This could use _socket_chat() but doesn't for speed reasons
+ if ($nresults < 0)
+ {
+ $self->{error} = $msg;
+ return;
+ }
+
+ for (1 .. $nresults)
+ {
+ $msg = <$fh>;
+ chomp $msg;
+ _debug "<- $msg\n";
+ next unless $msg =~ $pattern;
+ my ($time, $ident) = split / /, $msg, 2;
+
+ $ident = _parse_identifier ($ident);
+ $ident->{time} = int $time;
+
+ push (@ret, $ident);
+ } # for (i = 0 .. $status)
+
+ return @ret;
+} # listval
+
=item I<$res> = I<$self>-E<gt>B<listval> ()
Queries a list of values from the daemon. The list is returned as an array of
index 10289c706939427733330536e735dc9777e45ba6..2f7818b15799cb650e6d2288072286f4426ac583 100644 (file)
use strict;
use warnings;
-use Test::More tests => 12;
+use Test::More tests => 14;
use Collectd::Unixsock;
use Collectd::MockDaemon;
my $path = mockd_start();
END { mockd_stop(); }
+sub filter_time { return map { delete $_->{time}; $_ } @_ }
+
+sub test_query {
+ my ($s, $attr, $results) = @_;
+ my ($nresults, $resultdata) = @$results;
+ my $r = $s->getval(%{Collectd::Unixsock::_parse_identifier($attr)});
+ is(ref $r, 'HASH', "Got a result for $attr");
+ is(scalar keys $r, $nresults, "$nresults result result for $attr");
+ is_deeply($r, $resultdata, "Data or $attr matches");
+}
+
my $s = Collectd::Unixsock->new($path);
isnt($s, undef, "Collectd::Unixsock object created");
type => 'cpu',
host => 'h2gdf6120'
}, "Correct data returned for select element");
+@values = ();
+
+is_deeply([ filter_time $s->listval_filter() ] , [ filter_time $s->listval ], "listval_filter() w/o filter equivalent to listval()");
+is_deeply(
+ [ filter_time $s->listval_filter(host => 'a1d8f6310', plugin => 'disk', plugin_instance => 'vda6') ],
+ [
+ { 'plugin_instance' => 'vda6', 'type' => 'disk_merged', 'plugin' => 'disk', 'host' => 'a1d8f6310' },
+ { 'host' => 'a1d8f6310', 'plugin' => 'disk', 'plugin_instance' => 'vda6', 'type' => 'disk_octets' },
+ { 'type' => 'disk_ops', 'plugin_instance' => 'vda6', 'plugin' => 'disk', 'host' => 'a1d8f6310' },
+ { 'plugin' => 'disk', 'host' => 'a1d8f6310', 'type' => 'disk_time', 'plugin_instance' => 'vda6' }
+ ],
+ "Correct result from listval_filter on <host>, <plugin> and <plugin_instance>"
+);
# TODO more test for putval() and the like
-sub test_query {
- my ($s, $attr, $results) = @_;
- my ($nresults, $resultdata) = @$results;
- my $r = $s->getval(%{Collectd::Unixsock::_parse_identifier($attr)});
- is(ref $r, 'HASH', "Got a result for $attr");
- is(scalar keys $r, $nresults, "$nresults result result for $attr");
- is_deeply($r, $resultdata, "Data or $attr matches");
-}