mirror of
https://github.com/librenms/librenms-agent.git
synced 2024-05-09 09:54:52 +00:00
convert the FreeBSD NFS stuff over to JSON and add in lots of sanity (#190)
* convert fbsdnfsclient over to JSON * Convert the server stuff to JSON and fix the output of the client extend. * misc. stuff * lots of cleanup and sanity added to the FreeBSD NFS scripts * fix the #! line * update the docs at the top
This commit is contained in:
@ -1,135 +1,174 @@
|
||||
#!/usr/local/bin/perl
|
||||
#!/usr/bin/env perl
|
||||
|
||||
# Add this to snmpd.conf as below.
|
||||
# extend fbsdnfsclient /etc/snmp/fbsdnfsclient
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This is a SNMP extend for FreeBSD NFS server stats for use with LibreNMS.
|
||||
|
||||
For more information, see L<https://docs.librenms.org/#Extensions/Applications/#fbsd-nfs-client>.
|
||||
|
||||
=head1 SWITCHES
|
||||
|
||||
=head2 -p
|
||||
|
||||
Pretty print the JSON.
|
||||
|
||||
=head1 SNMPD SETUP EXAMPLES
|
||||
|
||||
Below is a basic example of setting it up snmpd.conf for NetSNMP.
|
||||
|
||||
extend fbsdnfsclient /etc/snmp/fbsdnfsclient
|
||||
|
||||
=cut
|
||||
|
||||
#Copyright (c) 2018, Zane C. Bowers-Hadley
|
||||
#All rights reserved.
|
||||
#
|
||||
#Redistribution and use in source and binary forms, with or without modification,
|
||||
#are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
#ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
#IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
#INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
#BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
#DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
#LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
#OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
#THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Std;
|
||||
use JSON;
|
||||
|
||||
#the version of returned data
|
||||
my $VERSION=1;
|
||||
|
||||
#gets the options
|
||||
my %opts=();
|
||||
getopts('p', \%opts);
|
||||
|
||||
$Getopt::Std::STANDARD_HELP_VERSION = 1;
|
||||
sub main::VERSION_MESSAGE {
|
||||
print "fbsdnfsclient SNMP extend 0.0.0\n";
|
||||
}
|
||||
|
||||
sub main::HELP_MESSAGE {
|
||||
print "\n".
|
||||
"-p Print the JSON in a pretty manner.\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
#the data to return
|
||||
my %to_return;
|
||||
$to_return{'version'}=$VERSION;
|
||||
$to_return{'error'}='0';
|
||||
$to_return{'errorString'}='';
|
||||
|
||||
my $nfsstatOutput=`/usr/bin/nfsstat`;
|
||||
$to_return{error}=$?;
|
||||
|
||||
# check for bad exit codes
|
||||
if ( $? == -1){
|
||||
$to_return{errorString}='failed to run nfsstat';
|
||||
}
|
||||
elsif ($? & 127) {
|
||||
$to_return{errorString}= sprintf "nfsstat died with signal %d, %s coredump\n",
|
||||
($? & 127), ($? & 128) ? 'with' : 'without';
|
||||
} else {
|
||||
$to_return{error}=$? >> 8;
|
||||
$to_return{errorString}="nfsstat exited with ".$to_return{error};
|
||||
}
|
||||
|
||||
# pull the output of nfssetat appart
|
||||
my %data;
|
||||
my @nfsstatOutputA=split( /\n/, $nfsstatOutput );
|
||||
my $int=0;
|
||||
|
||||
my (
|
||||
$Getattr,
|
||||
$Setattr,
|
||||
$Lookup,
|
||||
$Readlink,
|
||||
$Read,
|
||||
$Write,
|
||||
$Create,
|
||||
$Remove,
|
||||
$Rename,
|
||||
$Link,
|
||||
$Symlink,
|
||||
$Mkdir,
|
||||
$Rmdir,
|
||||
$Readdir,
|
||||
$RdirPlus,
|
||||
$Access,
|
||||
$Mknod,
|
||||
$Fsstat,
|
||||
$Fsinfo,
|
||||
$PathConf,
|
||||
$Commit,
|
||||
$TimedOut,
|
||||
$Invalid,
|
||||
$XReplies,
|
||||
$Retries,
|
||||
$Requests,
|
||||
$AttrHits,
|
||||
$AttrMisses,
|
||||
$LkupHits,
|
||||
$LkupMisses,
|
||||
$BioRHits,
|
||||
$BioRMisses,
|
||||
$BioWHits,
|
||||
$BioWMisses,
|
||||
$BioRLHits,
|
||||
$BioRLMisses,
|
||||
$BioDHits,
|
||||
$BioDMisses,
|
||||
$DirEHits,
|
||||
$DirEMisses,
|
||||
$AccsHits,
|
||||
$AccsMisses,
|
||||
);
|
||||
|
||||
while( defined( $nfsstatOutputA[$int] ) ){
|
||||
$nfsstatOutputA[$int]=~s/^ +//;
|
||||
$nfsstatOutputA[$int]=~s/ +/ /g;
|
||||
|
||||
if ( $int == 3 ){
|
||||
(
|
||||
$Getattr,
|
||||
$Setattr,
|
||||
$Lookup,
|
||||
$Readlink,
|
||||
$Read,
|
||||
$Write,
|
||||
$Create,
|
||||
$Remove,
|
||||
$data{Getattr},
|
||||
$data{Setattr},
|
||||
$data{Lookup},
|
||||
$data{Readlink},
|
||||
$data{Read},
|
||||
$data{Write},
|
||||
$data{Create},
|
||||
$data{Remove},
|
||||
)=split( /\ /, $nfsstatOutputA[$int] );
|
||||
|
||||
}
|
||||
|
||||
if ( $int == 5 ){
|
||||
(
|
||||
$Rename,
|
||||
$Link,
|
||||
$Symlink,
|
||||
$Mkdir,
|
||||
$Rmdir,
|
||||
$Readdir,
|
||||
$RdirPlus,
|
||||
$Access,
|
||||
$data{Rename},
|
||||
$data{Link},
|
||||
$data{Symlink},
|
||||
$data{Mkdir},
|
||||
$data{Rmdir},
|
||||
$data{Readdir},
|
||||
$data{RdirPlus},
|
||||
$data{Access},
|
||||
)=split( /\ /, $nfsstatOutputA[$int] );
|
||||
|
||||
}
|
||||
|
||||
if ( $int == 7 ){
|
||||
(
|
||||
$Mknod,
|
||||
$Fsstat,
|
||||
$Fsinfo,
|
||||
$PathConf,
|
||||
$Commit,
|
||||
$data{Mknod},
|
||||
$data{Fsstat},
|
||||
$data{Fsinfo},
|
||||
$data{PathConf},
|
||||
$data{Commit},
|
||||
)=split( /\ /, $nfsstatOutputA[$int] );
|
||||
|
||||
}
|
||||
|
||||
if ( $int == 10 ){
|
||||
(
|
||||
$TimedOut,
|
||||
$Invalid,
|
||||
$XReplies,
|
||||
$Retries,
|
||||
$Requests,
|
||||
$data{TimedOut},
|
||||
$data{Invalid},
|
||||
$data{XReplies},
|
||||
$data{Retries},
|
||||
$data{Requests},
|
||||
)=split( /\ /, $nfsstatOutputA[$int] );
|
||||
|
||||
}
|
||||
|
||||
if ( $int == 13 ){
|
||||
(
|
||||
$AttrHits,
|
||||
$AttrMisses,
|
||||
$LkupHits,
|
||||
$LkupMisses,
|
||||
$BioRHits,
|
||||
$BioRMisses,
|
||||
$BioWHits,
|
||||
$BioWMisses,
|
||||
$data{AttrHits},
|
||||
$data{AttrMisses},
|
||||
$data{LkupHits},
|
||||
$data{LkupMisses},
|
||||
$data{BioRHits},
|
||||
$data{BioRMisses},
|
||||
$data{BioWHits},
|
||||
$data{BioWMisses},
|
||||
)=split( /\ /, $nfsstatOutputA[$int] );
|
||||
|
||||
}
|
||||
|
||||
if ( $int == 15 ){
|
||||
(
|
||||
$BioRLHits,
|
||||
$BioRLMisses,
|
||||
$BioDHits,
|
||||
$BioDMisses,
|
||||
$DirEHits,
|
||||
$DirEMisses,
|
||||
$AccsHits,
|
||||
$AccsMisses,
|
||||
$data{BioRLHits},
|
||||
$data{BioRLMisses},
|
||||
$data{BioDHits},
|
||||
$data{BioDMisses},
|
||||
$data{DirEHits},
|
||||
$data{DirEMisses},
|
||||
$data{AccsHits},
|
||||
$data{AccsMisses},
|
||||
)=split( /\ /, $nfsstatOutputA[$int] );
|
||||
|
||||
}
|
||||
@ -137,45 +176,15 @@ while( defined( $nfsstatOutputA[$int] ) ){
|
||||
$int++;
|
||||
}
|
||||
|
||||
print $Getattr."\n".
|
||||
$Setattr."\n".
|
||||
$Lookup."\n".
|
||||
$Readlink."\n".
|
||||
$Read."\n".
|
||||
$Write."\n".
|
||||
$Create."\n".
|
||||
$Remove."\n".
|
||||
$Rename."\n".
|
||||
$Link."\n".
|
||||
$Symlink."\n".
|
||||
$Mkdir."\n".
|
||||
$Rmdir."\n".
|
||||
$Readdir."\n".
|
||||
$RdirPlus."\n".
|
||||
$Access."\n".
|
||||
$Mknod."\n".
|
||||
$Fsstat."\n".
|
||||
$Fsinfo."\n".
|
||||
$PathConf."\n".
|
||||
$Commit."\n".
|
||||
$TimedOut."\n".
|
||||
$Invalid."\n".
|
||||
$XReplies."\n".
|
||||
$Retries."\n".
|
||||
$Requests."\n".
|
||||
$AttrHits."\n".
|
||||
$AttrMisses."\n".
|
||||
$LkupHits."\n".
|
||||
$LkupMisses."\n".
|
||||
$BioRHits."\n".
|
||||
$BioRMisses."\n".
|
||||
$BioWHits."\n".
|
||||
$BioWMisses."\n".
|
||||
$BioRLHits."\n".
|
||||
$BioRLMisses."\n".
|
||||
$BioDHits."\n".
|
||||
$BioDMisses."\n".
|
||||
$DirEHits."\n".
|
||||
$DirEMisses."\n".
|
||||
$AccsHits."\n".
|
||||
$AccsMisses."\n";
|
||||
#add the data has to the return hash
|
||||
$to_return{data}=\%data;
|
||||
|
||||
#finally render the JSON
|
||||
my $j=JSON->new;
|
||||
if ( $opts{p} ){
|
||||
$j->pretty(1);
|
||||
}
|
||||
print $j->encode( \%to_return );
|
||||
if ( ! $opts{p} ){
|
||||
print "\n";
|
||||
}
|
||||
|
@ -1,117 +1,168 @@
|
||||
#!/usr/local/bin/perl
|
||||
|
||||
# Add this to snmpd.conf as below.
|
||||
# extend fbsdnfsserver /etc/snmp/fbsdnfsserver
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This is a SNMP extend for FreeBSD NFS server stats for use with LibreNMS.
|
||||
|
||||
For more information, see L<https://docs.librenms.org/#Extensions/Applications/#fbsd-nfs-server>.
|
||||
|
||||
=head1 SWITCHES
|
||||
|
||||
=head2 -p
|
||||
|
||||
Pretty print the JSON.
|
||||
|
||||
=head1 SNMPD SETUP EXAMPLES
|
||||
|
||||
Below is a basic example of setting it up snmpd.conf for NetSNMP.
|
||||
|
||||
extend fbsdnfsserver /etc/snmp/fbsdnfsserver
|
||||
|
||||
=cut
|
||||
|
||||
#Copyright (c) 2018, Zane C. Bowers-Hadley
|
||||
#All rights reserved.
|
||||
#
|
||||
#Redistribution and use in source and binary forms, with or without modification,
|
||||
#are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
#ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
#IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
#INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
#BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
#DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
#LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
#OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
#THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use JSON;
|
||||
use Getopt::Std;
|
||||
|
||||
#gets the options
|
||||
my %opts=();
|
||||
getopts('p', \%opts);
|
||||
|
||||
$Getopt::Std::STANDARD_HELP_VERSION = 1;
|
||||
sub main::VERSION_MESSAGE {
|
||||
print "fbsdnfsclient SNMP extend 0.0.0\n";
|
||||
}
|
||||
|
||||
sub main::HELP_MESSAGE {
|
||||
print "\n".
|
||||
"-p Print the JSON in a pretty manner.\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
my $VERSION=1;
|
||||
|
||||
#the data to return
|
||||
my %to_return;
|
||||
$to_return{'version'}=$VERSION;
|
||||
$to_return{'error'}='0';
|
||||
$to_return{'errorString'}='';
|
||||
|
||||
my $nfsstatOutput=`/usr/bin/nfsstat`;
|
||||
$to_return{error}=$?;
|
||||
|
||||
# check for bad exit codes
|
||||
if ( $? == -1){
|
||||
$to_return{errorString}='failed to run nfsstat';
|
||||
}
|
||||
elsif ($? & 127) {
|
||||
$to_return{errorString}= sprintf "nfsstat died with signal %d, %s coredump\n",
|
||||
($? & 127), ($? & 128) ? 'with' : 'without';
|
||||
} else {
|
||||
$to_return{error}=$? >> 8;
|
||||
$to_return{errorString}="nfsstat exited with ".$to_return{error};
|
||||
}
|
||||
|
||||
|
||||
my @nfsstatOutputA=split( /\n/, $nfsstatOutput );
|
||||
my $int=0;
|
||||
|
||||
my (
|
||||
$Getattr,
|
||||
$Setattr,
|
||||
$Lookup,
|
||||
$Readlink,
|
||||
$Read,
|
||||
$Write,
|
||||
$Create,
|
||||
$Remove,
|
||||
$Rename,
|
||||
$Link,
|
||||
$Symlink,
|
||||
$Mkdir,
|
||||
$Rmdir,
|
||||
$Readdir,
|
||||
$RdirPlus,
|
||||
$Access,
|
||||
$Mknod,
|
||||
$Fsstat,
|
||||
$Fsinfo,
|
||||
$PathConf,
|
||||
$Commit,
|
||||
$RetFailed,
|
||||
$Faults,
|
||||
$Inprog,
|
||||
$Idem,
|
||||
$Nonidem,
|
||||
$Misses,
|
||||
$WriteOps,
|
||||
$WriteRPC,
|
||||
$Opsaved
|
||||
);
|
||||
|
||||
my %data;
|
||||
while( defined( $nfsstatOutputA[$int] ) ){
|
||||
$nfsstatOutputA[$int]=~s/^ +//;
|
||||
$nfsstatOutputA[$int]=~s/ +/ /g;
|
||||
|
||||
if ( $int == 19 ){
|
||||
(
|
||||
$Getattr,
|
||||
$Setattr,
|
||||
$Lookup,
|
||||
$Readlink,
|
||||
$Read,
|
||||
$Write,
|
||||
$Create,
|
||||
$Remove,
|
||||
$data{'Getattr'},
|
||||
$data{'Setattr'},
|
||||
$data{'Lookup'},
|
||||
$data{'Readlink'},
|
||||
$data{'Read'},
|
||||
$data{'Write'},
|
||||
$data{'Create'},
|
||||
$data{'Remove'},
|
||||
)=split( /\ /, $nfsstatOutputA[$int] );
|
||||
|
||||
}
|
||||
|
||||
if ( $int == 21 ){
|
||||
(
|
||||
$Rename,
|
||||
$Link,
|
||||
$Symlink,
|
||||
$Mkdir,
|
||||
$Rmdir,
|
||||
$Readdir,
|
||||
$RdirPlus,
|
||||
$Access
|
||||
$data{'Rename'},
|
||||
$data{'Link'},
|
||||
$data{'Symlink'},
|
||||
$data{'Mkdir'},
|
||||
$data{'Rmdir'},
|
||||
$data{'Readdir'},
|
||||
$data{'RdirPlus'},
|
||||
$data{'Access'}
|
||||
)=split( /\ /, $nfsstatOutputA[$int] );
|
||||
|
||||
}
|
||||
|
||||
if ( $int == 23 ){
|
||||
(
|
||||
$Mknod,
|
||||
$Fsstat,
|
||||
$Fsinfo,
|
||||
$PathConf,
|
||||
$Commit
|
||||
$data{'Mknod'},
|
||||
$data{'Fsstat'},
|
||||
$data{'Fsinfo'},
|
||||
$data{'PathConf'},
|
||||
$data{'Commit'}
|
||||
)=split( /\ /, $nfsstatOutputA[$int] );
|
||||
|
||||
}
|
||||
|
||||
if ( $int == 25 ){
|
||||
(
|
||||
$RetFailed
|
||||
$data{'RetFailed'}
|
||||
)=split( /\ /, $nfsstatOutputA[$int] );
|
||||
|
||||
}
|
||||
|
||||
if ( $int == 27 ){
|
||||
(
|
||||
$Faults
|
||||
$data{'Faults'}
|
||||
)=split( /\ /, $nfsstatOutputA[$int] );
|
||||
|
||||
}
|
||||
|
||||
if ( $int == 30 ){
|
||||
(
|
||||
$Inprog,
|
||||
$Idem,
|
||||
$Nonidem,
|
||||
$Misses
|
||||
$data{'Inprog'},
|
||||
$data{'Idem'},
|
||||
$data{'Nonidem'},
|
||||
$data{'Misses'}
|
||||
)=split( /\ /, $nfsstatOutputA[$int] );
|
||||
|
||||
}
|
||||
|
||||
if ( $int == 33 ){
|
||||
(
|
||||
$WriteOps,
|
||||
$WriteRPC,
|
||||
$Opsaved
|
||||
$data{'WriteOps'},
|
||||
$data{'WriteRPC'},
|
||||
$data{'Opsaved'}
|
||||
)=split( /\ /, $nfsstatOutputA[$int] );
|
||||
|
||||
}
|
||||
@ -119,33 +170,15 @@ while( defined( $nfsstatOutputA[$int] ) ){
|
||||
$int++;
|
||||
}
|
||||
|
||||
print $Getattr."\n".
|
||||
$Setattr."\n".
|
||||
$Lookup."\n".
|
||||
$Readlink."\n".
|
||||
$Read."\n".
|
||||
$Write."\n".
|
||||
$Create."\n".
|
||||
$Remove."\n".
|
||||
$Rename."\n".
|
||||
$Link."\n".
|
||||
$Symlink."\n".
|
||||
$Mkdir."\n".
|
||||
$Rmdir."\n".
|
||||
$Readdir."\n".
|
||||
$RdirPlus."\n".
|
||||
$Access."\n".
|
||||
$Mknod."\n".
|
||||
$Fsstat."\n".
|
||||
$Fsinfo."\n".
|
||||
$PathConf."\n".
|
||||
$Commit."\n".
|
||||
$RetFailed."\n".
|
||||
$Faults."\n".
|
||||
$Inprog."\n".
|
||||
$Idem."\n".
|
||||
$Nonidem."\n".
|
||||
$Misses."\n".
|
||||
$WriteOps."\n".
|
||||
$WriteRPC."\n".
|
||||
$Opsaved."\n";
|
||||
#add the data has to the return hash
|
||||
$to_return{data}=\%data;
|
||||
|
||||
#finally render the JSON
|
||||
my $j=JSON->new;
|
||||
if ( $opts{p} ){
|
||||
$j->pretty(1);
|
||||
}
|
||||
print $j->encode( \%to_return );
|
||||
if ( ! $opts{p} ){
|
||||
print "\n";
|
||||
}
|
||||
|
Reference in New Issue
Block a user