$self->_socket_chat($msg, sub {
local $_ = shift;
my $ret = shift;
- /^\s*([^:]+):\s*(.*)/ and do {
- $1 =~ s/\s*$//;
- $ret->{$1} = $2;
- };
+ my ( $key, $val );
+ ( $key, $val ) = /^\s*([^:]+):\s*(.*)/ and do {
+ $key =~ s/\s*$//;
+ $ret->{$key} = $val;
+ };
}, $ret
);
return $ret;
AC_CHECK_FUNCS(getvfsstat, [have_getvfsstat="yes"])
have_listmntent="no"
AC_CHECK_FUNCS(listmntent, [have_listmntent="yes"])
+have_getmntent_r="no"
+AC_CHECK_FUNCS(getmntent_r, [have_getmntent_r="yes"])
have_getmntent="no"
AC_CHECK_FUNCS(getmntent, [have_getmntent="c"])
GANGLIA_LDFLAGS="-L$withval/lib"
with_libganglia="yes"
else
- with_libganglia_config="ganglia-config"
with_libganglia="$withval"
fi; fi; fi
],
[
- with_libganglia_config="ganglia-config"
with_libganglia="yes"
])
-if test "x$with_libganglia" = "xyes" && test "x$with_libganglia_config" != "x"
+if test "x$with_libganglia" = "xyes"
then
- if test "x$GANGLIA_CPPFLAGS" = "x"
+ if test "x$with_libganglia_config" != "x"
then
- GANGLIA_CPPFLAGS=`"$with_libganglia_config" --cflags 2>/dev/null`
- fi
+ if test "x$GANGLIA_CPPFLAGS" = "x"
+ then
+ GANGLIA_CPPFLAGS=`"$with_libganglia_config" --cflags 2>/dev/null`
+ fi
- if test "x$GANGLIA_LDFLAGS" = "x"
- then
- GANGLIA_LDFLAGS=`"$with_libganglia_config" --ldflags 2>/dev/null`
- fi
+ if test "x$GANGLIA_LDFLAGS" = "x"
+ then
+ GANGLIA_LDFLAGS=`"$with_libganglia_config" --ldflags 2>/dev/null`
+ fi
- if test "x$GANGLIA_LIBS" = "x"
- then
- GANGLIA_LIBS=`"$with_libganglia_config" --libs 2>/dev/null`
+ if test "x$GANGLIA_LIBS" = "x"
+ then
+ GANGLIA_LIBS=`"$with_libganglia_config" --libs 2>/dev/null`
+ fi
+ else
+ GANGLIA_LIBS="-lganglia"
fi
fi
])
if test "x$with_libmysql" = "xyes"
then
- with_mysql_cflags=`$with_mysql_config --cflags 2>/dev/null`
+ with_mysql_cflags=`$with_mysql_config --include 2>/dev/null`
mysql_config_status=$?
if test $mysql_config_status -ne 0
then
with_libmysql="no ($with_mysql_config failed)"
else
- AC_CHECK_LIB(mysqlclient, mysql_init,
- [with_libmysql="yes"],
- [with_libmysql="no (symbol 'mysql_init' not found)"],
- [$with_mysql_libs])
-
- AC_CHECK_LIB(mysqlclient, mysql_get_server_version,
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_mysql_cflags"
+ SAVE_LIBS="$LIBS"
+ LIBS="$with_mysql_libs"
+ AC_SEARCH_LIBS([mysql_get_server_version],
+ [],
[with_libmysql="yes"],
[with_libmysql="no (symbol 'mysql_get_server_version' not found)"],
- [$with_mysql_libs])
+ [])
+ CPPFLAGS="$SAVE_CPPFLAGS"
+ LIBS="$SAVE_LIBS"
fi
fi
if test "x$with_libmysql" = "xyes"
AC_COLLECTD([debug], [enable], [feature], [debugging])
AC_COLLECTD([daemon], [disable], [feature], [daemon mode])
AC_COLLECTD([getifaddrs],[enable], [feature], [getifaddrs under Linux])
+AC_COLLECTD([werror], [disable], [feature], [building with -Werror])
dependency_warning="no"
dependency_error="no"
plugin_df="yes"
fi
+if test "x$c_cv_have_getmntent_r" = "xyes"
+then
+ plugin_df="yes"
+fi
+
# Df plugin: Check if we have either `statfs' or `statvfs' second.
if test "x$plugin_df" = "xyes"
then
AC_CONFIG_FILES(src/libcollectdclient/collectd/lcc_features.h)
+AM_CFLAGS="-Wall"
+if test "x$enable_werror" != "xno"
+then
+ AM_CFLAGS="$AM_CFLAGS -Werror"
+fi
+AC_SUBST([AM_CFLAGS])
+
AC_CONFIG_FILES([Makefile src/Makefile src/daemon/Makefile src/collectd.conf src/libcollectdclient/Makefile src/libcollectdclient/libcollectdclient.pc src/liboconfig/Makefile bindings/Makefile bindings/java/Makefile])
AC_OUTPUT
cat <<EOF;
Configuration:
+ Build:
+ Platform . . . . . . $ac_system
+ CC . . . . . . . . . $CC
+ CFLAGS . . . . . . . $AM_CFLAGS $CFLAGS
+ CPP . . . . . . . . . $CPP
+ CPPFLAGS . . . . . . $CPPFLAGS
+ LD . . . . . . . . . $LD
+ LDFLAGS . . . . . . . $LDFLAGS
+ YACC . . . . . . . . $YACC
+ YFLAGS . . . . . . . $YFLAGS
+
Libraries:
intel mic . . . . . . $with_mic
libaquaero5 . . . . . $with_libaquaero5
ExecStart=/usr/sbin/collectd
EnvironmentFile=-/etc/sysconfig/collectd
EnvironmentFile=-/etc/default/collectd
+ProtectSystem=full
+ProtectHome=true
+
+# drop all capabilities:
+CapabilityBoundingSet=
+# use this instead if you use the dns or ping plugin
+#CapabilityBoundingSet=CAP_NET_RAW
+# turn this on if you use the iptables next to the dns or ping plugin
+#CapabilityBoundingSet=CAP_NET_RAW CAP_NET_ADMIN
+
+NoNewPrivileges=true
# Tell systemd it will receive a notification from collectd over it's control
# socket once the daemon is ready. See systemd.service(5) for more details.
Type=notify
-NotifyAccess=main
# Restart the collectd daemon after a 10 seconds delay, in case it crashes.
-Restart=always
-RestartSec=10
-
-# Send all console messages to syslog.
-StandardOutput=syslog
-StandardError=syslog
+Restart=on-failure
[Install]
WantedBy=multi-user.target
PLUGIN_LDFLAGS = -module -avoid-version -export-symbols-regex '\<module_register\>'
-if COMPILER_IS_GCC
-AM_CFLAGS = -Wall -Werror
-endif
-
AM_CPPFLAGS = -I$(srcdir)/daemon
AM_CPPFLAGS += -DPREFIX='"${prefix}"'
AM_CPPFLAGS += -DCONFIGFILE='"${sysconfdir}/${PACKAGE_NAME}.conf"'
TESTS += test_utils_vl_lookup
test_utils_vl_lookup_SOURCES = utils_vl_lookup_test.c testing.h
test_utils_vl_lookup_LDADD = liblookup.la daemon/libcommon.la daemon/libplugin_mock.la
+if BUILD_WITH_LIBKSTAT
+test_utils_vl_lookup_LDADD += -lkstat
+endif
noinst_LTLIBRARIES += libmount.la
libmount_la_SOURCES = utils_mount.c utils_mount.h
TESTS += test_utils_mount
test_utils_mount_SOURCES = utils_mount_test.c testing.h
test_utils_mount_LDADD = libmount.la daemon/libcommon.la daemon/libplugin_mock.la
-
+if BUILD_WITH_LIBKSTAT
+test_utils_mount_LDADD += -lkstat
+endif
sbin_PROGRAMS = collectdmon
bin_PROGRAMS = collectd-nagios collectdctl collectd-tg
if BUILD_PLUGIN_CGROUPS
pkglib_LTLIBRARIES += cgroups.la
-cgroups_la_SOURCES = cgroups.c \
- utils_ignorelist.c utils_ignorelist.h
+cgroups_la_SOURCES = cgroups.c
cgroups_la_LDFLAGS = $(PLUGIN_LDFLAGS)
cgroups_la_LIBADD = libmount.la
endif
if BUILD_PLUGIN_DF
pkglib_LTLIBRARIES += df.la
-df_la_SOURCES = df.c \
- utils_ignorelist.c utils_ignorelist.h
+df_la_SOURCES = df.c
df_la_LDFLAGS = $(PLUGIN_LDFLAGS)
df_la_LIBADD = libmount.la
endif
if BUILD_PLUGIN_DISK
pkglib_LTLIBRARIES += disk.la
-disk_la_SOURCES = disk.c \
- utils_ignorelist.c utils_ignorelist.h
+disk_la_SOURCES = disk.c
disk_la_CFLAGS = $(AM_CFLAGS)
disk_la_LDFLAGS = $(PLUGIN_LDFLAGS)
disk_la_LIBADD =
if BUILD_PLUGIN_INTERFACE
pkglib_LTLIBRARIES += interface.la
-interface_la_SOURCES = interface.c \
- utils_ignorelist.c utils_ignorelist.h
+interface_la_SOURCES = interface.c
interface_la_CFLAGS = $(AM_CFLAGS)
interface_la_LDFLAGS = $(PLUGIN_LDFLAGS)
interface_la_LIBADD =
if BUILD_PLUGIN_IPMI
pkglib_LTLIBRARIES += ipmi.la
-ipmi_la_SOURCES = ipmi.c \
- utils_ignorelist.c utils_ignorelist.h
+ipmi_la_SOURCES = ipmi.c
ipmi_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_OPENIPMI_CFLAGS)
ipmi_la_LDFLAGS = $(PLUGIN_LDFLAGS)
ipmi_la_LIBADD = $(BUILD_WITH_OPENIPMI_LIBS)
if BUILD_PLUGIN_IRQ
pkglib_LTLIBRARIES += irq.la
-irq_la_SOURCES = irq.c \
- utils_ignorelist.c utils_ignorelist.h
+irq_la_SOURCES = irq.c
irq_la_LDFLAGS = $(PLUGIN_LDFLAGS)
endif
if BUILD_PLUGIN_MADWIFI
pkglib_LTLIBRARIES += madwifi.la
-madwifi_la_SOURCES = madwifi.c madwifi.h \
- utils_ignorelist.c utils_ignorelist.h
+madwifi_la_SOURCES = madwifi.c madwifi.h
madwifi_la_LDFLAGS = $(PLUGIN_LDFLAGS)
endif
if BUILD_PLUGIN_MD
pkglib_LTLIBRARIES += md.la
-md_la_SOURCES = md.c \
- utils_ignorelist.c utils_ignorelist.h
+md_la_SOURCES = md.c
md_la_LDFLAGS = $(PLUGIN_LDFLAGS)
endif
if BUILD_PLUGIN_MIC
pkglib_LTLIBRARIES += mic.la
-mic_la_SOURCES = mic.c \
- utils_ignorelist.c utils_ignorelist.h
+mic_la_SOURCES = mic.c
mic_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_MIC_LIBPATH)
mic_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_MIC_CPPFLAGS)
mic_la_LIBADD = $(BUILD_WITH_MIC_LDADD)
if BUILD_PLUGIN_NETAPP
pkglib_LTLIBRARIES += netapp.la
-netapp_la_SOURCES = netapp.c \
- utils_ignorelist.c utils_ignorelist.h
+netapp_la_SOURCES = netapp.c
netapp_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBNETAPP_CPPFLAGS)
netapp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBNETAPP_LDFLAGS)
netapp_la_LIBADD = $(LIBNETAPP_LIBS)
if BUILD_PLUGIN_ONEWIRE
pkglib_LTLIBRARIES += onewire.la
-onewire_la_SOURCES = onewire.c \
- utils_ignorelist.c utils_ignorelist.h
+onewire_la_SOURCES = onewire.c
onewire_la_CFLAGS = $(AM_CFLAGS)
onewire_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBOWCAPI_CPPFLAGS)
onewire_la_LIBADD = $(BUILD_WITH_LIBOWCAPI_LIBS)
if BUILD_PLUGIN_PROTOCOLS
pkglib_LTLIBRARIES += protocols.la
-protocols_la_SOURCES = protocols.c \
- utils_ignorelist.c utils_ignorelist.h
+protocols_la_SOURCES = protocols.c
protocols_la_LDFLAGS = $(PLUGIN_LDFLAGS)
endif
if BUILD_PLUGIN_SENSORS
pkglib_LTLIBRARIES += sensors.la
-sensors_la_SOURCES = sensors.c \
- utils_ignorelist.c utils_ignorelist.h
+sensors_la_SOURCES = sensors.c
sensors_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBSENSORS_CFLAGS)
sensors_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBSENSORS_LDFLAGS)
sensors_la_LIBADD = -lsensors
if BUILD_PLUGIN_SMART
if BUILD_WITH_LIBUDEV
pkglib_LTLIBRARIES += smart.la
-smart_la_SOURCES = smart.c \
- utils_ignorelist.c utils_ignorelist.h
+smart_la_SOURCES = smart.c
smart_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBATASMART_CPPFLAGS)
smart_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBATASMART_LDFLAGS)
smart_la_LIBADD = $(BUILD_WITH_LIBATASMART_LIBS) -ludev
if BUILD_PLUGIN_THERMAL
pkglib_LTLIBRARIES += thermal.la
-thermal_la_SOURCES = thermal.c \
- utils_ignorelist.c utils_ignorelist.h
+thermal_la_SOURCES = thermal.c
thermal_la_LDFLAGS = $(PLUGIN_LDFLAGS)
endif
if BUILD_PLUGIN_VIRT
pkglib_LTLIBRARIES += virt.la
-virt_la_SOURCES = virt.c \
- utils_ignorelist.c utils_ignorelist.h
+virt_la_SOURCES = virt.c
virt_la_CFLAGS = $(AM_CFLAGS) \
$(BUILD_WITH_LIBVIRT_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS)
virt_la_LIBADD = $(BUILD_WITH_LIBVIRT_LIBS) $(BUILD_WITH_LIBXML2_LIBS)
static int apache_read_host (user_data_t *user_data) /* {{{ */
{
- int i;
-
char *ptr;
char *saveptr;
- char *lines[16];
- int lines_num = 0;
+ char *line;
char *fields[4];
int fields_num;
ptr = st->apache_buffer;
saveptr = NULL;
- while ((lines[lines_num] = strtok_r (ptr, "\n\r", &saveptr)) != NULL)
+ while ((line = strtok_r (ptr, "\n\r", &saveptr)) != NULL)
{
ptr = NULL;
- lines_num++;
-
- if (lines_num >= 16)
- break;
- }
-
- for (i = 0; i < lines_num; i++)
- {
- fields_num = strsplit (lines[i], fields, 4);
+ fields_num = strsplit (line, fields, STATIC_ARRAY_SIZE (fields));
if (fields_num == 3)
{
- if ((strcmp (fields[0], "Total") == 0)
- && (strcmp (fields[1], "Accesses:") == 0))
- submit_derive ("apache_requests", "",
- atoll (fields[2]), st);
- else if ((strcmp (fields[0], "Total") == 0)
- && (strcmp (fields[1], "kBytes:") == 0))
- submit_derive ("apache_bytes", "",
- 1024LL * atoll (fields[2]), st);
+ if ((strcmp (fields[0], "Total") == 0) && (strcmp (fields[1], "Accesses:") == 0))
+ submit_derive ("apache_requests", "", atoll (fields[2]), st);
+ else if ((strcmp (fields[0], "Total") == 0) && (strcmp (fields[1], "kBytes:") == 0))
+ submit_derive ("apache_bytes", "", 1024LL * atoll (fields[2]), st);
}
else if (fields_num == 2)
{
if (status != 0)
{
char errbuf[1024];
- INFO ("getaddrinfo failed: %s",
+ INFO ("apcups plugin: getaddrinfo failed: %s",
(status == EAI_SYSTEM)
? sstrerror (errno, errbuf, sizeof (errbuf))
: gai_strerror (status));
if (sd < 0)
{
- DEBUG ("Unable to open a socket");
+ DEBUG ("apcups plugin: Unable to open a socket");
freeaddrinfo (ai_return);
return (-1);
}
if (status != 0) /* `connect(2)' failed */
{
char errbuf[1024];
- INFO ("connect failed: %s",
+ INFO ("apcups plugin: connect failed: %s",
sstrerror (errno, errbuf, sizeof (errbuf)));
close (sd);
return (-1);
}
- DEBUG ("Done opening a socket %i", sd);
+ DEBUG ("apcups plugin: Done opening a socket %i", sd);
return (sd);
} /* int net_open */
*/
if (status != 0)
{
- DEBUG ("apc_query_server (%s, %s) = %i",
+ DEBUG ("apcups plugin: apc_query_server (%s, %s) = %i",
(conf_node == NULL) ? APCUPS_DEFAULT_NODE : conf_node,
(conf_service == NULL) ? APCUPS_DEFAULT_SERVICE : conf_service,
status);
=head1 DESCRIPTION
-The C<exec plugin> forks of an executable either to receive values or to
+The C<exec plugin> forks off an executable either to receive values or to
dispatch notifications to the outside world. The syntax of the configuration is
explained in L<collectd.conf(5)> but summarized in the above synopsis.
See L<EXEC DATA FORMAT> below for a description of the output format expected
from these programs.
-B<Warning:> If the executable only writes one value and then exits I will be
+B<Warning:> If the executable only writes one value and then exits it will be
executed every I<Interval> seconds. If I<Interval> is short (the default is 10
seconds) this may result in serious system load.
#include <signal.h>
#include <errno.h>
#include <math.h>
+#include <sys/time.h>
#include "utils_heap.h"
#<Plugin "battery">
# ValuesPercentage false
-# ReportDegraded
+# ReportDegraded false
#</Plugin>
#<Plugin "bind">
# Prefix "collectd"
# StoreRates true
# Retain false
+# CACert "/etc/ssl/ca.crt"
+# CertificateFile "/etc/ssl/client.crt"
+# CertificateKeyFile "/etc/ssl/client.pem"
+# TLSProtocol "tlsv1.2"
+# CipherSuite "ciphers"
# </Publish>
# <Subscribe "name">
# Host "localhost"
</Query>
<Database "product_information">
Driver "mysql"
+ Interval 120
DriverOption "host" "localhost"
DriverOption "username" "collectd"
DriverOption "password" "aZo6daiw"
=over 4
+=item B<Interval> I<Interval>
+
+Sets the interval (in seconds) in which the values will be collected from this
+database. By default the global B<Interval> setting will be used.
+
=item B<Driver> I<Driver>
Specifies the driver to use to connect to the database. In many cases those
multi level C<#> wildcards. Defaults to B<collectd/#>, i.e. all topics beneath
the B<collectd> branch.
+=item B<CACert> I<file>
+
+Path to the PEM-encoded CA certificate file. Setting this option enables TLS
+communication with the MQTT broker, and as such, B<Port> should be the TLS-enabled
+port of the MQTT broker.
+A valid TLS configuration requires B<CACert>, B<CertificateFile> and B<CertificateKeyFile>.
+
+=item B<CertificateFile> I<file>
+
+Path to the PEM-encoded certificate file to use as client certificate when
+connecting to the MQTT broker.
+A valid TLS configuration requires B<CACert>, B<CertificateFile> and B<CertificateKeyFile>.
+
+=item B<CertificateKeyFile> I<file>
+
+Path to the unencrypted PEM-encoded key file corresponding to B<CertificateFile>.
+A valid TLS configuration requires B<CACert>, B<CertificateFile> and B<CertificateKeyFile>.
+
+=item B<TLSProtocol> I<protocol>
+
+If configured, this specifies the string protocol version (e.g. C<tlsv1>,
+C<tlsv1.2>) to use for the TLS connection to the broker. If not set a default
+version is used which depends on the version of OpenSSL the Mosquitto library
+was linked against.
+
+=item B<CipherSuite> I<ciphersuite>
+
+A string describing the ciphers available for use. See L<ciphers(1)> and the
+C<openssl ciphers> utility for more information. If unset, the default ciphers
+will be used.
+
+
=back
=head2 Plugin C<mysql>
B<address> means use the interface's mac address. This is useful since the
interface path might change between reboots of a guest or across migrations.
-=item B<PluginInstanceFormat> B<name|uuid>
+=item B<PluginInstanceFormat> B<name|uuid|none>
When the virt plugin logs data, it sets the plugin_instance of the collected
-data according to this setting. The default is to use the guest name as provided
-by the hypervisor, which is equal to setting B<name>.
+data according to this setting. The default is to not set the plugin_instance.
+B<name> means use the guest's name as provided by the hypervisor.
B<uuid> means use the guest's UUID.
+You can also specify combinations of the B<name> and B<uuid> fields.
+For example B<name uuid> means to concatenate the guest name and UUID
+(with a literal colon character between, thus I<"foo:1234-1234-1234-1234">).
+
=back
=head2 Plugin C<vmem>
all the data in the current send buffer will probably be lost. Defaults to 0,
which means the connection never times out.
+=item B<LogHttpError> B<false>|B<true>
+
+Enables printing of HTTP error code to log. Turned off by default.
+
The C<write_http> plugin regularly submits the collected values to the HTTP
server. How frequently this happens depends on how much data you are collecting
and the size of B<BufferSize>. The optimal value to set B<Timeout> to is
Timeout 1000
Prefix "collectd/"
Database 1
+ MaxSetSize -1
+ StoreRates true
</Node>
</Plugin>
C<ZRANGEBYSCORE> I<Redis> command. Additionally, all the identifiers of these
I<Sorted Sets> are kept in a I<Set> called C<collectd/values> (or
C<${prefix}/values> if the B<Prefix> option was specified) and can be retrieved
-using the C<SMEMBERS> I<Redis> command. You can specify the database to use
+using the C<SMEMBERS> I<Redis> command. You can specify the database to use
with the B<Database> parameter (default is C<0>). See
L<http://redis.io/commands#sorted_set> and L<http://redis.io/commands#set> for
details.
=item B<Database> I<Index>
-This index selects the redis database to use for writing operations. Defaults to C<0>.
+This index selects the redis database to use for writing operations. Defaults
+to C<0>.
+
+=item B<MaxSetSize> I<Items>
+
+The B<MaxSetSize> option limits the number of items that the I<Sorted Sets> can
+hold. Negative values for I<Items> sets no limit, which is the default behavior.
+
+=item B<StoreRates> B<true>|B<false>
+
+If set to B<true> (the default), convert counter values to rates. If set to
+B<false> counter values are stored as is, i.e. as an increasing integer number.
=back
=item B<AlwaysAppendDS> B<false>|B<true>
-If set the B<true>, append the name of the I<Data Source> (DS) to the
+If set to B<true>, append the name of the I<Data Source> (DS) to the
"service", i.e. the field that, together with the "host" field, uniquely
identifies a metric in I<Riemann>. If set to B<false> (the default), this is
only done when there is more than one DS.
-if COMPILER_IS_GCC
-AM_CFLAGS = -Wall -Werror
-endif
-
AM_CPPFLAGS = -I$(top_srcdir)/src
AM_CPPFLAGS += -DPREFIX='"${prefix}"'
AM_CPPFLAGS += -DCONFIGFILE='"${sysconfdir}/${PACKAGE_NAME}.conf"'
plugin.c plugin.h \
utils_cache.c utils_cache.h \
utils_complain.c utils_complain.h \
+ utils_ignorelist.c utils_ignorelist.h \
utils_llist.c utils_llist.h \
utils_random.c utils_random.h \
utils_tail_match.c utils_tail_match.h \
unsetenv ("NOTIFY_SOCKET");
+#if defined(SOCK_CLOEXEC)
+ fd = socket (AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, /* protocol = */ 0);
+#else
fd = socket (AF_UNIX, SOCK_DGRAM, /* protocol = */ 0);
+#endif
if (fd < 0) {
char errbuf[1024];
ERROR ("creating UNIX socket failed: %s",
}
else
{
-#if KERNEL_LINUX
/* Linux abstract namespace socket: specify address as "\0foo", i.e.
* start with a null byte. Since null bytes have no special meaning in
* that case, we have to set su_size correctly to cover only the bytes
su_size = sizeof (sa_family_t) + strlen (notifysocket);
if (su_size > sizeof (su))
su_size = sizeof (su);
-#else
- ERROR ("Systemd socket uses Linux abstract namespace notation (\"%s\"), "
- "but I don't appear to be running on Linux.", notifysocket);
- return 0;
-#endif
}
if (sendto (fd, buffer, strlen (buffer), MSG_NOSIGNAL, (void *) &su, (socklen_t) su_size) < 0)
return 0;
}
+ unsetenv ("NOTIFY_SOCKET");
close(fd);
return 1;
}
#include <sys/types.h>
#include <netdb.h>
+#include <poll.h>
+
#if HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
const char *ptr;
size_t nleft;
ssize_t status;
+ struct pollfd pfd;
ptr = (const char *) buf;
nleft = count;
+
+ /* checking for closed peer connection */
+ pfd.fd = fd;
+ pfd.events = POLLIN | POLLHUP;
+ pfd.revents = 0;
+ if (poll(&pfd, 1, 0) > 0) {
+ char buffer[32];
+ if (recv(fd, buffer, sizeof(buffer), MSG_PEEK | MSG_DONTWAIT) == 0) {
+ // if recv returns zero (even though poll() said there is data to be read),
+ // that means the connection has been closed
+ return -1;
+ }
+ }
while (nleft > 0)
{
#include "testing.h"
#include "common.h"
+#if HAVE_LIBKSTAT
+kstat_ctl_t *kc;
+#endif /* HAVE_LIBKSTAT */
+
DEF_TEST(sstrncpy)
{
char buffer[16] = "";
if (md == NULL)
return;
- pthread_mutex_destroy(&md->lock);
md_entry_free (md->head);
pthread_mutex_destroy (&md->lock);
free (md);
/* success */
plugin_mark_loaded (plugin_name);
ret = 0;
+ INFO ("plugin_load: plugin \"%s\" successfully loaded.", plugin_name);
break;
}
else
write_threads_num = 5;
}
- start_write_threads ((size_t) write_threads_num);
-
if ((list_init == NULL) && (read_heap == NULL))
return;
le = le->next;
}
+ start_write_threads ((size_t) write_threads_num);
+
max_read_interval = global_option_get_time ("MaxReadInterval",
DEFAULT_MAX_READ_INTERVAL);
*value = n->value;
free_node (n);
+ --t->size;
rebalance (t, p);
return (0);
#include "testing.h"
#include "collectd.h"
#include "utils_avltree.h"
+#include "common.h" /* STATIC_ARRAY_SIZE */
static int compare_total_count = 0;
#define RESET_COUNTS() do { compare_total_count = 0; } while (0)
DEF_TEST(success)
{
+ struct {
+ char *key;
+ char *value;
+ } cases[] = {
+ {"Eeph7chu", "vai1reiV"},
+ {"igh3Paiz", "teegh1Ee"},
+ {"caip6Uu8", "ooteQu8n"},
+ {"Aech6vah", "AijeeT0l"},
+ {"Xah0et2L", "gah8Taep"},
+ {"BocaeB8n", "oGaig8io"},
+ {"thai8AhM", "ohjeFo3f"},
+ {"ohth6ieC", "hoo8ieWo"},
+ {"aej7Woow", "phahuC2s"},
+ {"Hai8ier2", "Yie6eimi"},
+ {"phuXi3Li", "JaiF7ieb"},
+ {"Shaig5ef", "aihi5Zai"},
+ {"voh6Aith", "Oozaeto0"},
+ {"zaiP5kie", "seep5veM"},
+ {"pae7ba7D", "chie8Ojo"},
+ {"Gou2ril3", "ouVoo0ha"},
+ {"lo3Thee3", "ahDu4Zuj"},
+ {"Rah8kohv", "ieShoc7E"},
+ {"ieN5engi", "Aevou1ah"},
+ {"ooTe4OhP", "aingai5Y"},
+ };
+
c_avl_tree_t *t;
- char key_orig[] = "foo";
- char value_orig[] = "bar";
- char *key_ret = NULL;
- char *value_ret = NULL;
+ size_t i;
RESET_COUNTS ();
- t = c_avl_create (compare_callback);
- OK (t != NULL);
+ CHECK_NOT_NULL (t = c_avl_create (compare_callback));
+
+ /* insert */
+ for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
+ {
+ char *key;
+ char *value;
- OK (c_avl_insert (t, key_orig, value_orig) == 0);
- OK (c_avl_size (t) == 1);
+ CHECK_NOT_NULL (key = strdup (cases[i].key));
+ CHECK_NOT_NULL (value = strdup (cases[i].value));
+
+ CHECK_ZERO (c_avl_insert (t, key, value));
+ EXPECT_EQ_INT ((int) (i + 1), c_avl_size (t));
+ }
/* Key already exists. */
- OK (c_avl_insert (t, "foo", "qux") > 0);
+ for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
+ EXPECT_EQ_INT (1, c_avl_insert (t, cases[i].key, cases[i].value));
+
+ /* get */
+ for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
+ {
+ char *value_ret = NULL;
+
+ CHECK_ZERO (c_avl_get (t, cases[i].key, (void *) &value_ret));
+ EXPECT_EQ_STR (cases[i].value, value_ret);
+ }
+
+ /* remove half */
+ for (i = 0; i < STATIC_ARRAY_SIZE (cases) / 2; i++)
+ {
+ char *key = NULL;
+ char *value = NULL;
+
+ int expected_size = (int) (STATIC_ARRAY_SIZE (cases) - (i + 1));
+
+ CHECK_ZERO (c_avl_remove (t, cases[i].key, (void *) &key, (void *) &value));
+
+ EXPECT_EQ_STR (cases[i].key, key);
+ EXPECT_EQ_STR (cases[i].value, value);
+
+ free (key);
+ free (value);
+
+ EXPECT_EQ_INT (expected_size, c_avl_size (t));
+ }
+
+ /* pick the other half */
+ for (i = STATIC_ARRAY_SIZE (cases) / 2; i < STATIC_ARRAY_SIZE (cases); i++)
+ {
+ char *key = NULL;
+ char *value = NULL;
+
+ int expected_size = (int) (STATIC_ARRAY_SIZE (cases) - (i + 1));
+
+ EXPECT_EQ_INT (expected_size + 1, c_avl_size (t));
+ EXPECT_EQ_INT (0, c_avl_pick (t, (void *) &key, (void *) &value));
- OK (c_avl_get (t, "foo", (void *) &value_ret) == 0);
- OK (value_ret == &value_orig[0]);
+ free (key);
+ free (value);
- key_ret = value_ret = NULL;
- OK (c_avl_remove (t, "foo", (void *) &key_ret, (void *) &value_ret) == 0);
- OK (key_ret == &key_orig[0]);
- OK (value_ret == &value_orig[0]);
- OK (c_avl_size (t) == 0);
+ EXPECT_EQ_INT (expected_size, c_avl_size (t));
+ }
c_avl_destroy (t);
--- /dev/null
+/**
+ * collectd - src/utils_ignorelist.c
+ * Copyright (C) 2006 Lubos Stanek <lubek at users.sourceforge.net>
+ * Copyright (C) 2008 Florian Forster <octo at collectd.org>
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public Licence for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * Licence along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ * USA.
+ *
+ * Authors:
+ * Lubos Stanek <lubek at users.sourceforge.net>
+ * Florian Forster <octo at collectd.org>
+ **/
+/**
+ * ignorelist handles plugin's list of configured collectable
+ * entries with global ignore action
+ **/
+/**
+ * Usage:
+ *
+ * Define plugin's global pointer variable of type ignorelist_t:
+ * ignorelist_t *myconfig_ignore;
+ * If you know the state of the global ignore (IgnoreSelected),
+ * allocate the variable with:
+ * myconfig_ignore = ignorelist_create (YourKnownIgnore);
+ * If you do not know the state of the global ignore,
+ * initialize the global variable and set the ignore flag later:
+ * myconfig_ignore = ignorelist_init ();
+ * Append single entries in your cf_register'ed callback function:
+ * ignorelist_add (myconfig_ignore, newentry);
+ * When you hit the IgnoreSelected config option,
+ * offer it to the list:
+ * ignorelist_ignore (myconfig_ignore, instantly_got_value_of_ignore);
+ * That is all for the ignorelist initialization.
+ * Later during read and write (plugin's registered functions) get
+ * the information whether this entry would be collected or not:
+ * if (ignorelist_match (myconfig_ignore, thisentry))
+ * return;
+ **/
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "common.h"
+#include "plugin.h"
+#include "utils_ignorelist.h"
+
+/*
+ * private prototypes
+ */
+struct ignorelist_item_s
+{
+#if HAVE_REGEX_H
+ regex_t *rmatch; /* regular expression entry identification */
+#endif
+ char *smatch; /* string entry identification */
+ struct ignorelist_item_s *next;
+};
+typedef struct ignorelist_item_s ignorelist_item_t;
+
+struct ignorelist_s
+{
+ int ignore; /* ignore entries */
+ ignorelist_item_t *head; /* pointer to the first entry */
+};
+
+/* *** *** *** ********************************************* *** *** *** */
+/* *** *** *** *** *** *** private functions *** *** *** *** *** *** */
+/* *** *** *** ********************************************* *** *** *** */
+
+static inline void ignorelist_append (ignorelist_t *il, ignorelist_item_t *item)
+{
+ assert ((il != NULL) && (item != NULL));
+
+ item->next = il->head;
+ il->head = item;
+}
+
+#if HAVE_REGEX_H
+static int ignorelist_append_regex(ignorelist_t *il, const char *re_str)
+{
+ regex_t *re;
+ ignorelist_item_t *entry;
+ int status;
+
+ re = malloc (sizeof (*re));
+ if (re == NULL)
+ {
+ ERROR ("utils_ignorelist: malloc failed");
+ return (ENOMEM);
+ }
+ memset (re, 0, sizeof (*re));
+
+ status = regcomp (re, re_str, REG_EXTENDED);
+ if (status != 0)
+ {
+ char errbuf[1024] = "";
+ regerror (status, re, errbuf, sizeof (errbuf));
+ ERROR ("utils_ignorelist: regcomp failed: %s", errbuf);
+ regfree (re);
+ sfree (re);
+ return (status);
+ }
+
+ entry = malloc (sizeof (*entry));
+ if (entry == NULL)
+ {
+ ERROR ("utils_ignorelist: malloc failed");
+ regfree (re);
+ sfree (re);
+ return (ENOMEM);
+ }
+ memset (entry, 0, sizeof (*entry));
+ entry->rmatch = re;
+
+ ignorelist_append (il, entry);
+ return (0);
+} /* int ignorelist_append_regex */
+#endif
+
+static int ignorelist_append_string(ignorelist_t *il, const char *entry)
+{
+ ignorelist_item_t *new;
+
+ /* create new entry */
+ if ((new = malloc(sizeof(ignorelist_item_t))) == NULL )
+ {
+ ERROR ("cannot allocate new entry");
+ return (1);
+ }
+ memset (new, '\0', sizeof(ignorelist_item_t));
+ new->smatch = sstrdup(entry);
+
+ /* append new entry */
+ ignorelist_append (il, new);
+
+ return (0);
+} /* int ignorelist_append_string(ignorelist_t *il, const char *entry) */
+
+#if HAVE_REGEX_H
+/*
+ * check list for entry regex match
+ * return 1 if found
+ */
+static int ignorelist_match_regex (ignorelist_item_t *item, const char *entry)
+{
+ assert ((item != NULL) && (item->rmatch != NULL)
+ && (entry != NULL) && (strlen (entry) > 0));
+
+ /* match regex */
+ if (regexec (item->rmatch, entry, 0, NULL, 0) == 0)
+ return (1);
+
+ return (0);
+} /* int ignorelist_match_regex (ignorelist_item_t *item, const char *entry) */
+#endif
+
+/*
+ * check list for entry string match
+ * return 1 if found
+ */
+static int ignorelist_match_string (ignorelist_item_t *item, const char *entry)
+{
+ assert ((item != NULL) && (item->smatch != NULL)
+ && (entry != NULL) && (strlen (entry) > 0));
+
+ if (strcmp (entry, item->smatch) == 0)
+ return (1);
+
+ return (0);
+} /* int ignorelist_match_string (ignorelist_item_t *item, const char *entry) */
+
+
+/* *** *** *** ******************************************** *** *** *** */
+/* *** *** *** *** *** *** public functions *** *** *** *** *** *** */
+/* *** *** *** ******************************************** *** *** *** */
+
+/*
+ * create the ignorelist_t with known ignore state
+ * return pointer to ignorelist_t
+ */
+ignorelist_t *ignorelist_create (int invert)
+{
+ ignorelist_t *il;
+
+ /* smalloc exits if it failes */
+ il = (ignorelist_t *) smalloc (sizeof (ignorelist_t));
+ memset (il, '\0', sizeof (ignorelist_t));
+
+ /*
+ * ->ignore == 0 => collect
+ * ->ignore == 1 => ignore
+ */
+ il->ignore = invert ? 0 : 1;
+
+ return (il);
+} /* ignorelist_t *ignorelist_create (int ignore) */
+
+/*
+ * free memory used by ignorelist_t
+ */
+void ignorelist_free (ignorelist_t *il)
+{
+ ignorelist_item_t *this;
+ ignorelist_item_t *next;
+
+ if (il == NULL)
+ return;
+
+ for (this = il->head; this != NULL; this = next)
+ {
+ next = this->next;
+#if HAVE_REGEX_H
+ if (this->rmatch != NULL)
+ {
+ regfree (this->rmatch);
+ sfree (this->rmatch);
+ this->rmatch = NULL;
+ }
+#endif
+ if (this->smatch != NULL)
+ {
+ sfree (this->smatch);
+ this->smatch = NULL;
+ }
+ sfree (this);
+ }
+
+ sfree (il);
+ il = NULL;
+} /* void ignorelist_destroy (ignorelist_t *il) */
+
+/*
+ * set ignore state of the ignorelist_t
+ */
+void ignorelist_set_invert (ignorelist_t *il, int invert)
+{
+ if (il == NULL)
+ {
+ DEBUG("ignore call with ignorelist_t == NULL");
+ return;
+ }
+
+ il->ignore = invert ? 0 : 1;
+} /* void ignorelist_set_invert (ignorelist_t *il, int ignore) */
+
+/*
+ * append entry into ignorelist_t
+ * return 0 for success
+ */
+int ignorelist_add (ignorelist_t *il, const char *entry)
+{
+ size_t entry_len;
+
+ if (il == NULL)
+ {
+ DEBUG ("add called with ignorelist_t == NULL");
+ return (1);
+ }
+
+ entry_len = strlen (entry);
+
+ /* append nothing */
+ if (entry_len == 0)
+ {
+ DEBUG("not appending: empty entry");
+ return (1);
+ }
+
+#if HAVE_REGEX_H
+ /* regex string is enclosed in "/.../" */
+ if ((entry_len > 2) && (entry[0] == '/') && entry[entry_len - 1] == '/')
+ {
+ char *entry_copy;
+ size_t entry_copy_size;
+ int status;
+
+ /* We need to copy `entry' since it's const */
+ entry_copy_size = entry_len - 1;
+ entry_copy = smalloc (entry_copy_size);
+ sstrncpy (entry_copy, entry + 1, entry_copy_size);
+
+ status = ignorelist_append_regex(il, entry_copy);
+ sfree (entry_copy);
+ return status;
+ }
+#endif
+
+ return ignorelist_append_string(il, entry);
+} /* int ignorelist_add (ignorelist_t *il, const char *entry) */
+
+/*
+ * check list for entry
+ * return 1 for ignored entry
+ */
+int ignorelist_match (ignorelist_t *il, const char *entry)
+{
+ ignorelist_item_t *traverse;
+
+ /* if no entries, collect all */
+ if ((il == NULL) || (il->head == NULL))
+ return (0);
+
+ if ((entry == NULL) || (strlen (entry) == 0))
+ return (0);
+
+ /* traverse list and check entries */
+ for (traverse = il->head; traverse != NULL; traverse = traverse->next)
+ {
+#if HAVE_REGEX_H
+ if (traverse->rmatch != NULL)
+ {
+ if (ignorelist_match_regex (traverse, entry))
+ return (il->ignore);
+ }
+ else
+#endif
+ {
+ if (ignorelist_match_string (traverse, entry))
+ return (il->ignore);
+ }
+ } /* for traverse */
+
+ return (1 - il->ignore);
+} /* int ignorelist_match (ignorelist_t *il, const char *entry) */
+
--- /dev/null
+/**
+ * collectd - src/utils_ignorelist.h
+ * Copyright (C) 2006 Lubos Stanek <lubek at users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public Licence for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * Licence along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ * USA.
+ *
+ * Authors:
+ * Lubos Stanek <lubek at users.sourceforge.net>
+ **/
+/**
+ * ignorelist handles plugin's list of configured collectable
+ * entries with global ignore action
+ **/
+
+#ifndef UTILS_IGNORELIST_H
+#define UTILS_IGNORELIST_H 1
+
+#include "collectd.h"
+
+#if HAVE_REGEX_H
+# include <regex.h>
+#endif
+
+/* public prototypes */
+
+struct ignorelist_s;
+typedef struct ignorelist_s ignorelist_t;
+
+/*
+ * create the ignorelist_t with known ignore state
+ * return pointer to ignorelist_t
+ */
+ignorelist_t *ignorelist_create (int invert);
+
+/*
+ * free memory used by ignorelist_t
+ */
+void ignorelist_free (ignorelist_t *il);
+
+/*
+ * set ignore state of the ignorelist_t
+ */
+void ignorelist_set_invert (ignorelist_t *il, int invert);
+
+/*
+ * append entry to ignorelist_t
+ * returns zero on success, non-zero upon failure.
+ */
+int ignorelist_add (ignorelist_t *il, const char *entry);
+
+/*
+ * check list for entry
+ * return 1 for ignored entry
+ */
+int ignorelist_match (ignorelist_t *il, const char *entry);
+
+#endif /* UTILS_IGNORELIST_H */
#include "common.h" /* for STATIC_ARRAY_SIZE */
#include "utils_subst.h"
+#if HAVE_LIBKSTAT
+kstat_ctl_t *kc;
+#endif /* HAVE_LIBKSTAT */
+
DEF_TEST(subst)
{
struct {
(tsp)->tv_sec = CDTIME_T_TO_TIME_T (cdt); \
(tsp)->tv_nsec = (long) CDTIME_T_TO_NS ((cdt) & 0x3fffffff); \
} while (0)
-#define TIMESPEC_TO_CDTIME_T(ts) NS_TO_CDTIME_T(1000000000 * (ts)->tv_sec + (ts)->tv_nsec)
+#define TIMESPEC_TO_CDTIME_T(ts) NS_TO_CDTIME_T(1000000000ULL * (ts)->tv_sec + (ts)->tv_nsec)
cdtime_t cdtime (void);
char *name;
char *select_db;
+ cdtime_t interval;
+
char *driver;
char *host;
cdbi_driver_option_t *driver_options;
*
* <Database "plugin_instance1">
* Driver "mysql"
+ * Interval 120
* DriverOption "hostname" "localhost"
* ...
* Query "plugin_instance0"
&db->queries, &db->queries_num);
else if (strcasecmp ("Host", child->key) == 0)
status = cf_util_get_string (child, &db->host);
+ else if (strcasecmp ("Interval", child->key) == 0)
+ status = cf_util_get_cdtime(child, &db->interval);
else
{
WARNING ("dbi plugin: Option `%s' not allowed here.", child->key);
plugin_register_complex_read (/* group = */ NULL,
/* name = */ name ? name : db->name,
/* callback = */ cdbi_read_database,
- /* interval = */ 0,
+ /* interval = */ (db->interval > 0) ? db->interval : 0,
/* user_data = */ &ud);
free (name);
}
udb_query_prepare_result (q, prep_area, (db->host ? db->host : hostname_g),
/* plugin = */ "dbi", db->name,
- column_names, column_num, /* interval = */ 0);
+ column_names, column_num, /* interval = */ (db->interval > 0) ? db->interval : 0);
/* 0 = error; 1 = success; */
status = dbi_result_first_row (res); /* {{{ */
AUTOMAKE_OPTIONS = foreign no-dependencies
-if COMPILER_IS_GCC
-AM_CFLAGS = -Wall -Werror
-endif
-
pkginclude_HEADERS = collectd/client.h collectd/network.h collectd/network_buffer.h collectd/lcc_features.h
lib_LTLIBRARIES = libcollectdclient.la
nodist_pkgconfig_DATA = libcollectdclient.pc
* format time as a UTC ISO 8601 compliant string
*/
strftime (timestamp_str, sizeof (timestamp_str),
- "%Y-%m-%d %H:%M:%SZ", ×tamp_tm);
+ "%Y-%m-%dT%H:%M:%SZ", ×tamp_tm);
timestamp_str[sizeof (timestamp_str) - 1] = '\0';
if (yajl_gen_string(g, (u_char *)timestamp_str,
#elif HAVE_LIBKSTAT
static int pagesize;
static kstat_t *ksp;
+static kstat_t *ksz;
/* #endif HAVE_LIBKSTAT */
#elif HAVE_SYSCTL
ksp = NULL;
return (-1);
}
+ if (get_kstat (&ksz, "zfs", 0, "arcstats") != 0)
+ {
+ ksz = NULL;
+ return (-1);
+ }
+
/* #endif HAVE_LIBKSTAT */
#elif HAVE_SYSCTL
long long mem_lock;
long long mem_kern;
long long mem_unus;
+ long long arcsize;
+
long long pp_kernel;
long long physmem;
if (ksp == NULL)
return (-1);
+ if (ksz == NULL)
+ return (-1);
mem_used = get_kstat_value (ksp, "pagestotal");
mem_free = get_kstat_value (ksp, "pagesfree");
mem_lock = get_kstat_value (ksp, "pageslocked");
- mem_kern = 0;
- mem_unus = 0;
-
+ arcsize = get_kstat_value (ksz, "size");
pp_kernel = get_kstat_value (ksp, "pp_kernel");
physmem = get_kstat_value (ksp, "physmem");
availrmem = get_kstat_value (ksp, "availrmem");
+ mem_kern = 0;
+ mem_unus = 0;
+
if ((mem_used < 0LL) || (mem_free < 0LL) || (mem_lock < 0LL))
{
WARNING ("memory plugin: one of used, free or locked is negative.");
mem_lock *= pagesize; /* some? ;) */
mem_kern *= pagesize; /* it's 2011 RAM is cheap */
mem_unus *= pagesize;
+ mem_kern -= arcsize;
+
MEMORY_SUBMIT ("used", (gauge_t) mem_used,
"free", (gauge_t) mem_free,
"locked", (gauge_t) mem_lock,
"kernel", (gauge_t) mem_kern,
+ "arc", (gauge_t) arcsize,
"unusable", (gauge_t) mem_unus);
/* #endif HAVE_LIBKSTAT */
* Authors:
* Marc Falzon <marc at baha dot mu>
* Florian octo Forster <octo at collectd.org>
+ * Jan-Piet Mens <jpmens at gmail.com>
**/
// Reference: http://mosquitto.org/api/files/mosquitto-h.html
#ifndef MQTT_KEEPALIVE
# define MQTT_KEEPALIVE 60
#endif
+#ifndef SSL_VERIFY_PEER
+# define SSL_VERIFY_PEER 1
+#endif
/*
char *username;
char *password;
int qos;
+ char *cacertificatefile;
+ char *certificatefile;
+ char *certificatekeyfile;
+ char *tlsprotocol;
+ char *ciphersuite;
/* For publishing */
char *topic_prefix;
char *payload;
int status;
- if ((msg->payloadlen <= 0)
- || (((uint8_t *) msg->payload)[msg->payloadlen - 1] != 0))
+ if (msg->payloadlen <= 0) {
+ DEBUG ("mqtt plugin: message has empty payload");
return;
+ }
topic = strdup (msg->topic);
name = strip_prefix (topic);
}
vl.values_len = ds->ds_num;
- payload = strdup ((void *) msg->payload);
+ payload = malloc (msg->payloadlen+1);
+ if (payload == NULL)
+ {
+ ERROR ("mqtt plugin: malloc for payload buffer failed.");
+ return;
+ }
+ memmove (payload, msg->payload, msg->payloadlen);
+ payload[msg->payloadlen] = 0;
+
DEBUG ("mqtt plugin: payload = \"%s\"", payload);
status = parse_values (payload, &vl, ds);
if (status != 0)
return (-1);
}
+#if LIBMOSQUITTO_MAJOR != 0
+ if (conf->cacertificatefile) {
+ status = mosquitto_tls_set(conf->mosq, conf->cacertificatefile, NULL,
+ conf->certificatefile, conf->certificatekeyfile, /* pw_callback */NULL);
+ if (status != MOSQ_ERR_SUCCESS) {
+ ERROR ("mqtt plugin: cannot mosquitto_tls_set: %s", mosquitto_strerror(status));
+ mosquitto_destroy (conf->mosq);
+ conf->mosq = NULL;
+ return (-1);
+ }
+
+ status = mosquitto_tls_opts_set(conf->mosq, SSL_VERIFY_PEER, conf->tlsprotocol, conf->ciphersuite);
+ if (status != MOSQ_ERR_SUCCESS) {
+ ERROR ("mqtt plugin: cannot mosquitto_tls_opts_set: %s", mosquitto_strerror(status));
+ mosquitto_destroy (conf->mosq);
+ conf->mosq = NULL;
+ return (-1);
+ }
+
+ status = mosquitto_tls_insecure_set(conf->mosq, false);
+ if (status != MOSQ_ERR_SUCCESS) {
+ ERROR ("mqtt plugin: cannot mosquitto_tls_insecure_set: %s", mosquitto_strerror(status));
+ mosquitto_destroy (conf->mosq);
+ conf->mosq = NULL;
+ return (-1);
+ }
+ }
+#endif
+
if (conf->username && conf->password)
{
status = mosquitto_username_pw_set (conf->mosq, conf->username, conf->password);
{
char errbuf[1024];
c_complain (LOG_ERR,
- &conf->complaint_cantpublish,
- "plugin mqtt: mosquitto_publish failed: %s",
- status == MOSQ_ERR_ERRNO ?
- sstrerror(errno, errbuf, sizeof (errbuf)) :
- mosquitto_strerror(status));
+ &conf->complaint_cantpublish,
+ "mqtt plugin: mosquitto_publish failed: %s",
+ (status == MOSQ_ERR_ERRNO)
+ ? sstrerror(errno, errbuf, sizeof (errbuf))
+ : mosquitto_strerror(status));
/* Mark our connection "down" regardless of the error as a safety
* measure; we will try to reconnect the next time we have to publish a
* message */
* StoreRates true
* Retain false
* QoS 0
+ * CACert "ca.pem" Enables TLS if set
+ * CertificateFile "client-cert.pem" optional
+ * CertificateKeyFile "client-key.pem" optional
+ * TLSProtocol "tlsv1.2" optional
* </Publish>
*/
static int mqtt_config_publisher (oconfig_item_t *ci)
conf->topic_prefix = strdup (MQTT_DEFAULT_TOPIC_PREFIX);
conf->store_rates = 1;
+ status = pthread_mutex_init (&conf->lock, NULL);
+ if (status != 0)
+ {
+ mqtt_free (conf);
+ return (status);
+ }
+
C_COMPLAIN_INIT (&conf->complaint_cantpublish);
for (i = 0; i < ci->children_num; i++)
cf_util_get_boolean (child, &conf->store_rates);
else if (strcasecmp ("Retain", child->key) == 0)
cf_util_get_boolean (child, &conf->retain);
+ else if (strcasecmp ("CACert", child->key) == 0)
+ cf_util_get_string (child, &conf->cacertificatefile);
+ else if (strcasecmp ("CertificateFile", child->key) == 0)
+ cf_util_get_string (child, &conf->certificatefile);
+ else if (strcasecmp ("CertificateKeyFile", child->key) == 0)
+ cf_util_get_string (child, &conf->certificatekeyfile);
+ else if (strcasecmp ("TLSProtocol", child->key) == 0)
+ cf_util_get_string (child, &conf->tlsprotocol);
+ else if (strcasecmp ("CipherSuite", child->key) == 0)
+ cf_util_get_string (child, &conf->ciphersuite);
else
ERROR ("mqtt plugin: Unknown config option: %s", child->key);
}
* User "guest"
* Password "secret"
* Topic "collectd/#"
- * </Publish>
+ * </Subscribe>
*/
static int mqtt_config_subscriber (oconfig_item_t *ci)
{
conf->topic = strdup (MQTT_DEFAULT_TOPIC);
conf->clean_session = 1;
+ status = pthread_mutex_init (&conf->lock, NULL);
+ if (status != 0)
+ {
+ mqtt_free (conf);
+ return (status);
+ }
+
C_COMPLAIN_INIT (&conf->complaint_cantpublish);
for (i = 0; i < ci->children_num; i++)
pse.io_syscw = -1;
ps_list_add (procs[i].ki_comm, have_cmdline ? cmdline : NULL, &pse);
- } /* if ((proc_ptr == NULL) || (proc_ptr->ki_pid != procs[i].ki_pid)) */
- switch (procs[i].ki_stat)
- {
- case SSTOP: stopped++; break;
- case SSLEEP: sleeping++; break;
- case SRUN: running++; break;
- case SIDL: idle++; break;
- case SWAIT: wait++; break;
- case SLOCK: blocked++; break;
- case SZOMB: zombies++; break;
- }
+ switch (procs[i].ki_stat)
+ {
+ case SSTOP: stopped++; break;
+ case SSLEEP: sleeping++; break;
+ case SRUN: running++; break;
+ case SIDL: idle++; break;
+ case SWAIT: wait++; break;
+ case SLOCK: blocked++; break;
+ case SZOMB: zombies++; break;
+ }
+ } /* if ((proc_ptr == NULL) || (proc_ptr->ki_pid != procs[i].ki_pid)) */
}
kvm_close(kd);
pse.cswitch_invol = -1;
ps_list_add (procs[i].p_comm, have_cmdline ? cmdline : NULL, &pse);
- } /* if ((proc_ptr == NULL) || (proc_ptr->p_pid != procs[i].p_pid)) */
- switch (procs[i].p_stat)
- {
- case SSTOP: stopped++; break;
- case SSLEEP: sleeping++; break;
- case SRUN: running++; break;
- case SIDL: idle++; break;
- case SONPROC: onproc++; break;
- case SDEAD: dead++; break;
- case SZOMB: zombies++; break;
- }
+ switch (procs[i].p_stat)
+ {
+ case SSTOP: stopped++; break;
+ case SSLEEP: sleeping++; break;
+ case SRUN: running++; break;
+ case SIDL: idle++; break;
+ case SONPROC: onproc++; break;
+ case SDEAD: dead++; break;
+ case SZOMB: zombies++; break;
+ }
+ } /* if ((proc_ptr == NULL) || (proc_ptr->p_pid != procs[i].p_pid)) */
}
kvm_close(kd);
Py_XDECREF(traceback);
return;
}
- list = PyObject_CallFunction(cpy_format_exception, "NNN", type, value, traceback); /* New reference. */
+ list = PyObject_CallFunction(cpy_format_exception, "NNN", type, value, traceback); /* New reference. Steals references from "type", "value" and "traceback". */
if (list)
l = PyObject_Length(list);
for (i = 0; i < l; ++i) {
}
Py_XDECREF(list);
PyErr_Clear();
- Py_DECREF(type);
- Py_XDECREF(value);
- Py_XDECREF(traceback);
}
static int cpy_read_callback(user_data_t *data) {
tmp_unsigned = (uint32_t) *vl->val.integer;
tmp_signed = (int32_t) *vl->val.integer;
- if ((vl->type == ASN_INTEGER)
- || (vl->type == ASN_GAUGE))
+ if (vl->type == ASN_INTEGER)
prefer_signed = 1;
DEBUG ("snmp plugin: Parsed int32 value is %"PRIu64".", tmp_unsigned);
if (host->sess_handle == NULL)
{
- DEBUG ("snmp plugin: csnmp_read_table: host->sess_handle == NULL");
+ DEBUG ("snmp plugin: csnmp_read_value: host->sess_handle == NULL");
return (-1);
}
else
values[0].gauge = (gauge_t) c_avl_size (metric->set);
}
- else
- values[0].derive = (derive_t) metric->value;
+ else { /* STATSD_COUNTER */
+ /*
+ * Expand a single value to two metrics:
+ *
+ * - The absolute counter, as a gauge
+ * - A derived rate for this counter
+ */
+ values[0].derive = (derive_t) metric->value;
+ plugin_dispatch_values(&vl);
+
+ sstrncpy(vl.type, "gauge", sizeof (vl.type));
+ values[0].gauge = (gauge_t) metric->value;
+ }
return (plugin_dispatch_values (&vl));
} /* }}} int statsd_metric_submit_unsafe */
while (c_avl_pick (metrics_tree, &key, &value) == 0)
{
sfree (key);
- sfree (value);
+ statsd_metric_free (value);
}
c_avl_destroy (metrics_tree);
metrics_tree = NULL;
}
if (i <= tbl->max_colnum) {
- log_err ("Not enough columns in line "
+ log_warn ("Not enough columns in line "
"(expected at least %zu, got %zu).",
tbl->max_colnum + 1, i);
return -1;
while (NULL != fgets (buf, sizeof (buf), fh)) {
if ('\0' != buf[sizeof (buf) - 1]) {
buf[sizeof (buf) - 1] = '\0';
- log_err ("Table %s: Truncated line: %s", tbl->file, buf);
+ log_warn ("Table %s: Truncated line: %s", tbl->file, buf);
}
if (0 != tbl_parse_line (tbl, buf, sizeof (buf))) {
- log_err ("Table %s: Failed to parse line: %s", tbl->file, buf);
+ log_warn ("Table %s: Failed to parse line: %s", tbl->file, buf);
continue;
}
}
cache_operation value:DERIVE:0:U
cache_ratio value:GAUGE:0:100
cache_result value:DERIVE:0:U
-cache_size value:GAUGE:0:U
+cache_size value:GAUGE:0:1125899906842623
+capacity value:GAUGE:0:U
ceph_bytes value:GAUGE:U:U
ceph_latency value:GAUGE:U:U
ceph_rate value:DERIVE:0:U
+++ /dev/null
-/**
- * collectd - src/utils_ignorelist.c
- * Copyright (C) 2006 Lubos Stanek <lubek at users.sourceforge.net>
- * Copyright (C) 2008 Florian Forster <octo at collectd.org>
- *
- * This program is free software; you can redistribute it and/
- * or modify it under the terms of the GNU General Public Li-
- * cence as published by the Free Software Foundation; either
- * version 2 of the Licence, or any later version.
- *
- * This program is distributed in the hope that it will be use-
- * ful, but WITHOUT ANY WARRANTY; without even the implied war-
- * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public Licence for more details.
- *
- * You should have received a copy of the GNU General Public
- * Licence along with this program; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
- * USA.
- *
- * Authors:
- * Lubos Stanek <lubek at users.sourceforge.net>
- * Florian Forster <octo at collectd.org>
- **/
-/**
- * ignorelist handles plugin's list of configured collectable
- * entries with global ignore action
- **/
-/**
- * Usage:
- *
- * Define plugin's global pointer variable of type ignorelist_t:
- * ignorelist_t *myconfig_ignore;
- * If you know the state of the global ignore (IgnoreSelected),
- * allocate the variable with:
- * myconfig_ignore = ignorelist_create (YourKnownIgnore);
- * If you do not know the state of the global ignore,
- * initialize the global variable and set the ignore flag later:
- * myconfig_ignore = ignorelist_init ();
- * Append single entries in your cf_register'ed callback function:
- * ignorelist_add (myconfig_ignore, newentry);
- * When you hit the IgnoreSelected config option,
- * offer it to the list:
- * ignorelist_ignore (myconfig_ignore, instantly_got_value_of_ignore);
- * That is all for the ignorelist initialization.
- * Later during read and write (plugin's registered functions) get
- * the information whether this entry would be collected or not:
- * if (ignorelist_match (myconfig_ignore, thisentry))
- * return;
- **/
-
-#if HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "common.h"
-#include "plugin.h"
-#include "utils_ignorelist.h"
-
-/*
- * private prototypes
- */
-struct ignorelist_item_s
-{
-#if HAVE_REGEX_H
- regex_t *rmatch; /* regular expression entry identification */
-#endif
- char *smatch; /* string entry identification */
- struct ignorelist_item_s *next;
-};
-typedef struct ignorelist_item_s ignorelist_item_t;
-
-struct ignorelist_s
-{
- int ignore; /* ignore entries */
- ignorelist_item_t *head; /* pointer to the first entry */
-};
-
-/* *** *** *** ********************************************* *** *** *** */
-/* *** *** *** *** *** *** private functions *** *** *** *** *** *** */
-/* *** *** *** ********************************************* *** *** *** */
-
-static inline void ignorelist_append (ignorelist_t *il, ignorelist_item_t *item)
-{
- assert ((il != NULL) && (item != NULL));
-
- item->next = il->head;
- il->head = item;
-}
-
-#if HAVE_REGEX_H
-static int ignorelist_append_regex(ignorelist_t *il, const char *re_str)
-{
- regex_t *re;
- ignorelist_item_t *entry;
- int status;
-
- re = malloc (sizeof (*re));
- if (re == NULL)
- {
- ERROR ("utils_ignorelist: malloc failed");
- return (ENOMEM);
- }
- memset (re, 0, sizeof (*re));
-
- status = regcomp (re, re_str, REG_EXTENDED);
- if (status != 0)
- {
- char errbuf[1024] = "";
- regerror (status, re, errbuf, sizeof (errbuf));
- ERROR ("utils_ignorelist: regcomp failed: %s", errbuf);
- regfree (re);
- sfree (re);
- return (status);
- }
-
- entry = malloc (sizeof (*entry));
- if (entry == NULL)
- {
- ERROR ("utils_ignorelist: malloc failed");
- regfree (re);
- sfree (re);
- return (ENOMEM);
- }
- memset (entry, 0, sizeof (*entry));
- entry->rmatch = re;
-
- ignorelist_append (il, entry);
- return (0);
-} /* int ignorelist_append_regex */
-#endif
-
-static int ignorelist_append_string(ignorelist_t *il, const char *entry)
-{
- ignorelist_item_t *new;
-
- /* create new entry */
- if ((new = malloc(sizeof(ignorelist_item_t))) == NULL )
- {
- ERROR ("cannot allocate new entry");
- return (1);
- }
- memset (new, '\0', sizeof(ignorelist_item_t));
- new->smatch = sstrdup(entry);
-
- /* append new entry */
- ignorelist_append (il, new);
-
- return (0);
-} /* int ignorelist_append_string(ignorelist_t *il, const char *entry) */
-
-#if HAVE_REGEX_H
-/*
- * check list for entry regex match
- * return 1 if found
- */
-static int ignorelist_match_regex (ignorelist_item_t *item, const char *entry)
-{
- assert ((item != NULL) && (item->rmatch != NULL)
- && (entry != NULL) && (strlen (entry) > 0));
-
- /* match regex */
- if (regexec (item->rmatch, entry, 0, NULL, 0) == 0)
- return (1);
-
- return (0);
-} /* int ignorelist_match_regex (ignorelist_item_t *item, const char *entry) */
-#endif
-
-/*
- * check list for entry string match
- * return 1 if found
- */
-static int ignorelist_match_string (ignorelist_item_t *item, const char *entry)
-{
- assert ((item != NULL) && (item->smatch != NULL)
- && (entry != NULL) && (strlen (entry) > 0));
-
- if (strcmp (entry, item->smatch) == 0)
- return (1);
-
- return (0);
-} /* int ignorelist_match_string (ignorelist_item_t *item, const char *entry) */
-
-
-/* *** *** *** ******************************************** *** *** *** */
-/* *** *** *** *** *** *** public functions *** *** *** *** *** *** */
-/* *** *** *** ******************************************** *** *** *** */
-
-/*
- * create the ignorelist_t with known ignore state
- * return pointer to ignorelist_t
- */
-ignorelist_t *ignorelist_create (int invert)
-{
- ignorelist_t *il;
-
- /* smalloc exits if it failes */
- il = (ignorelist_t *) smalloc (sizeof (ignorelist_t));
- memset (il, '\0', sizeof (ignorelist_t));
-
- /*
- * ->ignore == 0 => collect
- * ->ignore == 1 => ignore
- */
- il->ignore = invert ? 0 : 1;
-
- return (il);
-} /* ignorelist_t *ignorelist_create (int ignore) */
-
-/*
- * free memory used by ignorelist_t
- */
-void ignorelist_free (ignorelist_t *il)
-{
- ignorelist_item_t *this;
- ignorelist_item_t *next;
-
- if (il == NULL)
- return;
-
- for (this = il->head; this != NULL; this = next)
- {
- next = this->next;
-#if HAVE_REGEX_H
- if (this->rmatch != NULL)
- {
- regfree (this->rmatch);
- sfree (this->rmatch);
- this->rmatch = NULL;
- }
-#endif
- if (this->smatch != NULL)
- {
- sfree (this->smatch);
- this->smatch = NULL;
- }
- sfree (this);
- }
-
- sfree (il);
- il = NULL;
-} /* void ignorelist_destroy (ignorelist_t *il) */
-
-/*
- * set ignore state of the ignorelist_t
- */
-void ignorelist_set_invert (ignorelist_t *il, int invert)
-{
- if (il == NULL)
- {
- DEBUG("ignore call with ignorelist_t == NULL");
- return;
- }
-
- il->ignore = invert ? 0 : 1;
-} /* void ignorelist_set_invert (ignorelist_t *il, int ignore) */
-
-/*
- * append entry into ignorelist_t
- * return 0 for success
- */
-int ignorelist_add (ignorelist_t *il, const char *entry)
-{
- size_t entry_len;
-
- if (il == NULL)
- {
- DEBUG ("add called with ignorelist_t == NULL");
- return (1);
- }
-
- entry_len = strlen (entry);
-
- /* append nothing */
- if (entry_len == 0)
- {
- DEBUG("not appending: empty entry");
- return (1);
- }
-
-#if HAVE_REGEX_H
- /* regex string is enclosed in "/.../" */
- if ((entry_len > 2) && (entry[0] == '/') && entry[entry_len - 1] == '/')
- {
- char *entry_copy;
- size_t entry_copy_size;
- int status;
-
- /* We need to copy `entry' since it's const */
- entry_copy_size = entry_len - 1;
- entry_copy = smalloc (entry_copy_size);
- sstrncpy (entry_copy, entry + 1, entry_copy_size);
-
- status = ignorelist_append_regex(il, entry_copy);
- sfree (entry_copy);
- return status;
- }
-#endif
-
- return ignorelist_append_string(il, entry);
-} /* int ignorelist_add (ignorelist_t *il, const char *entry) */
-
-/*
- * check list for entry
- * return 1 for ignored entry
- */
-int ignorelist_match (ignorelist_t *il, const char *entry)
-{
- ignorelist_item_t *traverse;
-
- /* if no entries, collect all */
- if ((il == NULL) || (il->head == NULL))
- return (0);
-
- if ((entry == NULL) || (strlen (entry) == 0))
- return (0);
-
- /* traverse list and check entries */
- for (traverse = il->head; traverse != NULL; traverse = traverse->next)
- {
-#if HAVE_REGEX_H
- if (traverse->rmatch != NULL)
- {
- if (ignorelist_match_regex (traverse, entry))
- return (il->ignore);
- }
- else
-#endif
- {
- if (ignorelist_match_string (traverse, entry))
- return (il->ignore);
- }
- } /* for traverse */
-
- return (1 - il->ignore);
-} /* int ignorelist_match (ignorelist_t *il, const char *entry) */
-
+++ /dev/null
-/**
- * collectd - src/utils_ignorelist.h
- * Copyright (C) 2006 Lubos Stanek <lubek at users.sourceforge.net>
- *
- * This program is free software; you can redistribute it and/
- * or modify it under the terms of the GNU General Public Li-
- * cence as published by the Free Software Foundation; either
- * version 2 of the Licence, or any later version.
- *
- * This program is distributed in the hope that it will be use-
- * ful, but WITHOUT ANY WARRANTY; without even the implied war-
- * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public Licence for more details.
- *
- * You should have received a copy of the GNU General Public
- * Licence along with this program; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
- * USA.
- *
- * Authors:
- * Lubos Stanek <lubek at users.sourceforge.net>
- **/
-/**
- * ignorelist handles plugin's list of configured collectable
- * entries with global ignore action
- **/
-
-#ifndef UTILS_IGNORELIST_H
-#define UTILS_IGNORELIST_H 1
-
-#include "collectd.h"
-
-#if HAVE_REGEX_H
-# include <regex.h>
-#endif
-
-/* public prototypes */
-
-struct ignorelist_s;
-typedef struct ignorelist_s ignorelist_t;
-
-/*
- * create the ignorelist_t with known ignore state
- * return pointer to ignorelist_t
- */
-ignorelist_t *ignorelist_create (int invert);
-
-/*
- * free memory used by ignorelist_t
- */
-void ignorelist_free (ignorelist_t *il);
-
-/*
- * set ignore state of the ignorelist_t
- */
-void ignorelist_set_invert (ignorelist_t *il, int invert);
-
-/*
- * append entry to ignorelist_t
- * returns zero on success, non-zero upon failure.
- */
-int ignorelist_add (ignorelist_t *il, const char *entry);
-
-/*
- * check list for entry
- * return 1 for ignored entry
- */
-int ignorelist_match (ignorelist_t *il, const char *entry);
-
-#endif /* UTILS_IGNORELIST_H */
#warn "This version of `getmntent' hat not yet been implemented!"
/* #endif HAVE_SEQ_GETMNTENT */
+#elif HAVE_GETMNTENT_R
+static cu_mount_t *cu_mount_getmntent (void)
+{
+ FILE *fp;
+ struct mntent me;
+ char mntbuf[1024];
+
+ cu_mount_t *first = NULL;
+ cu_mount_t *last = NULL;
+ cu_mount_t *new = NULL;
+
+ DEBUG ("utils_mount: (void); COLLECTD_MNTTAB = %s", COLLECTD_MNTTAB);
+
+ if ((fp = setmntent (COLLECTD_MNTTAB, "r")) == NULL)
+ {
+ char errbuf[1024];
+ ERROR ("setmntent (%s): %s", COLLECTD_MNTTAB,
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ return (NULL);
+ }
+
+ while (getmntent_r (fp, &me, mntbuf, sizeof (mntbuf) ))
+ {
+ if ((new = malloc (sizeof (cu_mount_t))) == NULL)
+ break;
+ memset (new, '\0', sizeof (cu_mount_t));
+
+ /* Copy values from `struct mntent *' */
+ new->dir = sstrdup (me.mnt_dir);
+ new->spec_device = sstrdup (me.mnt_fsname);
+ new->type = sstrdup (me.mnt_type);
+ new->options = sstrdup (me.mnt_opts);
+ new->device = get_device_name (new->options);
+ new->next = NULL;
+
+ DEBUG ("utils_mount: new = {dir = %s, spec_device = %s, type = %s, options = %s, device = %s}",
+ new->dir, new->spec_device, new->type, new->options, new->device);
+
+ /* Append to list */
+ if (first == NULL)
+ {
+ first = new;
+ last = new;
+ }
+ else
+ {
+ last->next = new;
+ last = new;
+ }
+ }
+
+ endmntent (fp);
+
+ DEBUG ("utils_mount: return (0x%p)", (void *) first);
+
+ return (first);
+} /* HAVE_GETMNTENT_R */
+
#elif HAVE_ONE_GETMNTENT
static cu_mount_t *cu_mount_getmntent (void)
{
#include "collectd.h"
#include "utils_mount.h"
+#if HAVE_LIBKSTAT
+kstat_ctl_t *kc;
+#endif /* HAVE_LIBKSTAT */
+
DEF_TEST(cu_mount_checkoption)
{
char line_opts[] = "foo=one,bar=two,qux=three";
#include "utils_vl_lookup.h"
#include "utils_avltree.h"
+#if HAVE_LIBKSTAT
+kstat_ctl_t *kc;
+#endif /* HAVE_LIBKSTAT */
+
#if BUILD_TEST
# define sstrncpy strncpy
# define plugin_log(s, ...) do { \
};
static enum plginst_field plugin_instance_format[PLGINST_MAX_FIELDS] =
- { plginst_name };
+ { plginst_none };
/* InterfaceFormat. */
enum if_field {
else if (strcasecmp (fields[i], "uuid") == 0)
hostname_format[i] = hf_uuid;
else {
- sfree (value_copy);
ERROR (PLUGIN_NAME " plugin: unknown HostnameFormat field: %s", fields[i]);
+ sfree (value_copy);
return -1;
}
}
}
for (i = 0; i < n; ++i) {
- if (strcasecmp (fields[i], "name") == 0)
+ if (strcasecmp (fields[i], "none") == 0) {
+ plugin_instance_format[i] = plginst_none;
+ break;
+ } else if (strcasecmp (fields[i], "name") == 0)
plugin_instance_format[i] = plginst_name;
else if (strcasecmp (fields[i], "uuid") == 0)
plugin_instance_format[i] = plginst_uuid;
else {
+ ERROR (PLUGIN_NAME " plugin: unknown PluginInstanceFormat field: %s", fields[i]);
sfree (value_copy);
- ERROR (PLUGIN_NAME " plugin: unknown HostnameFormat field: %s", fields[i]);
return -1;
}
}
char *clientkeypass;
long sslversion;
_Bool store_rates;
+ _Bool log_http_error;
int low_speed_limit;
time_t low_speed_time;
int timeout;
};
typedef struct wh_callback_s wh_callback_t;
+static void wh_log_http_error (wh_callback_t *cb)
+{
+ if (!cb->log_http_error)
+ return;
+
+ long http_code = 0;
+
+ curl_easy_getinfo (cb->curl, CURLINFO_RESPONSE_CODE, &http_code);
+
+ if (http_code != 200)
+ INFO ("write_http plugin: HTTP Error code: %lu", http_code);
+}
+
static void wh_reset_buffer (wh_callback_t *cb) /* {{{ */
{
memset (cb->send_buffer, 0, cb->send_buffer_size);
curl_easy_setopt (cb->curl, CURLOPT_POSTFIELDS, cb->send_buffer);
status = curl_easy_perform (cb->curl);
+
+ wh_log_http_error (cb);
+
if (status != CURLE_OK)
{
ERROR ("write_http plugin: curl_easy_perform failed with "
cb->sslversion = CURL_SSLVERSION_DEFAULT;
cb->low_speed_limit = 0;
cb->timeout = 0;
+ cb->log_http_error = 0;
pthread_mutex_init (&cb->send_lock, /* attr = */ NULL);
cf_util_get_int (child, &cb->low_speed_limit);
else if (strcasecmp ("Timeout", child->key) == 0)
cf_util_get_int (child, &cb->timeout);
+ else if (strcasecmp ("LogHttpError", child->key) == 0)
+ cf_util_get_boolean (child, &cb->log_http_error);
else
{
ERROR ("write_http plugin: Invalid configuration "
struct timeval timeout;
char *prefix;
int database;
+ int max_set_size;
+ _Bool store_rates;
redisContext *conn;
pthread_mutex_t lock;
char *value_ptr;
int status;
redisReply *rr;
- int i;
status = FORMAT_VL (ident, sizeof (ident), vl);
if (status != 0)
memset (value, 0, sizeof (value));
value_size = sizeof (value);
value_ptr = &value[0];
-
-#define APPEND(...) do { \
- status = snprintf (value_ptr, value_size, __VA_ARGS__); \
- if (((size_t) status) > value_size) \
- { \
- value_ptr += value_size; \
- value_size = 0; \
- } \
- else \
- { \
- value_ptr += status; \
- value_size -= status; \
- } \
-} while (0)
-
- APPEND ("%s:", time);
-
- for (i = 0; i < ds->ds_num; i++)
- {
- if (ds->ds[i].type == DS_TYPE_COUNTER)
- APPEND ("%llu", vl->values[i].counter);
- else if (ds->ds[i].type == DS_TYPE_GAUGE)
- APPEND (GAUGE_FORMAT, vl->values[i].gauge);
- else if (ds->ds[i].type == DS_TYPE_DERIVE)
- APPEND ("%"PRIi64, vl->values[i].derive);
- else if (ds->ds[i].type == DS_TYPE_ABSOLUTE)
- APPEND ("%"PRIu64, vl->values[i].absolute);
- else
- assert (23 == 42);
- }
-
-#undef APPEND
-
- status = format_values (value_ptr, value_size, ds, vl, /* store rates = */ 0);
+ status = format_values (value_ptr, value_size, ds, vl, node->store_rates);
pthread_mutex_lock (&node->lock);
if (status != 0)
return (status);
pthread_mutex_unlock (&node->lock);
return (-1);
}
-
+
rr = redisCommand(node->conn, "SELECT %d", node->database);
if (rr == NULL)
WARNING("SELECT command error. database:%d message:%s", node->database, node->conn->errstr);
else
freeReplyObject (rr);
+ if (node->max_set_size >= 0)
+ {
+ rr = redisCommand (node->conn, "ZREMRANGEBYRANK %s %d %d", key, 0, (-1 * node->max_set_size) - 1);
+ if (rr == NULL)
+ WARNING("ZREMRANGEBYRANK command error. key:%s message:%s", key, node->conn->errstr);
+ else
+ freeReplyObject (rr);
+ }
+
/* TODO(octo): This is more overhead than necessary. Use the cache and
* metadata to determine if it is a new metric and call SADD only once for
* each metric. */
node->conn = NULL;
node->prefix = NULL;
node->database = 0;
+ node->max_set_size = -1;
+ node->store_rates = 1;
pthread_mutex_init (&node->lock, /* attr = */ NULL);
status = cf_util_get_string_buffer (ci, node->name, sizeof (node->name));
else if (strcasecmp ("Database", child->key) == 0) {
status = cf_util_get_int (child, &node->database);
}
+ else if (strcasecmp ("MaxSetSize", child->key) == 0) {
+ status = cf_util_get_int (child, &node->max_set_size);
+ }
+ else if (strcasecmp ("StoreRates", child->key) == 0) {
+ status = cf_util_get_boolean (child, &node->store_rates);
+ }
else
WARNING ("write_redis plugin: Ignoring unknown config option \"%s\".",
child->key);
/* Sizes */
za_read_gauge (ksp, "size", "cache_size", "arc");
+ za_read_gauge (ksp, "c", "cache_size", "c");
+ za_read_gauge (ksp, "c_min", "cache_size", "c_min");
+ za_read_gauge (ksp, "c_max", "cache_size", "c_max");
/* The "l2_size" value has disappeared from Solaris some time in
* early 2013, and has only reappeared recently in Solaris 11.2.