├── README.md ├── iostat ├── README.md ├── dev-discovery.sh ├── iostat-check.sh ├── iostat-cron.conf ├── iostat-cron.sh ├── iostat-params.conf └── iostat-template.xml ├── jvm ├── README.md ├── jvm-check.pl ├── jvm-params.conf ├── jvm-service.pl └── jvm-template.xml ├── mongo ├── README.md ├── mongo.conf └── mongodb-template.xml ├── mysql ├── README.md ├── mysql-check.sh ├── mysql-params.conf └── mysql-template.xml ├── nginx ├── README.md ├── nginx-check.sh ├── nginx-params.conf └── nginx-template.xml ├── php-fpm ├── README.md ├── php-fpm-check.sh ├── php-fpm-params.conf └── php-fpm-template.xml ├── scripts ├── daily_report.py ├── install_zabbix_agent.py ├── send_mail.py ├── zabbix-nginx.conf └── zabbix_conf.py └── tcp-port ├── README.md ├── get_port.py └── tcp-port.conf /README.md: -------------------------------------------------------------------------------- 1 | Zabbix-Templates-Scripts 2 | ======================== 3 | 4 | Zabbix templates and scripts. 5 | 6 | -------------------------------------------------------------------------------- /iostat/README.md: -------------------------------------------------------------------------------- 1 | Template iostat 2 | =============== 3 | 4 | Show `iostat` result in Zabbix. 5 | 6 | 7 | INSTALL 8 | ------- 9 | 10 | Assume the Zabbix agent directory is /zabbix-agent/. 11 | 12 | ### Install Cron Job 13 | 14 | Since the first output of `iostat` is the statistics since boot time, we need to wait for a period (like 10 seconds) to get the result, which should be done through cron job, otherwise it'll surpass the zabbix agent's timeout. 15 | 16 | Do the following two steps: 17 | 18 | 1. Copy iostat-cron.sh to /zabbix-agent/bin/; 19 | 2. Copy iostat-cron.conf to /etc/cron.d/; 20 | 21 | After a while, you'll see the iostat-data file in /zabbix-agent/var/. 22 | 23 | ### Install User Parameters 24 | 25 | To expose the iostat-data to Zabbix, do the following steps: 26 | 27 | 1. Copy dev-discovery.sh and iostat-check.sh to /zabbix-agent/bin/, the former one is to enable disk device discovery capability. 28 | 2. Copy iostat-params.conf to /zabbix-agent/etc/zabbix_agentd.conf.d/. 29 | 30 | ### Import Template 31 | 32 | Import iostat-template.xml, and link it to a host. 33 | 34 | 35 | CREDITS 36 | ------- 37 | 38 | Some of the scripts are from https://github.com/zbal/zabbix. 39 | 40 | -------------------------------------------------------------------------------- /iostat/dev-discovery.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DEVICES=`iostat | awk '{ if ($1 ~ "^([shxv]|xv)d[a-z]$") { print $1 } }'` 4 | 5 | COUNT=`echo "$DEVICES" | wc -l` 6 | INDEX=0 7 | echo '{"data":[' 8 | echo "$DEVICES" | while read LINE; do 9 | echo -n '{"{#DEVNAME}":"'$LINE'"}' 10 | INDEX=`expr $INDEX + 1` 11 | if [ $INDEX -lt $COUNT ]; then 12 | echo ',' 13 | fi 14 | done 15 | echo ']}' 16 | 17 | -------------------------------------------------------------------------------- /iostat/iostat-check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ################################## 3 | # Zabbix monitoring script 4 | # 5 | # iostat: 6 | # - IO 7 | # - running / blocked processes 8 | # - swap in / out 9 | # - block in / out 10 | # 11 | # Info: 12 | # - vmstat data are gathered via cron job 13 | ################################## 14 | # Contact: 15 | # vincent.viallet@gmail.com 16 | ################################## 17 | # ChangeLog: 18 | # 20100922 VV initial creation 19 | ################################## 20 | 21 | # Zabbix requested parameter 22 | ZBX_REQ_DATA="$2" 23 | ZBX_REQ_DATA_DEV="$1" 24 | 25 | # source data file 26 | SOURCE_DATA=/usr/local/zabbix-agent-ops/var/iostat-data 27 | 28 | # 29 | # Error handling: 30 | # - need to be displayable in Zabbix (avoid NOT_SUPPORTED) 31 | # - items need to be of type "float" (allow negative + float) 32 | # 33 | ERROR_NO_DATA_FILE="-0.9900" 34 | ERROR_OLD_DATA="-0.9901" 35 | ERROR_WRONG_PARAM="-0.9902" 36 | ERROR_MISSING_PARAM="-0.9903" 37 | 38 | # No data file to read from 39 | if [ ! -f "$SOURCE_DATA" ]; then 40 | echo $ERROR_NO_DATA_FILE 41 | exit 1 42 | fi 43 | 44 | # Missing device to get data from 45 | if [ -z "$ZBX_REQ_DATA_DEV" ]; then 46 | echo $ERROR_MISSING_PARAM 47 | exit 1 48 | fi 49 | 50 | # 51 | # Old data handling: 52 | # - in case the cron can not update the data file 53 | # - in case the data are too old we want to notify the system 54 | # Consider the data as non-valid if older than OLD_DATA minutes 55 | # 56 | OLD_DATA=5 57 | if [ $(stat -c "%Y" $SOURCE_DATA) -lt $(date -d "now -$OLD_DATA min" "+%s" ) ]; then 58 | echo $ERROR_OLD_DATA 59 | exit 1 60 | fi 61 | 62 | # 63 | # Grab data from SOURCE_DATA for key ZBX_REQ_DATA 64 | # 65 | # 1st check the device exists and gets data gathered by cron job 66 | device_count=$(grep -Ec "^$ZBX_REQ_DATA_DEV " $SOURCE_DATA) 67 | if [ $device_count -eq 0 ]; then 68 | echo $ERROR_WRONG_PARAM 69 | exit 1 70 | fi 71 | 72 | # 2nd grab the data from the source file 73 | case $ZBX_REQ_DATA in 74 | rrqm/s) grep -E "^$ZBX_REQ_DATA_DEV " $SOURCE_DATA | tail -1 | awk '{print $2}';; 75 | wrqm/s) grep -E "^$ZBX_REQ_DATA_DEV " $SOURCE_DATA | tail -1 | awk '{print $3}';; 76 | r/s) grep -E "^$ZBX_REQ_DATA_DEV " $SOURCE_DATA | tail -1 | awk '{print $4}';; 77 | w/s) grep -E "^$ZBX_REQ_DATA_DEV " $SOURCE_DATA | tail -1 | awk '{print $5}';; 78 | rkB/s) grep -E "^$ZBX_REQ_DATA_DEV " $SOURCE_DATA | tail -1 | awk '{print $6}';; 79 | wkB/s) grep -E "^$ZBX_REQ_DATA_DEV " $SOURCE_DATA | tail -1 | awk '{print $7}';; 80 | avgrq-sz) grep -E "^$ZBX_REQ_DATA_DEV " $SOURCE_DATA | tail -1 | awk '{print $8}';; 81 | avgqu-sz) grep -E "^$ZBX_REQ_DATA_DEV " $SOURCE_DATA | tail -1 | awk '{print $9}';; 82 | await) grep -E "^$ZBX_REQ_DATA_DEV " $SOURCE_DATA | tail -1 | awk '{print $10}';; 83 | svctm) grep -E "^$ZBX_REQ_DATA_DEV " $SOURCE_DATA | tail -1 | awk '{print $11}';; 84 | %util) grep -E "^$ZBX_REQ_DATA_DEV " $SOURCE_DATA | tail -1 | awk '{print $12}';; 85 | *) echo $ERROR_WRONG_PARAM; exit 1;; 86 | esac 87 | 88 | exit 0 89 | 90 | -------------------------------------------------------------------------------- /iostat/iostat-cron.conf: -------------------------------------------------------------------------------- 1 | * * * * * root /usr/local/zabbix-agent-ops/bin/iostat-cron.sh 2 | -------------------------------------------------------------------------------- /iostat/iostat-cron.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ################################## 3 | # Zabbix monitoring script 4 | # 5 | # Info: 6 | # - cron job to gather iostat data 7 | # - can not do real time as iostat data gathering will exceed 8 | # Zabbix agent timeout 9 | ################################## 10 | # Contact: 11 | # vincent.viallet@gmail.com 12 | ################################## 13 | # ChangeLog: 14 | # 20100922 VV initial creation 15 | ################################## 16 | 17 | # source data file 18 | DEST_DATA=/usr/local/zabbix-agent-ops/var/iostat-data 19 | TMP_DATA=/usr/local/zabbix-agent-ops/var/iostat-data.tmp 20 | 21 | # 22 | # gather data in temp file first, then move to final location 23 | # it avoids zabbix-agent to gather data from a half written source file 24 | # 25 | # iostat -kx 10 2 - will display 2 lines : 26 | # - 1st: statistics since boot -- useless 27 | # - 2nd: statistics over the last 10 sec 28 | # 29 | iostat -kx 10 2 > $TMP_DATA 30 | mv $TMP_DATA $DEST_DATA 31 | 32 | 33 | -------------------------------------------------------------------------------- /iostat/iostat-params.conf: -------------------------------------------------------------------------------- 1 | UserParameter=custom.vfs.dev.discovery,/usr/local/zabbix-agent-ops/bin/dev-discovery.sh 2 | UserParameter=iostat[*],/usr/local/zabbix-agent-ops/bin/iostat-check.sh $1 $2 3 | -------------------------------------------------------------------------------- /iostat/iostat-template.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 2.0 4 | 2013-03-25T07:00:53Z 5 | 6 | 7 | Templates 8 | 9 | 10 | 11 | 743 | 744 | 745 | -------------------------------------------------------------------------------- /jvm/README.md: -------------------------------------------------------------------------------- 1 | Template JVM 2 | ============ 3 | 4 | Show JVM statistics in Zabbix. 5 | 6 | INSTALL 7 | ------- 8 | 9 | Assume the Zabbix agent is installed in /zabbix-agent/ directory. 10 | 11 | ### A Compatible JDK 12 | 13 | This package uses `jstat` and `jstack` commands to gather information of jVM. 14 | 15 | ### Start Daemon 16 | 17 | Since the Zabbix agent runs in zabbix user, making it impossible to attache to JVMs running under other users. The solution is to start a daemon under that user and provide socket access to gather the information. 18 | 19 | $ ./jvm-service.pl -d 20 | 21 | It will write logs into /tmp/jvm-service.log 22 | 23 | ### Install Script and Add User Parameters 24 | 25 | Copy jvm-check.pl to /zabbix-agent/bin/. Copy jvm-params.conf to /zabbix-agent/etc/zabbix_agentd.conf.d/. Restart Zabbix agent. 26 | 27 | ### Import Template 28 | 29 | Import jvm-template.xml, and link it to a host. Set the host macro {$JVMPORT} to which the JVM you want to monitor bind. 30 | 31 | HOW IT WORKS 32 | ------------ 33 | 34 | To gather information more effectively, I didn't use a lot of user parameters in the configuration file, to run multiple times. Instead, I used the 'zabbix agent trapper' data type, and run another script sending multiple data items to zabbix server. 35 | 36 | Again, instead of setup a cron job for the script, I used another 'zabbix agent' data type to let the server trigger this script. 37 | 38 | In case the `jstat` command spends more than 3 seconds, which surpasses the timeout limit of Zabbix, so you may want to adjust the `Timeout` option in *both* Zabbix server and agent configuration. 39 | 40 | -------------------------------------------------------------------------------- /jvm/jvm-check.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Getopt::Long; 5 | use Pod::Usage; 6 | use IO::Socket::INET; 7 | 8 | use constant COLLECTOR_UP => 1; 9 | use constant COLLECTOR_DOWN => 0; 10 | 11 | sub stats { 12 | my ($host, $jvmport, $service_addr, $zabbix_bin) = @_; 13 | my ($service_ip, $service_port) = split(/:/, $service_addr); 14 | 15 | my $client = IO::Socket::INET->new( 16 | PeerAddr => $service_ip, 17 | PeerPort => $service_port, 18 | Type => SOCK_STREAM 19 | ) || die "Unable to connect to server.\n"; 20 | 21 | print $client "JVMPORT $jvmport\n"; 22 | my $status = <$client>; 23 | chomp($status); 24 | if ($status ne 'OK') { 25 | print COLLECTOR_DOWN; 26 | return 2; 27 | } 28 | 29 | open my $fd, "| $zabbix_bin -s \"$host\" -i- >/dev/null 2>&1"; 30 | 31 | while (<$client>) { 32 | chomp; 33 | my ($key, $value) = split /\s+/; 34 | if (!$key) { 35 | next; 36 | } 37 | $key = lc $key; 38 | $key =~ s/%/p/g; 39 | print $fd "- jvm.$key $value\n"; 40 | } 41 | 42 | close($fd); 43 | close($client); 44 | 45 | print COLLECTOR_UP; 46 | return 0; 47 | } 48 | 49 | my $help = 0; 50 | my $host = ''; 51 | my $jvmport = 0; 52 | my $service_addr = '127.0.0.1:10060'; 53 | my $zabbix_sender = '/usr/local/zabbix-agent-ops/bin/zabbix_sender'; 54 | my $zabbix_conf = '/usr/local/zabbix-agent-ops/etc/zabbix_agentd.conf'; 55 | 56 | GetOptions ( 57 | 'help|?' => \$help, 58 | 'host=s' => \$host, 59 | 'jvmport=i' => \$jvmport, 60 | 'service-addr=s' => \$service_addr, 61 | 'zabbix-sender=s' => \$zabbix_sender, 62 | 'zabbix-conf=s' => \$zabbix_conf 63 | ) || pod2usage(2); 64 | pod2usage(1) if $help || !$jvmport || !$host; 65 | 66 | exit(stats($host, $jvmport, $service_addr, "$zabbix_sender -c \"$zabbix_conf\"")); 67 | 68 | __END__ 69 | 70 | =head1 NAME 71 | 72 | JVM Statistics 73 | 74 | =head1 SYNOPSIS 75 | 76 | jvm-check.pl [options] 77 | 78 | Options: 79 | -help brief help message 80 | -host hostname recognized by zabbix server 81 | -jvmport JVM port 82 | -service-addr service address "ip:port" 83 | -zabbix-sender path to zabbix_sender binary 84 | -zabbix-conf path to zabbix_agentd.conf 85 | 86 | =cut 87 | -------------------------------------------------------------------------------- /jvm/jvm-params.conf: -------------------------------------------------------------------------------- 1 | UserParameter=jvm.collector[*],/usr/local/zabbix-agent-ops/bin/jvm-check.pl -host "$1" -jvmport "$2" 2 | -------------------------------------------------------------------------------- /jvm/jvm-service.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Getopt::Long; 5 | use Pod::Usage; 6 | use IO::Socket::INET; 7 | use POSIX 'setsid'; 8 | 9 | sub stats { 10 | my $jvmport = shift(@_); 11 | 12 | my @netstat = `netstat -nlpt`; 13 | my $pid = 0; 14 | foreach my $line (@netstat) { 15 | if ($line =~ /.*?:$jvmport\s.*?([0-9]+)\/java\s*$/) { 16 | $pid = $1; 17 | last; 18 | } 19 | } 20 | if (!$pid) { 21 | return 0; 22 | } 23 | 24 | my $result = ''; 25 | 26 | my @jstat = `jstat -gc $pid`; 27 | $result .= kv_parse(@jstat); 28 | 29 | my @jstack = `jstack $pid`; 30 | my $threads = 0; 31 | my $threads_running = 0; 32 | for my $line (@jstack) { 33 | if (index($line, '"') != -1) { 34 | $threads += 1; 35 | } 36 | if (index($line, 'java.lang.Thread.State: RUNNABLE') != -1) { 37 | $threads_running += 1; 38 | } 39 | } 40 | $result .= "threads $threads\n"; 41 | $result .= "threads_running $threads_running\n"; 42 | 43 | my @ps = `ps -o pcpu,rss -p $pid`; 44 | $result .= kv_parse(@ps); 45 | 46 | return $result; 47 | 48 | } 49 | 50 | sub kv_parse { 51 | my @kv_data = @_; 52 | 53 | map { s/^\s+|\s+$// } @kv_data; 54 | my @kv_keys = split(/\s+/, $kv_data[0]); 55 | my @kv_vals = split(/\s+/, $kv_data[1]); 56 | 57 | my $result = ''; 58 | for my $i (0 .. $#kv_keys) { 59 | $result .= "$kv_keys[$i] $kv_vals[$i]\n"; 60 | } 61 | 62 | return $result; 63 | } 64 | 65 | sub process { 66 | my $client = shift; 67 | 68 | my $input = <$client>; 69 | chomp($input); 70 | 71 | if ($input =~ /^JVMPORT ([0-9]+)$/) { 72 | 73 | print "JVMPORT is $1.\n"; 74 | 75 | if (my $result = stats($1)) { 76 | print $client "OK\n", $result, "\n"; 77 | print "[$$] OK\n"; 78 | } else { 79 | print $client "ERROR\n"; 80 | print "[$$] ERROR\n"; 81 | } 82 | 83 | } else { 84 | print "[$$] Invalid input '$input'.\n"; 85 | } 86 | 87 | close($client); 88 | } 89 | 90 | sub daemonize { 91 | exit if fork(); 92 | chdir('/'); 93 | umask(0); 94 | setsid(); 95 | exit if fork(); 96 | open STDIN, '<', '/dev/null'; 97 | open STDOUT, '>>', '/tmp/jvm-service.log'; 98 | open STDERR, '>&', \*STDOUT; 99 | } 100 | 101 | my $help = 0; 102 | my $port = 10060; 103 | my $daemonize = 0; 104 | 105 | GetOptions( 106 | 'help|?' => \$help, 107 | 'port=i' => \$port, 108 | 'daemonize' => \$daemonize 109 | ) || pod2usage(2); 110 | pod2usage(1) if $help; 111 | 112 | if ($daemonize) { 113 | daemonize(); 114 | } 115 | 116 | print "Bind to port $port.\n"; 117 | 118 | my $server = IO::Socket::INET->new( 119 | LocalPort => $port, 120 | Type => SOCK_STREAM, 121 | Reuse => 1, 122 | Listen => SOMAXCONN 123 | ) || die "Unable to create server.\n"; 124 | 125 | # signal handlers 126 | 127 | sub REAPER { 128 | my $pid; 129 | while (($pid = waitpid(-1, 'WNOHANG')) > 0) { 130 | print "SIGCHLD pid $pid\n"; 131 | } 132 | } 133 | 134 | my $interrupted = 0; 135 | 136 | sub INTERRUPTER { 137 | $interrupted = 1; 138 | } 139 | 140 | $SIG{CHLD} = \&REAPER; 141 | $SIG{TERM} = \&INTERRUPTER; 142 | $SIG{INT} = \&INTERRUPTER; 143 | 144 | while (!$interrupted) { 145 | 146 | if (my $client = $server->accept()) { 147 | 148 | my $pid = fork(); 149 | 150 | if ($pid > 0) { 151 | close($client); 152 | print "forked child pid $pid\n"; 153 | } elsif ($pid == 0) { 154 | close($server); 155 | process($client); 156 | exit; 157 | } else { 158 | print "unable to fork\n"; 159 | } 160 | 161 | } 162 | 163 | } 164 | 165 | close($server); 166 | print "Service quit.\n"; 167 | 168 | __END__ 169 | 170 | =head1 NAME 171 | 172 | JVM Statistics 173 | 174 | =head1 SYNOPSIS 175 | 176 | jvm-server.pl [options] 177 | 178 | Options: 179 | -help brief help message 180 | -port bind to tcp port 181 | 182 | =cut 183 | -------------------------------------------------------------------------------- /jvm/jvm-template.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 2.0 4 | 2013-03-28T14:39:43Z 5 | 6 | 7 | Templates 8 | 9 | 10 | 11 | 813 | 814 | 815 | 816 | JVM CPU Usage 817 | 900 818 | 200 819 | 0.0000 820 | 100.0000 821 | 1 822 | 1 823 | 0 824 | 1 825 | 0 826 | 0.0000 827 | 0.0000 828 | 0 829 | 0 830 | 0 831 | 0 832 | 833 | 834 | 0 835 | 5 836 | EE0000 837 | 0 838 | 2 839 | 0 840 | 841 | Template JVM 842 | jvm.pcpu 843 | 844 | 845 | 846 | 847 | 848 | JVM Eden Space 849 | 900 850 | 200 851 | 0.0000 852 | 100.0000 853 | 1 854 | 1 855 | 0 856 | 1 857 | 0 858 | 0.0000 859 | 0.0000 860 | 0 861 | 0 862 | 0 863 | 0 864 | 865 | 866 | 0 867 | 0 868 | C80000 869 | 0 870 | 2 871 | 0 872 | 873 | Template JVM 874 | jvm.ec 875 | 876 | 877 | 878 | 1 879 | 0 880 | 00C800 881 | 0 882 | 2 883 | 0 884 | 885 | Template JVM 886 | jvm.eu 887 | 888 | 889 | 890 | 891 | 892 | JVM GC Count / sec 893 | 900 894 | 200 895 | 0.0000 896 | 100.0000 897 | 1 898 | 1 899 | 0 900 | 1 901 | 0 902 | 0.0000 903 | 0.0000 904 | 0 905 | 0 906 | 0 907 | 0 908 | 909 | 910 | 0 911 | 0 912 | C80000 913 | 0 914 | 2 915 | 0 916 | 917 | Template JVM 918 | jvm.fgc 919 | 920 | 921 | 922 | 1 923 | 0 924 | 00C800 925 | 0 926 | 2 927 | 0 928 | 929 | Template JVM 930 | jvm.ygc 931 | 932 | 933 | 934 | 935 | 936 | JVM GC Time 937 | 900 938 | 200 939 | 0.0000 940 | 100.0000 941 | 1 942 | 1 943 | 0 944 | 1 945 | 0 946 | 0.0000 947 | 0.0000 948 | 0 949 | 0 950 | 0 951 | 0 952 | 953 | 954 | 0 955 | 0 956 | BBBBBB 957 | 0 958 | 2 959 | 0 960 | 961 | Template JVM 962 | jvm.gct 963 | 964 | 965 | 966 | 1 967 | 0 968 | EE0000 969 | 0 970 | 2 971 | 0 972 | 973 | Template JVM 974 | jvm.fgct 975 | 976 | 977 | 978 | 2 979 | 0 980 | 00EE00 981 | 0 982 | 2 983 | 0 984 | 985 | Template JVM 986 | jvm.ygct 987 | 988 | 989 | 990 | 991 | 992 | JVM Old Space 993 | 900 994 | 200 995 | 0.0000 996 | 100.0000 997 | 1 998 | 1 999 | 0 1000 | 1 1001 | 0 1002 | 0.0000 1003 | 0.0000 1004 | 0 1005 | 0 1006 | 0 1007 | 0 1008 | 1009 | 1010 | 0 1011 | 0 1012 | C80000 1013 | 0 1014 | 2 1015 | 0 1016 | 1017 | Template JVM 1018 | jvm.oc 1019 | 1020 | 1021 | 1022 | 1 1023 | 0 1024 | 00C800 1025 | 0 1026 | 2 1027 | 0 1028 | 1029 | Template JVM 1030 | jvm.ou 1031 | 1032 | 1033 | 1034 | 1035 | 1036 | JVM Perm Space 1037 | 900 1038 | 200 1039 | 0.0000 1040 | 100.0000 1041 | 1 1042 | 1 1043 | 0 1044 | 1 1045 | 0 1046 | 0.0000 1047 | 0.0000 1048 | 0 1049 | 0 1050 | 0 1051 | 0 1052 | 1053 | 1054 | 0 1055 | 0 1056 | C80000 1057 | 0 1058 | 2 1059 | 0 1060 | 1061 | Template JVM 1062 | jvm.pc 1063 | 1064 | 1065 | 1066 | 1 1067 | 0 1068 | 00C800 1069 | 0 1070 | 2 1071 | 0 1072 | 1073 | Template JVM 1074 | jvm.pu 1075 | 1076 | 1077 | 1078 | 1079 | 1080 | JVM RSS Usage 1081 | 900 1082 | 200 1083 | 0.0000 1084 | 100.0000 1085 | 1 1086 | 1 1087 | 0 1088 | 1 1089 | 0 1090 | 0.0000 1091 | 0.0000 1092 | 0 1093 | 0 1094 | 0 1095 | 0 1096 | 1097 | 1098 | 0 1099 | 1 1100 | AA00AA 1101 | 0 1102 | 2 1103 | 0 1104 | 1105 | Template JVM 1106 | jvm.rss 1107 | 1108 | 1109 | 1110 | 1111 | 1112 | JVM Suvivor Space 1113 | 900 1114 | 200 1115 | 0.0000 1116 | 100.0000 1117 | 1 1118 | 1 1119 | 0 1120 | 1 1121 | 0 1122 | 0.0000 1123 | 0.0000 1124 | 0 1125 | 0 1126 | 0 1127 | 0 1128 | 1129 | 1130 | 0 1131 | 0 1132 | EEEE00 1133 | 0 1134 | 2 1135 | 0 1136 | 1137 | Template JVM 1138 | jvm.s0c 1139 | 1140 | 1141 | 1142 | 1 1143 | 0 1144 | EE00EE 1145 | 0 1146 | 2 1147 | 0 1148 | 1149 | Template JVM 1150 | jvm.s0u 1151 | 1152 | 1153 | 1154 | 2 1155 | 0 1156 | EE0000 1157 | 0 1158 | 2 1159 | 0 1160 | 1161 | Template JVM 1162 | jvm.s1c 1163 | 1164 | 1165 | 1166 | 3 1167 | 0 1168 | 00EE00 1169 | 0 1170 | 2 1171 | 0 1172 | 1173 | Template JVM 1174 | jvm.s1u 1175 | 1176 | 1177 | 1178 | 1179 | 1180 | JVM Threads 1181 | 900 1182 | 200 1183 | 0.0000 1184 | 100.0000 1185 | 1 1186 | 1 1187 | 0 1188 | 1 1189 | 0 1190 | 0.0000 1191 | 0.0000 1192 | 0 1193 | 0 1194 | 0 1195 | 0 1196 | 1197 | 1198 | 0 1199 | 0 1200 | EE0000 1201 | 0 1202 | 2 1203 | 0 1204 | 1205 | Template JVM 1206 | jvm.threads 1207 | 1208 | 1209 | 1210 | 1 1211 | 0 1212 | 00DD00 1213 | 0 1214 | 2 1215 | 0 1216 | 1217 | Template JVM 1218 | jvm.threads_running 1219 | 1220 | 1221 | 1222 | 1223 | 1224 | 1225 | -------------------------------------------------------------------------------- /mongo/README.md: -------------------------------------------------------------------------------- 1 | Template Mongo 2 | ============== 3 | 4 | Show Mongo status in Zabbix. 5 | 6 | INSTALL 7 | ------- 8 | 9 | Assume the Zabbix agent is installed in /zabbix-agent/ directory. 10 | 11 | ### Add User Parameters 12 | 13 | Add line "Include=/usr/local/zabbix/conf/zabbix_agentd/*.conf" in /usr/local/zabbix/conf/zabbix_agentd.conf 14 | Copy mongo.conf to /usr/local/zabbix/conf/zabbix_agentd/. Restart Zabbix agent. 15 | 16 | ### Import Template 17 | 18 | Import mongodb-template.xml, and link it to a host. 19 | 20 | -------------------------------------------------------------------------------- /mongo/mongo.conf: -------------------------------------------------------------------------------- 1 | UserParameter=mongo.service,ps -ef | grep mongo | grep -v grep | wc -l 2 | UserParameter=mongo.network[*],echo "db.serverStatus().network" | mongo | grep $1 | cut -d ":" -f 2 | cut -d "," -f1 | cut -d " " -f 2 3 | UserParameter=mongo.opcounters[*],echo "db.serverStatus().opcounters" | mongo | grep $1 | cut -d ":" -f 2 | cut -d "," -f 1 | cut -d " " -f 2 4 | UserParameter=mongo.mem_resident,echo "db.serverStatus().mem" | mongo | grep resident | cut -d ":" -f 2 | cut -d "," -f 1 | cut -d " " -f 2 5 | UserParameter=mongo.mem_virtual,echo "db.serverStatus().mem" | mongo | grep virtual | cut -d ":" -f 2 | cut -d "," -f 1| cut -d " " -f 2 6 | UserParameter=mongo.mem_mapped,echo "db.serverStatus().mem" | mongo | grep '\bmapped\b' | cut -d ":" -f 2 | cut -d "," -f 1 | cut -d " " -f 2 7 | UserParameter=mongo.connection_current,echo "db.serverStatus().connections.current"| mongo | sed -n 3p 8 | UserParameter=mongo.connection_available,echo "db.serverStatus().connections.available"| mongo | sed -n 3p 9 | UserParameter=mongo.queue_write,echo "db.serverStatus().globalLock.currentQueue.writers" | mongo |sed -n 3p 10 | UserParameter=mongo.queue_reader,echo "db.serverStatus().globalLock.currentQueue.readers" | mongo |sed -n 3p 11 | UserParameter=mongo.cursors_totalOpen,echo "db.serverStatus().cursors.totalOpen" | mongo | sed -n 3p 12 | UserParameter=mongo.cursors_timedOut,echo "db.serverStatus().cursors.timedOut" | mongo | sed -n 3p 13 | UserParameter=mongo.backgroundFlush,echo "db.serverStatus().backgroundFlushing.last_ms" | mongo | sed -n 3p 14 | UserParameter=mongo.rpstatus,echo "rs.status()"| mongo | grep myState| cut -d ":" -f 2 | cut -d "," -f 1 | cut -d " " -f 2 15 | UserParameter=mongo.pagefaults,echo "db.serverStatus().extra_info.page_faults" | mongo | sed -n 3p 16 | UserParameter=mongo.oplog_storetime,echo "db.printReplicationInfo()" | mongo | sed -n 4p | cut -d "(" -f 2 | cut -d "h" -f 1 17 | -------------------------------------------------------------------------------- /mysql/README.md: -------------------------------------------------------------------------------- 1 | Template MySQL 2 | ============ 3 | 4 | Show MySQL statistics in Zabbix. Version 2 uses LLD (Low Level Discovery) to bind multiple MySQL instances to the same host. 5 | 6 | INSTALL 7 | ------- 8 | 9 | Assume the Zabbix agent is installed in /zabbix-agent/ directory. 10 | 11 | ### Preparatory 12 | 13 | This package uses `mysql` and `mysqladmin` commands to gather information of MySQL. 14 | 15 | ### Install Script and Add User Parameters 16 | 17 | * Copy mysql-check-v2.sh to /zabbix-agent/bin/. 18 | * Copy mysql-params-v2.conf to /zabbix-agent/etc/zabbix_agentd.conf.d/. 19 | * Edit mysql-check-v2.sh to configure username and password. 20 | * Restart Zabbix agent. 21 | 22 | ### Import Template 23 | 24 | Import mysql-template-v2.xml, and link it to a host. 25 | 26 | HOW IT WORKS 27 | ------------ 28 | 29 | ### Discovery 30 | 31 | `mysql-check-v2.sh` has two forms of invocation: 32 | 33 | * `./mysql-check-v2.sh discovery` Return a JSON encoded string indicating the MySQL instances (or ports) to be discovered. 34 | * `./mysql-check-v2.sh collector "$host" $port` Get and submit the statistics from MySQL Server to Zabbix Server. (use `zabbix trapper` data type) 35 | 36 | ### Collector 37 | 38 | In order not to run `mysqladmin` several times to get enough information, here we use `Zabbix trapper` data type to let the agent send data actively. Also to save the trouble of adding a cron job, here we use a `Zabbix agent` item to trigger the data collection process. 39 | 40 | ### `mysqladmin` 41 | 42 | Most statistics items are from `mysqladmin extended-status`. 43 | 44 | ### Replication Delay 45 | 46 | To detect the replication delay (in sec) of Slave database, we use a dedicated `heartbeat_db`, in which the Master database update the timestamp periodically, and the Slave agents check the difference between current timestamp and the heartbeat_db's timestamp. 47 | 48 | The `heartbeat_db.heartbeat` table's structure is: 49 | 50 | ```sql 51 | CREATE TABLE `heartbeat` ( 52 | `id` int(11) NOT NULL AUTO_INCREMENT, 53 | `ts` datetime NOT NULL, 54 | RIMARY KEY (`id`) 55 | ) 56 | ``` 57 | -------------------------------------------------------------------------------- /mysql/mysql-check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | MYSQL_USERNAME="root" 4 | MYSQL_PASSWORD="password" 5 | MYSQL_PORTS="3306" # use space-seperated multiple instance ports 6 | 7 | MYSQL_VARIABLES="Connections Aborted_clients Aborted_connects Com_select Com_insert Com_update Com_replace Com_delete Slow_queries Threads_connected Threads_running" 8 | 9 | ZABBIX_HOME="/usr/local/zabbix-agent-ops" 10 | ZABBIX_BIN="$ZABBIX_HOME/bin/zabbix_sender -c $ZABBIX_HOME/etc/zabbix_agentd.conf" 11 | 12 | function usage() { 13 | echo "Usage: ./mysql-check-v2.sh [host] [port]" 14 | exit 1 15 | } 16 | 17 | if [ "x$1" = "xdiscovery" ]; then 18 | 19 | COUNT=`echo "$MYSQL_PORTS" | wc -w` 20 | INDEX=0 21 | echo '{"data":[' 22 | for MYSQL_PORT in $MYSQL_PORTS; do 23 | echo -n '{"{#MYSQL_PORT}":"'$MYSQL_PORT'"}' 24 | INDEX=`expr $INDEX + 1` 25 | if [ $INDEX -lt $COUNT ]; then 26 | echo ',' 27 | fi 28 | done 29 | echo ']}' 30 | 31 | elif [ "x$1" = "xcollector" ]; then 32 | 33 | if [ -z $2 ] || [ -z $3 ]; then 34 | usage 35 | fi 36 | 37 | HOST_HOST=$2 38 | MYSQL_PORT=$3 39 | 40 | EXTENDED_STATUS=`mysqladmin -u$MYSQL_USERNAME -p$MYSQL_PASSWORD -h127.0.0.1 -P$MYSQL_PORT extended-status` 41 | 42 | DATA="" 43 | for MYSQL_VARIABLE in $MYSQL_VARIABLES; do 44 | VALUE=`echo "$EXTENDED_STATUS" | grep -w "$MYSQL_VARIABLE" | awk '{print $4}'` 45 | if [ -n "$VALUE" ]; then 46 | DATA=$DATA"- mysql-v2.check[$MYSQL_PORT,$MYSQL_VARIABLE] $VALUE\n" 47 | fi 48 | done 49 | 50 | REPLICATION_DELAY=`mysql -u$MYSQL_USERNAME -p$MYSQL_PASSWORD -h127.0.0.1 -P$MYSQL_PORT -Dheartbeat_db -e "SELECT UNIX_TIMESTAMP() - UNIX_TIMESTAMP(ts) FROM heartbeat ORDER BY id DESC LIMIT 1" | sed '1d'` 51 | 52 | if [ -n "$REPLICATION_DELAY" ]; then 53 | DATA=$DATA"- mysql-v2.check[$MYSQL_PORT,Replication_delay] $REPLICATION_DELAY\n" 54 | fi 55 | 56 | if [ -n "$DATA" ]; then 57 | echo -e "$DATA" | $ZABBIX_BIN -s "$HOST_HOST" -i- >/dev/null 2>&1 58 | echo 1 59 | else 60 | echo 0 61 | fi 62 | 63 | else 64 | usage 65 | fi 66 | -------------------------------------------------------------------------------- /mysql/mysql-params.conf: -------------------------------------------------------------------------------- 1 | UserParameter=mysql-v2.discovery,/usr/local/zabbix-agent-ops/bin/mysql-check-v2.sh discovery 2 | UserParameter=mysql-v2.collector[*],/usr/local/zabbix-agent-ops/bin/mysql-check-v2.sh collector "$1" $2 3 | -------------------------------------------------------------------------------- /mysql/mysql-template.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 2.0 4 | 2013-05-03T13:52:15Z 5 | 6 | 7 | Templates 8 | 9 | 10 | 11 | 821 | 822 | 823 | -------------------------------------------------------------------------------- /nginx/README.md: -------------------------------------------------------------------------------- 1 | Template Nginx 2 | ============== 3 | 4 | Show Nginx status in Zabbix. 5 | 6 | INSTALL 7 | ------- 8 | 9 | Assume the Zabbix agent is installed in /zabbix-agent/ directory. 10 | 11 | ### Nginx HttpStubStatusModule 12 | 13 | Nginx needs to be built with HttpStubStatusModule, i.e. --with-http_stub_status_module. You can use `nginx -V` to check whether the current binary includes this module. 14 | 15 | More information could be found in this [Wiki][1] 16 | 17 | ### Add Configuration 18 | 19 | Add the following into Nginx configuration: 20 | 21 |
22 | server {
23 |     listen 10051;
24 |     location /nginx_status {
25 |         stub_status on;
26 |         access_log off;
27 |         allow 127.0.0.1;
28 |         deny all;
29 |     }
30 | }
31 | 
32 | 33 | Reload Nginx, and use `curl http://127.0.0.1:10051/nginx_status` to get the statistics. 34 | 35 | ### Add User Parameters 36 | 37 | Copy nginx-params.conf to /usr/local/zabbix/conf/zabbix_agentd/. Restart Zabbix agent. 38 | Add line "Include=/usr/local/zabbix/conf/zabbix_agentd/*.conf" in /usr/local/zabbix/conf/zabbix_agentd.conf 39 | 40 | ### Import Template 41 | 42 | Import nginx-template.xml, and link it to a host. Set the host macro {$NGINX_STATUS_URL} if needed. 43 | 44 | 45 | CREDITS 46 | ------- 47 | 48 | The scripts are form http://github.com/zbal/zabbix. 49 | 50 | [1]: http://wiki.nginx.org/HttpStubStatusModule 51 | -------------------------------------------------------------------------------- /nginx/nginx-check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ################################## 3 | # Zabbix monitoring script 4 | # 5 | # nginx: 6 | # - anything available via nginx stub-status module 7 | # 8 | ################################## 9 | # Contact: 10 | # vincent.viallet@gmail.com 11 | ################################## 12 | # ChangeLog: 13 | # 20100922 VV initial creation 14 | ################################## 15 | 16 | # Zabbix requested parameter 17 | ZBX_REQ_DATA="$1" 18 | ZBX_REQ_DATA_URL="$2" 19 | 20 | # Nginx defaults 21 | NGINX_STATUS_DEFAULT_URL="http://localhost:80/nginx_status" 22 | WGET_BIN="/usr/bin/wget" 23 | 24 | # 25 | # Error handling: 26 | # - need to be displayable in Zabbix (avoid NOT_SUPPORTED) 27 | # - items need to be of type "float" (allow negative + float) 28 | # 29 | ERROR_NO_ACCESS_FILE="-0.9900" 30 | ERROR_NO_ACCESS="-0.9901" 31 | ERROR_WRONG_PARAM="-0.9902" 32 | ERROR_DATA="-0.9903" # either can not connect / bad host / bad port 33 | 34 | # Handle host and port if non-default 35 | if [ ! -z "$ZBX_REQ_DATA_URL" ]; then 36 | URL="$ZBX_REQ_DATA_URL" 37 | else 38 | URL="$NGINX_STATUS_DEFAULT_URL" 39 | fi 40 | 41 | # save the nginx stats in a variable for future parsing 42 | NGINX_STATS=$($WGET_BIN -q $URL -O - 2> /dev/null) 43 | 44 | # error during retrieve 45 | if [ $? -ne 0 -o -z "$NGINX_STATS" ]; then 46 | echo $ERROR_DATA 47 | exit 1 48 | fi 49 | 50 | # 51 | # Extract data from nginx stats 52 | # 53 | case $ZBX_REQ_DATA in 54 | active_connections) echo "$NGINX_STATS" | head -1 | cut -f3 -d' ';; 55 | accepted_connections) echo "$NGINX_STATS" | grep -Ev '[a-zA-Z]' | cut -f2 -d' ';; 56 | handled_connections) echo "$NGINX_STATS" | grep -Ev '[a-zA-Z]' | cut -f3 -d' ';; 57 | handled_requests) echo "$NGINX_STATS" | grep -Ev '[a-zA-Z]' | cut -f4 -d' ';; 58 | reading) echo "$NGINX_STATS" | tail -1 | cut -f2 -d' ';; 59 | writing) echo "$NGINX_STATS" | tail -1 | cut -f4 -d' ';; 60 | waiting) echo "$NGINX_STATS" | tail -1 | cut -f6 -d' ';; 61 | *) echo $ERROR_WRONG_PARAM; exit 1;; 62 | esac 63 | 64 | exit 0 65 | -------------------------------------------------------------------------------- /nginx/nginx-params.conf: -------------------------------------------------------------------------------- 1 | UserParameter=nginx[*],/usr/local/zabbix/bin/nginx-check.sh "$1" "$2" 2 | -------------------------------------------------------------------------------- /nginx/nginx-template.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 2.0 4 | 2013-03-26T04:17:58Z 5 | 6 | 7 | Templates 8 | 9 | 10 | 11 | 344 | 345 | 346 | 347 | {Template_Nginx:proc.num[nginx].last(0)}=0 348 | Nginx is not running on {HOSTNAME} 349 | 350 | 0 351 | 4 352 | Nginx is not running. 353 | 354 | It has been stopped / shutdown or has crashed. 355 | Check on the server for more details: 356 | - w / last 357 | - dmesg logs 358 | - /var/log/messages 359 | - nginx error logs 360 | 0 361 | 362 | 363 | 364 | 365 | 366 | Nginx - Connections and Requests status 367 | 900 368 | 200 369 | 0.0000 370 | 100.0000 371 | 0 372 | 0 373 | 0 374 | 1 375 | 0 376 | 0.0000 377 | 0.0000 378 | 1 379 | 0 380 | 0 381 | 0 382 | 383 | 384 | 0 385 | 1 386 | FF9999 387 | 0 388 | 4 389 | 0 390 | 391 | Template_Nginx 392 | nginx[accepted_connections,{$NGINX_STATUS_URL}] 393 | 394 | 395 | 396 | 1 397 | 2 398 | 990000 399 | 0 400 | 4 401 | 0 402 | 403 | Template_Nginx 404 | nginx[handled_connections,{$NGINX_STATUS_URL}] 405 | 406 | 407 | 408 | 2 409 | 0 410 | 009900 411 | 0 412 | 4 413 | 0 414 | 415 | Template_Nginx 416 | nginx[handled_requests,{$NGINX_STATUS_URL}] 417 | 418 | 419 | 420 | 421 | 422 | Nginx - Threads status 423 | 900 424 | 200 425 | 0.0000 426 | 100.0000 427 | 0 428 | 0 429 | 1 430 | 1 431 | 0 432 | 0.0000 433 | 0.0000 434 | 1 435 | 0 436 | 0 437 | 0 438 | 439 | 440 | 0 441 | 1 442 | 990000 443 | 0 444 | 4 445 | 0 446 | 447 | Template_Nginx 448 | nginx[writing,{$NGINX_STATUS_URL}] 449 | 450 | 451 | 452 | 1 453 | 1 454 | 999900 455 | 0 456 | 4 457 | 0 458 | 459 | Template_Nginx 460 | nginx[reading,{$NGINX_STATUS_URL}] 461 | 462 | 463 | 464 | 2 465 | 1 466 | 009900 467 | 0 468 | 4 469 | 0 470 | 471 | Template_Nginx 472 | nginx[waiting,{$NGINX_STATUS_URL}] 473 | 474 | 475 | 476 | 477 | 478 | 479 | -------------------------------------------------------------------------------- /php-fpm/README.md: -------------------------------------------------------------------------------- 1 | Template php-fpm 2 | ================ 3 | 4 | Show php-fpm statistics in Zabbix. 5 | 6 | INSTALL 7 | ------- 8 | 9 | Assume the Zabbix agent is installed in /zabbix-agent/ directory. 10 | 11 | ### Configure php-fpm 12 | 13 | Open the php-fpm pool's configuration file, uncomment the 'pm.status=' directive: 14 | 15 | pm.status_path = /php-fpm_status 16 | 17 | Since php-fpm's statistics is collected by different pools, so you need to create corresponding hosts for them. 18 | 19 | ### Configure Nginx 20 | 21 | Add the following lines to Nginx configuration: 22 | 23 | ``` 24 | server { 25 | listen 10061; 26 | 27 | location /php-fpm_status { 28 | fastcgi_pass 127.0.0.1:9000; 29 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 30 | include fastcgi_params; 31 | } 32 | } 33 | ``` 34 | 35 | After restarting both php-fpm and nginx, try the following command to test: 36 | 37 | $ curl http://127.0.0.1:10061/php-fpm_status 38 | 39 | ### Add User Parameters 40 | 41 | Copy php-fpm-params.conf to /zabbix-agent/etc/zabbix_agentd.conf.d/. Restart Zabbix agent. 42 | 43 | ### Import Template 44 | 45 | Import php-fpm-template.xml, and link it to a host. Set the host macro {$PHP_FPM_STATUS_URL} if needed. 46 | 47 | 48 | CREDITS 49 | ------- 50 | 51 | Some of the scripts are form http://github.com/zbal/zabbix. 52 | 53 | -------------------------------------------------------------------------------- /php-fpm/php-fpm-check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ################################## 3 | # Zabbix monitoring script 4 | # 5 | # php-fpm: 6 | # - anything available via FPM status page 7 | # 8 | ################################## 9 | # Contact: 10 | # vincent.viallet@gmail.com 11 | ################################## 12 | # ChangeLog: 13 | # 20100922 VV initial creation 14 | ################################## 15 | 16 | # Zabbix requested parameter 17 | ZBX_REQ_DATA="$1" 18 | ZBX_REQ_DATA_URL="$2" 19 | 20 | # Nginx defaults 21 | NGINX_STATUS_DEFAULT_URL="http://localhost:80/php-fpm_status" 22 | WGET_BIN="/usr/bin/wget" 23 | 24 | # 25 | # Error handling: 26 | # - need to be displayable in Zabbix (avoid NOT_SUPPORTED) 27 | # - items need to be of type "float" (allow negative + float) 28 | # 29 | ERROR_NO_ACCESS_FILE="-0.9900" 30 | ERROR_NO_ACCESS="-0.9901" 31 | ERROR_WRONG_PARAM="-0.9902" 32 | ERROR_DATA="-0.9903" # either can not connect / bad host / bad port 33 | 34 | # Handle host and port if non-default 35 | if [ ! -z "$ZBX_REQ_DATA_URL" ]; then 36 | URL="$ZBX_REQ_DATA_URL" 37 | else 38 | URL="$NGINX_STATUS_DEFAULT_URL" 39 | fi 40 | 41 | # save the nginx stats in a variable for future parsing 42 | NGINX_STATS=$($WGET_BIN -q $URL -O - 2> /dev/null) 43 | 44 | # error during retrieve 45 | if [ $? -ne 0 -o -z "$NGINX_STATS" ]; then 46 | echo $ERROR_DATA 47 | exit 1 48 | fi 49 | 50 | # 51 | # Extract data from nginx stats 52 | # 53 | RESULT=$(echo "$NGINX_STATS" | awk 'match($0, "^'"$ZBX_REQ_DATA"':[[:space:]]+(.*)", a) { print a[1] }') 54 | if [ $? -ne 0 -o -z "$RESULT" ]; then 55 | echo $ERROR_WRONG_PARAM 56 | exit 1 57 | fi 58 | 59 | echo $RESULT 60 | 61 | exit 0 62 | -------------------------------------------------------------------------------- /php-fpm/php-fpm-params.conf: -------------------------------------------------------------------------------- 1 | UserParameter=php-fpm[*],/usr/local/zabbix-agent-ops/bin/php-fpm-check.sh "$1" "$2" 2 | -------------------------------------------------------------------------------- /php-fpm/php-fpm-template.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 2.0 4 | 2013-03-26T04:12:09Z 5 | 6 | 7 | Templates 8 | 9 | 10 | 11 | 309 | 310 | 311 | 312 | php-fpm Accepted Connections / sec 313 | 900 314 | 200 315 | 0.0000 316 | 100.0000 317 | 1 318 | 1 319 | 0 320 | 1 321 | 0 322 | 0.0000 323 | 0.0000 324 | 0 325 | 0 326 | 0 327 | 0 328 | 329 | 330 | 0 331 | 0 332 | C80000 333 | 0 334 | 2 335 | 0 336 | 337 | Template php-fpm 338 | php-fpm["accepted conn",{$PHP_FPM_STATUS_URL}] 339 | 340 | 341 | 342 | 343 | 344 | php-fpm Listen Queue 345 | 900 346 | 200 347 | 0.0000 348 | 100.0000 349 | 1 350 | 1 351 | 0 352 | 1 353 | 0 354 | 0.0000 355 | 0.0000 356 | 0 357 | 0 358 | 0 359 | 0 360 | 361 | 362 | 0 363 | 0 364 | EE0000 365 | 0 366 | 2 367 | 0 368 | 369 | Template php-fpm 370 | php-fpm["listen queue len",{$PHP_FPM_STATUS_URL}] 371 | 372 | 373 | 374 | 1 375 | 0 376 | 00EE00 377 | 0 378 | 2 379 | 0 380 | 381 | Template php-fpm 382 | php-fpm["listen queue",{$PHP_FPM_STATUS_URL}] 383 | 384 | 385 | 386 | 387 | 388 | php-fpm Processes 389 | 900 390 | 200 391 | 0.0000 392 | 100.0000 393 | 1 394 | 1 395 | 0 396 | 1 397 | 0 398 | 0.0000 399 | 0.0000 400 | 0 401 | 0 402 | 0 403 | 0 404 | 405 | 406 | 0 407 | 0 408 | C80000 409 | 0 410 | 2 411 | 0 412 | 413 | Template php-fpm 414 | php-fpm["total processes",{$PHP_FPM_STATUS_URL}] 415 | 416 | 417 | 418 | 1 419 | 0 420 | 00C800 421 | 0 422 | 2 423 | 0 424 | 425 | Template php-fpm 426 | php-fpm["active processes",{$PHP_FPM_STATUS_URL}] 427 | 428 | 429 | 430 | 2 431 | 0 432 | 0000C8 433 | 0 434 | 2 435 | 0 436 | 437 | Template php-fpm 438 | php-fpm["idle processes",{$PHP_FPM_STATUS_URL}] 439 | 440 | 441 | 442 | 443 | 444 | php-fpm Slow Requests / sec 445 | 900 446 | 200 447 | 0.0000 448 | 100.0000 449 | 1 450 | 1 451 | 0 452 | 1 453 | 0 454 | 0.0000 455 | 0.0000 456 | 0 457 | 0 458 | 0 459 | 0 460 | 461 | 462 | 0 463 | 0 464 | C80000 465 | 0 466 | 2 467 | 0 468 | 469 | Template php-fpm 470 | php-fpm["slow requests",{$PHP_FPM_STATUS_URL}] 471 | 472 | 473 | 474 | 475 | 476 | 477 | -------------------------------------------------------------------------------- /scripts/daily_report.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | import os 4 | import time 5 | import shutil 6 | import MySQLdb 7 | import smtplib 8 | import requests 9 | import datetime 10 | 11 | from email.MIMEText import MIMEText 12 | from email.MIMEImage import MIMEImage 13 | from email.MIMEMultipart import MIMEMultipart 14 | 15 | 16 | # based on zabbix 2.4.4 17 | ZABBIX_HOST = '127.0.0.1' 18 | ZABBIX_USER = 'Admin' 19 | ZABBIX_PWD = 'password' 20 | 21 | ZABBIX_DB_HOST = 'localhost' 22 | ZABBIX_DB_USER = 'zabbix' 23 | ZABBIX_DB_PWD = 'db_password' 24 | ZABBIX_DB_NAME = 'zabbix' 25 | 26 | GRAPH_PATH = '/tmp/zabbix_graph' 27 | GRAPH_PERIOD = 86400 # one day 28 | 29 | EMAIL_DOMAIN = '163.com' 30 | EMAIL_USERNAME = 'wuxianglong098' 31 | EMAIL_PASSWORD = 'email_password' 32 | 33 | 34 | def query_screens(screen_name): 35 | conn = MySQLdb.connect(host=ZABBIX_DB_HOST, user=ZABBIX_DB_USER, passwd=ZABBIX_DB_PWD, 36 | db=ZABBIX_DB_NAME, charset='utf8', connect_timeout=20) 37 | cur = conn.cursor() 38 | count = cur.execute(""" 39 | select a.name, a.screenid, b.resourceid, b.width, b.height 40 | from screens a, screens_items as b 41 | where a.screenid=b.screenid and a.templateid<=>NULL and a.name='%s' 42 | order by a.screenid; 43 | """ % screen_name) 44 | if count == 0: 45 | result = 0 46 | else: 47 | result = cur.fetchall() 48 | 49 | cur.close() 50 | conn.close() 51 | 52 | return result 53 | 54 | 55 | def generate_graphs(screens): 56 | login_resp = requests.post('http://%s/index.php' % ZABBIX_HOST, data={ 57 | 'name': ZABBIX_USER, 58 | 'password': ZABBIX_PWD, 59 | 'enter': 'Sign in', 60 | 'autologin': 1, 61 | }) 62 | session_id = login_resp.cookies['zbx_sessionid'] 63 | 64 | graphs = [] 65 | for i, (screen_name, screen_id, graph_id, width, height) in enumerate(screens): 66 | params = { 67 | 'screenid': screen_id, 68 | 'graphid': graph_id, 69 | 'width': width * 2, 70 | 'height': height * 2, 71 | 'period': GRAPH_PERIOD, 72 | 'stime': datetime.datetime.utcnow().strftime('%Y%m%d%H%M%S'), 73 | } 74 | resp = requests.get('http://%s/chart2.php' % ZABBIX_HOST, params=params, 75 | cookies={'zbx_sessionid': session_id}) 76 | file_name = '_'.join(map(str, screens[i][:3])).replace(' ', '_') + '.png' 77 | with open(os.path.join(GRAPH_PATH, file_name), 'wb') as fp: 78 | fp.write(resp.content) 79 | graphs.append(file_name) 80 | 81 | return graphs 82 | 83 | 84 | def send_mail(screen_name, graphs, to_list): 85 | me = 'Zabbix <%s@%s>' % (EMAIL_USERNAME, EMAIL_DOMAIN) 86 | 87 | def _create_msg(): 88 | msg = MIMEMultipart('related') 89 | msg['Subject'] = 'Zabbix Screen Report: %s' % screen_name 90 | msg['From'] = me 91 | msg['To'] = ';'.join(to_list) 92 | msg.preamble = 'This is a multi-part message in MIME format.' 93 | 94 | contents = "

