diff options
Diffstat (limited to 'src/pmdas/samba')
-rw-r--r-- | src/pmdas/samba/GNUmakefile | 52 | ||||
-rwxr-xr-x | src/pmdas/samba/Install | 43 | ||||
-rwxr-xr-x | src/pmdas/samba/Remove | 25 | ||||
-rw-r--r-- | src/pmdas/samba/pmdasamba.pl | 198 |
4 files changed, 318 insertions, 0 deletions
diff --git a/src/pmdas/samba/GNUmakefile b/src/pmdas/samba/GNUmakefile new file mode 100644 index 0000000..e5602e2 --- /dev/null +++ b/src/pmdas/samba/GNUmakefile @@ -0,0 +1,52 @@ +#!gmake +# +# Copyright (c) 2009 Aconex. All Rights Reserved. +# +# 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. +# + +TOPDIR = ../../.. +include $(TOPDIR)/src/include/builddefs + +IAM = samba +PMDADIR = $(PCP_PMDAS_DIR)/$(IAM) +LSRCFILES = Install Remove pmda$(IAM).pl +LDIRT = domain.h root pmns *.log $(MAN_PAGES) + +ifneq ($(POD2MAN),) +MAN_SECTION = 1 +MAN_PAGES = pmda$(IAM).$(MAN_SECTION) +MAN_DEST = $(PCP_MAN_DIR)/man$(MAN_SECTION) +endif + +default: check_domain $(MAN_PAGES) + +pmda$(IAM).1: pmda$(IAM).pl + $(POD_MAKERULE) + +include $(BUILDRULES) + +ifneq "$(TARGET_OS)" "mingw" +install: default + $(INSTALL) -m 755 -d $(PMDADIR) + $(INSTALL) -m 755 Install Remove $(PMDADIR) + $(INSTALL) -m 644 pmda$(IAM).pl $(PMDADIR)/pmda$(IAM).pl + @$(INSTALL_MAN) +else +install: +endif + +default_pcp : default + +install_pcp : install + +check_domain: ../../pmns/stdpmid + $(DOMAIN_PERLRULE) diff --git a/src/pmdas/samba/Install b/src/pmdas/samba/Install new file mode 100755 index 0000000..8a1aa7f --- /dev/null +++ b/src/pmdas/samba/Install @@ -0,0 +1,43 @@ +#! /bin/sh +# +# Copyright (c) 2009 Aconex. All Rights Reserved. +# +# 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. +# +# Install the Samba PMDA +# + +. $PCP_DIR/etc/pcp.env +. $PCP_SHARE_DIR/lib/pmdaproc.sh + +iam=samba +perl_opt=true +daemon_opt=false + +if ! test -x /usr/sbin/smbd; then + echo "Samba \"smbd\" daemon is not installed" && exit 1 +fi +/usr/sbin/smbd -b | egrep 'WITH_PROFILE|HAVE_PROFILE' >/dev/null +if test $? -ne 0; then + echo "Samba \"smbd\" not built with profiling support" && exit 1 +fi + +if ! test -x /usr/bin/smbcontrol; then + echo "Samba \"smbcontrol\" tool is not installed" && exit 1 +fi +/usr/bin/smbcontrol smbd profile on +if test $? -ne 0; then + echo "Samba \"smbcontrol\" failed to enable profiling" && exit 1 +fi + +pmdaSetup +pmdaInstall +exit 0 diff --git a/src/pmdas/samba/Remove b/src/pmdas/samba/Remove new file mode 100755 index 0000000..9e92afe --- /dev/null +++ b/src/pmdas/samba/Remove @@ -0,0 +1,25 @@ +#! /bin/sh +# +# Copyright (c) 2009 Aconex. All Rights Reserved. +# +# 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. +# +# Remove the Samba PMDA +# + +. $PCP_DIR/etc/pcp.env +. $PCP_SHARE_DIR/lib/pmdaproc.sh + +iam=samba + +pmdaSetup +pmdaRemove +exit 0 diff --git a/src/pmdas/samba/pmdasamba.pl b/src/pmdas/samba/pmdasamba.pl new file mode 100644 index 0000000..f10d7e1 --- /dev/null +++ b/src/pmdas/samba/pmdasamba.pl @@ -0,0 +1,198 @@ +# +# Copyright (c) 2012-2013 Red Hat. +# Copyright (c) 2009 Aconex. All Rights Reserved. +# +# 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; + +use vars qw( $pmda %metrics ); + +# +# This is the main workhorse routine, both value extraction and +# namespace population is under-pinned by this. The approach we +# use here is to extract profile output, construct a hash (keyed +# by metric ID), containing name and value pairs (array refs). +# +sub samba_fetch +{ + my $item = 0; + my $cluster = 0; + my $prefix = ''; + my $generated_cluster = 20; # start well above hard-coded ones + + # work around smbstatus / libpopt adverse reaction to these variables + delete $ENV{'POSIXLY_CORRECT'}; + delete $ENV{'POSIX_ME_HARDER'}; + + my $smbstats = "smbstatus --profile"; + open(STATS, "$smbstats |") || + $pmda->err("pmdasamba failed to open $smbstats pipe: $!"); + + while (<STATS>) { + if (m/^\*\*\*\*\s+(\w+[^*]*)\**$/) { + my $heading = $1; + $heading =~ s/ +$//g; + $item = 0; + if ($heading eq 'System Calls') { + $cluster = 1; $prefix = 'syscalls'; + } elsif ($heading eq 'Stat Cache') { + $cluster = 2; $prefix = 'statcache'; + } elsif ($heading eq 'Write Cache') { + $cluster = 3; $prefix = 'writecache'; + } elsif ($heading eq 'SMB Calls') { + $cluster = 4; $prefix = 'smb'; + } elsif ($heading eq 'Pathworks Calls') { + $cluster = 5; $prefix = 'pathworks'; + } elsif ($heading eq 'Trans2 Calls') { + $cluster = 6; $prefix = 'trans2'; + } elsif ($heading eq 'NT Transact Calls') { + $cluster = 7; $prefix = 'NTtransact'; + } elsif ($heading eq 'ACL Calls') { + $cluster = 8; $prefix = 'acl'; + } elsif ($heading eq 'NMBD Calls') { + $cluster = 9; $prefix = 'nmb'; + } else { + # samba 4.1 renames several clusters of statistics. + # Let's generate cluster names instead of hard-coding them. + $cluster = $generated_cluster++; + $prefix = $heading; + $prefix =~ s/ /_/g; + $prefix =~ tr/A-Z/a-z/; + } + # $pmda->log("metric cluster: $cluster = $prefix"); + } + # we've found a real name/value pair, work out PMID and hash it + elsif (m/^([\[\]\w]+):\s+(\d+)$/) { + my @metric = ( $1, $2 ); + my $pmid; + + $metric[0] =~ tr/\[\]/_/d; + + if ($cluster == 0) { + $metric[0] = "samba.$metric[0]"; + } else { + $metric[0] = "samba.$prefix.$metric[0]"; + } + $pmid = pmda_pmid($cluster,$item++); + $metrics{$pmid} = \@metric; + # $pmda->log("metric: $metric[0], ID = $pmid, value = $metric[1]"); + } + else { + $pmda->log("pmdasamba failed to parse line $_"); + } + } + close STATS; +} + +sub samba_fetch_callback +{ + my ($cluster, $item, $inst) = @_; + my $pmid = pmda_pmid($cluster, $item); + my $value; + +# $pmda->log("samba_fetch_callback $metric_name $cluster:$item ($inst)\n"); + + if ($inst != PM_IN_NULL) { return (PM_ERR_INST, 0); } + + # hash lookup based on PMID, value is $metrics{$pmid}[1] + $value = $metrics{$pmid}; + if (!defined($value)) { return (PM_ERR_APPVERSION, 0); } + return ($value->[1], 1); +} + +$pmda = PCP::PMDA->new('samba', 76); + +samba_fetch(); # extract names and values into %metrics, keyed on PMIDs + +# hash iterate, keys are PMIDs, names and values are in @metrics{$pmid}. +foreach my $pmid (sort(keys %metrics)) { + my $name = $metrics{$pmid}[0]; + if ($name eq 'samba.writecache.num_write_caches' || + $name eq 'samba.writecache.allocated_caches') { + $pmda->add_metric($pmid, PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_INSTANT, + pmda_units(0,0,1,0,0,PM_COUNT_ONE), $name, '', ''); + } elsif ($name =~ /_time$/) { + $pmda->add_metric($pmid, PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER, + pmda_units(0,1,0,0,PM_TIME_USEC,0), $name, '', ''); + } else { + $pmda->add_metric($pmid, PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_COUNTER, + pmda_units(0,0,1,0,0,PM_COUNT_ONE), $name, '', ''); + } + # $pmda->log("pmdasamba added metric $name\n"); +} +# close STATS; + +$pmda->set_fetch(\&samba_fetch); +$pmda->set_fetch_callback(\&samba_fetch_callback); +# NB: needs to run as root, as smb usually does +$pmda->run; + +=pod + +=head1 NAME + +pmdasamba - Samba performance metrics domain agent (PMDA) + +=head1 DESCRIPTION + +B<pmdasamba> is a Performance Metrics Domain Agent (PMDA) which exports +metric values from Samba, a Windows SMB/CIFS server for UNIX. + +In order for values to be made available by this PMDA, Samba must have +been built with profiling support (WITH_PROFILE in "smbd -b" output). +This PMDA dynamically enumerates much of its metric hierarchy, based on +the contents of "smbstatus --profile". + +When the agent is installed (see below), the Install script will attempt +to enable Samba statistics gathering, using "smbcontrol --profile". + +=head1 INSTALLATION + +If you want access to the names and values for the samba performance +metrics, do the following as root: + + # cd $PCP_PMDAS_DIR/samba + # ./Install + +If you want to undo the installation, do the following as root: + + # cd $PCP_PMDAS_DIR/samba + # ./Remove + +B<pmdasamba> is launched by pmcd(1) and should never be executed +directly. The Install and Remove scripts notify pmcd(1) when +the agent is installed or removed. + +=head1 FILES + +=over + +=item $PCP_PMDAS_DIR/samba/Install + +installation script for the B<pmdasamba> agent + +=item $PCP_PMDAS_DIR/samba/Remove + +undo installation script for the B<pmdasamba> agent + +=item $PCP_LOG_DIR/pmcd/samba.log + +default log file for error messages from B<pmdasamba> + +=back + +=head1 SEE ALSO + +pmcd(1), smbd(1) and samba(7). |