[pcp] PCP Zabbix Agent PMDA

Marko Myllynen myllynen at redhat.com
Wed Oct 28 04:47:00 CDT 2015


Hi!

As mentioned in [1], one of the possible alternatives to integrate PCP
with Zabbix would be to create a Zabbix agent PMDA. But as already
warned in [1], this is probably not what most people want:

There's certain correlation between the ugliness of the code and its
uselessness so most people should probably completely ignore this one.

1) http://oss.sgi.com/pipermail/pcp/2015-October/008550.html

The PMDA was easy enough to implement so I did it anyway and thought to
share it here. I think it might worth adding to pcp.git but after the
comments above obviously I'm not going to protest loudly if that won't
happen :)


https://www.zabbix.com/documentation/3.0/manual/config/items/itemtypes/zabbix_agent
https://www.zabbix.com/documentation/3.0/manual/appendix/items/supported_by_platform
https://www.zabbix.com/documentation/3.0/manual/appendix/items/activepassive

---
 src/pmdas/zabbixagent/Install            |  32 ++++++
 src/pmdas/zabbixagent/Remove             |  23 ++++
 src/pmdas/zabbixagent/pmdazabbixagent.1  |  86 ++++++++++++++
 src/pmdas/zabbixagent/pmdazabbixagent.pl | 186 +++++++++++++++++++++++++++++++
 4 files changed, 327 insertions(+)
 create mode 100644 src/pmdas/zabbixagent/Install
 create mode 100644 src/pmdas/zabbixagent/Remove
 create mode 100644 src/pmdas/zabbixagent/pmdazabbixagent.1
 create mode 100644 src/pmdas/zabbixagent/pmdazabbixagent.pl

