initial commit
This commit is contained in:
3
Conf/userparameter_backup_age.conf
Normal file
3
Conf/userparameter_backup_age.conf
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
UserParameter=status_file.discovery,{{ zabbix_script_dir }}/lld_backup_status_file.py
|
||||||
|
UserParameter=check_age[*],sudo {{ zabbix_script_dir }}/check_age_quiet.py "$1"
|
||||||
|
|
||||||
2
Conf/userparameter_certificates.conf
Normal file
2
Conf/userparameter_certificates.conf
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
UserParameter=certificate.discovery,{{ zabbix_script_dir }}/lld_certlist.py
|
||||||
|
|
||||||
13
Conf/userparameter_diskstats.conf
Normal file
13
Conf/userparameter_diskstats.conf
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
UserParameter=custom.vfs.discover_disks,{{ zabbix_script_dir }}/lld-disks.py
|
||||||
|
|
||||||
|
UserParameter=custom.vfs.dev.read.ops[*],awk '{print $$1}' /sys/class/block/$1/stat
|
||||||
|
UserParameter=custom.vfs.dev.read.merged[*],awk '{print $$2}' /sys/class/block/$1/stat
|
||||||
|
UserParameter=custom.vfs.dev.read.sectors[*],awk '{print $$3}' /sys/class/block/$1/stat
|
||||||
|
UserParameter=custom.vfs.dev.read.ms[*],awk '{print $$4}' /sys/class/block/$1/stat
|
||||||
|
UserParameter=custom.vfs.dev.write.ops[*],awk '{print $$5}' /sys/class/block/$1/stat
|
||||||
|
UserParameter=custom.vfs.dev.write.merged[*],awk '{print $$6}' /sys/class/block/$1/stat
|
||||||
|
UserParameter=custom.vfs.dev.write.sectors[*],awk '{print $$7}' /sys/class/block/$1/stat
|
||||||
|
UserParameter=custom.vfs.dev.write.ms[*],awk '{print $$8}' /sys/class/block/$1/stat
|
||||||
|
UserParameter=custom.vfs.dev.io.active[*],awk '{print $$9}' /sys/class/block/$1/stat
|
||||||
|
UserParameter=custom.vfs.dev.io.ms[*],awk '{print $$10}' /sys/class/block/$1/stat
|
||||||
|
UserParameter=custom.vfs.dev.weight.io.ms[*],awk '{print $$11}' /sys/class/block/$1/stat
|
||||||
1
Conf/userparameter_filelist.conf
Normal file
1
Conf/userparameter_filelist.conf
Normal file
@@ -0,0 +1 @@
|
|||||||
|
UserParameter=lld_file_list.discovery[*],{{ zabbix_script_dir }}/lld_filelist.py "$1"
|
||||||
2
Conf/userparameter_mountpoint.conf
Normal file
2
Conf/userparameter_mountpoint.conf
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
UserParameter=check_mountpoint[*],grep -q "$1" /proc/mounts ; echo $?
|
||||||
|
|
||||||
21
Conf/userparameter_mysql.conf
Normal file
21
Conf/userparameter_mysql.conf
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# For all the following commands HOME should be set to the directory that has .my.cnf file with password information.
|
||||||
|
|
||||||
|
# Flexible parameter to grab global variables. On the frontend side, use keys like mysql.status[Com_insert].
|
||||||
|
# Key syntax is mysql.status[variable].
|
||||||
|
UserParameter=mysql.status[*],echo "show global status where Variable_name='$1';" | HOME={{ zabbix_home_dir }} mysql -N | awk '{print $$2}'
|
||||||
|
UserParameter=mysql.status_on[*],echo "show global status where Variable_name='$1';" | HOME={{ zabbix_home_dir }} mysql -N | awk '{print $$2}'| sed 's/ON/1/' | sed 's/OFF/0/'
|
||||||
|
|
||||||
|
# Flexible parameter to determine database or table size. On the frontend side, use keys like mysql.size[zabbix,history,data].
|
||||||
|
# Key syntax is mysql.size[<database>,<table>,<type>].
|
||||||
|
# Database may be a database name or "all". Default is "all".
|
||||||
|
# Table may be a table name or "all". Default is "all".
|
||||||
|
# Type may be "data", "index", "free" or "both". Both is a sum of data and index. Default is "both".
|
||||||
|
# Database is mandatory if a table is specified. Type may be specified always.
|
||||||
|
# Returns value in bytes.
|
||||||
|
# 'sum' on data_length or index_length alone needed when we are getting this information for whole database instead of a single table
|
||||||
|
UserParameter=mysql.size[*],bash -c 'echo "select sum($(case "$3" in both|"") echo "data_length+index_length";; data|index) echo "$3_length";; free) echo "data_free";; esac)) from information_schema.tables$([[ "$1" = "all" || ! "$1" ]] || echo " where table_schema=\"$1\"")$([[ "$2" = "all" || ! "$2" ]] || echo "and table_name=\"$2\"");" | HOME={{ zabbix_home_dir }} mysql -N'
|
||||||
|
|
||||||
|
UserParameter=mysql.ping,HOME={{ zabbix_home_dir }} mysqladmin ping | grep -c alive
|
||||||
|
UserParameter=mysql.version,mysql -V
|
||||||
|
|
||||||
|
|
||||||
2
Conf/userparameter_postfix.conf
Normal file
2
Conf/userparameter_postfix.conf
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
UserParameter=postfix.queue,mailq | grep -v "Mail queue is empty" | egrep -c '^[0-9A-F]{10}'
|
||||||
|
|
||||||
1
Conf/userparameter_processlist.conf
Normal file
1
Conf/userparameter_processlist.conf
Normal file
@@ -0,0 +1 @@
|
|||||||
|
UserParameter=processlist.discovery[*],{{ zabbix_script_dir }}/lld_filelist.py {{ zabbix_process_list_file }}
|
||||||
7
Conf/userparameter_smart.conf
Normal file
7
Conf/userparameter_smart.conf
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
UserParameter=uHDD[*], sudo smartctl -A $1| grep -i "$2"| tail -1| cut -c 88-|cut -f1 -d' '
|
||||||
|
UserParameter=uHDD.model.[*],sudo smartctl -i $1 |grep -i "Device Model"| cut -f2 -d: |tr -d " "
|
||||||
|
UserParameter=uHDD.sn.[*],sudo smartctl -i $1 |grep -i "Serial Number"| cut -f2 -d: |tr -d " "
|
||||||
|
UserParameter=uHDD.health.[*],sudo smartctl -H $1 |grep -i "test"| cut -f2 -d: |tr -d " " || true
|
||||||
|
UserParameter=uHDD.errorlog.[*],sudo smartctl -l error $1 |grep -i "ATA Error Count"| cut -f2 -d: |tr -d " "
|
||||||
|
### Discovery
|
||||||
|
UserParameter=uHDD.discovery,sudo {{ zabbix_script_dir }}/smartctl-disks-discovery.pl
|
||||||
19
README.md
Normal file
19
README.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Zabbix scripts
|
||||||
|
|
||||||
|
Custom discovery and check scripts used by zabbix
|
||||||
|
|
||||||
|
Scripts/* should go in /etc/zabbix/scripts/
|
||||||
|
|
||||||
|
Conf/* should go in /etc/zabbix/zabbix_agentd.d/
|
||||||
|
|
||||||
|
- Scripts/check_ssl_cert.sh
|
||||||
|
- Scripts/lld_backup_status_file.py - list all .status files in /var/run -
|
||||||
|
- Scripts/lld_certlist.py - list all certificates from /etc/letsencrypt/renewal/*.conf
|
||||||
|
- Scripts/lld_filelist.py - list all files listed in arg1
|
||||||
|
- Scripts/lld_php_fpm_url.py - get url of phpfpm status from apache config (⚠️ RH only )
|
||||||
|
- Scripts/lld_smart_disks.pl - get smart list disk
|
||||||
|
|
||||||
|
|
||||||
|
## Issues
|
||||||
|
|
||||||
|
are all these scripts really used ?
|
||||||
68
Scripts/check_ssl_cert.sh
Executable file
68
Scripts/check_ssl_cert.sh
Executable file
@@ -0,0 +1,68 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
#------------------------------------------------------------
|
||||||
|
# zext_ssl_cert.sh
|
||||||
|
# Script checks for number of days until certificate expires or the issuing authority
|
||||||
|
# depending on switch passed on command line.
|
||||||
|
#
|
||||||
|
#Based on script from aperto.fr (http://aperto.fr/cms/en/blog/15-blog-en/15-ssl-certificate-expiration-monitoring-with-zabbix.html)
|
||||||
|
#with additions by racooper@tamu.edu
|
||||||
|
#------------------------------------------------------------
|
||||||
|
|
||||||
|
DEBUG=0
|
||||||
|
if [ $DEBUG -gt 0 ]
|
||||||
|
then
|
||||||
|
exec 2>>/tmp/my.log
|
||||||
|
set -x
|
||||||
|
fi
|
||||||
|
|
||||||
|
f=$1
|
||||||
|
host=$2
|
||||||
|
port=$3
|
||||||
|
sni=$4
|
||||||
|
proto=$5
|
||||||
|
|
||||||
|
if [ -z "$sni" ]
|
||||||
|
then
|
||||||
|
servername=$host
|
||||||
|
else
|
||||||
|
servername=$sni
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$proto" ]
|
||||||
|
then
|
||||||
|
starttls="-starttls $proto"
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $f in
|
||||||
|
-d)
|
||||||
|
end_date=`openssl s_client -servername $servername -host $host -port $port -showcerts $starttls -prexit </dev/null 2>/dev/null |
|
||||||
|
sed -n '/BEGIN CERTIFICATE/,/END CERT/p' |
|
||||||
|
openssl x509 -text 2>/dev/null |
|
||||||
|
sed -n 's/ *Not After : *//p'`
|
||||||
|
|
||||||
|
if [ -n "$end_date" ]
|
||||||
|
then
|
||||||
|
end_date_seconds=`date '+%s' --date "$end_date"`
|
||||||
|
now_seconds=`date '+%s'`
|
||||||
|
echo "($end_date_seconds-$now_seconds)/24/3600" | bc
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
-i)
|
||||||
|
issue_dn=`openssl s_client -servername $servername -host $host -port $port -showcerts $starttls -prexit </dev/null 2>/dev/null |
|
||||||
|
sed -n '/BEGIN CERTIFICATE/,/END CERT/p' |
|
||||||
|
openssl x509 -text 2>/dev/null |
|
||||||
|
sed -n 's/ *Issuer: *//p'`
|
||||||
|
|
||||||
|
if [ -n "$issue_dn" ]
|
||||||
|
then
|
||||||
|
issuer=`echo $issue_dn | sed -n 's/.*CN=*//p'`
|
||||||
|
echo $issuer
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "usage: $0 [-i|-d] hostname port sni"
|
||||||
|
echo " -i Show Issuer"
|
||||||
|
echo " -d Show valid days remaining"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
13
Scripts/lld_backup_status_file.py
Executable file
13
Scripts/lld_backup_status_file.py
Executable file
@@ -0,0 +1,13 @@
|
|||||||
|
#jinja2:variable_start_string:'[%',variable_end_string:'%]',comment_start_string:'<%',comment_end_string:'%>'
|
||||||
|
#! [% discovered_interpreter_python %]
|
||||||
|
import glob
|
||||||
|
import json
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# Iterate over all block devices, but ignore them if they are in the
|
||||||
|
# skippable set
|
||||||
|
skippable = ()
|
||||||
|
data=[]
|
||||||
|
files=(file for file in glob.glob( "/var/run/*.status" ))
|
||||||
|
data = [{"{#STATUSFILE}": file} for file in files]
|
||||||
|
print(json.dumps({"data": data}, indent=4))
|
||||||
19
Scripts/lld_certlist.py
Executable file
19
Scripts/lld_certlist.py
Executable file
@@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import glob
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
data=[]
|
||||||
|
filelist = glob.glob( '/etc/letsencrypt/renewal/*.conf' )
|
||||||
|
cert=[]
|
||||||
|
for line in filelist:
|
||||||
|
cert.append( os.path.basename(os.path.splitext(line)[0]) )
|
||||||
|
print( os.path.splitext(line)[0] )
|
||||||
|
|
||||||
|
data = [{"{#CERT}": line.strip()} for line in set(cert)]
|
||||||
|
print(json.dumps({"data": data}, indent=4))
|
||||||
|
|
||||||
15
Scripts/lld_filelist.py
Executable file
15
Scripts/lld_filelist.py
Executable file
@@ -0,0 +1,15 @@
|
|||||||
|
#! {{ discovered_interpreter_python }}
|
||||||
|
import glob
|
||||||
|
import json
|
||||||
|
from sys import argv,stderr
|
||||||
|
import sys
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
data=[]
|
||||||
|
try:
|
||||||
|
file = open( sys.argv[1] )
|
||||||
|
except:
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
data = [{"{#FILE}": line.strip()} for line in file.readlines()]
|
||||||
|
print(json.dumps({"data": data}, indent=4))
|
||||||
25
Scripts/lld_php_fpm_url.py
Executable file
25
Scripts/lld_php_fpm_url.py
Executable file
@@ -0,0 +1,25 @@
|
|||||||
|
#jinja2:variable_start_string:'[%',variable_end_string:'%]',comment_start_string:'<%',comment_end_string:'%>'
|
||||||
|
#! [% discovered_interpreter_python %]
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import glob
|
||||||
|
|
||||||
|
dir="/etc/httpd/conf.d/"
|
||||||
|
|
||||||
|
phpfpm_status_url="ncstatus"
|
||||||
|
|
||||||
|
# we get all url from apache config files
|
||||||
|
# we know that name of site == name of file
|
||||||
|
if __name__ == "__main__":
|
||||||
|
filelist = glob.glob( dir + '*.conf' )
|
||||||
|
result=[]
|
||||||
|
for file in filelist:
|
||||||
|
poolname=os.path.basename( file )
|
||||||
|
poolname=re.sub( '\.conf$', '', poolname )
|
||||||
|
for line in open(file):
|
||||||
|
res=re.search( phpfpm_status_url, line)
|
||||||
|
if res:
|
||||||
|
url=re.sub( r'\.conf$', '', os.path.basename(file) )
|
||||||
|
result.append({ "{#POOLNAME}": poolname, "{#POOLURL}": 'https://' +url +"/"+ phpfpm_status_url})
|
||||||
|
print(json.dumps({"data": result}, indent=4))
|
||||||
158
Scripts/lld_smart_disks.pl
Executable file
158
Scripts/lld_smart_disks.pl
Executable file
@@ -0,0 +1,158 @@
|
|||||||
|
#jinja2:variable_start_string:'[%',variable_end_string:'%]',comment_start_string:'<%',comment_end_string:'%>'
|
||||||
|
#!/usr/bin/perl
|
||||||
|
use warnings;
|
||||||
|
use strict;
|
||||||
|
|
||||||
|
#must be run as root
|
||||||
|
my $VERSION = 0.9;
|
||||||
|
|
||||||
|
#add path if needed into $smartctl_cmd
|
||||||
|
my $smartctl_cmd = "smartctl";
|
||||||
|
my @input_disks;
|
||||||
|
my @global_serials;
|
||||||
|
my @smart_disks;
|
||||||
|
|
||||||
|
if ( $^O eq 'darwin' ) { # if MAC OSX
|
||||||
|
|
||||||
|
while ( glob('/dev/disk*') ) {
|
||||||
|
if ( $_ =~ /\/(disk+[0-9])$/ ) { push @input_disks, $1; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (`$smartctl_cmd --scan-open`) {
|
||||||
|
|
||||||
|
#my $testline = "# /dev/sdc -d usbjmicron # /dev/sdc [USB JMicron], ATA device open" ;
|
||||||
|
#for ($testline) {
|
||||||
|
#splitting lines like "/dev/sda -d scsi # /dev/sda, SCSI device"
|
||||||
|
#"/dev/sda [SAT] -d sat [ATA] (opened)" # in debian 6 and smartctl 5.4
|
||||||
|
#"/dev/sda -d sat # /dev/sda [SAT], ATA device" # in debian 8 and smartctl 6.4
|
||||||
|
#"/dev/bus/0 -d megaraid,01" for megaraid
|
||||||
|
#"# /dev/sdc -d usbjmicron # /dev/sdc [USB JMicron], ATA device open "
|
||||||
|
|
||||||
|
my ($disk_name) = $_ =~ /(\/(.+?))\s/;
|
||||||
|
my ($disk_args) = $_ =~ /(-d [A-Za-z0-9,\+]+)/;
|
||||||
|
|
||||||
|
if ( $disk_name and $disk_args ) {
|
||||||
|
push @input_disks,
|
||||||
|
{
|
||||||
|
disk_name => $disk_name,
|
||||||
|
disk_args => $disk_args,
|
||||||
|
subdisk => 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach my $disk (@input_disks) {
|
||||||
|
|
||||||
|
my @output_arr;
|
||||||
|
if ( @output_arr = get_smart_disks($disk) ) {
|
||||||
|
push @smart_disks, @output_arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
json_discovery( \@smart_disks );
|
||||||
|
|
||||||
|
sub get_smart_disks {
|
||||||
|
my $disk = shift;
|
||||||
|
my @disks;
|
||||||
|
|
||||||
|
$disk->{smart_enabled} = 0;
|
||||||
|
|
||||||
|
chomp( $disk->{disk_name} );
|
||||||
|
chomp( $disk->{disk_args} );
|
||||||
|
|
||||||
|
#my $testline = "open failed: Two devices connected, try '-d usbjmicron,[01]'";
|
||||||
|
#my $testline = "open device: /dev/sdc [USB JMicron] failed: Two devices connected, try '-d usbjmicron,[01]'";
|
||||||
|
#if ($disk->{subdisk} == 1) {
|
||||||
|
#$testline = "/dev/sdb -d usbjmicron,$disk->{disk_args} # /dev/sdb [USB JMicron], ATA device";
|
||||||
|
#}
|
||||||
|
foreach my $line (`$smartctl_cmd -i $disk->{disk_name} $disk->{disk_args} 2>&1`) {
|
||||||
|
#foreach my $line ($testline) {
|
||||||
|
#print $line;
|
||||||
|
#Some disks have "Number" and some "number", so
|
||||||
|
if ( $line =~ /^Serial (N|n)umber: +(.+)$/ ) {
|
||||||
|
|
||||||
|
#print "Serial number is ".$2."\n";
|
||||||
|
if ( grep /$2/, @global_serials ) {
|
||||||
|
|
||||||
|
#print "disk already exist skipping\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
push @global_serials, $2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elsif ( $line =~ /Permission denied/ ) {
|
||||||
|
|
||||||
|
warn $line;
|
||||||
|
|
||||||
|
}
|
||||||
|
elsif ( $disk->{subdisk} == 0 and $line =~ /failed: [A-zA-Z]+ devices connected, try '(-d [a-zA-Z0-9]+,)\[([0-9]+)\]'/) {
|
||||||
|
#check for usbjmicron: "open failed: Two devices connected, try '-d usbjmicron,[01]'"
|
||||||
|
# or "open device: /dev/sdc [USB JMicron] failed: Two devices connected, try '-d usbjmicron,[01]'"
|
||||||
|
#not $disk->{subdisk} works as a guard against endless recursion
|
||||||
|
|
||||||
|
foreach ( split //, $2 ) { #splitting [01]
|
||||||
|
|
||||||
|
push @disks,
|
||||||
|
get_smart_disks(
|
||||||
|
{
|
||||||
|
disk_name => $disk->{disk_name},
|
||||||
|
disk_args => $1 . $_,
|
||||||
|
subdisk => 1
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
return @disks;
|
||||||
|
|
||||||
|
}
|
||||||
|
elsif ( $line =~ /^SMART.+?: +(.+)$/ ) {
|
||||||
|
|
||||||
|
if ( $1 =~ /Enabled/ ) {
|
||||||
|
$disk->{smart_enabled} = 1;
|
||||||
|
}
|
||||||
|
elsif ( $1 =~ /Unavailable/ ) {
|
||||||
|
`$smartctl_cmd -i $disk->{disk_name} $disk->{disk_args} 2>&1`;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if SMART is disabled then try to enable it (also offline tests etc)
|
||||||
|
elsif ( $1 =~ /Disabled/ ) {
|
||||||
|
foreach (`smartctl -s on -o on -S on $disk->{disk_name} $disk->{disk_args}`)
|
||||||
|
{
|
||||||
|
if (/SMART Enabled/) { $disk->{smart_enabled} = 1; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
push @disks, $disk;
|
||||||
|
return @disks;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sub json_discovery {
|
||||||
|
my $disks = shift;
|
||||||
|
|
||||||
|
my $first = 1;
|
||||||
|
print "{\n";
|
||||||
|
print "\t\"data\":[\n\n";
|
||||||
|
|
||||||
|
foreach my $disk ( @{$disks} ) {
|
||||||
|
|
||||||
|
print ",\n" if not $first;
|
||||||
|
$first = 0;
|
||||||
|
print "\t\t{\n";
|
||||||
|
print "\t\t\t\"{#DISKNAME}\":\"".$disk->{disk_name}.q{ }.$disk->{disk_args}."\",\n";
|
||||||
|
#print "\t\t\t\"{#DISKCMD}\":\"".$disk->{disk_name}.q{ }.$disk->{disk_args}."\",\n";
|
||||||
|
print "\t\t\t\"{#SMART_ENABLED}\":\"".$disk->{smart_enabled}."\"\n";
|
||||||
|
print "\t\t}";
|
||||||
|
|
||||||
|
}
|
||||||
|
print "\n\t]\n";
|
||||||
|
print "}\n";
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user