Screen %s


" % screen_name 95 | contents += "" 96 | for g_name in graphs: 97 | with open(os.path.join(GRAPH_PATH, g_name), 'rb') as fp: 98 | msg_image = MIMEImage(fp.read()) 99 | msg_image.add_header('Content-ID', "<%s>" % g_name) 100 | msg.attach(msg_image) 101 | 102 | contents += '' 103 | contents += "" % g_name 104 | contents += "
" 105 | 106 | msg_text = MIMEText(contents, 'html') 107 | msg_alternative = MIMEMultipart('alternative') 108 | msg_alternative.attach(msg_text) 109 | msg.attach(msg_alternative) 110 | 111 | return msg 112 | 113 | try: 114 | server = smtplib.SMTP() 115 | server.connect('smtp.%s' % EMAIL_DOMAIN) 116 | server.login('%s@%s' % (EMAIL_USERNAME, EMAIL_DOMAIN), EMAIL_PASSWORD) 117 | server.sendmail(me, to_list, _create_msg().as_string()) 118 | server.close() 119 | print 'send mail Ok!' 120 | except Exception, e: 121 | print e 122 | 123 | 124 | if __name__ == '__main__': 125 | # remove old dirs 126 | if os.path.exists(GRAPH_PATH): 127 | shutil.rmtree(GRAPH_PATH) 128 | os.makedirs(GRAPH_PATH) 129 | 130 | for srn_name in (u'Zabbix server', u'Nginx Connections'): 131 | # get screens 132 | all_screens = query_screens(srn_name) 133 | print all_screens 134 | 135 | # generate graphs 136 | graphs = generate_graphs(all_screens) 137 | 138 | send_mail(srn_name, graphs, ['wuxianglong098@163.com']) 139 | -------------------------------------------------------------------------------- /scripts/install_zabbix_agent.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | import time 4 | import Queue 5 | import socket 6 | import paramiko 7 | import threading 8 | 9 | QUEUE = Queue.Queue() 10 | SSH_USERNAME = 'ubuntu' 11 | SSH_KEY = '/home/xianglong/.ssh/admin.pem' 12 | 13 | HOSTS = [ 14 | ['host-name', 'public-ip', 'private-ip'], 15 | ] 16 | THREAD_NUM = 10 17 | ZABBIX_SERVER = '127.0.0.1' 18 | 19 | 20 | def get_list(filename): 21 | lst = [] 22 | with open(filename, 'r') as f: 23 | for i in f.readlines(): 24 | lst.append(i.rstrip().split()) 25 | return lst 26 | 27 | 28 | class SSH(paramiko.SSHClient): 29 | 30 | def call(self, command, bufsize=-1): 31 | new_exec = self._transport.open_session() 32 | new_exec.exec_command(command) 33 | 34 | stdin = new_exec.makefile('wb', bufsize) 35 | stdout = new_exec.makefile('rb', bufsize) 36 | stderr = new_exec.makefile('rb', bufsize) 37 | status = new_exec.recv_exit_status() 38 | 39 | return stdin, stdout, stderr, status 40 | 41 | 42 | def connect(ip): 43 | """ connect server via ssh protocol """ 44 | session = SSH() 45 | session.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 46 | rsa_key = paramiko.RSAKey.from_private_key_file(SSH_KEY) 47 | 48 | try: 49 | session.connect(ip, 22, username=SSH_USERNAME, pkey=rsa_key, timeout=15) 50 | except socket.timeout: 51 | print '%s connect timeout' % ip 52 | return None 53 | 54 | return session 55 | 56 | 57 | def general_task(name): 58 | tasks = [ 59 | [1, 'sudo mv /etc/zabbix/zabbix_agentd.conf /tmp/'], 60 | [1, 'sudo service zabbix-agent stop'], 61 | [2, 'sudo apt-get purge zabbix_agent -y'], 62 | [2, 'sudo killall zabbix_agentd'], 63 | [3, 'sudo mv /usr/local/zabbix /tmp/zabbix_%s' % time.time()], 64 | [3, 'sudo userdel zabbix'], 65 | [3, 'rm zabbix_agents_2.4.4.linux2_6.amd64.tar.gz'], 66 | [4, 'sudo wget http://www.zabbix.com/downloads/2.4.4/zabbix_agents_2.4.4.linux2_6.amd64.tar.gz'], 67 | [3, 'sudo mkdir /usr/local/zabbix'], 68 | [5, 'sudo tar -zxvf zabbix_agents_2.4.4.linux2_6.amd64.tar.gz -C /usr/local/zabbix'], 69 | [6, 'sudo chown -R root:root /usr/local/zabbix'], 70 | [7, "sudo sed -i -e 's/ServerActive=127.0.0.1/ServerActive=%s/g' /usr/local/zabbix/conf/zabbix_agentd.conf" 71 | % ZABBIX_SERVER], 72 | [8, "sudo sed -i -e 's/Server=127.0.0.1/Server=%s/g' /usr/local/zabbix/conf/zabbix_agentd.conf" 73 | % ZABBIX_SERVER], 74 | [9, "sudo sed -i -e 's/Hostname=Zabbix\ server/Hostname=%s/g' /usr/local/zabbix/conf/zabbix_agentd.conf" 75 | % name], 76 | [3, 'sudo useradd zabbix'], 77 | [12, 'sudo /usr/local/zabbix/sbin/zabbix_agentd -c /usr/local/zabbix/conf/zabbix_agentd.conf'] 78 | ] 79 | 80 | return tasks 81 | 82 | 83 | def task(host): 84 | tasks = general_task(host[0]) 85 | session = connect(host[1]) 86 | if session: 87 | for command in tasks: 88 | stdin, stdout, stderr, status = session.call(command[1]) 89 | if status != 0 and command[0] < 4: 90 | print 'Host: %s, Failed Command: %s' % (host, command[1]) 91 | elif status != 0 and command[0] >= 4: 92 | print 'Host: %s, Failed Command: %s' % (host, command[1]) 93 | session.close() 94 | else: 95 | print '%s execute %s success' % (host, command[1]) 96 | print host[0], host[1], '|' 97 | 98 | 99 | class ThreadTask(threading.Thread): 100 | def __init__(self, queue): 101 | threading.Thread.__init__(self) 102 | self.queue = queue 103 | 104 | def run(self): 105 | while True: 106 | host = self.queue.get() 107 | try: 108 | print 'Task of %s Start.' % host 109 | task(host) 110 | except Exception, e: 111 | print 'Task of %s Failed: %s' % (host, e) 112 | self.queue.task_done() 113 | 114 | 115 | def install(): 116 | for i in range(THREAD_NUM): 117 | t = ThreadTask(QUEUE) 118 | t.setDaemon(True) 119 | t.start() 120 | 121 | for host in HOSTS: 122 | QUEUE.put(host) 123 | QUEUE.join() 124 | 125 | if __name__ == '__main__': 126 | install() 127 | -------------------------------------------------------------------------------- /scripts/send_mail.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | import sys 4 | import smtplib 5 | import requests 6 | from email.mime.text import MIMEText 7 | 8 | MAIL_HOST = "smtp.163.com" 9 | MAIL_USER = "wuxianglong098@163.com" 10 | MAIL_PWD = "password" 11 | 12 | 13 | def send_mail(to_list, subject, body): 14 | msg = MIMEText(body) 15 | msg['Subject'] = subject 16 | msg['From'] = MAIL_USER 17 | msg['To'] = to_list 18 | try: 19 | s = smtplib.SMTP() 20 | s.connect(MAIL_HOST) 21 | s.login(MAIL_USER, MAIL_PWD) 22 | s.sendmail(MAIL_USER, to_list, msg.as_string()) 23 | s.close() 24 | return True 25 | except Exception, e: 26 | print str(e) 27 | return False 28 | 29 | 30 | def send_email_by_mailgun(mail_to, subject, body): 31 | r = requests.post('https://api.mailgun.net/v2/colorba.us/messages', auth=('api', ''), 32 | data={'from': '', 'to': ['%s' % mail_to], 'subject': '%s' % subject, 'text': '%s' % body}) 33 | print r.text 34 | 35 | 36 | if __name__ == '__main__': 37 | send_mail(*sys.argv[1: 4]) 38 | 39 | -------------------------------------------------------------------------------- /scripts/zabbix-nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | server_name 127.0.0.1; 3 | root /usr/share/zabbix/; 4 | index index.php index.html; 5 | client_max_body_size 5m; 6 | client_body_buffer_size 128k; 7 | 8 | access_log /var/log/nginx/zabbix-access.log; 9 | 10 | location ~ \.php$ { 11 | fastcgi_pass unix:/var/run/zabbix.socket; 12 | include fastcgi_params; 13 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 14 | fastcgi_param SCRIPT_NAME $fastcgi_script_name; 15 | } 16 | 17 | location ~* \.(jpg|jpeg|png|gif|css|js|ico)$ { 18 | expires max; 19 | log_not_found off; 20 | } 21 | 22 | location ~ /\.ht { 23 | deny all; 24 | } 25 | 26 | location ~ /\. { 27 | deny all; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /scripts/zabbix_conf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | import json 4 | import time 5 | import requests 6 | 7 | HOSTS = [ 8 | ['host-name', 'public-ip', 'private-ip'], 9 | ] 10 | 11 | DOMAIN = "http://127.0.0.1/api_jsonrpc.php" 12 | JSON_HEADERS = {"content-type": "application/json"} 13 | GROUP_ID = 2 14 | TEMPLATE_ID = 10001 15 | 16 | 17 | def get_list(filename): 18 | lst = [] 19 | with open(filename, 'r') as f: 20 | for i in f.readlines(): 21 | lst.append(i.rstrip()) 22 | return lst 23 | 24 | 25 | def get_token(): 26 | login_data = json.dumps({ 27 | "jsonrpc": "2.0", 28 | "method": "user.login", 29 | "params": { 30 | "user": "Admin", 31 | "password": "password", 32 | }, 33 | "id": 1 34 | }) 35 | request = requests.post(DOMAIN, data=login_data, headers=JSON_HEADERS, timeout=30) 36 | 37 | print request.text 38 | 39 | return request.json()['result'] 40 | 41 | 42 | def add_host(host): 43 | data = json.dumps({ 44 | "jsonrpc": "2.0", 45 | "method": "host.create", 46 | "params": { 47 | "host": "%s" % host[0], 48 | "interfaces": [ 49 | { 50 | "type": 1, 51 | "main": 1, 52 | "useip": 1, 53 | "ip": host[2], 54 | "dns": "", 55 | "port": "10050" 56 | } 57 | ], 58 | "groups": [{ 59 | "groupid": GROUP_ID, 60 | }], 61 | "templates": [{ 62 | "templateid": TEMPLATE_ID, 63 | }], 64 | }, 65 | "auth": get_token(), 66 | "id": 1, 67 | }) 68 | request = requests.post(DOMAIN, data=data, headers=JSON_HEADERS) 69 | print data 70 | print request.json() 71 | 72 | 73 | if __name__ == "__main__": 74 | for ht in HOSTS: 75 | print ht 76 | add_host(ht) 77 | -------------------------------------------------------------------------------- /tcp-port/README.md: -------------------------------------------------------------------------------- 1 | Template for Discovery Port 2 | =========================== 3 | 4 | Check TCP port status in Zabbix using discovery. 5 | 6 | INSTALL 7 | ------- 8 | 9 | ### Add User Parameters 10 | 11 | Copy get_port.py to /usr/local/zabbix/bin/ and run "sudo chmod 777 get_port.py" 12 | Copy tcp-port.conf to /usr/local/zabbix/conf/zabbix_agentd/. Restart Zabbix agent. 13 | Add line "Include=/usr/local/zabbix/conf/zabbix_agentd/*.conf" in /usr/local/zabbix/conf/zabbix_agentd.conf 14 | 15 | ### Add discovery 16 | 17 | See: http://www.linuxyan.com/cacti-nagios/396.html 18 | 19 | -------------------------------------------------------------------------------- /tcp-port/get_port.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | #-*- coding: utf-8 -*- 3 | import os 4 | import json 5 | 6 | ports = [line.split()[3].split(':')[1] for line in os.popen('netstat -tpln | grep LISTEN | grep -v tcp6').readlines()] 7 | data = { 8 | 'data': [{'{#TCP_PORT}': p} for p in set(ports)], 9 | } 10 | print json.dumps(data, sort_keys=True, indent=4) 11 | 12 | -------------------------------------------------------------------------------- /tcp-port/tcp-port.conf: -------------------------------------------------------------------------------- 1 | UserParameter=tcpportlisten,sudo /usr/local/zabbix/bin/get_port.py 2 | --------------------------------------------------------------------------------