diff --git a/src/pmdas/zabbixagent/Install b/src/pmdas/zabbixagent/Install
new file mode 100644
index 0000000..d5ac72b
--- /dev/null
+++ b/src/pmdas/zabbixagent/Install
@@ -0,0 +1,32 @@
+#!/bin/sh
+#
+# Copyright (C) 2015 Marko Myllynen <myllynen at redhat.com>
+#
+# 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
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+
+. $PCP_DIR/etc/pcp.env
+. $PCP_SHARE_DIR/lib/pmdaproc.sh
+
+iam=zabbixagent
+perl_opt=true
+daemon_opt=false
+forced_restart=false
+
+which zabbix_get > /dev/null 2>&1
+if test $? -ne 0; then
+    echo "zabbix_get is not installed"
+    exit 1
+fi
+
+pmdaSetup
+pmdaInstall
+exit 0
diff --git a/src/pmdas/zabbixagent/Remove b/src/pmdas/zabbixagent/Remove
new file mode 100644
index 0000000..3ff7875
--- /dev/null
+++ b/src/pmdas/zabbixagent/Remove
@@ -0,0 +1,23 @@
+#!/bin/sh
+#
+# Copyright (C) 2015 Marko Myllynen <myllynen at redhat.com>
+#
+# 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
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+
+. $PCP_DIR/etc/pcp.env
+. $PCP_SHARE_DIR/lib/pmdaproc.sh
+
+iam=zabbixagent
+
+pmdaSetup
+pmdaRemove
+exit 0
diff --git a/src/pmdas/zabbixagent/pmdazabbixagent.1 b/src/pmdas/zabbixagent/pmdazabbixagent.1
new file mode 100644
index 0000000..91cbdfe
--- /dev/null
+++ b/src/pmdas/zabbixagent/pmdazabbixagent.1
@@ -0,0 +1,86 @@
+'\"macro stdmacro
+.\"
+.\" Copyright (C) 2015 Marko Myllynen <myllynen at redhat.com>
+.\" 
+.\" 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
+.\" Free Software Foundation; either version 2 of the License, or (at your
+.\" option) any later version.
+.\" 
+.\" This program is distributed in the hope that it will be useful, but
+.\" WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+.\" or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+.\" for more details.
+.\"
+.TH PMDAZABBIXAGENT 1 "PCP" "Performance Co-Pilot"
+.SH NAME
+\f3pmdazabbixagent\f1 \- Zabbix agent PMDA
+.SH DESCRIPTION
+\f3pmdazabbixagent\f1 is a Performance Metrics Domain Agent (\s-1PMDA\s0)
+which extracts live metrics from a running Zabbix agent instance.
+.PP
+See the Zabbix documentation for description of each standard metric.
+Note that only a small subset of those standard metrics are provided by
+this PMDA. Also, possible custom metrics provided by loadable modules
+used to extend the Zabbix agent metric set need to be manually added in
+the PMDA code. Thus this PMDA should be considered more as an example or
+a starting point rather than a fully featured PMDA.
+.PP
+Currenly only passive checks for metrics are supported.
+.PP
+This PMDA does not work with default SELinux rules enabled. Preferably
+use \fIaudit2allow\fR(1) to create the needed rules or disable SELinux.
+.PP
+.SH INSTALLATION
+\f3pmdazabbixagent\f1 uses a configuration file
+.IP "\(bu" 4
+.I $PCP_PMDAS_DIR/zabbixagent/zabbixagent.conf
+.PP
+This file can contain overridden values (Perl code) for the settings
+listed at the start of
+.IR pmdazabbixagent.pl ,
+namely:
+.IP "\(bu" 4
+Zabbix agent host
+.IP "\(bu" 4
+Zabbix agent port
+.IP "\(bu" 4
+Source IP for requests
+.PP
+Once this is setup, you can access the names and values for the
+Zabbix agent metrics by doing the following as root:
+.PP
+      # cd $PCP_PMDAS_DIR/zabbixagent
+.br
+      # ./Install
+.PP
+To uninstall, do the following as root:
+.PP
+      # cd $PCP_PMDAS_DIR/zabbixagent
+.br
+      # ./Remove
+.PP
+\fBpmdazabbixagent\fR is launched by \fIpmcd\fR(1) and should never be
+executed directly. The Install and Remove scripts notify \fIpmcd\fR(1)
+when the PMDA is installed or removed.
+.SH FILES
+.IP "\fB$PCP_PMDAS_DIR/zabbixagent/zabbixagent.conf\fR" 4
+configuration file for the \fBpmdazabbixagent\fR PMDA
+.IP "\fB$PCP_PMDAS_DIR/zabbixagent/Install\fR" 4 
+installation script for the \fBpmdazabbixagent\fR PMDA
+.IP "\fB$PCP_PMDAS_DIR/zabbixagent/Remove\fR" 4 
+undo installation script for the \fBpmdazabbixagent\fR PMDA
+.IP "\fB$PCP_LOG_DIR/pmcd/zabbixagent.log\fR" 4 
+default log file for error messages from \fBpmdazabbixagent\fR PMDA
+.SH PCP ENVIRONMENT
+Environment variables with the prefix \fBPCP_\fR are used to parameterize
+the file and directory names used by \fBPCP\fR. On each installation, the
+file \fB/etc/pcp.conf\fR contains the local values for these variables. 
+The \fB$PCP_CONF\fR variable may be used to specify an alternative 
+configuration file, as described in \fIpcp.conf\fR(5).
+.SH SEE ALSO
+.BR PCPIntro (1),
+.BR pmcd (1),
+.BR zabbix_get (1)
+and
+.BR audit2allow (1).
diff --git a/src/pmdas/zabbixagent/pmdazabbixagent.pl b/src/pmdas/zabbixagent/pmdazabbixagent.pl
new file mode 100644
index 0000000..91f0925
--- /dev/null
+++ b/src/pmdas/zabbixagent/pmdazabbixagent.pl
@@ -0,0 +1,186 @@
+#
+# Copyright (C) 2015 Marko Myllynen <myllynen at redhat.com>
+#
+# 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
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+
+use strict;
+use warnings;
+use PCP::PMDA;
+
+our $host  = '127.0.0.1';
+our $port  = '10050';
+our $srcip = '';
+our $pmda  = PCP::PMDA->new('zabbixagent', 480);
+
+# Example instance configuration
+our $net_indom = 0;
+our $vfs_indom = 1;
+our @net_insts = sort(split('\n', `ls -1 /sys/class/net`));
+our @vfs_insts = sort(split('\n', `awk '/^\\/|tmpfs/ {print \$2}' /proc/mounts`));
+our %insts = ( 'net.if.in'    => \@net_insts,
+               'net.if.out'   => \@net_insts,
+               'net.if.total' => \@net_insts,
+               'vfs.fs.size'  => \@vfs_insts, );
+our @net_len = (0..$#net_insts);
+our @vfs_len = (0..$#vfs_insts);
+$pmda->add_indom($net_indom, [map {$net_len[$_], $net_insts[$_]} 0..$#net_len], '', '');
+$pmda->add_indom($vfs_indom, [map {$vfs_len[$_], $vfs_insts[$_]} 0..$#vfs_len], '', '');
+
+# Configuration files for overriding the above settings
+for my $file (pmda_config('PCP_PMDAS_DIR') . '/zabbixagent/zabbixagent.conf', './zabbixagent.conf') {
+	eval `cat $file` unless ! -f $file;
+}
+
+use vars qw( $conn_ok $getcmd );
+
+# Fetch command (could be replaced with direct socket communications)
+# https://www.zabbix.com/documentation/3.0/manual/appendix/items/activepassive
+if ($srcip ne '') {
+	$getcmd = "zabbix_get -s $host -p $port -I $srcip -k ";
+} else {
+	$getcmd = "zabbix_get -s $host -p $port -k ";
+}
+
+sub zabbix_agent_connection_test {
+	$pmda->log("pinging $host");
+	my $res = `$getcmd agent.ping`;
+	chomp($res);
+	if ($res eq 1) {
+		$conn_ok = 1;
+		$pmda->log("ping to $host ok");
+	} else {
+		$conn_ok = 0;
+		$pmda->log("ping to $host failed: " . $res);
+	}
+}
+
+sub zabbix_agent_fetch_callback {
+	if (!defined($conn_ok)) {
+		zabbix_agent_connection_test();
+	}
+	return (PM_ERR_NOTCONN, 0) unless $conn_ok;
+
+	my ($cluster, $item, $inst) = @_;
+
+	my $q = pmda_pmid_name($cluster, $item);
+	$q =~ s/zabbixagent.//;
+	my ($name, $mode) = $q =~ /(.*)\.(.*)/;
+
+	# Reformat the queried item key as needed
+	if (exists($insts{$name})) {
+		# vfs.fs.size.mode -> vfs.fs.size[mnt,mode]
+		$q = $name . "[$insts{$name}[$inst],$mode]";
+	} elsif ($inst != PM_IN_NULL) {
+		# net.if.collisions -> $net_indom
+		my $indom = substr($name, 0, index($name, "."));
+		no strict 'refs';
+		$indom = ${$indom."_indom"};
+		$q = $name . "." . "$mode" . "[" . pmda_inst_name($indom, $inst) . "]";
+	}
+
+	my $value = `$getcmd $q`;
+	chomp($value);
+
+	if (!defined($value))		{ return (PM_ERR_NAME, 0); }
+	if ($value =~ /^ZBX_/)		{ return (PM_ERR_INST, 0); }
+
+	return ($value, 1);
+}
+
+# https://www.zabbix.com/documentation/3.0/manual/config/items/itemtypes/zabbix_agent
+$pmda->add_metric(pmda_pmid(0,0), PM_TYPE_STRING, PM_INDOM_NULL,
+		PM_SEM_INSTANT, pmda_units(0,0,0,0,0,0),
+		'zabbixagent.agent.hostname', '', '');
+$pmda->add_metric(pmda_pmid(0,1), PM_TYPE_U32, PM_INDOM_NULL,
+		PM_SEM_DISCRETE, pmda_units(0,0,0,0,0,0),
+		'zabbixagent.agent.ping', '', '');
+$pmda->add_metric(pmda_pmid(0,2), PM_TYPE_STRING, PM_INDOM_NULL,
+		PM_SEM_DISCRETE, pmda_units(0,0,0,0,0,0),
+		'zabbixagent.agent.version', '', '');
+
+$pmda->add_metric(pmda_pmid(1,0), PM_TYPE_U32, PM_INDOM_NULL,
+		PM_SEM_DISCRETE, pmda_units(0,0,0,0,0,0),
+		'zabbixagent.kernel.maxfiles', '', '');
+$pmda->add_metric(pmda_pmid(1,1), PM_TYPE_U32, PM_INDOM_NULL,
+		PM_SEM_DISCRETE, pmda_units(0,0,0,0,0,0),
+		'zabbixagent.kernel.maxproc', '', '');
+
+$pmda->add_metric(pmda_pmid(3,0), PM_TYPE_U64, $net_indom,
+		PM_SEM_COUNTER, pmda_units(0,0,1,0,0,PM_COUNT_ONE),
+		'zabbixagent.net.if.collisions', '', '');
+$pmda->add_metric(pmda_pmid(3,1), PM_TYPE_STRING, PM_INDOM_NULL,
+		PM_SEM_DISCRETE, pmda_units(0,0,0,0,0,0),
+		'zabbixagent.net.if.discovery', '', '');
+$pmda->add_metric(pmda_pmid(3,2), PM_TYPE_U64, $net_indom,
+		PM_SEM_COUNTER, pmda_units(0,0,1,0,0,PM_COUNT_ONE),
+		'zabbixagent.net.if.in.bytes', '', '');
+$pmda->add_metric(pmda_pmid(3,3), PM_TYPE_U64, $net_indom,
+		PM_SEM_COUNTER, pmda_units(0,0,1,0,0,PM_COUNT_ONE),
+		'zabbixagent.net.if.in.packets', '', '');
+$pmda->add_metric(pmda_pmid(3,4), PM_TYPE_U64, $net_indom,
+		PM_SEM_COUNTER, pmda_units(0,0,1,0,0,PM_COUNT_ONE),
+		'zabbixagent.net.if.in.errors', '', '');
+$pmda->add_metric(pmda_pmid(3,5), PM_TYPE_U64, $net_indom,
+		PM_SEM_COUNTER, pmda_units(0,0,1,0,0,PM_COUNT_ONE),
+		'zabbixagent.net.if.in.dropped', '', '');
+$pmda->add_metric(pmda_pmid(3,6), PM_TYPE_U64, $net_indom,
+		PM_SEM_COUNTER, pmda_units(0,0,1,0,0,PM_COUNT_ONE),
+		'zabbixagent.net.if.out.bytes', '', '');
+$pmda->add_metric(pmda_pmid(3,7), PM_TYPE_U64, $net_indom,
+		PM_SEM_COUNTER, pmda_units(0,0,1,0,0,PM_COUNT_ONE),
+		'zabbixagent.net.if.out.packets', '', '');
+$pmda->add_metric(pmda_pmid(3,8), PM_TYPE_U64, $net_indom,
+		PM_SEM_COUNTER, pmda_units(0,0,1,0,0,PM_COUNT_ONE),
+		'zabbixagent.net.if.out.errors', '', '');
+$pmda->add_metric(pmda_pmid(3,9), PM_TYPE_U64, $net_indom,
+		PM_SEM_COUNTER, pmda_units(0,0,1,0,0,PM_COUNT_ONE),
+		'zabbixagent.net.if.out.dropped', '', '');
+$pmda->add_metric(pmda_pmid(3,10), PM_TYPE_U64, $net_indom,
+		PM_SEM_COUNTER, pmda_units(0,0,1,0,0,PM_COUNT_ONE),
+		'zabbixagent.net.if.total.bytes', '', '');
+$pmda->add_metric(pmda_pmid(3,11), PM_TYPE_U64, $net_indom,
+		PM_SEM_COUNTER, pmda_units(0,0,1,0,0,PM_COUNT_ONE),
+		'zabbixagent.net.if.total.packets', '', '');
+$pmda->add_metric(pmda_pmid(3,12), PM_TYPE_U64, $net_indom,
+		PM_SEM_COUNTER, pmda_units(0,0,1,0,0,PM_COUNT_ONE),
+		'zabbixagent.net.if.total.errors', '', '');
+$pmda->add_metric(pmda_pmid(3,13), PM_TYPE_U64, $net_indom,
+		PM_SEM_COUNTER, pmda_units(0,0,1,0,0,PM_COUNT_ONE),
+		'zabbixagent.net.if.total.dropped', '', '');
+
+$pmda->add_metric(pmda_pmid(6,0), PM_TYPE_U32, PM_INDOM_NULL,
+		PM_SEM_INSTANT, pmda_units(0,1,0,0,PM_TIME_SEC,0),
+		'zabbixagent.system.boottime', '', '');
+
+$pmda->add_metric(pmda_pmid(7,0), PM_TYPE_U64, $vfs_indom,
+		PM_SEM_INSTANT, pmda_units(1,0,0,PM_SPACE_BYTE,0,0),
+		'zabbixagent.vfs.fs.size.total', '', '');
+$pmda->add_metric(pmda_pmid(7,1), PM_TYPE_U64, $vfs_indom,
+		PM_SEM_INSTANT, pmda_units(1,0,0,PM_SPACE_BYTE,0,0),
+		'zabbixagent.vfs.fs.size.used', '', '');
+$pmda->add_metric(pmda_pmid(7,2), PM_TYPE_U64, $vfs_indom,
+		PM_SEM_INSTANT, pmda_units(1,0,0,PM_SPACE_BYTE,0,0),
+		'zabbixagent.vfs.fs.size.free', '', '');
+
+$pmda->add_metric(pmda_pmid(8,0), PM_TYPE_U64, PM_INDOM_NULL,
+		PM_SEM_INSTANT, pmda_units(1,0,0,PM_SPACE_BYTE,0,0),
+		'zabbixagent.vm.memory.size[total]', '', '');
+$pmda->add_metric(pmda_pmid(8,1), PM_TYPE_U64, PM_INDOM_NULL,
+		PM_SEM_INSTANT, pmda_units(1,0,0,PM_SPACE_BYTE,0,0),
+		'zabbixagent.vm.memory.size[used]', '', '');
+$pmda->add_metric(pmda_pmid(8,2), PM_TYPE_U64, PM_INDOM_NULL,
+		PM_SEM_INSTANT, pmda_units(1,0,0,PM_SPACE_BYTE,0,0),
+		'zabbixagent.vm.memory.size[available]', '', '');
+
+$pmda->set_fetch_callback(\&zabbix_agent_fetch_callback);
+$pmda->set_user('pcp');
+$pmda->run;


Thanks,

-- 
Marko Myllynen



More information about the pcp mailing list