}
sub listval {
- my $now = time;
+ my @timevals = (
+ 1479835353.75,
+ 1479835354.434,
+ 1479835356,
+ 1479835354,
+ 1479835354,
+ 1479835350.820,
+ 1479835351,
+ 1479835354.2,
+ 1479835353,
+ );
+ my $i = 0;
return print_nvalues(scalar @metrics) .
- join('', map { "$now $_\n" } @metrics);
+ join('', map { $timevals[$i++ % @timevals] . " $_\n" } @metrics);
}
sub getval {
sub _escape_argument
{
- my $arg = shift;
+ my $arg = shift;
return $arg if $arg =~ /^\w+$/;
my $fh = $self->{sock} or confess ('object has no filehandle');
- if($args) {
- my $identifier = _create_identifier ($args) or return;
- $command .= ' ' . _escape_argument ($identifier) . "\n";
- } else {
- $command .= "\n";
- }
+ if($args) {
+ my $identifier = _create_identifier ($args) or return;
+ $command .= ' ' . _escape_argument ($identifier) . "\n";
+ } else {
+ $command .= "\n";
+ }
_debug "-> $command";
$fh->print($command);
my $response = $fh->getline;
chomp $response;
_debug "<- $response\n";
- return $response;
+ return $response;
}
# Read any remaining results from a socket and pass them to
my $entry = $fh->getline;
chomp $entry;
_debug "<- $entry\n";
- $callback->($entry, $cbdata);
+ $callback->($entry, $cbdata);
}
return $cbdata;
}
my %args = @_;
my $ret = {};
- my $msg = $self->_socket_command('GETVAL', \%args) or return;
- $self->_socket_chat($msg, sub {
- local $_ = shift;
- my $ret = shift;
- /^(\w+)=NaN$/ and $ret->{$1} = undef, return;
- /^(\w+)=(.*)$/ and looks_like_number($2) and $ret->{$1} = 0 + $2, return;
- }, $ret
- );
+ my $msg = $self->_socket_command('GETVAL', \%args) or return;
+ $self->_socket_chat($msg, sub {
+ local $_ = shift;
+ my $ret = shift;
+ /^(\w+)=NaN$/ and $ret->{$1} = undef, return;
+ /^(\w+)=(.*)$/ and looks_like_number($2) and $ret->{$1} = 0 + $2, return;
+ }, $ret
+ );
return $ret;
} # }}} sub getval
my %args = @_;
my $ret = {};
- my $msg = $self->_socket_command('GETTHRESHOLD', \%args) or return;
- $self->_socket_chat($msg, sub {
- local $_ = shift;
- my $ret = shift;
- my ( $key, $val );
- ( $key, $val ) = /^\s*([^:]+):\s*(.*)/ and do {
- $key =~ s/\s*$//;
- $ret->{$key} = $val;
- };
- }, $ret
- );
+ my $msg = $self->_socket_command('GETTHRESHOLD', \%args) or return;
+ $self->_socket_chat($msg, sub {
+ local $_ = shift;
+ my $ret = shift;
+ my ( $key, $val );
+ ( $key, $val ) = /^\s*([^:]+):\s*(.*)/ and do {
+ $key =~ s/\s*$//;
+ $ret->{$key} = $val;
+ };
+ }, $ret
+ );
return $ret;
} # }}} sub getthreshold
my $fh = $self->{sock} or confess;
my $interval = defined $args{interval} ?
- ' interval=' . _escape_argument ($args{interval}) : '';
+ ' interval=' . _escape_argument ($args{interval}) : '';
$identifier = _create_identifier (\%args) or return;
if (!$args{values})
sub listval_filter
{
my $self = shift;
- my %args = @_;
+ my %args = @_;
my @ret;
my $nresults;
my $fh = $self->{sock} or confess;
- my $pattern =
- (exists $args{host} ? "$args{host}" : '[^/]+') .
- (exists $args{plugin} ? "/$args{plugin}" : '/[^/-]+') .
+ 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$/;
+ $pattern = qr/^\d+(?:\.\d+)? $pattern$/;
- my $msg = $self->_socket_command('LISTVAL') or return;
+ my $msg = $self->_socket_command('LISTVAL') or return;
($nresults, $msg) = split / /, $msg, 2;
- # This could use _socket_chat() but doesn't for speed reasons
+ # This could use _socket_chat() but doesn't for speed reasons
if ($nresults < 0)
{
$self->{error} = $msg;
my ($time, $ident) = split / /, $msg, 2;
$ident = _parse_identifier ($ident);
- $ident->{time} = int $time;
+ $ident->{time} = 0+$time;
push (@ret, $ident);
- } # for (i = 0 .. $status)
+ } # for (i = 0 .. $nresults)
return @ret;
-} # listval
+} # listval_filter
=item I<$res> = I<$self>-E<gt>B<listval> ()
my @ret;
my $fh = $self->{sock} or confess;
- my $msg = $self->_socket_command('LISTVAL') or return;
+ my $msg = $self->_socket_command('LISTVAL') or return;
($nresults, $msg) = split / /, $msg, 2;
- # This could use _socket_chat() but doesn't for speed reasons
+ # This could use _socket_chat() but doesn't for speed reasons
if ($nresults < 0)
{
$self->{error} = $msg;
my ($time, $ident) = split / /, $msg, 2;
$ident = _parse_identifier ($ident);
- $ident->{time} = int $time;
+ $ident->{time} = 0+$time;
push (@ret, $ident);
- } # for (i = 0 .. $status)
+ } # for (i = 0 .. $nresults)
return @ret;
} # listval
my $msg; # message sent to the socket
- for my $arg (qw( message severity ))
- {
- cluck ("Need argument `$arg'"), return unless $args{$arg};
- }
+ for my $arg (qw( message severity ))
+ {
+ cluck ("Need argument `$arg'"), return unless $args{$arg};
+ }
$args{severity} = lc $args{severity};
if (($args{severity} ne 'failure')
&& ($args{severity} ne 'warning')
my $fh = $self->{sock} or confess;
- my $msg = "FLUSH";
+ my $msg = "FLUSH";
- $msg .= " timeout=$args{timeout}" if defined $args{timeout};
+ $msg .= " timeout=$args{timeout}" if defined $args{timeout};
if ($args{plugins})
{
$self->_send_message($msg) or return;
$msg = $pre;
}
-
+
$msg .= $ident_str;
}
}
-
+
return $self->_send_message($msg);
}
=cut
1;
-# vim: set fdm=marker :
+# vim: set fdm=marker noexpandtab:
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 @values = $s->listval;
is(scalar @values, 4984, "Correct number of results from LISTVAL");
-delete $values[1234]{time}; # won't be constant
is_deeply($values[1234], {
type_instance => 'nice',
plugin_instance => 21,
plugin => 'cpu',
type => 'cpu',
- host => 'h2gdf6120'
+ host => 'h2gdf6120',
+ time => 1479835354.434,
}, "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([ $s->listval_filter() ] , [ $s->listval ], "listval_filter() w/o filter equivalent to listval()");
is_deeply(
- [ filter_time $s->listval_filter(host => 'a1d8f6310', plugin => 'disk', plugin_instance => 'vda6') ],
+ [ $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' }
+ { 'plugin_instance' => 'vda6', 'type' => 'disk_merged', 'plugin' => 'disk', 'host' => 'a1d8f6310', time => 1479835354.434 },
+ { 'host' => 'a1d8f6310', 'plugin' => 'disk', 'plugin_instance' => 'vda6', 'type' => 'disk_octets', time => 1479835356 },
+ { 'type' => 'disk_ops', 'plugin_instance' => 'vda6', 'plugin' => 'disk', 'host' => 'a1d8f6310', time => 1479835354 },
+ { 'plugin' => 'disk', 'host' => 'a1d8f6310', 'type' => 'disk_time', 'plugin_instance' => 'vda6', time => 1479835354 }
],
"Correct result from listval_filter on <host>, <plugin> and <plugin_instance>"
);
# }}}
# --with-libdpdk {{{
-AC_ARG_WITH(libdpdk, [AS_HELP_STRING([--with-libdpdk@<:@=PREFIX@:>@], [Path to the DPDK build directory.])],
-[
- if test "x$withval" != "xno" && test "x$withval" != "xyes"
- then
- RTE_BUILD="$withval"
- with_libdpdk="yes"
- else
- RTE_BUILD="/usr"
- with_libdpdk="$withval"
- fi
- DPDK_INCLUDE="$RTE_BUILD/include"
- DPDK_LIB_DIR="$RTE_BUILD/lib"
- FOUND_DPDK=yes
-], [with_libdpdk="no"])
-
-if test "x$with_libdpdk" = "xyes"
-then
- LOCAL_DPDK_INSTALL="no"
- AC_CHECK_HEADER([$DPDK_INCLUDE/rte_config.h], [LOCAL_DPDK_INSTALL=yes],
- [AC_CHECK_HEADER([$DPDK_INCLUDE/dpdk/rte_config.h],
- [],
- [FOUND_DPDK=no], [])], [])
+LIBDPDK_CPPFLAGS="-I/usr/include/dpdk"
+LIBDPDK_LDFLAGS=""
+AC_ARG_VAR([LIBDPDK_CPPFLAGS], [Preprocessor flags for libdpdk])
+AC_ARG_VAR([LIBDPDK_LDFLAGS], [Linker flags for libdpdk])
- if test "x$LOCAL_DPDK_INSTALL" = "xno"
- then
- DPDK_INCLUDE=$DPDK_INCLUDE/dpdk
- fi
+AC_ARG_WITH([libdpdk], [AS_HELP_STRING([--without-libdpdk], [Disable libdpdk.])])
- if test "x$FOUND_DPDK" = "xno"
- then
- AC_MSG_ERROR([libdpdk error: rte_config.h not found])
- fi
+if test "x$with_libdpdk" != "xno"
+then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$LIBDPDK_CPPFLAGS $CPPFLAGS"
+ AC_CHECK_HEADERS([rte_config.h],
+ [with_libdpdk="yes"],
+ [with_libdpdk="no (rte_config.h not found)"]
+ )
+ CPPFLAGS="$SAVE_CPPFLAGS"
fi
if test "x$with_libdpdk" = "xyes"
then
SAVE_LDFLAGS="$LDFLAGS"
-
- if test "x$LOCAL_DPDK_INSTALL" != "xyes"
- then
- LDFLAGS="$LDFLAGS -L$DPDK_LIB_DIR"
- fi
-
- AC_CHECK_LIB(dpdk, rte_eal_init,
- [BUILD_WITH_DPDK_LIBS="-Wl,-ldpdk"],
- [FOUND_DPDK=no])
-
+ LDFLAGS="$LIBDPDK_LDFLAGS $LDFLAGS"
+ AC_CHECK_LIB([dpdk], [rte_eal_init],
+ [with_libdpkd="yes"],
+ [with_libdpdk="no (symbol 'rte_eal_init' not found)"]
+ )
LDFLAGS="$SAVE_LDFLAGS"
- if test "x$FOUND_DPDK" = "xno"
- then
- AC_MSG_ERROR([libdpdk error: cannot link with dpdk in $DPDK_LIB_DIR])
- fi
fi
-#
-# Note: An issue on Ubuntu 14.04 necessitates the use of -Wl,--no-as-needed:
-# If you try compile with the older linker, the dpdk symbols will be undefined.
-# This workaround should be removed when no longer necessary.
-#
-if test "x$with_libdpdk" = "xyes"
-then
- BUILD_WITH_DPDK_CFLAGS+="-I$DPDK_INCLUDE"
- if test "x$LOCAL_DPDK_INSTALL" != "xyes"
- then
- BUILD_WITH_DPDK_LDFLAGS="-Wl,--no-as-needed"
- else
- BUILD_WITH_DPDK_LDFLAGS="-L$DPDK_LIB_DIR -Wl,--no-as-needed"
- fi
- AC_SUBST(BUILD_WITH_DPDK_CFLAGS)
- AC_SUBST(BUILD_WITH_DPDK_LDFLAGS)
- AC_SUBST(BUILD_WITH_DPDK_LIBS)
-fi
# }}}
# --with-java {{{
plugin_df="no"
plugin_disk="no"
plugin_drbd="no"
-plugin_dpdk="no"
+plugin_dpdkstat="no"
plugin_entropy="no"
plugin_ethstat="no"
plugin_fhcount="no"
plugin_xencpu="yes"
fi
+if test "x$with_libdpkd" = "xyes"
+then
+ plugin_dpdkstat="yes"
+fi
+
m4_divert_once([HELP_ENABLE], [
collectd plugins:])
AC_PLUGIN([df], [$plugin_df], [Filesystem usage statistics])
AC_PLUGIN([disk], [$plugin_disk], [Disk usage statistics])
AC_PLUGIN([dns], [$with_libpcap], [DNS traffic analysis])
-AC_PLUGIN([dpdkstat], [$with_libdpdk], [Stats & Status from DPDK])
+AC_PLUGIN([dpdkstat], [$plugin_dpdkstat], [Stats & Status from DPDK])
AC_PLUGIN([drbd], [$plugin_drbd], [DRBD statistics])
AC_PLUGIN([email], [yes], [EMail statistics])
AC_PLUGIN([entropy], [$plugin_entropy], [Entropy statistics])
AC_MSG_RESULT([ df . . . . . . . . . $enable_df])
AC_MSG_RESULT([ disk . . . . . . . . $enable_disk])
AC_MSG_RESULT([ dns . . . . . . . . . $enable_dns])
-AC_MSG_RESULT([ dpdkstat . . . . . . .$enable_dpdkstat])
+AC_MSG_RESULT([ dpdkstat . . . . . . $enable_dpdkstat])
AC_MSG_RESULT([ drbd . . . . . . . . $enable_drbd])
AC_MSG_RESULT([ email . . . . . . . . $enable_email])
AC_MSG_RESULT([ entropy . . . . . . . $enable_entropy])
%define with_write_graphite 0%{!?_without_write_graphite:1}
%define with_write_http 0%{!?_without_write_http:1}
%define with_write_log 0%{!?_without_write_log:1}
+%define with_write_prometheus 0%{!?_without_write_prometheus:1}
%define with_write_redis 0%{!?_without_write_redis:1}
%define with_write_sensu 0%{!?_without_write_sensu:1}
%define with_write_tsdb 0%{!?_without_write_tsdb:1}
%define with_redis 0
%define with_smart 0
%define with_turbostat 0
+%define with_write_prometheus 0
%define with_write_redis 0
%endif
The write_kafka plugin sends values to kafka, a distributed messaging system.
%endif
+%if %{with_write_prometheus}
+%package write_prometheus
+Summary: Write-prometheus plugin for collectd
+Group: System Environment/Daemons
+Requires: %{name}%{?_isa} = %{version}-%{release}
+BuildRequires: libmicrohttpd-devel
+%description write_prometheus
+The Write Prometheus plugin exposes collected values using an embedded HTTP
+server, turning the collectd daemon into a Prometheus exporter.
+%endif
+
%if %{with_write_redis}
%package write_redis
Summary: Write-Redis plugin for collectd
%define _with_write_mongodb --disable-write_mongodb
%endif
+%if %{with_write_prometheus}
+%define _with_write_prometheus --enable-write_prometheus
+%else
+%define _with_write_prometheus --disable-write_prometheus
+%endif
+
%if %{with_write_redis}
%define _with_write_redis --enable-write_redis
%else
%{?_with_write_kafka} \
%{?_with_write_log} \
%{?_with_write_mongodb} \
+ %{?_with_write_prometheus} \
%{?_with_write_redis} \
%{?_with_write_riemann} \
%{?_with_write_sensu} \
%{_libdir}/%{name}/write_kafka.so
%endif
+%if %{with_write_prometheus}
+%files write_prometheus
+%{_libdir}/%{name}/write_prometheus.so
+%endif
+
%if %{with_write_redis}
%files write_redis
%{_libdir}/%{name}/write_redis.so
%changelog
* Mon Oct 10 2016 Marc Fournier <marc.fournier@camptocamp.com> - 5.7.0-1
- New PRE-RELEASE version
-- New plugins enabled by default: hugepages
+- New plugins enabled by default: hugepages, write_prometheus
- New plugins disabled by default: dpdkstat, intel_rdt
* Mon Oct 10 2016 Victor Demonchy <v.demonchy@criteo.com> - 5.6.1-1
if BUILD_PLUGIN_DPDKSTAT
pkglib_LTLIBRARIES += dpdkstat.la
dpdkstat_la_SOURCES = dpdkstat.c
-dpdkstat_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_DPDK_CFLAGS)
-dpdkstat_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_DPDK_LDFLAGS)
-dpdkstat_la_LIBADD = $(BUILD_WITH_DPDK_LIBS)
+dpdkstat_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBDPDK_CPPFLAGS)
+dpdkstat_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBDPDK_LDFLAGS)
+dpdkstat_la_LIBADD = -ldpdk
endif
if BUILD_PLUGIN_DRBD