diff --git a/doc/Extensions/Applications.md b/doc/Extensions/Applications.md index 47d980f234..747d43cab8 100644 --- a/doc/Extensions/Applications.md +++ b/doc/Extensions/Applications.md @@ -4,23 +4,42 @@ You can use Application support to graph performance statistics from many applic Different applications support a variety of ways collect data: by direct connection to the application, snmpd extend, or the agent. +1. [Apache](#apache) - SNMP extend 1. [BIND9/named](#bind9-aka-named) - Agent -2. [MySQL](#mysql) - Agent -3. [NGINX](#nginx) - Agent -4. [NTPD](#ntpd-server) - extend SNMP, Agent -5. [PowerDNS](#powerdns) - Agent -6. [PowerDNS Recursor](#powerdns-recursor) - Agent -7. [TinyDNS/djbdns](#tinydns-aka-djbdns) - Agent -8. [OS Updates](#os-updates) - extend SNMP -9. [DHCP Stats](#dhcp-stats) - extend SNMP -10. [Memcached](#memcached) - extend SNMP -11. [Unbound](#unbound) - Agent -12. [Proxmox](#proxmos) - extend SNMP -13. [Raspberry PI](#raspberry-pi) - extend SNMP -14. [Agent Setup](#agent-setup) +1. [DHCP Stats](#dhcp-stats) - SNMP extend +1. [Mailscanner](#mailscanner) - SNMP extend +1. [Memcached](#memcached) - SNMP extend +1. [MySQL](#mysql) - Agent +1. [NGINX](#nginx) - Agent +1. [NTPD](#ntpd-server) - SNMP extend, Agent +1. [OS Updates](#os-updates) - SNMP extend +1. [PowerDNS](#powerdns) - Agent +1. [PowerDNS Recursor](#powerdns-recursor) - Direct, Agent +1. [Proxmox](#proxmos) - SNMP extend +1. [Raspberry PI](#raspberry-pi) - SNMP extend +1. [TinyDNS/djbdns](#tinydns-aka-djbdns) - Agent +1. [Unbound](#unbound) - Agent +1. [Agent Setup](#agent-setup) + + + +### Apache +##### SNMP Extend +1. Download the script onto the desired host (the host must be added to LibreNMS devices) +``` +wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/apache-stats.py -o /etc/snmp/apache-stats.py +``` +2. Make the script executable (chmod +x /etc/snmp/apache-stats.py) +3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add: +``` +extend apache /etc/snmp/apache-stats.py +``` +4. Restart snmpd on your host +5. On the device page in Librenms, edit your host and check the `Apache` under the Applications tab. + + ### BIND9 aka named - ##### Agent [Install the agent](#agent-setup) on this device if it isn't already and copy the `bind` script to `/usr/lib/check_mk_agent/local/` @@ -48,8 +67,52 @@ In case you get a `Permission Denied` error, make sure you chown'ed correctly. Note: if you change the path you will need to change the path in `scripts/agent-local/bind`. -### MySQL +### DHCP Stats +A small shell script that reports current DHCP leases stats. + +##### SNMP Extend +1. Copy the shell script to the desired host (the host must be added to LibreNMS devices) +2. Make the script executable (chmod +x /opt/dhcp-status.sh) +3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add: +``` +extend dhcpstats /opt/dhcp-status.sh +``` +4. Restart snmpd on your host +5. On the device page in Librenms, edit your host and check the `DHCP Stats` under the Applications tab. + + + +### Mailscanner +##### SNMP Extend +1. Download the script onto the desired host (the host must be added to LibreNMS devices) +``` +wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/mailscanner.php -o /etc/snmp/mailscanner.php +``` +2. Make the script executable (chmod +x /etc/snmp/mailscanner.php) +3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add: +``` +extend mailscanner /etc/snmp/mailscanner.php +``` +4. Restart snmpd on your host +5. On the device page in Librenms, edit your host and check the `Mailscanner` under the Applications tab. + + + +### Memcached +##### SNMP Extend +1. Copy the [memcached script](https://github.com/librenms/librenms-agent/blob/master/agent-local/memcached) to `/usr/local/bin` (or any other suitable location) on your remote server. +2. Make the script executable: `chmod +x /usr/local/memcached` +3. Edit your snmpd.conf file (usually `/etc/snmp/snmpd.conf`) and add: +``` +extend memcached /usr/local/bin/memcached +``` +4. Restart snmpd on your host +5. On the device page in Librenms, edit your host and check `Memcached` under the Applications tab. + + + +### MySQL ##### Agent [Install the agent](#agent-setup) on this device if it isn't already and copy the `mysql` script to `/usr/lib/check_mk_agent/local/` @@ -67,8 +130,9 @@ $mysql_port = 3306; Verify it is working by running `/usr/lib/check_mk_agent/local/mysql` -### NGINX + +### NGINX NGINX is a free, open-source, high-performance HTTP server: https://www.nginx.org/ ##### Agent @@ -85,10 +149,12 @@ location /nginx-status { } ``` + + ### NTPD Server Supports NTPD Server (not client, that is separate) -##### Extend SNMP +##### SNMP Extend 1. Download the script onto the desired host (the host must be added to LibreNMS devices) ``` wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/ntpd-server.php -o /etc/snmp/ntpd-server.php @@ -104,6 +170,28 @@ extend ntpdserver /etc/snmp/ntpd-server.php ##### Agent Support is built into the agent, and this app will be automatically enabled. + + +### OS Updates +A small shell script that checks your system package manager for any available updates. Supports apt-get/pacman/yum/zypper package managers). + +For pacman users automatically refreshing the database, it is recommended you use an alternative database location `--dbpath=/var/lib/pacman/checkupdate` + +##### SNMP Extend +1. Copy the shell script to the desired host (the host must be added to LibreNMS devices) +2. Make the script executable (chmod +x /opt/os-updates.sh) +3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add: +``` +extend osupdate /opt/os-updates.sh +``` +4. Restart snmpd on your host +5. On the device page in Librenms, edit your host and check the `OS Updates` under the Applications tab. + +_Note_: apt-get depends on an updated package index. There are several ways to have your system run `apt-get update` automatically. The easiest is to create `/etc/apt/apt.conf.d/10periodic` and pasting the following in it: `APT::Periodic::Update-Package-Lists "1";`. +If you have apticron, cron-apt or apt-listchanges installed and configured, chances are that packages are already updated periodically. + + + ### PowerDNS An authoritative DNS server: https://www.powerdns.com/auth.html @@ -111,6 +199,7 @@ An authoritative DNS server: https://www.powerdns.com/auth.html [Install the agent](#agent-setup) on this device if it isn't already and copy the `powerdns` script to `/usr/lib/check_mk_agent/local/` + ### PowerDNS Recursor A recursive DNS server: https://www.powerdns.com/recursor.html @@ -129,6 +218,37 @@ The web-server must be enabled, see the Recursor docs: https://doc.powerdns.com/ This script uses `rec_control get-all` to collect stats. + +### Proxmox +1. Download the script onto the desired host (the host must be added to LibreNMS devices) +`wget https://github.com/librenms/librenms-agent/blob/master/agent-local/proxmox -o /usr/local/bin/proxmox` +2. Make the script executable: `chmod +x /usr/local/proxmox` +3. Edit your snmpd.conf file (usually `/etc/snmp/snmpd.conf`) and add: +`extend proxmox /usr/local/bin/proxmox` +(Note: if your snmpd doesn't run as root, you might have to invoke the script using sudo. `extend proxmox /usr/bin/sudo /usr/local/bin/proxmox`) +4. Restart snmpd on your host +5. On the device page in Librenms, edit your host and check `Proxmox` on the Applications tab. + + + +### Raspberry PI +SNMP extend script to get your PI data into your host. + +##### SNMP Extend +1. Copy the [raspberry script](https://github.com/librenms/librenms-agent/blob/master/snmp/raspberry.sh) to `/opt/` (or any other suitable location) on your PI host. +2. Make the script executable: `chmod +x /opt/raspberry.sh` +3. Edit your snmpd.conf file (usually `/etc/snmp/snmpd.conf`) and add: +``` +extend raspberry /opt/raspberry.sh +``` +4. Edit your sudo users (usually `visudo`) and add at the bottom: +``` +snmp ALL=(ALL) NOPASSWD: /opt/raspberry.sh, /usr/bin/vcgencmd* +``` +5. Restart snmpd on PI host + + + ### TinyDNS aka djbdns ##### Agent @@ -150,46 +270,7 @@ chown dnslog:nofiles /service/dns/log/main/tinystats 3. Restart TinyDNS and Daemontools: `/etc/init.d/svscan restart` _Note_: Some say `svc -t /service/dns` is enough, on my install (Gentoo) it doesn't rehook the logging and I'm forced to restart it entirely. -### OS Updates -A small shell script that checks your system package manager for any available updates. Supports apt-get/pacman/yum/zypper package managers). -For pacman users automatically refreshing the database, it is recommended you use an alternative database location `--dbpath=/var/lib/pacman/checkupdate` - -##### Extend SNMP -1. Copy the shell script to the desired host (the host must be added to LibreNMS devices) -2. Make the script executable (chmod +x /opt/os-updates.sh) -3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add: -``` -extend osupdate /opt/os-updates.sh -``` -4. Restart snmpd on your host -5. On the device page in Librenms, edit your host and check the `OS Updates` under the Applications tab. - -_Note_: apt-get depends on an updated package index. There are several ways to have your system run `apt-get update` automatically. The easiest is to create `/etc/apt/apt.conf.d/10periodic` and pasting the following in it: `APT::Periodic::Update-Package-Lists "1";`. -If you have apticron, cron-apt or apt-listchanges installed and configured, chances are that packages are already updated periodically. - -### DHCP Stats -A small shell script that reports current DHCP leases stats. - -##### Extend SNMP -1. Copy the shell script to the desired host (the host must be added to LibreNMS devices) -2. Make the script executable (chmod +x /opt/dhcp-status.sh) -3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add: -``` -extend dhcpstats /opt/dhcp-status.sh -``` -4. Restart snmpd on your host -5. On the device page in Librenms, edit your host and check the `DHCP Stats` under the Applications tab. - -### Memcached -1. Copy the [memcached script](https://github.com/librenms/librenms-agent/blob/master/agent-local/memcached) to `/usr/local/bin` (or any other suitable location) on your remote server. -2. Make the script executable: `chmod +x /usr/local/memcached` -3. Edit your snmpd.conf file (usually `/etc/snmp/snmpd.conf`) and add: -``` -extend memcached /usr/local/bin/memcached -``` -4. Restart snmpd on your host -5. On the device page in Librenms, edit your host and check `Memcached` under the Applications tab. ### Unbound @@ -208,32 +289,6 @@ server: Restart your unbound after changing the configuration,v erify it is working by running /usr/lib/check_mk_agent/local/unbound.sh -### Proxmox -1. Download the script onto the desired host (the host must be added to LibreNMS devices) -`wget https://github.com/librenms/librenms-agent/blob/master/agent-local/proxmox -o /usr/local/bin/proxmox` -2. Make the script executable: `chmod +x /usr/local/proxmox` -3. Edit your snmpd.conf file (usually `/etc/snmp/snmpd.conf`) and add: -`extend proxmox /usr/local/bin/proxmox` -(Note: if your snmpd doesn't run as root, you might have to invoke the script using sudo. `extend proxmox /usr/bin/sudo /usr/local/bin/proxmox`) -4. Restart snmpd on your host -5. On the device page in Librenms, edit your host and check `Proxmox` on the Applications tab. - -======= -### Raspberry PI -SNMP extend script to get your PI data into your host. - -##### Extend SNMP -1. Copy the [raspberry script](https://github.com/librenms/librenms-agent/blob/master/snmp/raspberry.sh) to `/opt/` (or any other suitable location) on your PI host. -2. Make the script executable: `chmod +x /opt/raspberry.sh` -3. Edit your snmpd.conf file (usually `/etc/snmp/snmpd.conf`) and add: -``` -extend raspberry /opt/raspberry.sh -``` -4. Edit your sudo users (usually `visudo`) and add at the bottom: -``` -snmp ALL=(ALL) NOPASSWD: /opt/raspberry.sh, /usr/bin/vcgencmd* -``` -5. Restart snmpd on PI host Agent Setup diff --git a/doc/Installation/Migrating-from-Observium.md b/doc/Installation/Migrating-from-Observium.md index 65cc793f3b..a86f4e1955 100644 --- a/doc/Installation/Migrating-from-Observium.md +++ b/doc/Installation/Migrating-from-Observium.md @@ -4,4 +4,4 @@ A LibreNMS user, [Dan](https://twitter.com/thedanbrown), has kindly provided ful See [his](https://vlan50.com/2015/04/17/migrating-from-observium-to-librenms/) blog for full details. -We have mirrored the scripts he's provided with consent, these are available in the `scripts` folder of your installation called LibreNMS.zip. +We have mirrored the scripts he's provided with consent, these are available in the `scripts\Migration` folder of your installation.. diff --git a/scripts/LibreNMS.zip b/scripts/LibreNMS.zip deleted file mode 100644 index f317bf2617..0000000000 Binary files a/scripts/LibreNMS.zip and /dev/null differ diff --git a/scripts/apache-stats b/scripts/apache-stats deleted file mode 100755 index 863514aea0..0000000000 --- a/scripts/apache-stats +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/env perl -# Original python script Copyright (C) 2009 Glen Pitt-Pladdy -# -# 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 LWP::Simple; - -$CACHETIME = 30; -$CACHEFILE = '/tmp/snmp-cache-apache'; - -# check for cache file newer CACHETIME seconds ago -if ( -f $CACHEFILE && time - (stat( $CACHEFILE ))[9] < $CACHETIME) { - # use cached data -#print "Using cached data from file $CACHEFILE.\n"; - open (INFILE, "<$CACHEFILE" ) - or die "File open failure: $CACHEFILE\n"; - @data = ; - close INFILE; -} else { - # grab the status URL (fresh data) - @data = split /(\n)/, LWP::Simple::get( 'http://localhost/server-status?auto' ) - or die "Data fetch failure.\n"; - - # write file - $tmpfile = "$CACHEFILE.TMP.$PID"; - open (OUTFILE, ">$tmpfile") - or die "File open failure: $tmpfile\n"; - print OUTFILE @data; - close OUTFILE; - rename ( $tmpfile, $CACHEFILE ); -} - -# dice up the data -@scoreboardkey = ( '_', 'S', 'R', 'W', 'K', 'D', 'C', 'L', 'G', 'I', '.' ); -%params = {}; -foreach $line (@data) { - chomp $line; - @fields = split( /: /, $line); - if ($fields[0] eq 'Scoreboard') { - # count up the scoreboard into states - %states = {}; - foreach $state (@scoreboardkey) { - $states{$state} = 0; - } - foreach $state ( split(//, $fields[1]) ) { - $states{$state}++; - } - } elsif ($fields[0] eq 'Total kBytes') { - # turn into base (byte) value - $params{$fields[0]} = int($fields[1])*1024; - } else { - # just store everything else - $params{$fields[0]} = $fields[1]; - } -} - -# output the data in order (this is because some platforms don't have them all) -@dataorder = ( - 'Total Accesses', - 'Total kBytes', - 'CPULoad', - 'Uptime', - 'ReqPerSec', - 'BytesPerSec', - 'BytesPerReq', - 'BusyServers', - 'IdleServers' -); -foreach $param (@dataorder) { - if (exists $params{$param}) { - print $params{$param}."\n"; - } else { - # not all Apache's have all stats - print "U\n"; - } -} - -# print the scoreboard -foreach $state (@scoreboardkey) { - print $states{$state}."\n"; -} diff --git a/scripts/apache-stats.py b/scripts/apache-stats.py deleted file mode 100755 index 891bd196ed..0000000000 --- a/scripts/apache-stats.py +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/python -# Copyright (C) 2009 Glen Pitt-Pladdy -# -# 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. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# -# - -CACHETIME = 30 -CACHEFILE = '/tmp/apache-snmp' - -# check for cache file newer CACHETIME seconds ago -import os -import time -if os.path.isfile ( CACHEFILE ) \ - and ( time.time() - os.stat ( CACHEFILE )[8] ) < CACHETIME: - # use cached data - f = open ( CACHEFILE, 'r' ) - data = f.read() - f.close() -else: - # grab the status URL (fresh data) - # need debian package python-urlgrabber - from urlgrabber import urlread - data = urlread ( 'http://localhost/server-status?auto', - user_agent = 'SNMP Apache Stats' ) - # write file - f = open ( CACHEFILE+'.TMP.'+`os.getpid()`, 'w' ) - f.write ( data ) - f.close() - os.rename ( CACHEFILE+'.TMP.'+`os.getpid()`, CACHEFILE ) - - -# dice up the data -scoreboardkey = [ '_', 'S', 'R', 'W', 'K', 'D', 'C', 'L', 'G', 'I', '.' ] -params = {} -for line in data.splitlines(): - fields = line.split( ': ' ) - if fields[0] == 'Scoreboard': - # count up the scoreboard into states - states = {} - for state in scoreboardkey: - states[state] = 0 - for state in fields[1]: - states[state] += 1 - elif fields[0] == 'Total kBytes': - # turn into base (byte) value - params[fields[0]] = int(fields[1])*1024 - else: - # just store everything else - params[fields[0]] = fields[1] - -# output the data in order (this is because some platforms don't have them all) -dataorder = [ - 'Total Accesses', - 'Total kBytes', - 'CPULoad', - 'Uptime', - 'ReqPerSec', - 'BytesPerSec', - 'BytesPerReq', - 'BusyWorkers', - 'IdleWorkers' -] -for param in dataorder: - try: - print params[param] -# print param - except: # not all Apache's have all stats - print 'U' - -# print the scoreboard -for state in scoreboardkey: - print states[state] -# print state diff --git a/scripts/check_mk_COPYING b/scripts/check_mk_COPYING deleted file mode 100644 index 1942c4334c..0000000000 --- a/scripts/check_mk_COPYING +++ /dev/null @@ -1,341 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) 19yy - - 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. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/scripts/check_mk_agent b/scripts/check_mk_agent deleted file mode 100755 index 6b6e03a422..0000000000 --- a/scripts/check_mk_agent +++ /dev/null @@ -1,659 +0,0 @@ -#!/bin/bash -# +------------------------------------------------------------------+ -# | ____ _ _ __ __ _ __ | -# | / ___| |__ ___ ___| | __ | \/ | |/ / | -# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | -# | | |___| | | | __/ (__| < | | | | . \ | -# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | -# | | -# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | -# +------------------------------------------------------------------+ -# -# This file is part of Check_MK. -# The official homepage is at http://mathias-kettner.de/check_mk. -# -# check_mk 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 in version 2. check_mk is distributed -# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- -# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. See the GNU General Public License for more de- -# ails. You should have received a copy of the GNU General Public -# License along with GNU Make; see the file COPYING. If not, write -# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, -# Boston, MA 02110-1301 USA. - -# Remove locale settings to eliminate localized outputs where possible -export LC_ALL=C -unset LANG - -export MK_LIBDIR="/usr/lib/check_mk_agent" -export MK_CONFDIR="/etc/check_mk" -export MK_VARDIR="/var/lib/check_mk_agent" - -# Provide information about the remote host. That helps when data -# is being sent only once to each remote host. -if [ "$REMOTE_HOST" ] ; then - export REMOTE=$REMOTE_HOST -elif [ "$SSH_CLIENT" ] ; then - export REMOTE=${SSH_CLIENT%% *} -fi - -# Make sure, locally installed binaries are found -PATH=$PATH:/usr/local/bin - -# All executables in PLUGINSDIR will simply be executed and their -# ouput appended to the output of the agent. Plugins define their own -# sections and must output headers with '<<<' and '>>>' -PLUGINSDIR=$MK_LIBDIR/plugins - -# All executables in LOCALDIR will by executabled and their -# output inserted into the section <<>>. Please -# refer to online documentation for details about local checks. -LOCALDIR=$MK_LIBDIR/local - -# All files in SPOOLDIR will simply appended to the agent -# output if they are not outdated (see below) -SPOOLDIR=$MK_VARDIR/spool - -# close standard input (for security reasons) and stderr -if [ "$1" = -d ] -then - set -xv -else - exec /dev/null -fi - -# Runs a command asynchronous by use of a cache file -function run_cached () { - local section= - if [ "$1" = -s ] ; then local section="echo '<<<$2>>>' ; " ; shift ; fi - local NAME=$1 - local MAXAGE=$2 - shift 2 - local CMDLINE="$section$@" - - if [ ! -d $MK_VARDIR/cache ]; then mkdir -p $MK_VARDIR/cache ; fi - CACHEFILE="$MK_VARDIR/cache/$NAME.cache" - - # Check if the creation of the cache takes suspiciously long and return - # nothing if the age (access time) of $CACHEFILE.new is twice the MAXAGE - local NOW=$(date +%s) - if [ -e "$CACHEFILE.new" ] ; then - local CF_ATIME=$(stat -c %X "$CACHEFILE.new") - if [ $((NOW - CF_ATIME)) -ge $((MAXAGE * 2)) ] ; then - # Kill the process still accessing that file in case - # it is still running. This avoids overlapping processes! - fuser -k -9 "$CACHEFILE.new" >/dev/null 2>&1 - rm -f "$CACHEFILE.new" - return - fi - fi - - # Check if cache file exists and is recent enough - if [ -s "$CACHEFILE" ] ; then - local MTIME=$(stat -c %Y "$CACHEFILE") - if [ $((NOW - MTIME)) -le $MAXAGE ] ; then local USE_CACHEFILE=1 ; fi - # Output the file in any case, even if it is - # outdated. The new file will not yet be available - cat "$CACHEFILE" - fi - - # Cache file outdated and new job not yet running? Start it - if [ -z "$USE_CACHEFILE" -a ! -e "$CACHEFILE.new" ] ; then - echo "set -o noclobber ; exec > \"$CACHEFILE.new\" || exit 1 ; $CMDLINE && mv \"$CACHEFILE.new\" \"$CACHEFILE\" || rm -f \"$CACHEFILE\" \"$CACHEFILE.new\"" | nohup bash >/dev/null 2>&1 & - fi -} - -# Make run_cached available for subshells (plugins, local checks, etc.) -export -f run_cached - -echo '<<>>' -echo Version: 1.2.6b5 -echo AgentOS: linux -echo AgentDirectory: $MK_CONFDIR -echo DataDirectory: $MK_VARDIR -echo SpoolDirectory: $SPOOLDIR -echo PluginsDirectory: $PLUGINSDIR -echo LocalDirectory: $LOCALDIR - -# If we are called via xinetd, try to find only_from configuration -if [ -n "$REMOTE_HOST" ] -then - echo -n 'OnlyFrom: ' - echo $(sed -n '/^service[[:space:]]*check_mk/,/}/s/^[[:space:]]*only_from[[:space:]]*=[[:space:]]*\(.*\)/\1/p' /etc/xinetd.d/* | head -n1) -fi - -# Print out Partitions / Filesystems. (-P gives non-wrapped POSIXed output) -# Heads up: NFS-mounts are generally supressed to avoid agent hangs. -# If hard NFS mounts are configured or you have too large nfs retry/timeout -# settings, accessing those mounts from the agent would leave you with -# thousands of agent processes and, ultimately, a dead monitored system. -# These should generally be monitored on the NFS server, not on the clients. - -echo '<<>>' -# The exclusion list is getting a bit of a problem. -l should hide any remote FS but seems -# to be all but working. -excludefs="-x smbfs -x cifs -x iso9660 -x udf -x nfsv4 -x nfs -x mvfs -x zfs" -df -PTlk $excludefs | sed 1d - -# df inodes information -echo '<<>>' -echo '[df_inodes_start]' -df -PTli $excludefs | sed 1d -echo '[df_inodes_end]' - -# Filesystem usage for ZFS -if type zfs > /dev/null 2>&1 ; then - echo '<<>>' - zfs get -Hp name,quota,used,avail,mountpoint,type -t filesystem,volume || \ - zfs get -Hp name,quota,used,avail,mountpoint,type - echo '[df]' - df -PTlk -t zfs | sed 1d -fi - -# Check NFS mounts by accessing them with stat -f (System -# call statfs()). If this lasts more then 2 seconds we -# consider it as hanging. We need waitmax. -if type waitmax >/dev/null -then - STAT_VERSION=$(stat --version | head -1 | cut -d" " -f4) - STAT_BROKE="5.3.0" - - echo '<<>>' - sed -n '/ nfs4\? /s/[^ ]* \([^ ]*\) .*/\1/p' < /proc/mounts | - sed 's/\\040/ /g' | - while read MP - do - if [ $STAT_VERSION != $STAT_BROKE ]; then - waitmax -s 9 2 stat -f -c "$MP ok %b %f %a %s" "$MP" || \ - echo "$MP hanging 0 0 0 0" - else - waitmax -s 9 2 stat -f -c "$MP ok %b %f %a %s" "$MP" && \ - printf '\n'|| echo "$MP hanging 0 0 0 0" - fi - done - - echo '<<>>' - sed -n '/ cifs\? /s/[^ ]* \([^ ]*\) .*/\1/p' < /proc/mounts | - sed 's/\\040/ /g' | - while read MP - do - if [ $STAT_VERSION != $STAT_BROKE ]; then - waitmax -s 9 2 stat -f -c "$MP ok %b %f %a %s" "$MP" || \ - echo "$MP hanging 0 0 0 0" - else - waitmax -s 9 2 stat -f -c "$MP ok %b %f %a %s" "$MP" && \ - printf '\n'|| echo "$MP hanging 0 0 0 0" - fi - done -fi - -# Check mount options. Filesystems may switch to 'ro' in case -# of a read error. -echo '<<>>' -grep ^/dev < /proc/mounts - -# processes including username, without kernel processes -echo '<<>>' -ps ax -o user,vsz,rss,cputime,pid,command --columns 10000 | sed -e 1d -e 's/ *\([^ ]*\) *\([^ ]*\) *\([^ ]*\) *\([^ ]*\) *\([^ ]*\) */(\1,\2,\3,\4,\5) /' - -# Memory usage -echo '<<>>' -egrep -v '^Swap:|^Mem:|total:' < /proc/meminfo - -# Load and number of processes -echo '<<>>' -echo "$(cat /proc/loadavg) $(grep -E '^CPU|^processor' < /proc/cpuinfo | wc -l)" - -# Uptime -echo '<<>>' -cat /proc/uptime - - -# New variant: Information about speed and state in one section -echo '<<>>' -sed 1,2d /proc/net/dev -if type ethtool > /dev/null -then - for eth in $(sed -e 1,2d < /proc/net/dev | cut -d':' -f1 | sort) - do - echo "[$eth]" - ethtool $eth | egrep '(Speed|Duplex|Link detected|Auto-negotiation):' - echo -en "\tAddress: " ; cat /sys/class/net/$eth/address ; echo - done -fi - - -# Current state of bonding interfaces -if [ -e /proc/net/bonding ] ; then - echo '<<>>' - pushd /proc/net/bonding > /dev/null ; head -v -n 1000 * ; popd -fi - -# Same for Open vSwitch bonding -if type ovs-appctl > /dev/null ; then - echo '<<>>' - for bond in $(ovs-appctl bond/list | sed -e 1d | cut -f2) ; do - echo "[$bond]" - ovs-appctl bond/show $bond - done -fi - - -# Number of TCP connections in the various states -echo '<<>>' -# waitmax 10 netstat -nt | awk ' /^tcp/ { c[$6]++; } END { for (x in c) { print x, c[x]; } }' -# New implementation: netstat is very slow for large TCP tables -cat /proc/net/tcp /proc/net/tcp6 2>/dev/null | awk ' /:/ { c[$4]++; } END { for (x in c) { print x, c[x]; } }' - -# Linux Multipathing -if type multipath >/dev/null ; then - echo '<<>>' - multipath -l -fi - -# Performancecounter Platten -echo '<<>>' -date +%s -egrep ' (x?[shv]d[a-z]*|cciss/c[0-9]+d[0-9]+|emcpower[a-z]+|dm-[0-9]+|VxVM.*|mmcblk.*) ' < /proc/diskstats -if type dmsetup >/dev/null ; then - echo '[dmsetup_info]' - dmsetup info -c --noheadings --separator ' ' -o name,devno,vg_name,lv_name -fi -if [ -d /dev/vx/dsk ] ; then - echo '[vx_dsk]' - stat -c "%t %T %n" /dev/vx/dsk/*/* -fi - - -# Performancecounter Kernel -echo '<<>>' -date +%s -cat /proc/vmstat /proc/stat - -# Hardware sensors via IPMI (need ipmitool) -if type ipmitool > /dev/null -then - run_cached -s ipmi 300 "ipmitool sensor list | grep -v 'command failed' | sed -e 's/ *| */|/g' -e 's/ /_/g' -e 's/_*"'$'"//' -e 's/|/ /g' | egrep -v '^[^ ]+ na ' | grep -v ' discrete '" -fi - - -# IPMI data via ipmi-sensors (of freeipmi). Please make sure, that if you -# have installed freeipmi that IPMI is really support by your hardware. -if type ipmi-sensors >/dev/null -then - echo '<<>>' - # Newer ipmi-sensors version have new output format; Legacy format can be used - if ipmi-sensors --help | grep -q legacy-output; then - IPMI_FORMAT="--legacy-output" - else - IPMI_FORMAT="" - fi - # At least with ipmi-sensoirs 0.7.16 this group is Power_Unit instead of "Power Unit" - run_cached -s ipmi_sensors 300 "for class in Temperature Power_Unit Fan - do - ipmi-sensors $IPMI_FORMAT --sdr-cache-directory /var/cache -g "$class" | sed -e 's/ /_/g' -e 's/:_\?/ /g' -e 's@ \([^(]*\)_(\([^)]*\))@ \2_\1@' - # In case of a timeout immediately leave loop. - if [ $? = 255 ] ; then break ; fi - done" -fi - -# RAID status of Linux software RAID -echo '<<>>' -cat /proc/mdstat - -# RAID status of Linux RAID via device mapper -if type dmraid >/dev/null && DMSTATUS=$(dmraid -r) -then - echo '<<>>' - - # Output name and status - dmraid -s | grep -e ^name -e ^status - - # Output disk names of the RAID disks - DISKS=$(echo "$DMSTATUS" | cut -f1 -d\:) - - for disk in $DISKS ; do - device=$(cat /sys/block/$(basename $disk)/device/model ) - status=$(echo "$DMSTATUS" | grep ^${disk}) - echo "$status Model: $device" - done -fi - -# RAID status of LSI controllers via cfggen -if type cfggen > /dev/null ; then - echo '<<>>' - cfggen 0 DISPLAY | egrep '(Target ID|State|Volume ID|Status of volume)[[:space:]]*:' | sed -e 's/ *//g' -e 's/:/ /' -fi - -# RAID status of LSI MegaRAID controller via MegaCli. You can download that tool from: -# http://www.lsi.com/downloads/Public/MegaRAID%20Common%20Files/8.02.16_MegaCLI.zip -if type MegaCli >/dev/null ; then - MegaCli_bin="MegaCli" -elif type MegaCli64 >/dev/null ; then - MegaCli_bin="MegaCli64" -elif type megacli >/dev/null ; then - MegaCli_bin="megacli" -else - MegaCli_bin="unknown" -fi - -if [ "$MegaCli_bin" != "unknown" ]; then - echo '<<>>' - for part in $($MegaCli_bin -EncInfo -aALL -NoLog < /dev/null \ - | sed -rn 's/:/ /g; s/[[:space:]]+/ /g; s/^ //; s/ $//; s/Number of enclosures on adapter ([0-9]+).*/adapter \1/g; /^(Enclosure|Device ID|adapter) [0-9]+$/ p'); do - [ $part = adapter ] && echo "" - [ $part = 'Enclosure' ] && echo -ne "\ndev2enc" - echo -n " $part" - done - echo - $MegaCli_bin -PDList -aALL -NoLog < /dev/null | egrep 'Enclosure|Raw Size|Slot Number|Device Id|Firmware state|Inquiry|Adapter' - echo '<<>>' - $MegaCli_bin -LDInfo -Lall -aALL -NoLog < /dev/null | egrep 'Size|State|Number|Adapter|Virtual' - echo '<<>>' - $MegaCli_bin -AdpBbuCmd -GetBbuStatus -aALL -NoLog < /dev/null | grep -v Exit -fi - -# RAID status of 3WARE disk controller (by Radoslaw Bak) -if type tw_cli > /dev/null ; then - for C in $(tw_cli show | awk 'NR < 4 { next } { print $1 }'); do - echo '<<<3ware_info>>>' - tw_cli /$C show all | egrep 'Model =|Firmware|Serial' - echo '<<<3ware_disks>>>' - tw_cli /$C show drivestatus | egrep 'p[0-9]' | sed "s/^/$C\//" - echo '<<<3ware_units>>>' - tw_cli /$C show unitstatus | egrep 'u[0-9]' | sed "s/^/$C\//" - done -fi - -# RAID controllers from areca (Taiwan) -# cli64 can be found at ftp://ftp.areca.com.tw/RaidCards/AP_Drivers/Linux/CLI/ -if type cli64 >/dev/null ; then - run_cached -s arc_raid_status 300 "cli64 rsf info | tail -n +3 | head -n -2" -fi - -# VirtualBox Guests. Section must always been output. Otherwise the -# check would not be executed in case no guest additions are installed. -# And that is something the check wants to detect -echo '<<>>' -if type VBoxControl >/dev/null 2>&1 ; then - VBoxControl -nologo guestproperty enumerate | cut -d, -f1,2 - [ ${PIPESTATUS[0]} = 0 ] || echo "ERROR" -fi - -# OpenVPN Clients. Currently we assume that the configuration # is in -# /etc/openvpn. We might find a safer way to find the configuration later. -if [ -e /etc/openvpn/openvpn-status.log ] ; then - echo '<<>>' - sed -n -e '/CLIENT LIST/,/ROUTING TABLE/p' < /etc/openvpn/openvpn-status.log | sed -e 1,3d -e '$d' -fi - -# Time synchronization with NTP -if type ntpq > /dev/null 2>&1 ; then - # remove heading, make first column space separated - run_cached -s ntp 30 "waitmax 5 ntpq -np | sed -e 1,2d -e 's/^\(.\)/\1 /' -e 's/^ /%/'" -fi - -# Time synchronization with Chrony -if type chronyc > /dev/null 2>&1 ; then - # Force successful exit code. Otherwise section will be missing if daemon not running - run_cached -s chrony 30 "waitmax 5 chronyc tracking || true" -fi - -if type nvidia-settings >/dev/null && [ -S /tmp/.X11-unix/X0 ] -then - echo '<<>>' - for var in GPUErrors GPUCoreTemp - do - DISPLAY=:0 waitmax 2 nvidia-settings -t -q $var | sed "s/^/$var: /" - done -fi - -if [ -e /proc/drbd ]; then - echo '<<>>' - cat /proc/drbd -fi - -# Status of CUPS printer queues -if type lpstat > /dev/null 2>&1; then - if pgrep cups > /dev/null 2>&1; then - echo '<<>>' - CPRINTCONF=/etc/cups/printers.conf - if [ -r "$CPRINTCONF" ] ; then - LOCAL_PRINTERS=$(grep -E "<(Default)?Printer .*>" $CPRINTCONF | awk '{print $2}' | sed -e 's/>//') - lpstat -p | while read LINE - do - PRINTER=$(echo $LINE | awk '{print $2}') - if echo "$LOCAL_PRINTERS" | grep -q "$PRINTER"; then - echo $LINE - fi - done - echo '---' - lpstat -o | while read LINE - do - PRINTER=${LINE%%-*} - if echo "$LOCAL_PRINTERS" | grep -q "$PRINTER"; then - echo $LINE - fi - done - else - lpstat -p - echo '---' - lpstat -o | sort - fi - fi -fi - -# Heartbeat monitoring -# Different handling for heartbeat clusters with and without CRM -# for the resource state -if [ -S /var/run/heartbeat/crm/cib_ro -o -S /var/run/crm/cib_ro ] || pgrep crmd > /dev/null 2>&1; then - echo '<<>>' - crm_mon -1 -r | grep -v ^$ | sed 's/^ //; /^\sResource Group:/,$ s/^\s//; s/^\s/_/g' -fi -if type cl_status > /dev/null 2>&1; then - echo '<<>>' - cl_status rscstatus - - echo '<<>>' - for NODE in $(cl_status listnodes); do - if [ $NODE != $(echo $HOSTNAME | tr 'A-Z' 'a-z') ]; then - STATUS=$(cl_status nodestatus $NODE) - echo -n "$NODE $STATUS" - for LINK in $(cl_status listhblinks $NODE 2>/dev/null); do - echo -n " $LINK $(cl_status hblinkstatus $NODE $LINK)" - done - echo - fi - done -fi - -# Postfix mailqueue monitoring -# -# Only handle mailq when postfix user is present. The mailq command is also -# available when postfix is not installed. But it produces different outputs -# which are not handled by the check at the moment. So try to filter out the -# systems not using postfix by searching for the postfix user.a -# -# Cannot take the whole outout. This could produce several MB of agent output -# on blocking queues. -# Only handle the last 6 lines (includes the summary line at the bottom and -# the last message in the queue. The last message is not used at the moment -# but it could be used to get the timestamp of the last message. -if type postconf >/dev/null ; then - echo '<<>>' - postfix_queue_dir=$(postconf -h queue_directory) - postfix_count=$(find $postfix_queue_dir/deferred -type f | wc -l) - postfix_size=$(du -ks $postfix_queue_dir/deferred | awk '{print $1 }') - if [ $postfix_count -gt 0 ] - then - echo -- $postfix_size Kbytes in $postfix_count Requests. - else - echo Mail queue is empty - fi -elif [ -x /usr/sbin/ssmtp ] ; then - echo '<<>>' - mailq 2>&1 | sed 's/^[^:]*: \(.*\)/\1/' | tail -n 6 -fi - -#Check status of qmail mailqueue -if type qmail-qstat >/dev/null -then - echo "<<>>" - qmail-qstat -fi - -# Check status of OMD sites -if type omd >/dev/null -then - run_cached -s omd_status 60 "omd status --bare --auto" -fi - - -# Welcome the ZFS check on Linux -# We do not endorse running ZFS on linux if your vendor doesnt support it ;) -# check zpool status -if type zpool >/dev/null; then - echo "<<>>" - zpool status -x -fi - - -# Fileinfo-Check: put patterns for files into /etc/check_mk/fileinfo.cfg -if [ -r "$MK_CONFDIR/fileinfo.cfg" ] ; then - echo '<<>>' - date +%s - stat -c "%n|%s|%Y" $(cat "$MK_CONFDIR/fileinfo.cfg") -fi - -# Get stats about OMD monitoring cores running on this machine. -# Since cd is a shell builtin the check does not affect the performance -# on non-OMD machines. -if cd /omd/sites -then - echo '<<>>' - for site in * - do - if [ -S "/omd/sites/$site/tmp/run/live" ] ; then - echo "[$site]" - echo -e "GET status" | waitmax 3 /omd/sites/$site/bin/unixcat /omd/sites/$site/tmp/run/live - fi - done -fi - -# Get statistics about monitored jobs. Below the job directory there -# is a sub directory per user that ran a job. That directory must be -# owned by the user so that a symlink or hardlink attack for reading -# arbitrary files can be avoided. -if pushd $MK_VARDIR/job >/dev/null; then - echo '<<>>' - for username in * - do - if [ -d "$username" ] && cd "$username" ; then - su "$username" -c "head -n -0 -v *" - cd .. - fi - done - popd > /dev/null -fi - -# Gather thermal information provided e.g. by acpi -# At the moment only supporting thermal sensors -if ls /sys/class/thermal/thermal_zone* >/dev/null 2>&1; then - echo '<<>>' - for F in /sys/class/thermal/thermal_zone*; do - echo -n "${F##*/} " - if [ ! -e $F/mode ] ; then echo -n "- " ; fi - cat $F/{mode,type,temp,trip_point_*} | tr \\n " " - echo - done -fi - -# Libelle Business Shadow -if type trd >/dev/null; then - echo "<<>>" - trd -s -fi - -# MK's Remote Plugin Executor -if [ -e "$MK_CONFDIR/mrpe.cfg" ] -then - echo '<<>>' - grep -Ev '^[[:space:]]*($|#)' "$MK_CONFDIR/mrpe.cfg" | \ - while read descr cmdline - do - PLUGIN=${cmdline%% *} - OUTPUT=$(eval "$cmdline") - echo -n "(${PLUGIN##*/}) $descr $? $OUTPUT" | tr \\n \\1 - echo - done -fi - - -# Local checks -echo '<<>>' -if cd $LOCALDIR ; then - for skript in $(ls) ; do - if [ -f "$skript" -a -x "$skript" ] ; then - ./$skript - fi - done - # Call some plugins only every X'th minute - for skript in [1-9]*/* ; do - if [ -x "$skript" ] ; then - run_cached local_${skript//\//\\} ${skript%/*} "$skript" - fi - done -fi - -# Plugins -if cd $PLUGINSDIR ; then - for skript in $(ls) ; do - if [ -f "$skript" -a -x "$skript" ] ; then - ./$skript - fi - done - # Call some plugins only every Xth minute - for skript in [1-9]*/* ; do - if [ -x "$skript" ] ; then - run_cached plugins_${skript//\//\\} ${skript%/*} "$skript" - fi - done -fi - -# Agent output snippets created by cronjobs, etc. -if [ -d "$SPOOLDIR" ] -then - pushd "$SPOOLDIR" > /dev/null - now=$(date +%s) - - for file in * - do - # output every file in this directory. If the file is prefixed - # with a number, then that number is the maximum age of the - # file in seconds. If the file is older than that, it is ignored. - maxage="" - part="$file" - - # Each away all digits from the front of the filename and - # collect them in the variable maxage. - while [ "${part/#[0-9]/}" != "$part" ] - do - maxage=$maxage${part:0:1} - part=${part:1} - done - - # If there is at least one digit, than we honor that. - if [ "$maxage" ] ; then - mtime=$(stat -c %Y "$file") - if [ $((now - mtime)) -gt $maxage ] ; then - continue - fi - fi - - # Output the file - cat "$file" - done - popd > /dev/null -fi diff --git a/scripts/check_mk_xinetd b/scripts/check_mk_xinetd deleted file mode 100644 index 9fefd584c6..0000000000 --- a/scripts/check_mk_xinetd +++ /dev/null @@ -1,49 +0,0 @@ -# +------------------------------------------------------------------+ -# | ____ _ _ __ __ _ __ | -# | / ___| |__ ___ ___| | __ | \/ | |/ / | -# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | -# | | |___| | | | __/ (__| < | | | | . \ | -# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | -# | | -# | Copyright Mathias Kettner 2013 mk@mathias-kettner.de | -# +------------------------------------------------------------------+ -# -# This file is part of Check_MK. -# The official homepage is at http://mathias-kettner.de/check_mk. -# -# check_mk 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 in version 2. check_mk is distributed -# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- -# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. See the GNU General Public License for more de- -# ails. You should have received a copy of the GNU General Public -# License along with GNU Make; see the file COPYING. If not, write -# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, -# Boston, MA 02110-1301 USA. - -service check_mk -{ - type = UNLISTED - port = 6556 - socket_type = stream - protocol = tcp - wait = no - user = root - server = /usr/bin/check_mk_agent - - # If you use fully redundant monitoring and poll the client - # from more then one monitoring servers in parallel you might - # want to use the agent cache wrapper: - #server = /usr/bin/check_mk_caching_agent - - # configure the IP address(es) of your Nagios server here: - #only_from = 127.0.0.1 10.0.20.1 10.0.20.2 - - # Don't be too verbose. Don't log every check. This might be - # commented out for debugging. If this option is commented out - # the default options will be used for this service. - log_on_success = - - disable = no -} diff --git a/scripts/geshi-ios.php b/scripts/geshi-ios.php deleted file mode 100755 index fbfd63c698..0000000000 --- a/scripts/geshi-ios.php +++ /dev/null @@ -1,173 +0,0 @@ - 'IOS', - 'COMMENT_SINGLE' => array(1 => '!'), - 'CASE_KEYWORDS' => GESHI_CAPS_LOWER, - 'OOLANG' => false, - 'NUMBERS' => GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX, - 'KEYWORDS' => array( - 1 => array( - 'no', - 'shutdown', - ), - // 2 => array( - // 'router', 'interface', 'service', 'config-register', 'upgrade', 'version', 'hostname', 'boot-start-marker', 'boot', 'boot-end-marker', 'enable', 'aaa', 'clock', 'ip', - // 'logging', 'access-list', 'route-map', 'snmp-server', 'mpls', 'speed', 'media-type', 'negotiation', 'timestamps', 'prefix-list', 'network', 'mask', 'unsuppress-map', - // 'neighbor', 'remote-as', 'ebgp-multihop', 'update-source', 'description', 'peer-group', 'policy-map', 'class-map', 'class', 'match', 'access-group', 'bandwidth', 'username', - // 'password', 'send-community', 'next-hop-self', 'route-reflector-client', 'ldp', 'discovery', 'advertise-labels', 'label', 'protocol', 'login', 'debug', 'log', 'duplex', 'router-id', - // 'authentication', 'mode', 'maximum-paths', 'address-family', 'set', 'local-preference', 'community', 'trap-source', 'location', 'host', 'tacacs-server', 'session-id', - // 'flow-export', 'destination', 'source', 'in', 'out', 'permit', 'deny', 'control-plane', 'line', 'con' ,'aux', 'vty', 'access-class', 'ntp', 'server', 'end', 'source-interface', - // 'key', 'chain', 'key-string', 'redundancy', 'match-any', 'queue-limit', 'encapsulation', 'pvc', 'vbr-nrt', 'address', 'bundle-enable', 'atm', 'sonet', 'clns', 'route-cache', - // 'default-information', 'redistribute', 'log-adjacency-changes', 'metric', 'spf-interval', 'prc-interval', 'lsp-refresh-interval', 'max-lsp-lifetime', 'set-overload-bit', - // 'on-startup', 'wait-for-bgp', 'system', 'flash', 'timezone', 'subnet-zero', 'cef', 'flow-cache', 'timeout', 'active', 'domain', 'lookup', 'dhcp', 'use', 'vrf', 'hello', 'interval', - // 'priority', 'ilmi-keepalive', 'buffered', 'debugging', 'fpd', 'secret', 'accounting', 'exec', 'group', 'local', 'recurring', 'source-route', 'call', 'rsvp-sync', 'scripting', - // 'mtu', 'passive-interface', 'area' , 'distribute-list', 'metric-style', 'is-type', 'originate', 'activate', 'both', 'auto-summary', 'synchronization', 'aggregate-address', 'le', 'ge', - // 'bgp-community', 'route', 'exit-address-family', 'standard', 'file', 'verify', 'domain-name', 'domain-lookup', 'route-target', 'export', 'import', 'map', 'rd', 'mfib', 'vtp', 'mls', - // 'hardware-switching', 'replication-mode', 'ingress', 'flow', 'error', 'action', 'slb', 'purge', 'share-global', 'routing', 'traffic-eng', 'tunnels', 'propagate-ttl', 'switchport', 'vlan', - // 'portfast', 'counters', 'max', 'age', 'ethernet', 'evc', 'uni', 'count', 'oam', 'lmi', 'gmt', 'netflow', 'pseudowire-class', 'spanning-tree', 'name', 'circuit-type' - // ), - // 3 => array( - // 'isis', 'ospf', 'eigrp', 'rip', 'igrp', 'bgp', 'ipv4', 'unicast', 'multicast', 'ipv6', 'connected', 'static', 'subnets', 'tcl' - // ), - // 4 => array( - // 'point-to-point', 'aal5snap', 'rj45', 'auto', 'full', 'half', 'precedence', 'percent', 'datetime', 'msec', 'locatime', 'summer-time', 'md5', 'wait-for-bgp', 'wide', - // 'level-1', 'level-2', 'log-neighbor-changes', 'directed-request', 'password-encryption', 'common', 'origin-as', 'bgp-nexthop', 'random-detect', 'localtime', 'sso', 'stm-1', - // 'dot1q', 'isl', 'new-model', 'always', 'summary-only', 'freeze', 'global', 'forwarded', 'access', 'trunk', 'edge', 'transparent' - // ), - ), - - 'REGEXPS' => array( - 1 => array( - GESHI_SEARCH => '(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})', - GESHI_REPLACE => '\\1', - GESHI_BEFORE => '', - ), - 2 => array( - GESHI_SEARCH => '(255\.\d{1,3}\.\d{1,3}\.\d{1,3})', - GESHI_REPLACE => '\\1', - GESHI_BEFORE => '', - ), - 3 => array( - GESHI_SEARCH => '(source|interface|update-source|router-id) ([A-Za-z0-9\/\:\-\.]+)', - GESHI_REPLACE => '\\2', - GESHI_BEFORE => '\\1 ', - ), - 4 => array( - GESHI_SEARCH => '(neighbor) ([\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}]+|[a-zA-Z0-9\-\_]+)', - GESHI_REPLACE => '\\2', - GESHI_BEFORE => '\\1 ', - ), - 5 => array( - GESHI_SEARCH => '(distribute-map|access-group|policy-map|class-map\ match-any|ip\ access-list\ extended|match\ community|community-list\ standard|community-list\ expanded|ip\ access-list\ standard|router\ bgp|remote-as|key\ chain|service-policy\ input|service-policy\ output|class|login\ authentication|authentication\ key-chain|username|import\ map|export\ map|domain-name|hostname|route-map|access-class|ip\ vrf\ forwarding|ip\ vrf|vtp\ domain|name|pseudowire-class|pw-class|prefix-list|vrf) ([A-Za-z0-9\-\_\.]+)', - GESHI_REPLACE => '\\2', - GESHI_BEFORE => '\\1 ', - ), - 6 => array( - GESHI_SEARCH => '(password|key-string|key) ([0-9]) (.+)', - GESHI_REPLACE => '\\2 \\3', - GESHI_BEFORE => '\\1 ', - ), - 7 => array( - GESHI_SEARCH => '(enable) ([a-z]+) ([0-9]) (.+)', - GESHI_REPLACE => '\\3 \\4', - GESHI_BEFORE => '\\1 \\2 ', - ), - 8 => array( - GESHI_SEARCH => '(description|location|contact|remark) (.+)', - GESHI_REPLACE => '\\2', - GESHI_BEFORE => '\\1 ', - ), - 9 => array( - GESHI_SEARCH => '([0-9\.\_\*]+\:[0-9\.\_\*]+)', - GESHI_REPLACE => '\\1', - ), - 10 => array( - GESHI_SEARCH => '(boot) ([a-z]+) (.+)', - GESHI_REPLACE => '\\3', - GESHI_BEFORE => '\\1 \\2 ', - ), - 11 => array( - GESHI_SEARCH => '(net) ([0-9a-z\.]+)', - GESHI_REPLACE => '\\2', - GESHI_BEFORE => '\\1 ', - ), - 12 => array( - GESHI_SEARCH => '(access-list|RO|RW) ([0-9]+)', - GESHI_REPLACE => '\\2', - GESHI_BEFORE => '\\1 ', - ), - 13 => array( - GESHI_SEARCH => '(vlan) ([0-9]+)', - GESHI_REPLACE => '\\2', - GESHI_BEFORE => '\\1 ', - ), - 14 => array( - GESHI_SEARCH => '(encapsulation|speed|duplex|mtu|metric|media-type|negotiation|transport\ input|bgp-community|set\ as-path\ prepend|maximum-prefix|version|local-preference|continue|redistribute|cluster-id|vtp\ mode|label\ protocol|spanning-tree\ mode) (.+)', - GESHI_REPLACE => '\\2', - GESHI_BEFORE => '\\1 ', - ), - - ), - - 'STYLES' => array( - 'REGEXPS' => array( - 0 => 'color: #ff0000;', - 1 => 'color: #0000cc;', - // x.x.x.x - 2 => 'color: #000099; font-style: italic', - // 255.x.x.x - 3 => 'color: #000000; font-weight: bold; font-style: italic;', - // interface xxx - 4 => 'color: #ff0000;', - // neighbor x.x.x.x - 5 => 'color: #000099;', - // variable names - 6 => 'color: #cc0000;', - 7 => 'color: #cc0000;', - // passwords - 8 => 'color: #555555;', - // description - 9 => 'color: #990099;', - // communities - 10 => 'color: #cc0000; font-style: italic;', - // no/shut - 11 => 'color: #000099;', - // net numbers - 12 => 'color: #000099;', - // acls - 13 => 'color: #000099;', - // acls - 14 => 'color: #990099;', - // warnings - ), - 'KEYWORDS' => array( - 1 => 'color: #cc0000; font-weight: bold;', - // no/shut - 2 => 'color: #000000;', - // commands - 3 => 'color: #000000; font-weight: bold;', - // proto/service - 4 => 'color: #000000;', - // options - 5 => 'color: #ff0000;', - ), - 'COMMENTS' => array(1 => 'color: #808080; font-style: italic;'), - 'ESCAPE_CHAR' => array(0 => 'color: #000099; font-weight: bold;'), - 'BRACKETS' => array(0 => 'color: #66cc66;'), - 'STRINGS' => array(0 => 'color: #ff0000;'), - 'NUMBERS' => array(0 => 'color: #cc0000;'), - 'METHODS' => array(0 => 'color: #006600;'), - 'SYMBOLS' => array(0 => 'color: #66cc66;'), - 'SCRIPT' => array( - 0 => '', - 1 => '', - 2 => '', - 3 => '', - ), - - ), - - -); diff --git a/scripts/get-geshi.sh b/scripts/get-geshi.sh deleted file mode 100755 index 4239c99ced..0000000000 --- a/scripts/get-geshi.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -wget http://surfnet.dl.sourceforge.net/sourceforge/geshi/GeSHi-1.0.8.3.tar.gz -tar zxf GeSHi-1.0.8.3.tar.gz -mv geshi html/includes -ln scripts/geshi-ios.php html/includes/geshi/geshi/ios.php -rm GeSHi-1.0.8.3.tar.gz diff --git a/scripts/get-jpgraph.sh b/scripts/get-jpgraph.sh deleted file mode 100755 index 3c20930feb..0000000000 --- a/scripts/get-jpgraph.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -mkdir jpgraph -cd jpgraph -wget http://hem.bredband.net/jpgraph2/jpgraph-3.0.2.tar.bz2 -tar jxf jpgraph-3.0.2.tar.bz2 -rm -rf html/includes/jpgraph -rm jpgraph-3.0.2.tar.bz2 -cd .. -mv jpgraph html/includes/jpgraph diff --git a/scripts/mailscanner.php b/scripts/mailscanner.php deleted file mode 100644 index b80fdb9ff3..0000000000 --- a/scripts/mailscanner.php +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env php - - /// - /////////////////////////////////////////////////////////////////////////////////////// - - - // START SETTINGS /// - - $mailstats = "/opt/librenms/scripts/watchmaillog/watchmaillog_counters"; - - // END SETTINGS /// - - - /// - // DO NOT EDIT BENETH THIS LINE - /// - /////////////////////////////////////////////////////////////////////////////////////// - - function doSNMPv2($vars) { - $stats = array(); - if (file_exists($vars)) { - $data = file($vars); - foreach ($data as $item=>$value) { - if (!empty($value)) { - $temp = explode(':', trim($value)); - if (isset($temp[1])) { - $stats[$temp[0]] = $temp[1]; - } - } - } - } - $var = array(); - $var['mess_recv'] = (isset($stats['mess_recv']) ? $stats['mess_recv'] : "U"); - $var['mess_rejected'] = (isset($stats['mess_rejected']) ? $stats['mess_rejected'] : "U"); - $var['mess_relay'] = (isset($stats['mess_relay']) ? $stats['mess_relay'] : "U"); - $var['mess_sent'] = (isset($stats['mess_sent']) ? $stats['mess_sent'] : "U"); - $var['mess_waiting'] = (isset($stats['mess_waiting']) ? $stats['mess_waiting'] : "U"); - $var['spam'] = (isset($stats['spam']) ? $stats['spam'] : "U"); - $var['virus'] = (isset($stats['virus']) ? $stats['virus'] : "U"); - foreach ($var as $item=>$count) { - echo $count."\n"; - } - } - - function clearStats($mailstats) { - if (file_exists($mailstats)) { - $fp = fopen($mailstats, 'w'); - fwrite($fp, "mess_recv:0\n"); - fwrite($fp, "mess_rejected:0\n"); - fwrite($fp, "mess_relay:0\n"); - fwrite($fp, "mess_sent:0\n"); - fwrite($fp, "mess_waiting:0\n"); - fwrite($fp, "spam:0\n"); - fwrite($fp, "virus:0\n"); - fclose($fp); - } - } - - doSNMPv2($mailstats); - //clearStats($mailstats); - -?> diff --git a/scripts/mysql-stats b/scripts/mysql-stats deleted file mode 100644 index d191bdbbc6..0000000000 --- a/scripts/mysql-stats +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env python2 -import warnings -import re -warnings.filterwarnings(action="ignore", message='the sets module is deprecated') -import sets -import MySQLdb -import base64 -conn = MySQLdb.connect(host='', - user='', - passwd='', - db='') - -cursor = conn.cursor () - - -cursor.execute ("SHOW GLOBAL STATUS") -rows = cursor.fetchall() - -datavariables = { - 'Command Counters': ['Com_delete','Com_insert','Com_insert_select','Com_load','Com_replace','Com_replace_select', 'Com_select', 'Com_update', 'Com_update_multi'], - 'Connections': ['max_connections', 'Max_used_connections', 'Aborted_clients', 'Aborted_connects','Threads_connected','Connections'], - 'Files and Tables': ['table_open_cache','Open_files','Open_tables','Opened_tables'], - 'InnoDB Buffer Pool': ['ib_bpool_size','ib_bpool_dbpages', 'ib_bpool_free','ib_bpool_modpages'], - 'InnoDB Buffer Pool Activity': ['ib_bpool_read','ib_bpool_created', 'ib_bpool_written'], - 'InnoDB Insert Buffer': ['ib_ibuf_inserts','ib_ibuf_merged_rec', 'ib_ibuf_merges'], - 'InnoDB IO': ['ib_io_read','ib_io_write','ib_io_log', 'ib_io_fsync'], - 'InnoDB IO Pending': ['ib_iop_log','ib_iop_sync', 'ib_iop_flush_log', 'ib_iop_flush_bpool', 'ib_iop_ibuf_aio','ib_iop_aioread','ib_iop_aiowrite'], - 'InnoDB Log': ['innodb_log_buffer_size','ib_log_flush','ib_log_written'], - 'InnoDB Row Operations': ['Innodb_rows_deleted','Innodb_rows_inserted','Innodb_rows_read','Innodb_rows_updated'], - 'InnoDB Semaphores': ['ib_spin_rounds','ib_spin_waits','ib_os_waits'], - 'InnoDB Transactions': ['ib_tnx'], - 'MyISAM Indexes': ['Key_read_requests','Key_reads','Key_write_requests','Key_writes'], - 'Network Traffic': ['Bytes_received','Bytes_sent'], - 'Query Cache': ['Qcache_queries_in_cache','Qcache_hits','Qcache_inserts','Qcache_not_cached','Qcache_lowmem_prunes'], - 'Query Cache Memory': ['query_cache_size','Qcache_free_memory'], - 'Select Types': ['Select_full_join','Select_full_range_join','Select_range','Select_range_check','Select_scan'], - 'Slow Queries': ['Slow_queries'], - 'Sorts': ['Sort_rows','Sort_range','Sort_merge_passes','Sort_scan'], - 'Table Locks': ['Table_locks_immediate','Table_locks_waited'], - 'Temporary Objects': ['Created_tmp_disk_tables','Created_tmp_tables','Created_tmp_files'] - } - -data = {} -for row in rows: - data[row[0]] = row[1] - -cursor = "" -cursor = conn.cursor () -cursor.execute ("SHOW VARIABLES") -rows = cursor.fetchall() - -for row in rows: - data[row[0]] = row[1] - -cursor = "" -cursor = conn.cursor() -cursor.execute("SHOW ENGINE INNODB STATUS") -rows = cursor.fetchall() - -for row in rows: - for line in row[2].split("\n"): - ib_bpool_size = re.match(r"Buffer\spool\ssize\s+(\d+)", line) - ib_bpool_free = re.match(r"Free\sbuffers\s+(\d+)", line) - ib_bpool_dbpages = re.match(r"Database\spages\s+(\d+)", line) - ib_bpool_modpages = re.match(r"Modified\sdb\spages\s+(\d+)", line) - ib_b_reg = re.match(r"Pages\sread\s(\d+),\screated\s(\d+),\swritten (\d+)", line) - ib_insert_buffer = re.match(r"(\d+)\sinserts,\s(\d+)\smerged\srecs,\s(\d+)", line) - ib_io = re.match(r"(\d+)\sOS\sfile\sreads,\s(\d+)\sOS\sfile\swrites,\s(\d+)\sOS\sfsyncs", line) - ib_io_log = re.match(r"(\d+)\slog\si\/o's\sdone.*", line) - ib_io_p1 = re.match(r"Pending\snormal\saio\sreads:\s(\d+),\saio\swrites:\s(\d+),", line) - ib_io_p2 = re.match(r"\s?ibuf\saio\sreads:\s(\d+),\slog\si\/o's:\s(\d+),\ssync\si\/o's:\s(\d+)", line) - ib_io_p3 = re.match(r"\s?Pending\sflushes\s\(fsync\)\slog:\s(\d+);\sbuffer\spool:\s(\d+)\s?", line) - ib_log_p1 = re.match(r"\s?Log\ssequence\snumber\s([[a-fA-F\d]+)(?: (\d+))?", line) - ib_log_p2 = re.match(r"\s?Log\sflushed\sup\sto\s+([[a-fA-F\d]+)(?: (\d+))?", line) - ib_semaphore = re.match(r"\s?Mutex\sspin\swaits\s(\d+),\srounds\s(\d+),\sOS waits\s(\d+)", line) - ib_tnx = re.match(r"\s?Trx\sid\scounter\s([[a-fA-F\d]+)(?: (\d+))?", line) - - if ib_bpool_size: - data['ib_bpool_size'] = ib_bpool_size.group(1) - elif ib_bpool_free: - data['ib_bpool_free'] = ib_bpool_free.group(1) - elif ib_bpool_dbpages: - data['ib_bpool_dbpages'] = ib_bpool_dbpages.group(1) - elif ib_bpool_modpages: - data['ib_bpool_modpages'] = ib_bpool_modpages.group(1) - elif ib_insert_buffer: - data['ib_ibuf_inserts'] = ib_insert_buffer.group(1) - data['ib_ibuf_merged_rec'] = ib_insert_buffer.group(2) - data['ib_ibuf_merges'] = ib_insert_buffer.group(3) - elif ib_io: - data['ib_io_read'] = ib_io.group(1) - data['ib_io_write'] = ib_io.group(2) - data['ib_io_fsync'] = ib_io.group(3) - elif ib_io_log: - data['ib_io_log'] = ib_io_log.group(1) - elif ib_io_p1: - data['ib_iop_aioread'] = ib_io_p1.group(1) - data['ib_iop_aiowrite'] = ib_io_p1.group(2) - elif ib_io_p2: - data['ib_iop_ibuf_aio'] = ib_io_p2.group(1) - data['ib_iop_log'] = ib_io_p2.group(2) - data['ib_iop_sync'] = ib_io_p2.group(3) - elif ib_io_p3: - data['ib_iop_flush_log'] = ib_io_p3.group(1) - data['ib_iop_flush_bpool'] = ib_io_p3.group(2) - elif ib_log_p1: - data['ib_log_written'] = ib_log_p1.group(1) - if ib_log_p1.group(2): - data['ib_log_written'] = int(data['ib_log_written']) + int(ib_log_p1.group(2)) - elif ib_log_p2: - data['ib_log_flush'] = ib_log_p2.group(1) - if ib_log_p2.group(2): - data['ib_log_flush'] = int(data['ib_log_flush']) + int(ib_log_p2.group(2)) - elif ib_semaphore: - data['ib_spin_waits'] = ib_semaphore.group(1) - data['ib_spin_rounds'] = ib_semaphore.group(2) - data['ib_os_waits'] = ib_semaphore.group(3) - elif ib_tnx: - data['ib_tnx'] = ib_tnx.group(1) - if ib_tnx.group(2): - data['ib_tnx'] = int(data['ib_tnx']) + int(ib_tnx.group(2)) - elif ib_b_reg: - data['ib_bpool_read'] = ib_b_reg.group(1) - data['ib_bpool_created'] = ib_b_reg.group(2) - data['ib_bpool_written'] = ib_b_reg.group(3) - - -for category in datavariables: - for variable in datavariables[category]: - if variable in data: - print data[variable] diff --git a/scripts/mysql_stats.php b/scripts/mysql_stats.php deleted file mode 100755 index 89522a61e5..0000000000 --- a/scripts/mysql_stats.php +++ /dev/null @@ -1,1247 +0,0 @@ - true, # Do you want to check InnoDB statistics? - 'master' => true, # Do you want to check binary logging? - 'slave' => true, # Do you want to check slave status? - 'procs' => true, # Do you want to check SHOW PROCESSLIST? -); - -$use_ss = FALSE; # Whether to use the script server or not -$debug = FALSE; # Define whether you want debugging behavior. -$debug_log = FALSE; # If $debug_log is a filename, it'll be used. - -# ============================================================================ -# You should not need to change anything below this line. -# ============================================================================ -$version = "1.1.7"; - -# ============================================================================ -# Include settings from an external config file (issue 39). -# ============================================================================ -if (file_exists(__FILE__ . '.cnf' ) ) { - require(__FILE__ . '.cnf'); -} - -# Make this a happy little script even when there are errors. -$no_http_headers = true; -ini_set('implicit_flush', false); # No output, ever. -if ($debug ) { - ini_set('display_errors', true); - ini_set('display_startup_errors', true); - ini_set('error_reporting', 2147483647); -} -else { - ini_set('error_reporting', E_ERROR); -} -ob_start(); # Catch all output such as notices of undefined array indexes. -function error_handler($errno, $errstr, $errfile, $errline) { - print("$errstr at $errfile line $errline\n"); - debug("$errstr at $errfile line $errline"); -} -# ============================================================================ -# Set up the stuff we need to be called by the script server. -# ============================================================================ -if ($use_ss ) { - if (file_exists( dirname(__FILE__) . "/../include/global.php") ) { - # See issue 5 for the reasoning behind this. - debug("including " . dirname(__FILE__) . "/../include/global.php"); - include_once(dirname(__FILE__) . "/../include/global.php"); - } - elseif (file_exists( dirname(__FILE__) . "/../include/config.php" ) ) { - # Some Cacti installations don't have global.php. - debug("including " . dirname(__FILE__) . "/../include/config.php"); - include_once(dirname(__FILE__) . "/../include/config.php"); - } -} - -# ============================================================================ -# Make sure we can also be called as a script. -# ============================================================================ -if (!isset($called_by_script_server)) { - debug($_SERVER["argv"]); - array_shift($_SERVER["argv"]); # Strip off this script's filename - $options = parse_cmdline($_SERVER["argv"]); - validate_options($options); - $result = ss_get_mysql_stats($options); - - debug($result); - if (!$debug ) { - # Throw away the buffer, which ought to contain only errors. - ob_end_clean(); - } - else { - ob_end_flush(); # In debugging mode, print out the errors. - } - - # Split the result up and extract only the desired parts of it. - $options['items'] = ""; - $wanted = explode(',', $options['items']); - $output = array(); - foreach ( explode(' ', $result) as $item ) { - if (in_array(substr($item, 0, 2), $wanted) ) { - $output[] = $item; - } - list($short, $val) = explode(":", $item); - echo(strtolower($short).":".strtolower($val)."\n"); - } - debug(array("Final result", $output)); - print(implode(' ', $output)); -} - -# ============================================================================ -# End "if file was not included" section. -# ============================================================================ -} - -# ============================================================================ -# Work around the lack of array_change_key_case in older PHP. -# ============================================================================ -if (!function_exists('array_change_key_case') ) { - function array_change_key_case($arr) { - $res = array(); - foreach ( $arr as $key => $val ) { - $res[strtolower($key)] = $val; - } - return $res; - } -} - -# ============================================================================ -# Validate that the command-line options are here and correct -# ============================================================================ -function validate_options($options) { - debug($options); - $opts = array('items', 'user', 'pass', 'heartbeat', 'nocache', 'port'); - # Required command-line options - foreach ( array() as $option ) { - if (!isset($options[$option]) || !$options[$option] ) { - usage("Required option --$option is missing"); - } - } - foreach ( $options as $key => $val ) { - if (!in_array($key, $opts) ) { - usage("Unknown option --$key"); - } - } -} - -# ============================================================================ -# Print out a brief usage summary -# ============================================================================ -function usage($message) { - global $mysql_host, $mysql_user, $mysql_pass, $mysql_port, $heartbeat; - - $usage = << --items [OPTION] - - --host Hostname to connect to; use host:port syntax to specify a port - Use :/path/to/socket if you want to connect via a UNIX socket - --items Comma-separated list of the items whose data you want - --user MySQL username; defaults to $mysql_user if not given - --pass MySQL password; defaults to $mysql_pass if not given - --heartbeat MySQL heartbeat table; defaults to '$heartbeat' (see mk-heartbeat) - --nocache Do not cache results in a file - --port MySQL port; defaults to $mysql_port if not given - --mysql_ssl Add the MYSQL_CLIENT_SSL flag to mysql_connect() call - -EOF; - die($usage); -} - -# ============================================================================ -# Parse command-line arguments, in the format --arg value --arg value, and -# return them as an array ( arg => value ) -# ============================================================================ -function parse_cmdline( $args ) { - $result = array(); - $cur_arg = ''; - foreach ($args as $val) { - if (strpos($val, '--') === 0 ) { - if (strpos($val, '--no') === 0 ) { - # It's an option without an argument, but it's a --nosomething so - # it's OK. - $result[substr($val, 2)] = 1; - $cur_arg = ''; - } - elseif ($cur_arg ) { # Maybe the last --arg was an option with no arg - if ($cur_arg == '--user' || $cur_arg == '--pass' || $cur_arg == '--port' ) { - # Special case because Cacti will pass these without an arg - $cur_arg = ''; - } - else { - die("No arg: $cur_arg\n"); - } - } - else { - $cur_arg = $val; - } - } - else { - $result[substr($cur_arg, 2)] = $val; - $cur_arg = ''; - } - } - if ($cur_arg && ($cur_arg != '--user' && $cur_arg != '--pass' && $cur_arg != '--port') ) { - die("No arg: $cur_arg\n"); - } - debug($result); - return $result; -} - -# ============================================================================ -# This is the main function. Some parameters are filled in from defaults at the -# top of this file. -# ============================================================================ -function ss_get_mysql_stats( $options ) { - # Process connection options and connect to MySQL. - global $debug, $mysql_user, $mysql_pass, $heartbeat, $cache_dir, $poll_time, - $chk_options, $mysql_host, $mysql_port, $mysql_ssl; - - # Connect to MySQL. - $user = isset($options['user']) ? $options['user'] : $mysql_user; - $pass = isset($options['pass']) ? $options['pass'] : $mysql_pass; - $port = isset($options['port']) ? $options['port'] : $mysql_port; - $host = isset($options['host']) ? $options['host'] : $mysql_host; - - $heartbeat = isset($options['heartbeat']) ? $options['heartbeat'] : $heartbeat; - # If there is a port, or if it's a non-standard port, we add ":$port" to the - # hostname. - $host_str = $host - . $port != 3306 ? ":$port" : ''; - debug(array('connecting to', $host_str, $user, $pass)); - if (!extension_loaded('mysql') ) { - debug("The MySQL extension is not loaded"); - die("The MySQL extension is not loaded"); - } - if ($mysql_ssl || (isset($options['mysql_ssl']) && $options['mysql_ssl']) ) { - $conn = mysql_connect($host_str, $user, $pass, true, MYSQL_CLIENT_SSL); - } - else { - $conn = mysql_connect($host_str, $user, $pass); - } - if (!$conn ) { - die("MySQL: " . mysql_error()); - } - - $sanitized_host = str_replace(array(":", "/"), array("", "_"), $host); - $cache_file = "$cache_dir/$sanitized_host-mysql_cacti_stats.txt" - . $port != 3306 ? ":$port" : ''; - debug("Cache file is $cache_file"); - - # First, check the cache. - $fp = null; - if (!isset($options['nocache']) ) { - if ($fp = fopen($cache_file, 'a+') ) { - $locked = flock($fp, 1); # LOCK_SH - if ($locked ) { - if (filesize($cache_file) > 0 - && filectime($cache_file) + ($poll_time/2) > time() - && ($arr = file($cache_file)) - ) {# The cache file is good to use. - debug("Using the cache file"); - fclose($fp); - return $arr[0]; - } - else { - debug("The cache file seems too small or stale"); - # Escalate the lock to exclusive, so we can write to it. - if (flock($fp, 2) ) { # LOCK_EX - # We might have blocked while waiting for that LOCK_EX, and - # another process ran and updated it. Let's see if we can just - # return the data now: - if (filesize($cache_file) > 0 - && filectime($cache_file) + ($poll_time/2) > time() - && ($arr = file($cache_file)) - ) {# The cache file is good to use. - debug("Using the cache file"); - fclose($fp); - return $arr[0]; - } - ftruncate($fp, 0); # Now it's ready for writing later. - } - } - } - else { - debug("Couldn't lock the cache file, ignoring it."); - $fp = null; - } - } - } - else { - $fp = null; - debug("Couldn't open the cache file"); - } - - # Set up variables. - $status = array( # Holds the result of SHOW STATUS, SHOW INNODB STATUS, etc - # Define some indexes so they don't cause errors with += operations. - 'relay_log_space' => null, - 'binary_log_space' => null, - 'current_transactions' => null, - 'locked_transactions' => null, - 'active_transactions' => null, - 'innodb_locked_tables' => null, - 'innodb_tables_in_use' => null, - 'innodb_lock_structs' => null, - 'innodb_lock_wait_secs' => null, - 'innodb_sem_waits' => null, - 'innodb_sem_wait_time_ms'=> null, - # Values for the 'state' column from SHOW PROCESSLIST (converted to - # lowercase, with spaces replaced by underscores) - 'State_closing_tables' => null, - 'State_copying_to_tmp_table' => null, - 'State_end' => null, - 'State_freeing_items' => null, - 'State_init' => null, - 'State_locked' => null, - 'State_login' => null, - 'State_preparing' => null, - 'State_reading_from_net' => null, - 'State_sending_data' => null, - 'State_sorting_result' => null, - 'State_statistics' => null, - 'State_updating' => null, - 'State_writing_to_net' => null, - 'State_none' => null, - 'State_other' => null, # Everything not listed above - ); - - # Get SHOW STATUS and convert the name-value array into a simple - # associative array. - $result = run_query("SHOW /*!50002 GLOBAL */ STATUS", $conn); - foreach ( $result as $row ) { - $status[$row[0]] = $row[1]; - } - - # Get SHOW VARIABLES and do the same thing, adding it to the $status array. - $result = run_query("SHOW VARIABLES", $conn); - foreach ( $result as $row ) { - $status[$row[0]] = $row[1]; - } - - # Get SHOW SLAVE STATUS, and add it to the $status array. - if ($chk_options['slave'] ) { - $result = run_query("SHOW SLAVE STATUS", $conn); - $slave_status_rows_gotten = 0; - foreach ( $result as $row ) { - $slave_status_rows_gotten++; - # Must lowercase keys because different MySQL versions have different - # lettercase. - $row = array_change_key_case($row, CASE_LOWER); - $status['relay_log_space'] = $row['relay_log_space']; - $status['slave_lag'] = $row['seconds_behind_master']; - - # Check replication heartbeat, if present. - if ($heartbeat ) { - $result2 = run_query( - "SELECT GREATEST(0, UNIX_TIMESTAMP() - UNIX_TIMESTAMP(ts) - 1)" - . " AS delay FROM $heartbeat WHERE id = 1", $conn); - $slave_delay_rows_gotten = 0; - foreach ( $result2 as $row2 ) { - $slave_delay_rows_gotten++; - if ($row2 && is_array($row2) - && array_key_exists('delay', $row2) ) - { - $status['slave_lag'] = $row2['delay']; - } - else { - debug("Couldn't get slave lag from $heartbeat"); - } - } - if ($slave_delay_rows_gotten == 0 ) { - debug("Got nothing from heartbeat query"); - } - } - - # Scale slave_running and slave_stopped relative to the slave lag. - $status['slave_running'] = ($row['slave_sql_running'] == 'Yes') - ? $status['slave_lag'] : 0; - $status['slave_stopped'] = ($row['slave_sql_running'] == 'Yes') - ? 0 : $status['slave_lag']; - } - if ($slave_status_rows_gotten == 0 ) { - debug("Got nothing from SHOW SLAVE STATUS"); - } - } - - # Get SHOW MASTER STATUS, and add it to the $status array. - if ($chk_options['master'] - && array_key_exists('log_bin', $status) - && $status['log_bin'] == 'ON' - ) { # See issue #8 - $binlogs = array(0); - $result = run_query("SHOW MASTER LOGS", $conn); - foreach ( $result as $row ) { - $row = array_change_key_case($row, CASE_LOWER); - # Older versions of MySQL may not have the File_size column in the - # results of the command. Zero-size files indicate the user is - # deleting binlogs manually from disk (bad user! bad!). - if (array_key_exists('file_size', $row) && $row['file_size'] > 0 ) { - $binlogs[] = $row['file_size']; - } - } - if (count($binlogs)) { - $status['binary_log_space'] = to_int(array_sum($binlogs)); - } - } - - # Get SHOW PROCESSLIST and aggregate it by state, then add it to the array - # too. - if ($chk_options['procs'] ) { - $result = run_query('SHOW PROCESSLIST', $conn); - foreach ( $result as $row ) { - $state = $row['State']; - if (is_null($state) ) { - $state = 'NULL'; - } - if ($state == '' ) { - $state = 'none'; - } - $state = str_replace(' ', '_', strtolower($state)); - if (array_key_exists("State_$state", $status) ) { - increment($status, "State_$state", 1); - } - else { - increment($status, "State_other", 1); - } - } - } - - # Get SHOW INNODB STATUS and extract the desired metrics from it, then add - # those to the array too. - if ($chk_options['innodb'] - && array_key_exists('have_innodb', $status) - && $status['have_innodb'] == 'YES' - ) { - $result = run_query("SHOW /*!50000 ENGINE*/ INNODB STATUS", $conn); - $istatus_text = $result[0]['Status']; - $istatus_vals = get_innodb_array($istatus_text); - - # Override values from InnoDB parsing with values from SHOW STATUS, - # because InnoDB status might not have everything and the SHOW STATUS is - # to be preferred where possible. - $overrides = array( - 'Innodb_buffer_pool_pages_data' => 'database_pages', - 'Innodb_buffer_pool_pages_dirty' => 'modified_pages', - 'Innodb_buffer_pool_pages_free' => 'free_pages', - 'Innodb_buffer_pool_pages_total' => 'pool_size', - 'Innodb_data_fsyncs' => 'file_fsyncs', - 'Innodb_data_pending_reads' => 'pending_normal_aio_reads', - 'Innodb_data_pending_writes' => 'pending_normal_aio_writes', - 'Innodb_os_log_pending_fsyncs' => 'pending_log_flushes', - 'Innodb_pages_created' => 'pages_created', - 'Innodb_pages_read' => 'pages_read', - 'Innodb_pages_written' => 'pages_written', - 'Innodb_rows_deleted' => 'rows_deleted', - 'Innodb_rows_inserted' => 'rows_inserted', - 'Innodb_rows_read' => 'rows_read', - 'Innodb_rows_updated' => 'rows_updated', - ); - - # If the SHOW STATUS value exists, override... - foreach ( $overrides as $key => $val ) { - if (array_key_exists($key, $status) ) { - debug("Override $key"); - $istatus_vals[$val] = $status[$key]; - } - } - - # Now copy the values into $status. - foreach ( $istatus_vals as $key => $val ) { - $status[$key] = $istatus_vals[$key]; - } - } - - # Make table_open_cache backwards-compatible (issue 63). - if (array_key_exists('table_open_cache', $status) ) { - $status['table_cache'] = $status['table_open_cache']; - } - - # Compute how much of the key buffer is used and unflushed (issue 127). - $status['Key_buf_bytes_used'] - = big_sub($status['key_buffer_size'], - big_multiply($status['Key_blocks_unused'], - $status['key_cache_block_size'])); - $status['Key_buf_bytes_unflushed'] - = big_multiply($status['Key_blocks_not_flushed'], - $status['key_cache_block_size']); - - if (array_key_exists('unflushed_log', $status) - && $status['unflushed_log'] - ) { - # TODO: I'm not sure what the deal is here; need to debug this. But the - # unflushed log bytes spikes a lot sometimes and it's impossible for it to - # be more than the log buffer. - debug("Unflushed log: $status[unflushed_log]"); - $status['unflushed_log'] - = max($status['unflushed_log'], $status['innodb_log_buffer_size']); - } - - # Define the variables to output. I use shortened variable names so maybe - # it'll all fit in 1024 bytes for Cactid and Spine's benefit. This list must - # come right after the word MAGIC_VARS_DEFINITIONS. The Perl script parses - # it and uses it as a Perl variable. - $keys = array( - 'Key_read_requests' => 'a0', - 'Key_reads' => 'a1', - 'Key_write_requests' => 'a2', - 'Key_writes' => 'a3', - 'history_list' => 'a4', - 'innodb_transactions' => 'a5', - 'read_views' => 'a6', - 'current_transactions' => 'a7', - 'locked_transactions' => 'a8', - 'active_transactions' => 'a9', - 'pool_size' => 'aa', - 'free_pages' => 'ab', - 'database_pages' => 'ac', - 'modified_pages' => 'ad', - 'pages_read' => 'ae', - 'pages_created' => 'af', - 'pages_written' => 'ag', - 'file_fsyncs' => 'ah', - 'file_reads' => 'ai', - 'file_writes' => 'aj', - 'log_writes' => 'ak', - 'pending_aio_log_ios' => 'al', - 'pending_aio_sync_ios' => 'am', - 'pending_buf_pool_flushes' => 'an', - 'pending_chkp_writes' => 'ao', - 'pending_ibuf_aio_reads' => 'ap', - 'pending_log_flushes' => 'aq', - 'pending_log_writes' => 'ar', - 'pending_normal_aio_reads' => 'as', - 'pending_normal_aio_writes' => 'at', - 'ibuf_inserts' => 'au', - 'ibuf_merged' => 'av', - 'ibuf_merges' => 'aw', - 'spin_waits' => 'ax', - 'spin_rounds' => 'ay', - 'os_waits' => 'az', - 'rows_inserted' => 'b0', - 'rows_updated' => 'b1', - 'rows_deleted' => 'b2', - 'rows_read' => 'b3', - 'Table_locks_waited' => 'b4', - 'Table_locks_immediate' => 'b5', - 'Slow_queries' => 'b6', - 'Open_files' => 'b7', - 'Open_tables' => 'b8', - 'Opened_tables' => 'b9', - 'innodb_open_files' => 'ba', - 'open_files_limit' => 'bb', - 'table_cache' => 'bc', - 'Aborted_clients' => 'bd', - 'Aborted_connects' => 'be', - 'Max_used_connections' => 'bf', - 'Slow_launch_threads' => 'bg', - 'Threads_cached' => 'bh', - 'Threads_connected' => 'bi', - 'Threads_created' => 'bj', - 'Threads_running' => 'bk', - 'max_connections' => 'bl', - 'thread_cache_size' => 'bm', - 'Connections' => 'bn', - 'slave_running' => 'bo', - 'slave_stopped' => 'bp', - 'Slave_retried_transactions' => 'bq', - 'slave_lag' => 'br', - 'Slave_open_temp_tables' => 'bs', - 'Qcache_free_blocks' => 'bt', - 'Qcache_free_memory' => 'bu', - 'Qcache_hits' => 'bv', - 'Qcache_inserts' => 'bw', - 'Qcache_lowmem_prunes' => 'bx', - 'Qcache_not_cached' => 'by', - 'Qcache_queries_in_cache' => 'bz', - 'Qcache_total_blocks' => 'c0', - 'query_cache_size' => 'c1', - 'Questions' => 'c2', - 'Com_update' => 'c3', - 'Com_insert' => 'c4', - 'Com_select' => 'c5', - 'Com_delete' => 'c6', - 'Com_replace' => 'c7', - 'Com_load' => 'c8', - 'Com_update_multi' => 'c9', - 'Com_insert_select' => 'ca', - 'Com_delete_multi' => 'cb', - 'Com_replace_select' => 'cc', - 'Select_full_join' => 'cd', - 'Select_full_range_join' => 'ce', - 'Select_range' => 'cf', - 'Select_range_check' => 'cg', - 'Select_scan' => 'ch', - 'Sort_merge_passes' => 'ci', - 'Sort_range' => 'cj', - 'Sort_rows' => 'ck', - 'Sort_scan' => 'cl', - 'Created_tmp_tables' => 'cm', - 'Created_tmp_disk_tables' => 'cn', - 'Created_tmp_files' => 'co', - 'Bytes_sent' => 'cp', - 'Bytes_received' => 'cq', - 'innodb_log_buffer_size' => 'cr', - 'unflushed_log' => 'cs', - 'log_bytes_flushed' => 'ct', - 'log_bytes_written' => 'cu', - 'relay_log_space' => 'cv', - 'binlog_cache_size' => 'cw', - 'Binlog_cache_disk_use' => 'cx', - 'Binlog_cache_use' => 'cy', - 'binary_log_space' => 'cz', - 'innodb_locked_tables' => 'd0', - 'innodb_lock_structs' => 'd1', - 'State_closing_tables' => 'd2', - 'State_copying_to_tmp_table' => 'd3', - 'State_end' => 'd4', - 'State_freeing_items' => 'd5', - 'State_init' => 'd6', - 'State_locked' => 'd7', - 'State_login' => 'd8', - 'State_preparing' => 'd9', - 'State_reading_from_net' => 'da', - 'State_sending_data' => 'db', - 'State_sorting_result' => 'dc', - 'State_statistics' => 'dd', - 'State_updating' => 'de', - 'State_writing_to_net' => 'df', - 'State_none' => 'dg', - 'State_other' => 'dh', - 'Handler_commit' => 'di', - 'Handler_delete' => 'dj', - 'Handler_discover' => 'dk', - 'Handler_prepare' => 'dl', - 'Handler_read_first' => 'dm', - 'Handler_read_key' => 'dn', - 'Handler_read_next' => 'do', - 'Handler_read_prev' => 'dp', - 'Handler_read_rnd' => 'dq', - 'Handler_read_rnd_next' => 'dr', - 'Handler_rollback' => 'ds', - 'Handler_savepoint' => 'dt', - 'Handler_savepoint_rollback' => 'du', - 'Handler_update' => 'dv', - 'Handler_write' => 'dw', - # Some InnoDB stats added later... - 'innodb_tables_in_use' => 'dx', - 'innodb_lock_wait_secs' => 'dy', - 'hash_index_cells_total' => 'dz', - 'hash_index_cells_used' => 'e0', - 'total_mem_alloc' => 'e1', - 'additional_pool_alloc' => 'e2', - 'uncheckpointed_bytes' => 'e3', - 'ibuf_used_cells' => 'e4', - 'ibuf_free_cells' => 'e5', - 'ibuf_cell_count' => 'e6', - 'adaptive_hash_memory' => 'e7', - 'page_hash_memory' => 'e8', - 'dictionary_cache_memory' => 'e9', - 'file_system_memory' => 'ea', - 'lock_system_memory' => 'eb', - 'recovery_system_memory' => 'ec', - 'thread_hash_memory' => 'ed', - 'innodb_sem_waits' => 'ee', - 'innodb_sem_wait_time_ms' => 'ef', - 'Key_buf_bytes_unflushed' => 'eg', - 'Key_buf_bytes_used' => 'eh', - 'key_buffer_size' => 'ei', - 'Innodb_row_lock_time' => 'ej', - 'Innodb_row_lock_waits' => 'ek', - ); - - # Return the output. - $output = array(); - foreach ($keys as $key => $short ) { - # If the value isn't defined, return -1 which is lower than (most graphs') - # minimum value of 0, so it'll be regarded as a missing value. - $val = isset($status[$key]) ? $status[$key] : -1; - $output[] = "$short:$val"; - } - $result = implode(' ', $output); - if ($fp ) { - if (fwrite($fp, $result) === FALSE ) { - die("Can't write '$cache_file'"); - } - fclose($fp); - } - - return $result; - -} - -# ============================================================================ -# Given INNODB STATUS text, returns a key-value array of the parsed text. Each -# line shows a sample of the input for both standard InnoDB as you would find in -# MySQL 5.0, and XtraDB or enhanced InnoDB from Percona if applicable. Note -# that extra leading spaces are ignored due to trim(). -# ============================================================================ -function get_innodb_array($text) { - $results = array( - 'spin_waits' => array(), - 'spin_rounds' => array(), - 'os_waits' => array(), - 'pending_normal_aio_reads' => null, - 'pending_normal_aio_writes' => null, - 'pending_ibuf_aio_reads' => null, - 'pending_aio_log_ios' => null, - 'pending_aio_sync_ios' => null, - 'pending_log_flushes' => null, - 'pending_buf_pool_flushes' => null, - 'file_reads' => null, - 'file_writes' => null, - 'file_fsyncs' => null, - 'ibuf_inserts' => null, - 'ibuf_merged' => null, - 'ibuf_merges' => null, - 'log_bytes_written' => null, - 'unflushed_log' => null, - 'log_bytes_flushed' => null, - 'pending_log_writes' => null, - 'pending_chkp_writes' => null, - 'log_writes' => null, - 'pool_size' => null, - 'free_pages' => null, - 'database_pages' => null, - 'modified_pages' => null, - 'pages_read' => null, - 'pages_created' => null, - 'pages_written' => null, - 'queries_inside' => null, - 'queries_queued' => null, - 'read_views' => null, - 'rows_inserted' => null, - 'rows_updated' => null, - 'rows_deleted' => null, - 'rows_read' => null, - 'innodb_transactions' => null, - 'unpurged_txns' => null, - 'history_list' => null, - 'current_transactions' => null, - 'hash_index_cells_total' => null, - 'hash_index_cells_used' => null, - 'total_mem_alloc' => null, - 'additional_pool_alloc' => null, - 'last_checkpoint' => null, - 'uncheckpointed_bytes' => null, - 'ibuf_used_cells' => null, - 'ibuf_free_cells' => null, - 'ibuf_cell_count' => null, - 'adaptive_hash_memory' => null, - 'page_hash_memory' => null, - 'dictionary_cache_memory' => null, - 'file_system_memory' => null, - 'lock_system_memory' => null, - 'recovery_system_memory' => null, - 'thread_hash_memory' => null, - 'innodb_sem_waits' => null, - 'innodb_sem_wait_time_ms' => null, - ); - $txn_seen = FALSE; - foreach ( explode("\n", $text) as $line ) { - $line = trim($line); - $row = preg_split('/ +/', $line); - - # SEMAPHORES - if (strpos($line, 'Mutex spin waits') === 0 ) { - # Mutex spin waits 79626940, rounds 157459864, OS waits 698719 - # Mutex spin waits 0, rounds 247280272495, OS waits 316513438 - $results['spin_waits'][] = to_int($row[3]); - $results['spin_rounds'][] = to_int($row[5]); - $results['os_waits'][] = to_int($row[8]); - } - elseif (strpos($line, 'RW-shared spins') === 0 ) { - # RW-shared spins 3859028, OS waits 2100750; RW-excl spins 4641946, OS waits 1530310 - $results['spin_waits'][] = to_int($row[2]); - $results['spin_waits'][] = to_int($row[8]); - $results['os_waits'][] = to_int($row[5]); - $results['os_waits'][] = to_int($row[11]); - } - elseif (strpos($line, 'seconds the semaphore:') > 0) { - # --Thread 907205 has waited at handler/ha_innodb.cc line 7156 for 1.00 seconds the semaphore: - increment($results, 'innodb_sem_waits', 1); - increment($results, - 'innodb_sem_wait_time_ms', to_int($row[9]) * 1000); - } - - # TRANSACTIONS - elseif (strpos($line, 'Trx id counter') === 0 ) { - # The beginning of the TRANSACTIONS section: start counting - # transactions - # Trx id counter 0 1170664159 - # Trx id counter 861B144C - $results['innodb_transactions'] = make_bigint($row[3], $row[4]); - $txn_seen = TRUE; - } - elseif (strpos($line, 'Purge done for trx') === 0 ) { - # Purge done for trx's n:o < 0 1170663853 undo n:o < 0 0 - # Purge done for trx's n:o < 861B135D undo n:o < 0 - $purged_to = make_bigint($row[6], $row[7] == 'undo' ? null : $row[7]); - $results['unpurged_txns'] - = big_sub($results['innodb_transactions'], $purged_to); - } - elseif (strpos($line, 'History list length') === 0 ) { - # History list length 132 - $results['history_list'] = to_int($row[3]); - } - elseif ($txn_seen && strpos($line, '---TRANSACTION') === 0 ) { - # ---TRANSACTION 0, not started, process no 13510, OS thread id 1170446656 - increment($results, 'current_transactions', 1); - if (strpos($line, 'ACTIVE') > 0 ) { - increment($results, 'active_transactions', 1); - } - } - elseif ($txn_seen && strpos($line, '------- TRX HAS BEEN') === 0 ) { - # ------- TRX HAS BEEN WAITING 32 SEC FOR THIS LOCK TO BE GRANTED: - increment($results, 'innodb_lock_wait_secs', to_int($row[5])); - } - elseif (strpos($line, 'read views open inside InnoDB') > 0 ) { - # 1 read views open inside InnoDB - $results['read_views'] = to_int($row[0]); - } - elseif (strpos($line, 'mysql tables in use') === 0 ) { - # mysql tables in use 2, locked 2 - increment($results, 'innodb_tables_in_use', to_int($row[4])); - increment($results, 'innodb_locked_tables', to_int($row[6])); - } - elseif ($txn_seen && strpos($line, 'lock struct(s)') > 0 ) { - # 23 lock struct(s), heap size 3024, undo log entries 27 - # LOCK WAIT 12 lock struct(s), heap size 3024, undo log entries 5 - # LOCK WAIT 2 lock struct(s), heap size 368 - if (strpos($line, 'LOCK WAIT') === 0 ) { - increment($results, 'innodb_lock_structs', to_int($row[2])); - increment($results, 'locked_transactions', 1); - } - else { - increment($results, 'innodb_lock_structs', to_int($row[0])); - } - } - - # FILE I/O - elseif (strpos($line, ' OS file reads, ') > 0 ) { - # 8782182 OS file reads, 15635445 OS file writes, 947800 OS fsyncs - $results['file_reads'] = to_int($row[0]); - $results['file_writes'] = to_int($row[4]); - $results['file_fsyncs'] = to_int($row[8]); - } - elseif (strpos($line, 'Pending normal aio reads:') === 0 ) { - # Pending normal aio reads: 0, aio writes: 0, - $results['pending_normal_aio_reads'] = to_int($row[4]); - $results['pending_normal_aio_writes'] = to_int($row[7]); - } - elseif (strpos($line, 'ibuf aio reads') === 0 ) { - # ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0 - $results['pending_ibuf_aio_reads'] = to_int($row[3]); - $results['pending_aio_log_ios'] = to_int($row[6]); - $results['pending_aio_sync_ios'] = to_int($row[9]); - } - elseif (strpos($line, 'Pending flushes (fsync)') === 0 ) { - # Pending flushes (fsync) log: 0; buffer pool: 0 - $results['pending_log_flushes'] = to_int($row[4]); - $results['pending_buf_pool_flushes'] = to_int($row[7]); - } - - # INSERT BUFFER AND ADAPTIVE HASH INDEX - elseif (strpos($line, 'Ibuf for space 0: size ') === 0 ) { - # Older InnoDB code seemed to be ready for an ibuf per tablespace. It - # had two lines in the output. Newer has just one line, see below. - # Ibuf for space 0: size 1, free list len 887, seg size 889, is not empty - # Ibuf for space 0: size 1, free list len 887, seg size 889, - $results['ibuf_used_cells'] = to_int($row[5]); - $results['ibuf_free_cells'] = to_int($row[9]); - $results['ibuf_cell_count'] = to_int($row[12]); - } - elseif (strpos($line, 'Ibuf: size ') === 0 ) { - # Ibuf: size 1, free list len 4634, seg size 4636, - $results['ibuf_used_cells'] = to_int($row[2]); - $results['ibuf_free_cells'] = to_int($row[6]); - $results['ibuf_cell_count'] = to_int($row[9]); - } - elseif (strpos($line, ' merged recs, ') > 0 ) { - # 19817685 inserts, 19817684 merged recs, 3552620 merges - $results['ibuf_inserts'] = to_int($row[0]); - $results['ibuf_merged'] = to_int($row[2]); - $results['ibuf_merges'] = to_int($row[5]); - } - elseif (strpos($line, 'Hash table size ') === 0 ) { - # In some versions of InnoDB, the used cells is omitted. - # Hash table size 4425293, used cells 4229064, .... - # Hash table size 57374437, node heap has 72964 buffer(s) <-- no used cells - $results['hash_index_cells_total'] = to_int($row[3]); - $results['hash_index_cells_used'] - = strpos($line, 'used cells') > 0 ? to_int($row[6]) : '0'; - } - - # LOG - elseif (strpos($line, " log i/o's done, ") > 0 ) { - # 3430041 log i/o's done, 17.44 log i/o's/second - # 520835887 log i/o's done, 17.28 log i/o's/second, 518724686 syncs, 2980893 checkpoints - # TODO: graph syncs and checkpoints - $results['log_writes'] = to_int($row[0]); - } - elseif (strpos($line, " pending log writes, ") > 0 ) { - # 0 pending log writes, 0 pending chkp writes - $results['pending_log_writes'] = to_int($row[0]); - $results['pending_chkp_writes'] = to_int($row[4]); - } - elseif (strpos($line, "Log sequence number") === 0 ) { - # This number is NOT printed in hex in InnoDB plugin. - # Log sequence number 13093949495856 //plugin - # Log sequence number 125 3934414864 //normal - $results['log_bytes_written'] - = isset($row[4]) - ? make_bigint($row[3], $row[4]) - : to_int($row[3]); - } - elseif (strpos($line, "Log flushed up to") === 0 ) { - # This number is NOT printed in hex in InnoDB plugin. - # Log flushed up to 13093948219327 - # Log flushed up to 125 3934414864 - $results['log_bytes_flushed'] - = isset($row[5]) - ? make_bigint($row[4], $row[5]) - : to_int($row[4]); - } - elseif (strpos($line, "Last checkpoint at") === 0 ) { - # Last checkpoint at 125 3934293461 - $results['last_checkpoint'] - = isset($row[4]) - ? make_bigint($row[3], $row[4]) - : to_int($row[3]); - } - - # BUFFER POOL AND MEMORY - elseif (strpos($line, "Total memory allocated") === 0 ) { - # Total memory allocated 29642194944; in additional pool allocated 0 - $results['total_mem_alloc'] = to_int($row[3]); - $results['additional_pool_alloc'] = to_int($row[8]); - } - elseif (strpos($line, 'Adaptive hash index ') === 0 ) { - # Adaptive hash index 1538240664 (186998824 + 1351241840) - $results['adaptive_hash_memory'] = to_int($row[3]); - } - elseif (strpos($line, 'Page hash ') === 0 ) { - # Page hash 11688584 - $results['page_hash_memory'] = to_int($row[2]); - } - elseif (strpos($line, 'Dictionary cache ') === 0 ) { - # Dictionary cache 145525560 (140250984 + 5274576) - $results['dictionary_cache_memory'] = to_int($row[2]); - } - elseif (strpos($line, 'File system ') === 0 ) { - # File system 313848 (82672 + 231176) - $results['file_system_memory'] = to_int($row[2]); - } - elseif (strpos($line, 'Lock system ') === 0 ) { - # Lock system 29232616 (29219368 + 13248) - $results['lock_system_memory'] = to_int($row[2]); - } - elseif (strpos($line, 'Recovery system ') === 0 ) { - # Recovery system 0 (0 + 0) - $results['recovery_system_memory'] = to_int($row[2]); - } - elseif (strpos($line, 'Threads ') === 0 ) { - # Threads 409336 (406936 + 2400) - $results['thread_hash_memory'] = to_int($row[1]); - } - elseif (strpos($line, 'innodb_io_pattern ') === 0 ) { - # innodb_io_pattern 0 (0 + 0) - $results['innodb_io_pattern_memory'] = to_int($row[1]); - } - elseif (strpos($line, "Buffer pool size ") === 0 ) { - # The " " after size is necessary to avoid matching the wrong line: - # Buffer pool size 1769471 - # Buffer pool size, bytes 28991012864 - $results['pool_size'] = to_int($row[3]); - } - elseif (strpos($line, "Free buffers") === 0 ) { - # Free buffers 0 - $results['free_pages'] = to_int($row[2]); - } - elseif (strpos($line, "Database pages") === 0 ) { - # Database pages 1696503 - $results['database_pages'] = to_int($row[2]); - } - elseif (strpos($line, "Modified db pages") === 0 ) { - # Modified db pages 160602 - $results['modified_pages'] = to_int($row[3]); - } - elseif (strpos($line, "Pages read ahead") === 0 ) { - # Must do this BEFORE the next test, otherwise it'll get fooled by this - # line from the new plugin (see samples/innodb-015.txt): - # Pages read ahead 0.00/s, evicted without access 0.06/s - # TODO: No-op for now, see issue 134. - } - elseif (strpos($line, "Pages read") === 0 ) { - # Pages read 15240822, created 1770238, written 21705836 - $results['pages_read'] = to_int($row[2]); - $results['pages_created'] = to_int($row[4]); - $results['pages_written'] = to_int($row[6]); - } - - # ROW OPERATIONS - elseif (strpos($line, 'Number of rows inserted') === 0 ) { - # Number of rows inserted 50678311, updated 66425915, deleted 20605903, read 454561562 - $results['rows_inserted'] = to_int($row[4]); - $results['rows_updated'] = to_int($row[6]); - $results['rows_deleted'] = to_int($row[8]); - $results['rows_read'] = to_int($row[10]); - } - elseif (strpos($line, " queries inside InnoDB, ") > 0 ) { - # 0 queries inside InnoDB, 0 queries in queue - $results['queries_inside'] = to_int($row[0]); - $results['queries_queued'] = to_int($row[4]); - } - } - - foreach ( array('spin_waits', 'spin_rounds', 'os_waits') as $key ) { - $results[$key] = to_int(array_sum($results[$key])); - } - $results['unflushed_log'] - = big_sub($results['log_bytes_written'], $results['log_bytes_flushed']); - $results['uncheckpointed_bytes'] - = big_sub($results['log_bytes_written'], $results['last_checkpoint']); - - -# foreach ($results as $key => $value) { -# echo(strtolower($key).":".strtolower($value)."\n"); -# } - - - return $results; -} - - -# ============================================================================ -# Returns a bigint from two ulint or a single hex number. This is tested in -# t/mysql_stats.php and copied, without tests, to ss_get_by_ssh.php. -# ============================================================================ -function make_bigint ($hi, $lo = null) { - debug(array($hi, $lo)); - if (is_null($lo) ) { - # Assume it is a hex string representation. - return base_convert($hi, 16, 10); - } - else { - $hi = $hi ? $hi : '0'; # Handle empty-string or whatnot - $lo = $lo ? $lo : '0'; - return big_add(big_multiply($hi, 4294967296), $lo); - } -} - -# ============================================================================ -# Extracts the numbers from a string. You can't reliably do this by casting to -# an int, because numbers that are bigger than PHP's int (varies by platform) -# will be truncated. And you can't use sprintf(%u) either, because the maximum -# value that will return on some platforms is 4022289582. So this just handles -# them as a string instead. It extracts digits until it finds a non-digit and -# quits. This is tested in t/mysql_stats.php and copied, without tests, to -# ss_get_by_ssh.php. -# ============================================================================ -function to_int ( $str ) { - debug($str); - global $debug; - preg_match('{(\d+)}', $str, $m); - if (isset($m[1]) ) { - return $m[1]; - } - elseif ($debug ) { - print_r(debug_backtrace()); - } - else { - return 0; - } -} - -# ============================================================================ -# Wrap mysql_query in error-handling, and instead of returning the result, -# return an array of arrays in the result. -# ============================================================================ -function run_query($sql, $conn) { - global $debug; - debug($sql); - $result = @mysql_query($sql, $conn); - if ($debug ) { - $error = @mysql_error($conn); - if ($error ) { - debug(array($sql, $error)); - die("SQLERR $error in $sql"); - } - } - $array = array(); - while ( $row = @mysql_fetch_array($result) ) { - $array[] = $row; - } - debug(array($sql, $array)); - return $array; -} - -# ============================================================================ -# Safely increments a value that might be null. -# ============================================================================ -function increment(&$arr, $key, $howmuch) { - debug(array($key, $howmuch)); - if (array_key_exists($key, $arr) && isset($arr[$key]) ) { - $arr[$key] = big_add($arr[$key], $howmuch); - } - else { - $arr[$key] = $howmuch; - } -} - -# ============================================================================ -# Multiply two big integers together as accurately as possible with reasonable -# effort. This is tested in t/mysql_stats.php and copied, without tests, to -# ss_get_by_ssh.php. $force is for testability. -# ============================================================================ -function big_multiply ($left, $right, $force = null) { - if (function_exists("gmp_mul") && (is_null($force) || $force == 'gmp') ) { - debug(array('gmp_mul', $left, $right)); - return gmp_strval( gmp_mul( $left, $right )); - } - elseif (function_exists("bcmul") && (is_null($force) || $force == 'bc') ) { - debug(array('bcmul', $left, $right)); - return bcmul( $left, $right ); - } - else { # Or $force == 'something else' - debug(array('sprintf', $left, $right)); - return sprintf("%.0f", $left * $right); - } -} - -# ============================================================================ -# Subtract two big integers as accurately as possible with reasonable effort. -# This is tested in t/mysql_stats.php and copied, without tests, to -# ss_get_by_ssh.php. $force is for testability. -# ============================================================================ -function big_sub ($left, $right, $force = null) { - debug(array($left, $right)); - if (is_null($left) ) { $left = 0; } - if (is_null($right) ) { $right = 0; } - if (function_exists("gmp_sub") && (is_null($force) || $force == 'gmp')) { - debug(array('gmp_sub', $left, $right)); - return gmp_strval( gmp_sub( $left, $right )); - } - elseif (function_exists("bcsub") && (is_null($force) || $force == 'bc')) { - debug(array('bcsub', $left, $right)); - return bcsub( $left, $right ); - } - else { # Or $force == 'something else' - debug(array('to_int', $left, $right)); - return to_int($left - $right); - } -} - -# ============================================================================ -# Add two big integers together as accurately as possible with reasonable -# effort. This is tested in t/mysql_stats.php and copied, without tests, to -# ss_get_by_ssh.php. $force is for testability. -# ============================================================================ -function big_add ($left, $right, $force = null) { - if (is_null($left) ) { $left = 0; } - if (is_null($right) ) { $right = 0; } - if (function_exists("gmp_add") && (is_null($force) || $force == 'gmp')) { - debug(array('gmp_add', $left, $right)); - return gmp_strval( gmp_add( $left, $right )); - } - elseif (function_exists("bcadd") && (is_null($force) || $force == 'bc')) { - debug(array('bcadd', $left, $right)); - return bcadd( $left, $right ); - } - else { # Or $force == 'something else' - debug(array('to_int', $left, $right)); - return to_int($left + $right); - } -} - -# ============================================================================ -# Writes to a debugging log. -# ============================================================================ -function debug($val) { - global $debug_log; - if (!$debug_log ) { - return; - } - if ($fp = fopen($debug_log, 'a+') ) { - $trace = debug_backtrace(); - $calls = array(); - $i = 0; - $line = 0; - $file = ''; - foreach ( debug_backtrace() as $arr ) { - if ($i++ ) { - $calls[] = "$arr[function]() at $file:$line"; - } - $line = array_key_exists('line', $arr) ? $arr['line'] : '?'; - $file = array_key_exists('file', $arr) ? $arr['file'] : '?'; - } - if (!count($calls) ) { - $calls[] = "at $file:$line"; - } - fwrite($fp, date('Y-m-d h:i:s') . ' ' . implode(' <- ', $calls)); - fwrite($fp, "\n" . var_export($val, TRUE) . "\n"); - fclose($fp); - } - else { # Disable logging - print("Warning: disabling debug logging to $debug_log\n"); - $debug_log = FALSE; - } -} - -?> diff --git a/scripts/nginx-stats b/scripts/nginx-stats deleted file mode 100644 index 1cedca5ba3..0000000000 --- a/scripts/nginx-stats +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python2 -import urllib2 -import re - - -data = urllib2.urlopen('http://127.0.0.1/nginx-status').read() - -params = {} - -for line in data.split("\n"): - smallstat = re.match(r"\s?Reading:\s(.*)\sWriting:\s(.*)\sWaiting:\s(.*)$", line) - req = re.match(r"\s+(\d+)\s+(\d+)\s+(\d+)", line) - if smallstat: - params["Reading"] = smallstat.group(1) - params["Writing"] = smallstat.group(2) - params["Waiting"] = smallstat.group(3) - elif req: - params["Requests"] = req.group(3) - else: - pass - - -dataorder = [ - "Active", - "Reading", - "Writing", - "Waiting", - "Requests" - ] - - -for param in dataorder: - if param == "Active": - Active = int(params["Reading"]) + int(params["Writing"]) + int(params["Waiting"]) - print Active - else: - print params[param] diff --git a/scripts/ntp-client.php b/scripts/ntp-client.php deleted file mode 100644 index 9332791af1..0000000000 --- a/scripts/ntp-client.php +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/env php - -// - -// START SETTINGS /// -$ntpq = '/usr/sbin/ntpq'; -// Change this to true if you have clk_jitter, sys_jitter in the ntpq -c rv output -$newstats_style = false; -// END SETTINGS /// - -// DO NOT EDIT UNDER THIS LINE - -$cmd = shell_exec($ntpq." -c rv | grep '^offset'"); -if ($newstats_style) { - $cmd2 = shell_exec($ntpq." -c rv | grep '^clk_wander'"); -} -else { - $cmd2 = shell_exec($ntpq." -c rv | grep '^stability'"); -} - -$vars = array(); -$vars2 = array(); -$vars = explode(',', $cmd); -$vars2 = explode(',', $cmd2); - - -function doSNMPv2($vars, $vars2, $newstats_style) -{ - $ntp = array(); - foreach ($vars as $item => $value) { - if (!empty($value)) { - $temp = explode('=', $value); - if (isset($temp[1])) { - $ntp[trim($temp[0])] = trim($temp[1]); - } - } - } - - foreach ($vars2 as $item => $value) { - if (!empty($value)) { - $temp = explode('=', $value); - if (isset($temp[1])) { - $ntp[trim($temp[0])] = trim($temp[1]); - } - } - } - - $var = array(); - $var['offset'] = (isset($ntp['offset']) ? $ntp['offset'] : 'U'); - $var['frequency'] = (isset($ntp['frequency']) ? $ntp['frequency'] : 'U'); - if ($newstats_style) { - $var['jitter'] = (isset($ntp['clk_jitter']) ? $ntp['clk_jitter'] : 'U'); - $var['noise'] = (isset($ntp['sys_jitter']) ? $ntp['sys_jitter'] : 'U'); - $var['stability'] = (isset($ntp['clk_wander']) ? $ntp['clk_wander'] : 'U'); - } - else { - $var['jitter'] = (isset($ntp['jitter']) ? $ntp['jitter'] : 'U'); - $var['noise'] = (isset($ntp['noise']) ? $ntp['noise'] : 'U'); - $var['stability'] = (isset($ntp['stability']) ? $ntp['stability'] : 'U'); - } - - foreach ($var as $item => $count) { - echo $count."\n"; - } - -}//end doSNMPv2() - - -doSNMPv2($vars, $vars2, $newstats_style); diff --git a/scripts/ntpd-server.php b/scripts/ntpd-server.php deleted file mode 100644 index aba7b1ffea..0000000000 --- a/scripts/ntpd-server.php +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env php - - -// START SETTINGS /// -$ntpq = '/usr/sbin/ntpq'; -$ntpdc = '/usr/sbin/ntpdc'; -// Change this to true if you have clk_jitter, sys_jitter in the ntpq -c rv output -$newstats_style = false; -// END SETTINGS /// - -// DO NOT EDIT UNDER THIS LINE - -$cmd = shell_exec($ntpq.' -c rv'); -$cmd2 = shell_exec($ntpdc.' -c iostats'); -$vars = array(); -$vars2 = array(); -$vars = explode(',', $cmd); -$vars2 = str_replace(' ', '', $cmd2); -$vars2 = explode("\n", $vars2); - - -function doSNMPv2($vars, $vars2, $newstats_style) -{ - $ntpd = array(); - foreach ($vars as $item => $value) { - if (!empty($value)) { - $temp = explode('=', $value); - if (isset($temp[1])) { - $ntpd[trim($temp[0])] = trim($temp[1]); - } - } - } - - foreach ($vars2 as $item => $value) { - if (!empty($value)) { - $temp = explode(':', $value); - if (isset($temp[1])) { - $ntpd[trim($temp[0])] = trim($temp[1]); - } - } - } - - $var = array(); - $var['stratum'] = (isset($ntpd['stratum']) ? $ntpd['stratum'] : 'U'); - $var['offset'] = (isset($ntpd['offset']) ? $ntpd['offset'] : 'U'); - $var['frequency'] = (isset($ntpd['frequency']) ? $ntpd['frequency'] : 'U'); - if ($newstats_style) { - $var['jitter'] = (isset($ntpd['clk_jitter']) ? $ntpd['clk_jitter'] : 'U'); - $var['noise'] = (isset($ntpd['sys_jitter']) ? $ntpd['sys_jitter'] : 'U'); - $var['stability'] = (isset($ntpd['clk_wander']) ? $ntpd['clk_wander'] : 'U'); - } - else { - $var['jitter'] = (isset($ntpd['jitter']) ? $ntpd['jitter'] : 'U'); - $var['noise'] = (isset($ntpd['noise']) ? $ntpd['noise'] : 'U'); - $var['stability'] = (isset($ntpd['stability']) ? $ntpd['stability'] : 'U'); - } - - $var['uptime'] = (isset($ntpd['timesincereset']) ? $ntpd['timesincereset'] : 'U'); - $var['buffer_recv'] = (isset($ntpd['receivebuffers']) ? $ntpd['receivebuffers'] : 'U'); - $var['buffer_free'] = (isset($ntpd['freereceivebuffers']) ? $ntpd['freereceivebuffers'] : 'U'); - $var['buffer_used'] = (isset($ntpd['usedreceivebuffers']) ? $ntpd['usedreceivebuffers'] : 'U'); - $var['packets_drop'] = (isset($ntpd['droppedpackets']) ? $ntpd['droppedpackets'] : 'U'); - $var['packets_ignore'] = (isset($ntpd['ignoredpackets']) ? $ntpd['ignoredpackets'] : 'U'); - $var['packets_recv'] = (isset($ntpd['receivedpackets']) ? $ntpd['receivedpackets'] : 'U'); - $var['packets_sent'] = (isset($ntpd['packetssent']) ? $ntpd['packetssent'] : 'U'); - foreach ($var as $item => $count) { - echo $count."\n"; - } - -}//end doSNMPv2() - - -doSNMPv2($vars, $vars2, $newstats_style); diff --git a/scripts/postfix-queues b/scripts/postfix-queues deleted file mode 100755 index dc1951cc18..0000000000 --- a/scripts/postfix-queues +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -#Written by Valec 2006. Steal and share. -#Get postfix queue lengths - -#extend mailq /opt/observer/scripts/getmailq.sh - -QUEUES="incoming active deferred hold" - -for i in $QUEUES; do - COUNT=`qshape $i | grep TOTAL | awk '{print $2}'` - printf "$COUNT\n" -done diff --git a/scripts/powerdns.php b/scripts/powerdns.php deleted file mode 100755 index 14103124c0..0000000000 --- a/scripts/powerdns.php +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env php - - -// START SETTINGS /// -$pdnscontrol = '/usr/bin/pdns_control'; -// END SETTINGS /// - -// DO NOT EDIT UNDER THIS LINE -// -$cmd = shell_exec($pdnscontrol.' show \*'); -$vars = array(); -$vars = explode(',', $cmd); - - -function doSNMP($vars) { - foreach ($vars as $item => $value) { - $value = trim($value); - if (!empty($value)) { - echo $value."\n"; - } - } - -}//end doSNMP() - -function doSNMPv2($vars) { - $pdns = array(); - foreach ($vars as $item => $value) { - if (!empty($value)) { - $temp = explode('=', $value); - if (isset($temp[1])) { - $pdns[$temp[0]] = $temp[1]; - } - } - } - - $var = array(); - $var['corrupt-packets'] = (isset($pdns['corrupt-packets']) ? $pdns['corrupt-packets'] : 'U'); - $var['deferred-cache-inserts'] = (isset($pdns['deferred-cache-inserts']) ? $pdns['deferred-cache-inserts'] : 'U'); - $var['deferred-cache-lookup'] = (isset($pdns['deferred-cache-lookup']) ? $pdns['deferred-cache-lookup'] : 'U'); - $var['latency'] = (isset($pdns['latency']) ? $pdns['latency'] : 'U'); - $var['packetcache-hit'] = (isset($pdns['packetcache-hit']) ? $pdns['packetcache-hit'] : 'U'); - $var['packetcache-miss'] = (isset($pdns['packetcache-miss']) ? $pdns['packetcache-miss'] : 'U'); - $var['packetcache-size'] = (isset($pdns['packetcache-size']) ? $pdns['packetcache-size'] : 'U'); - $var['qsize-q'] = (isset($pdns['qsize-q']) ? $pdns['qsize-q'] : 'U'); - $var['query-cache-hit'] = (isset($pdns['query-cache-hit']) ? $pdns['query-cache-hit'] : 'U'); - $var['query-cache-miss'] = (isset($pdns['query-cache-miss']) ? $pdns['query-cache-miss'] : 'U'); - $var['recursing-answers'] = (isset($pdns['recursing-answers']) ? $pdns['recursing-answers'] : 'U'); - $var['recursing-questions'] = (isset($pdns['recursing-questions']) ? $pdns['recursing-questions'] : 'U'); - $var['servfail-packets'] = (isset($pdns['servfail-packets']) ? $pdns['servfail-packets'] : 'U'); - $var['tcp-answers'] = (isset($pdns['tcp-answers']) ? $pdns['tcp-answers'] : 'U'); - $var['tcp-queries'] = (isset($pdns['tcp-queries']) ? $pdns['tcp-queries'] : 'U'); - $var['timedout-packets'] = (isset($pdns['timedout-packets']) ? $pdns['timedout-packets'] : 'U'); - $var['udp-answers'] = (isset($pdns['udp-answers']) ? $pdns['udp-answers'] : 'U'); - $var['udp-queries'] = (isset($pdns['udp-queries']) ? $pdns['udp-queries'] : 'U'); - $var['udp4-answers'] = (isset($pdns['udp4-answers']) ? $pdns['udp4-answers'] : 'U'); - $var['udp4-queries'] = (isset($pdns['udp4-queries']) ? $pdns['udp4-queries'] : 'U'); - $var['udp6-answers'] = (isset($pdns['udp6-answers']) ? $pdns['udp6-answers'] : 'U'); - $var['udp6-queries'] = (isset($pdns['udp6-queries']) ? $pdns['udp6-queries'] : 'U'); - foreach ($var as $item => $count) { - echo $count."\n"; - } - -}//end doSNMPv2() - - -doSNMPv2($vars); diff --git a/scripts/shoutcast.default.conf b/scripts/shoutcast.default.conf deleted file mode 100644 index d38367babb..0000000000 --- a/scripts/shoutcast.default.conf +++ /dev/null @@ -1,3 +0,0 @@ -server1:8050 -server2:8000 -server2:8010 diff --git a/scripts/shoutcast.php b/scripts/shoutcast.php deleted file mode 100644 index 4c588355a2..0000000000 --- a/scripts/shoutcast.php +++ /dev/null @@ -1,122 +0,0 @@ -#!/usr/bin/env php - - /// - /////////////////////////////////////////////////////////////////////////////////////// - - - // START SETTINGS /// - - $config = "/opt/librenms/scripts/shoutcast.conf"; - $cache = "/opt/librenms/scripts/shoutcast.cache"; - - // END SETTINGS /// - - - /// - // DO NOT EDIT BENETH THIS LINE - /// - /////////////////////////////////////////////////////////////////////////////////////// - - /* Do NOT run this script through a web browser */ - if (!isset($_SERVER["argv"][0]) || isset($_SERVER['REQUEST_METHOD']) || isset($_SERVER['REMOTE_ADDR'])) { - die('This script is only meant to run at the command line.'); - } - - $cmd = (isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : ""); - - function get_data($host, $port) { - $fp = @fsockopen($host, $port, $errno, $errstr, 5); - if(!$fp) { $connect = 0; } - if (!isset($connect)) { - fputs($fp, "GET /7.html HTTP/1.0\r\n" - . "User-Agent: All In One - SHOUTcast Stats Parser" - . " (Mozilla Compatible)\r\n\r\n"); - while (!feof($fp)) { - $rawdata = fgets($fp, 1024); - } - fclose($fp); - } - preg_match('/body>(.*)<\/body/', $rawdata, $matches); - $res = explode(',', $matches[1], 7); - $res[7] = $host; - $res[8] = $port; - return $res; - } - - function get_list($config) { - if (file_exists($config)) { - $servers = file($config); - $data = array(); - foreach ($servers as $item=>$server) { - list($host, $port) = explode(":", $server, 2); - array_push($data, get_data(trim($host), trim($port))); - } - return $data; - } - } - - function doSNMPv2($vars) { - $res = array(); - foreach ($vars as $items=>$server) { - $var = array(); - $var['bitrate'] = (isset($server['5']) ? (($server['5'] / 8) * 1000) : "0"); - //$var['bitrate'] = (isset($server['5']) ? ($server['5'] * 1024) : "0"); - $var['traf_in'] = (isset($server['1']) ? ($var['bitrate'] * $server['1']) : "0"); - $var['traf_out'] = (isset($server['0']) ? ($var['bitrate'] * $server['0']) : "0"); - $var['current'] = (isset($server['0']) ? $server['0'] : "0"); - $var['status'] = (isset($server['1']) ? $server['1'] : "0"); - $var['peak'] = (isset($server['2']) ? $server['2'] : "0"); - $var['max'] = (isset($server['3']) ? $server['3'] : "0"); - $var['unique'] = (isset($server['4']) ? $server['4'] : "0"); - $host = (isset($server['7']) ? $server['7'] : "unknown"); - $port = (isset($server['8']) ? $server['8'] : "unknown"); - $tmp = $host.":".$port; - foreach ($var as $item=>$value) { - $tmp .= ";".$value; - } - array_push($res, $tmp); - } - return $res; - } - - function makeCacheFile($data, $cache) { - $fp = fopen($cache, 'w'); - foreach ($data as $item=>$value) { - fwrite($fp, $value."\n"); - } - fclose($fp); - } - - function readCacheFile($cache) { - if (file_exists($cache)) { - $data = file($cache); - foreach ($data as $item=>$value) { - echo trim($value)."\n"; - } - } - } - - if ($cmd == "makeCache") { - $servers = get_list($config); - $data = doSNMPv2($servers); - makeCacheFile($data, $cache); - } else { - readCacheFile($cache); - } - -?>