Compare commits
18 commits
Author | SHA1 | Date | |
---|---|---|---|
fc37d736f5 | |||
598eeab975 | |||
5bdf0dd8d2 | |||
c1b254ea02 | |||
c1c132199d | |||
407d99c45d | |||
195b0c5b90 | |||
af6b9daf16 | |||
97d6a3669e | |||
a49297eda7 | |||
f5bf5494c6 | |||
e396d5a4a4 | |||
45f23e6450 | |||
c2336a1cd2 | |||
9be96f3705 | |||
684be87f62 | |||
95aad74ded | |||
5a124aacec |
208
.gitignore
vendored
208
.gitignore
vendored
|
@ -1,3 +1,207 @@
|
|||
*.pyc
|
||||
.*.swp
|
||||
# ---> Python
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# ---> Vim
|
||||
# Swap
|
||||
[._]*.s[a-v][a-z]
|
||||
!*.svg # comment out if you don't need vector files
|
||||
[._]*.sw[a-p]
|
||||
[._]s[a-rt-v][a-z]
|
||||
[._]ss[a-gi-z]
|
||||
[._]sw[a-p]
|
||||
|
||||
# Session
|
||||
Session.vim
|
||||
Sessionx.vim
|
||||
|
||||
# Temporary
|
||||
.netrwhist
|
||||
*~
|
||||
# Auto-generated tag files
|
||||
tags
|
||||
# Persistent undo
|
||||
[._]*.un~
|
||||
|
||||
# ---> Perl
|
||||
!Build/
|
||||
.last_cover_stats
|
||||
/META.yml
|
||||
/META.json
|
||||
/MYMETA.*
|
||||
*.o
|
||||
*.pm.tdy
|
||||
*.bs
|
||||
|
||||
# Devel::Cover
|
||||
cover_db/
|
||||
|
||||
# Devel::NYTProf
|
||||
nytprof.out
|
||||
|
||||
# Dizt::Zilla
|
||||
/.build/
|
||||
|
||||
# Module::Build
|
||||
_build/
|
||||
Build
|
||||
Build.bat
|
||||
|
||||
# Module::Install
|
||||
inc/
|
||||
|
||||
# ExtUtils::MakeMaker
|
||||
/blib/
|
||||
/_eumm/
|
||||
/*.gz
|
||||
/Makefile
|
||||
/Makefile.old
|
||||
/MANIFEST.bak
|
||||
/pm_to_blib
|
||||
/*.zip
|
||||
|
||||
# ---> Perl6
|
||||
# Gitignore for Perl 6 (http://www.perl6.org)
|
||||
# As part of https://github.com/github/gitignore
|
||||
|
||||
# precompiled files
|
||||
.precomp
|
||||
lib/.precomp
|
||||
|
||||
|
||||
|
|
319
LICENSE
Normal file
319
LICENSE
Normal file
|
@ -0,0 +1,319 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 Lesser 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.
|
||||
|
||||
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.
|
||||
|
||||
<one line to give the program's name and an idea of what it does.>
|
||||
|
||||
Copyright (C) <yyyy> <name of author>
|
||||
|
||||
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.
|
||||
|
||||
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) year 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.
|
||||
|
||||
<signature of Ty Coon>, 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 Lesser General Public License instead
|
||||
of this License.
|
6
MyMonPlugin/__init__.py
Normal file
6
MyMonPlugin/__init__.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
__version__ = '0.0.161124'
|
||||
__all__ = ['MonitoringPlugin', 'SNMPMonitoringPlugin']
|
||||
|
||||
from .monitoringplugin import MonitoringPlugin
|
||||
from .snmpmonitoringplugin import SNMPMonitoringPlugin
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
#####################################################################
|
||||
# (c) 2010-2011 by Sven Velt and team(ix) GmbH, Nuernberg, Germany #
|
||||
# sv@teamix.net #
|
||||
# (c) 2016 by Sven Velt, Germany #
|
||||
# sven-mymonplugins@velt.biz #
|
||||
# (c) 2016- by Sven Velt, Germany #
|
||||
# sven-mymonplugins@velt.biz #
|
||||
# #
|
||||
# This file is part of "velt.biz - My Monitoring Plugins" #
|
||||
# a fork of "team(ix) Monitoring Plugins" in 2015 #
|
||||
|
@ -25,15 +25,11 @@
|
|||
# along with this file. If not, see <http://www.gnu.org/licenses/>. #
|
||||
#####################################################################
|
||||
|
||||
__version__ = '0.0.161124'
|
||||
__all__ = ['MonitoringPlugin', 'SNMPMonitoringPlugin']
|
||||
|
||||
import datetime, optparse, os, re, sys
|
||||
|
||||
try:
|
||||
import netsnmp
|
||||
except ImportError:
|
||||
pass
|
||||
import datetime
|
||||
import optparse
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
class MonitoringPlugin(object):
|
||||
|
||||
|
@ -78,12 +74,47 @@ class MonitoringPlugin(object):
|
|||
if self._cmdlineoptions_parsed:
|
||||
return
|
||||
# self.__optparser.add_option('-V', '--version', action='version', help='show version number and exit')
|
||||
self.__optparser.add_option('-v', '--verbose', dest='verbose', help='Verbosity, more for more ;-)', action='count')
|
||||
self.__optparser.add_option('-v', '--verbose', dest='verbose', help='Verbosity, more for more ;-)', default=0, action='count')
|
||||
|
||||
(self.options, self.args) = self.__optparser.parse_args()
|
||||
self._cmdlineoptions_parsed = True
|
||||
|
||||
|
||||
def args2checks(self):
|
||||
checks = []
|
||||
try:
|
||||
separator = self.options.separator
|
||||
except AttributeError:
|
||||
separator = ','
|
||||
|
||||
try:
|
||||
subseparator = self.options.subseparator
|
||||
except AttributeError:
|
||||
subseparator = '+'
|
||||
|
||||
for quad in self.args:
|
||||
quad = quad.split(separator)
|
||||
quad = (quad + ['', '', ''])[:4] # Fix length to 4, fill with ''
|
||||
|
||||
# Convert list of checks to list
|
||||
if subseparator in quad[0]:
|
||||
quad[0] = quad[0].split(subseparator)
|
||||
else:
|
||||
quad[0] = [quad[0],]
|
||||
|
||||
# Convert list of targets to list
|
||||
if subseparator in quad[1]:
|
||||
quad[1] = quad[1].split(subseparator)
|
||||
else:
|
||||
quad[1] = [quad[1],]
|
||||
|
||||
for target in quad[1]:
|
||||
for check in quad[0]:
|
||||
checks.append(tuple([check, target, quad[2], quad[3]]))
|
||||
|
||||
return(checks)
|
||||
|
||||
|
||||
def range_to_limits(self, range):
|
||||
# Check if we must negate result
|
||||
if len(range) > 0 and range[0] == '@':
|
||||
|
@ -302,7 +333,7 @@ class MonitoringPlugin(object):
|
|||
|
||||
|
||||
def seconds_to_timedelta(self, seconds):
|
||||
return datetime.timedelta(seconds=long(seconds))
|
||||
return datetime.timedelta(seconds=int(seconds))
|
||||
|
||||
|
||||
def human_to_number(self, value, total=None, unit=['',]):
|
||||
|
@ -365,8 +396,8 @@ class MonitoringPlugin(object):
|
|||
bol = 'V' + str(level) + ':' + ' ' * level
|
||||
if prefix:
|
||||
bol += '%s' % prefix
|
||||
if type(output) in [str, unicode, ]:
|
||||
print(bol + output)
|
||||
if type(output) in [str, ]:
|
||||
print(bol + output.lstrip().rstrip().replace('\n', '\n' + bol))
|
||||
elif type(output) in [list, ]:
|
||||
print('\n'.join( ['%s%s' % (bol, l) for l in output] ) )
|
||||
else:
|
||||
|
@ -423,273 +454,13 @@ class MonitoringPlugin(object):
|
|||
|
||||
# Exit program or return output line(s)
|
||||
if exit:
|
||||
print out
|
||||
print(out)
|
||||
sys.exit(returncode)
|
||||
else:
|
||||
return (returncode, out)
|
||||
|
||||
##############################################################################
|
||||
|
||||
class SNMPMonitoringPlugin(MonitoringPlugin):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
# Same as "MonitoringPlugin.__init__(*args, **kwargs)" but a little bit more flexible
|
||||
#super(MonitoringPlugin, self).__init__(*args, **kwargs)
|
||||
MonitoringPlugin.__init__(self, *args, **kwargs)
|
||||
|
||||
self.add_cmdlineoption('-H', '', 'host', 'Host to check', default='127.0.0.1')
|
||||
self.add_cmdlineoption('-P', '', 'snmpversion', 'SNMP protocol version', metavar='1', default='1')
|
||||
self.add_cmdlineoption('-C', '', 'snmpauth', 'SNMP v1/v2c community OR SNMP v3 quadruple', metavar='public', default='public')
|
||||
self.add_cmdlineoption('', '--snmpcmdlinepath', 'snmpcmdlinepath', 'Path to "snmpget" and "snmpwalk"', metavar='/usr/bin/', default='/usr/bin')
|
||||
# FIXME
|
||||
self.add_cmdlineoption('', '--nonetsnmp', 'nonetsnmp', 'Do not use NET-SNMP python bindings', action='store_true')
|
||||
# self.__optparser.add_option('', '--nonetsnmp', dest='nonetsnmp', help='Do not use NET-SNMP python bindings', action='store_true')
|
||||
|
||||
self.__SNMP_Cache = {}
|
||||
|
||||
self.__use_netsnmp = False
|
||||
self.__prepared_snmp = False
|
||||
|
||||
|
||||
def prepare_snmp(self):
|
||||
if not self._cmdlineoptions_parsed:
|
||||
self.parse_cmdlineoptions()
|
||||
|
||||
if not self.options.nonetsnmp:
|
||||
try:
|
||||
import netsnmp
|
||||
self.__use_netsnmp = True
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
if self.__use_netsnmp:
|
||||
self.verbose(1, 'Using NET-SNMP Python bindings')
|
||||
|
||||
self.SNMPGET_wrapper = self.__SNMPGET_netsnmp
|
||||
self.SNMPWALK_wrapper = self.__SNMPWALK_netsnmp
|
||||
|
||||
if self.options.snmpversion == '2c':
|
||||
self.options.snmpversion = '2'
|
||||
|
||||
else:
|
||||
self.verbose(1, 'Using NET-SNMP command line tools')
|
||||
|
||||
self.SNMPGET_wrapper = self.__SNMPGET_cmdline
|
||||
self.SNMPWALK_wrapper = self.__SNMPWALK_cmdline
|
||||
|
||||
# Building command lines
|
||||
self.__CMDLINE_get = os.path.join(self.options.snmpcmdlinepath, 'snmpget') + ' -OqevtU '
|
||||
self.__CMDLINE_walk = os.path.join(self.options.snmpcmdlinepath, 'snmpwalk') + ' -OqevtU '
|
||||
|
||||
if self.options.snmpversion in [1, 2, '1', '2', '2c']:
|
||||
if self.options.snmpversion in [2, '2']:
|
||||
self.options.snmpversion = '2c'
|
||||
self.__CMDLINE_get += ' -v' + str(self.options.snmpversion) + ' -c' + self.options.snmpauth + ' '
|
||||
self.__CMDLINE_walk += ' -v' + str(self.options.snmpversion) + ' -c' + self.options.snmpauth + ' '
|
||||
elif options.snmpversion == [3, '3']:
|
||||
# FIXME: Better error handling
|
||||
try:
|
||||
snmpauth = self.options.snmpauth.split(':')
|
||||
self.__CMDLINE_get += ' -v3 -l' + snmpauth[0] + ' -u' + snmpauth[1] + ' -a' + snmpauth[2] + ' -A' + snmpauth[3] + ' '
|
||||
self.__CMDLINE_walk += ' -v3 -l' + snmpauth[0] + ' -u' + snmpauth[1] + ' -a' + snmpauth[2] + ' -A' + snmpauth[3] + ' '
|
||||
except:
|
||||
self.back2nagios(3, 'Could not build SNMPv3 command line, need "SecLevel:SecName:AuthProtocol:AuthKey"')
|
||||
else:
|
||||
self.back2nagios(3, 'Unknown SNMP version "' + str(self.options.snmpversion) + '"')
|
||||
|
||||
self.__CMDLINE_get += ' ' + self.options.host + ' %s 2>/dev/null'
|
||||
self.__CMDLINE_walk += ' ' + self.options.host + ' %s 2>/dev/null'
|
||||
|
||||
self.verbose(3, 'Using commandline: ' + self.__CMDLINE_get)
|
||||
self.verbose(3, 'Using commandline: ' + self.__CMDLINE_walk)
|
||||
|
||||
# Test if snmp(get|walk) are executable
|
||||
for fpath in [self.__CMDLINE_get, self.__CMDLINE_walk,]:
|
||||
fpath = fpath.split(' ',1)[0]
|
||||
if not( os.path.exists(fpath) and os.path.isfile(fpath) and os.access(fpath, os.X_OK) ):
|
||||
self.back2nagios(3, 'Could not execute "%s"' % fpath)
|
||||
|
||||
self.__prepared_snmp = True
|
||||
|
||||
|
||||
def find_index_for_value(self, list_indexes, list_values, wanted):
|
||||
self.verbose(2, 'Look for "' + str(wanted) + '"')
|
||||
|
||||
index = None
|
||||
|
||||
if len(list_indexes) != len(list_values):
|
||||
self.verbose(1, 'Length of index and value lists do not match!')
|
||||
return None
|
||||
|
||||
try:
|
||||
index = list_values.index(wanted)
|
||||
index = list_indexes[index]
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
if index:
|
||||
self.verbose(2, 'Found "' + str(wanted) +'" with index "' + str(index) + '"')
|
||||
else:
|
||||
self.verbose(2, 'Nothing found!')
|
||||
|
||||
return index
|
||||
|
||||
|
||||
def find_in_table(self, oid_index, oid_values, wanted):
|
||||
self.verbose(2, 'Look for "' + str(wanted) + '" in "' + str(oid_values) +'"')
|
||||
|
||||
index = None
|
||||
indexes = list(self.SNMPWALK(oid_index))
|
||||
values = list(self.SNMPWALK(oid_values))
|
||||
|
||||
if len(indexes) != len(values):
|
||||
self.back2nagios(3, 'Different data from 2 SNMP Walks!')
|
||||
|
||||
return self.find_index_for_value(indexes, values, wanted)
|
||||
|
||||
|
||||
def SNMPGET(self, baseoid, idx=None, exitonerror=True):
|
||||
if type(baseoid) in (list, tuple):
|
||||
if idx not in ['', None]:
|
||||
idx = '.' + str(idx)
|
||||
else:
|
||||
idx = ''
|
||||
|
||||
if self.options.snmpversion in [1, '1']:
|
||||
value_low = long(self.SNMPGET_wrapper(baseoid[1] + idx, exitonerror=exitonerror))
|
||||
if value_low < 0L:
|
||||
value_low += 2 ** 32
|
||||
|
||||
value_hi = long(self.SNMPGET_wrapper(baseoid[2] + idx, exitonerror=exitonerror))
|
||||
if value_hi < 0L:
|
||||
value_hi += 2 ** 32
|
||||
|
||||
return value_hi * 2L ** 32L + value_low
|
||||
|
||||
elif self.options.snmpversion in [2, 3, '2', '2c', '3']:
|
||||
return long(self.SNMPGET_wrapper(baseoid[0] + idx, exitonerror=exitonerror))
|
||||
|
||||
elif type(baseoid) in (str, ) and idx != None:
|
||||
return self.SNMPGET_wrapper(baseoid + '.' + str(idx), exitonerror=exitonerror)
|
||||
else:
|
||||
return self.SNMPGET_wrapper(baseoid, exitonerror=exitonerror)
|
||||
|
||||
|
||||
def SNMPWALK(self, baseoid, exitonerror=True):
|
||||
return self.SNMPWALK_wrapper(baseoid, exitonerror=exitonerror)
|
||||
|
||||
|
||||
def __SNMPGET_netsnmp(self, oid, exitonerror=True):
|
||||
if not self.__prepared_snmp:
|
||||
self.prepare_snmp()
|
||||
|
||||
if oid in self.__SNMP_Cache:
|
||||
self.verbose(2, "%40s -> (CACHED) %s" % (oid, self.__SNMP_Cache[oid]))
|
||||
return self.__SNMP_Cache[oid]
|
||||
|
||||
result = netsnmp.snmpget(oid, Version=int(self.options.snmpversion), DestHost=self.options.host, Community=self.options.snmpauth)[0]
|
||||
|
||||
if not result:
|
||||
if exitonerror:
|
||||
self.back2nagios(3, 'Timeout or no answer from "%s" looking for "%s"' % (self.options.host, oid))
|
||||
else:
|
||||
return None
|
||||
|
||||
self.__SNMP_Cache[oid] = result
|
||||
|
||||
self.verbose(2, "%40s -> %s" % (oid, result))
|
||||
return result
|
||||
|
||||
|
||||
def __SNMPWALK_netsnmp(self, oid, exitonerror=True):
|
||||
if not self.__prepared_snmp:
|
||||
self.prepare_snmp()
|
||||
|
||||
if oid in self.__SNMP_Cache:
|
||||
self.verbose(2, "%40s -> (CACHED) %s" % (oid, self.__SNMP_Cache[oid]))
|
||||
return self.__SNMP_Cache[oid]
|
||||
|
||||
result = netsnmp.snmpwalk(oid, Version=int(self.options.snmpversion), DestHost=self.options.host, Community=self.options.snmpauth)
|
||||
|
||||
if not result:
|
||||
if exitonerror:
|
||||
self.back2nagios(3, 'Timeout or no answer from "%s" looking for "%s"' % (self.options.host, oid))
|
||||
else:
|
||||
return None
|
||||
|
||||
self.__SNMP_Cache[oid] = result
|
||||
|
||||
self.verbose(2, "%40s -> %s" % (oid, result))
|
||||
return result
|
||||
|
||||
|
||||
def __SNMPGET_cmdline(self, oid, exitonerror=True):
|
||||
if not self.__prepared_snmp:
|
||||
self.prepare_snmp()
|
||||
|
||||
cmdline = self.__CMDLINE_get % oid
|
||||
self.verbose(2, cmdline)
|
||||
|
||||
if oid in self.__SNMP_Cache:
|
||||
self.verbose(2, "(CACHED) %s" % (self.__SNMP_Cache[oid]))
|
||||
return self.__SNMP_Cache[oid]
|
||||
|
||||
cmd = os.popen(cmdline)
|
||||
out = cmd.readline().rstrip().replace('"','')
|
||||
retcode = cmd.close()
|
||||
|
||||
if retcode:
|
||||
if not exitonerror:
|
||||
return None
|
||||
if retcode == 256:
|
||||
self.back2nagios(3, 'Timeout - no SNMP answer from "' + self.options.host + '"')
|
||||
elif retcode ==512:
|
||||
self.back2nagios(3, 'OID "' + oid + '" not found')
|
||||
else:
|
||||
self.back2nagios(3, 'Unknown error code "' + str(retcode) + '" from command line utils')
|
||||
|
||||
self.__SNMP_Cache[oid] = out
|
||||
|
||||
self.verbose(1, out)
|
||||
return out
|
||||
|
||||
|
||||
def __SNMPWALK_cmdline(self, oid, exitonerror=True):
|
||||
if not self.__prepared_snmp:
|
||||
self.prepare_snmp()
|
||||
|
||||
cmdline = self.__CMDLINE_walk % oid
|
||||
self.verbose(2, cmdline)
|
||||
|
||||
if oid in self.__SNMP_Cache:
|
||||
self.verbose(2, "(CACHED) %s" % (self.__SNMP_Cache[oid]))
|
||||
return self.__SNMP_Cache[oid]
|
||||
|
||||
cmd = os.popen(cmdline)
|
||||
out = cmd.readlines()
|
||||
retcode = cmd.close()
|
||||
|
||||
if retcode:
|
||||
if not exitonerror:
|
||||
return None
|
||||
if retcode == 256:
|
||||
self.back2nagios(3, 'Timeout - no SNMP answer from "' + self.options.host + '"')
|
||||
elif retcode ==512:
|
||||
self.back2nagios(3, 'OID "' + oid + '" not found')
|
||||
else:
|
||||
self.back2nagios(3, 'Unknown error code "' + str(retcode) + '" from command line utils')
|
||||
|
||||
for line in range(0,len(out)):
|
||||
out[line] = out[line].rstrip().replace('"','')
|
||||
|
||||
self.__SNMP_Cache[oid] = out
|
||||
|
||||
self.verbose(1, str(out))
|
||||
return out
|
||||
|
||||
|
||||
##############################################################################
|
||||
|
||||
def main():
|
||||
myplugin = MonitoringPlugin(pluginname='check_testplugin', tagforstatusline='TEST')
|
||||
|
||||
|
@ -703,14 +474,14 @@ def main():
|
|||
pprint(myplugin.back2nagios(3, 'Nr. 13: Exit Code UNKNOWN', exit=False) )
|
||||
|
||||
ret = myplugin.back2nagios(0, 'Nr. 20: Plugin with string-based multiline output', 'Line 2\nLine 3\nLine4', exit=False)
|
||||
print ret[1]
|
||||
print 'Returncode: ' + str(ret[0])
|
||||
print(ret[1])
|
||||
print('Returncode: ' + str(ret[0]))
|
||||
ret = myplugin.back2nagios(0, 'Nr. 21: Plugin with list-based multiline output', ['Line 2', 'Line 3', 'Line4'], exit=False)
|
||||
print ret[1]
|
||||
print 'Returncode: ' + str(ret[0])
|
||||
print(ret[1])
|
||||
print('Returncode: ' + str(ret[0]))
|
||||
ret = myplugin.back2nagios(0, 'Nr. 22: Plugin with tuple-based multiline output', ('Line 2', 'Line 3', 'Line4'), exit=False)
|
||||
print ret[1]
|
||||
print 'Returncode: ' + str(ret[0])
|
||||
print(ret[1])
|
||||
print('Returncode: ' + str(ret[0]))
|
||||
|
||||
myplugin.add_performancedata('Val1', 42, '')
|
||||
myplugin.add_performancedata('Val2', 23, 'c', warn=10, crit=20, min=0, max=100)
|
||||
|
@ -723,4 +494,4 @@ def main():
|
|||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
#vim: ts=4 sw=4
|
||||
#vim: ts=4 sw=4 sts=4
|
289
MyMonPlugin/snmpmonitoringplugin.py
Normal file
289
MyMonPlugin/snmpmonitoringplugin.py
Normal file
|
@ -0,0 +1,289 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
#####################################################################
|
||||
# (c) 2010-2011 by Sven Velt and team(ix) GmbH, Nuernberg, Germany #
|
||||
# sv@teamix.net #
|
||||
# (c) 2016- by Sven Velt, Germany #
|
||||
# sven-mymonplugins@velt.biz #
|
||||
# #
|
||||
# This file is part of "velt.biz - My Monitoring Plugins" #
|
||||
# a fork of "team(ix) Monitoring Plugins" in 2015 #
|
||||
# URL: https://gogs.velt.biz/velt.biz/MyMonPlugins/ #
|
||||
# #
|
||||
# This file 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 file 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 file. If not, see <http://www.gnu.org/licenses/>. #
|
||||
#####################################################################
|
||||
|
||||
from .monitoringplugin import MonitoringPlugin
|
||||
|
||||
import os
|
||||
|
||||
class SNMPMonitoringPlugin(MonitoringPlugin):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
# Same as "MonitoringPlugin.__init__(*args, **kwargs)" but a little bit more flexible
|
||||
#super(MonitoringPlugin, self).__init__(*args, **kwargs)
|
||||
MonitoringPlugin.__init__(self, *args, **kwargs)
|
||||
|
||||
self.add_cmdlineoption('-H', '', 'host', 'Host to check', default='127.0.0.1')
|
||||
self.add_cmdlineoption('-P', '', 'snmpversion', 'SNMP protocol version', metavar='1', default='1')
|
||||
self.add_cmdlineoption('-C', '', 'snmpauth', 'SNMP v1/v2c community OR SNMP v3 quadruple', metavar='public', default='public')
|
||||
self.add_cmdlineoption('', '--snmpcmdlinepath', 'snmpcmdlinepath', 'Path to "snmpget" and "snmpwalk"', metavar='/usr/bin/', default='/usr/bin')
|
||||
# FIXME
|
||||
self.add_cmdlineoption('', '--nonetsnmp', 'nonetsnmp', 'Do not use NET-SNMP python bindings', action='store_true')
|
||||
# self.__optparser.add_option('', '--nonetsnmp', dest='nonetsnmp', help='Do not use NET-SNMP python bindings', action='store_true')
|
||||
|
||||
self.__SNMP_Cache = {}
|
||||
|
||||
self.__use_netsnmp = False
|
||||
self.__prepared_snmp = False
|
||||
|
||||
|
||||
def prepare_snmp(self):
|
||||
if not self._cmdlineoptions_parsed:
|
||||
self.parse_cmdlineoptions()
|
||||
|
||||
if not self.options.nonetsnmp:
|
||||
try:
|
||||
import netsnmp
|
||||
self.__use_netsnmp = True
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
if self.__use_netsnmp:
|
||||
self.verbose(1, 'Using NET-SNMP Python bindings')
|
||||
|
||||
self.SNMPGET_wrapper = self.__SNMPGET_netsnmp
|
||||
self.SNMPWALK_wrapper = self.__SNMPWALK_netsnmp
|
||||
|
||||
if self.options.snmpversion == '2c':
|
||||
self.options.snmpversion = '2'
|
||||
|
||||
else:
|
||||
self.verbose(1, 'Using NET-SNMP command line tools')
|
||||
|
||||
self.SNMPGET_wrapper = self.__SNMPGET_cmdline
|
||||
self.SNMPWALK_wrapper = self.__SNMPWALK_cmdline
|
||||
|
||||
# Building command lines
|
||||
self.__CMDLINE_get = os.path.join(self.options.snmpcmdlinepath, 'snmpget') + ' -OqevtU '
|
||||
self.__CMDLINE_walk = os.path.join(self.options.snmpcmdlinepath, 'snmpwalk') + ' -OqevtU '
|
||||
|
||||
if self.options.snmpversion in [1, 2, '1', '2', '2c']:
|
||||
if self.options.snmpversion in [2, '2']:
|
||||
self.options.snmpversion = '2c'
|
||||
self.__CMDLINE_get += ' -v' + str(self.options.snmpversion) + ' -c' + self.options.snmpauth + ' '
|
||||
self.__CMDLINE_walk += ' -v' + str(self.options.snmpversion) + ' -c' + self.options.snmpauth + ' '
|
||||
elif options.snmpversion == [3, '3']:
|
||||
# FIXME: Better error handling
|
||||
try:
|
||||
snmpauth = self.options.snmpauth.split(':')
|
||||
self.__CMDLINE_get += ' -v3 -l' + snmpauth[0] + ' -u' + snmpauth[1] + ' -a' + snmpauth[2] + ' -A' + snmpauth[3] + ' '
|
||||
self.__CMDLINE_walk += ' -v3 -l' + snmpauth[0] + ' -u' + snmpauth[1] + ' -a' + snmpauth[2] + ' -A' + snmpauth[3] + ' '
|
||||
except:
|
||||
self.back2nagios(3, 'Could not build SNMPv3 command line, need "SecLevel:SecName:AuthProtocol:AuthKey"')
|
||||
else:
|
||||
self.back2nagios(3, 'Unknown SNMP version "' + str(self.options.snmpversion) + '"')
|
||||
|
||||
self.__CMDLINE_get += ' ' + self.options.host + ' %s 2>/dev/null'
|
||||
self.__CMDLINE_walk += ' ' + self.options.host + ' %s 2>/dev/null'
|
||||
|
||||
self.verbose(3, 'Using commandline: ' + self.__CMDLINE_get)
|
||||
self.verbose(3, 'Using commandline: ' + self.__CMDLINE_walk)
|
||||
|
||||
# Test if snmp(get|walk) are executable
|
||||
for fpath in [self.__CMDLINE_get, self.__CMDLINE_walk,]:
|
||||
fpath = fpath.split(' ',1)[0]
|
||||
if not( os.path.exists(fpath) and os.path.isfile(fpath) and os.access(fpath, os.X_OK) ):
|
||||
self.back2nagios(3, 'Could not execute "%s"' % fpath)
|
||||
|
||||
self.__prepared_snmp = True
|
||||
|
||||
|
||||
def find_index_for_value(self, list_indexes, list_values, wanted):
|
||||
self.verbose(2, 'Look for "' + str(wanted) + '"')
|
||||
|
||||
index = None
|
||||
|
||||
if len(list_indexes) != len(list_values):
|
||||
self.verbose(1, 'Length of index and value lists do not match!')
|
||||
return None
|
||||
|
||||
try:
|
||||
index = list_values.index(wanted)
|
||||
index = list_indexes[index]
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
if index:
|
||||
self.verbose(2, 'Found "' + str(wanted) +'" with index "' + str(index) + '"')
|
||||
else:
|
||||
self.verbose(2, 'Nothing found!')
|
||||
|
||||
return index
|
||||
|
||||
|
||||
def find_in_table(self, oid_index, oid_values, wanted):
|
||||
self.verbose(2, 'Look for "' + str(wanted) + '" in "' + str(oid_values) +'"')
|
||||
|
||||
index = None
|
||||
indexes = list(self.SNMPWALK(oid_index))
|
||||
values = list(self.SNMPWALK(oid_values))
|
||||
|
||||
if len(indexes) != len(values):
|
||||
self.back2nagios(3, 'Different data from 2 SNMP Walks!')
|
||||
|
||||
return self.find_index_for_value(indexes, values, wanted)
|
||||
|
||||
|
||||
def SNMPGET(self, baseoid, idx=None, exitonerror=True):
|
||||
if type(baseoid) in (list, tuple):
|
||||
if idx not in ['', None]:
|
||||
idx = '.' + str(idx)
|
||||
else:
|
||||
idx = ''
|
||||
|
||||
if self.options.snmpversion in [1, '1']:
|
||||
value_low = int(self.SNMPGET_wrapper(baseoid[1] + idx, exitonerror=exitonerror))
|
||||
if value_low < 0:
|
||||
value_low += 2 ** 32
|
||||
|
||||
value_hi = int(self.SNMPGET_wrapper(baseoid[2] + idx, exitonerror=exitonerror))
|
||||
if value_hi < 0:
|
||||
value_hi += 2 ** 32
|
||||
|
||||
return value_hi * 2 ** 32 + value_low
|
||||
|
||||
elif self.options.snmpversion in [2, 3, '2', '2c', '3']:
|
||||
return int(self.SNMPGET_wrapper(baseoid[0] + idx, exitonerror=exitonerror))
|
||||
|
||||
elif type(baseoid) in (str, ) and idx != None:
|
||||
return self.SNMPGET_wrapper(baseoid + '.' + str(idx), exitonerror=exitonerror)
|
||||
else:
|
||||
return self.SNMPGET_wrapper(baseoid, exitonerror=exitonerror)
|
||||
|
||||
|
||||
def SNMPWALK(self, baseoid, exitonerror=True):
|
||||
return self.SNMPWALK_wrapper(baseoid, exitonerror=exitonerror)
|
||||
|
||||
|
||||
def __SNMPGET_netsnmp(self, oid, exitonerror=True):
|
||||
if not self.__prepared_snmp:
|
||||
self.prepare_snmp()
|
||||
|
||||
if oid in self.__SNMP_Cache:
|
||||
self.verbose(2, "%40s -> (CACHED) %s" % (oid, self.__SNMP_Cache[oid]))
|
||||
return self.__SNMP_Cache[oid]
|
||||
|
||||
result = netsnmp.snmpget(oid, Version=int(self.options.snmpversion), DestHost=self.options.host, Community=self.options.snmpauth)[0]
|
||||
|
||||
if not result:
|
||||
if exitonerror:
|
||||
self.back2nagios(3, 'Timeout or no answer from "%s" looking for "%s"' % (self.options.host, oid))
|
||||
else:
|
||||
return None
|
||||
|
||||
self.__SNMP_Cache[oid] = result
|
||||
|
||||
self.verbose(2, "%40s -> %s" % (oid, result))
|
||||
return result
|
||||
|
||||
|
||||
def __SNMPWALK_netsnmp(self, oid, exitonerror=True):
|
||||
if not self.__prepared_snmp:
|
||||
self.prepare_snmp()
|
||||
|
||||
if oid in self.__SNMP_Cache:
|
||||
self.verbose(2, "%40s -> (CACHED) %s" % (oid, self.__SNMP_Cache[oid]))
|
||||
return self.__SNMP_Cache[oid]
|
||||
|
||||
result = netsnmp.snmpwalk(oid, Version=int(self.options.snmpversion), DestHost=self.options.host, Community=self.options.snmpauth)
|
||||
|
||||
if not result:
|
||||
if exitonerror:
|
||||
self.back2nagios(3, 'Timeout or no answer from "%s" looking for "%s"' % (self.options.host, oid))
|
||||
else:
|
||||
return None
|
||||
|
||||
self.__SNMP_Cache[oid] = result
|
||||
|
||||
self.verbose(2, "%40s -> %s" % (oid, result))
|
||||
return result
|
||||
|
||||
|
||||
def __SNMPGET_cmdline(self, oid, exitonerror=True):
|
||||
if not self.__prepared_snmp:
|
||||
self.prepare_snmp()
|
||||
|
||||
cmdline = self.__CMDLINE_get % oid
|
||||
self.verbose(2, cmdline)
|
||||
|
||||
if oid in self.__SNMP_Cache:
|
||||
self.verbose(2, "(CACHED) %s" % (self.__SNMP_Cache[oid]))
|
||||
return self.__SNMP_Cache[oid]
|
||||
|
||||
cmd = os.popen(cmdline)
|
||||
out = cmd.readline().rstrip().replace('"','')
|
||||
retcode = cmd.close()
|
||||
|
||||
if retcode:
|
||||
if not exitonerror:
|
||||
return None
|
||||
if retcode == 256:
|
||||
self.back2nagios(3, 'Timeout - no SNMP answer from "' + self.options.host + '"')
|
||||
elif retcode ==512:
|
||||
self.back2nagios(3, 'OID "' + oid + '" not found')
|
||||
else:
|
||||
self.back2nagios(3, 'Unknown error code "' + str(retcode) + '" from command line utils')
|
||||
|
||||
self.__SNMP_Cache[oid] = out
|
||||
|
||||
self.verbose(1, out)
|
||||
return out
|
||||
|
||||
|
||||
def __SNMPWALK_cmdline(self, oid, exitonerror=True):
|
||||
if not self.__prepared_snmp:
|
||||
self.prepare_snmp()
|
||||
|
||||
cmdline = self.__CMDLINE_walk % oid
|
||||
self.verbose(2, cmdline)
|
||||
|
||||
if oid in self.__SNMP_Cache:
|
||||
self.verbose(2, "(CACHED) %s" % (self.__SNMP_Cache[oid]))
|
||||
return self.__SNMP_Cache[oid]
|
||||
|
||||
cmd = os.popen(cmdline)
|
||||
out = cmd.readlines()
|
||||
retcode = cmd.close()
|
||||
|
||||
if retcode:
|
||||
if not exitonerror:
|
||||
return None
|
||||
if retcode == 256:
|
||||
self.back2nagios(3, 'Timeout - no SNMP answer from "' + self.options.host + '"')
|
||||
elif retcode ==512:
|
||||
self.back2nagios(3, 'OID "' + oid + '" not found')
|
||||
else:
|
||||
self.back2nagios(3, 'Unknown error code "' + str(retcode) + '" from command line utils')
|
||||
|
||||
for line in range(0,len(out)):
|
||||
out[line] = out[line].rstrip().replace('"','')
|
||||
|
||||
self.__SNMP_Cache[oid] = out
|
||||
|
||||
self.verbose(1, str(out))
|
||||
return out
|
||||
|
||||
|
28
README.md
28
README.md
|
@ -1,30 +1,16 @@
|
|||
MyMonPlugins
|
||||
# MyMonPlugins
|
||||
|
||||
This is the old master branch! New development takes place in the "main" branch!
|
||||
|
||||
Default branch will change in the near future.
|
||||
Python modules to simplify complex Naemon/Icinga/Nagios plugin development
|
||||
|
||||
---
|
||||
|
||||
(c) 2010-2011 by Sven Velt and team(ix) GmbH, Nuernberg, Germany
|
||||
sv@teamix.net
|
||||
(c) 2016 by Sven Velt, Germany
|
||||
sven-mymonplugins@velt.biz
|
||||
(c) 2016-2020 by Sven Velt, Germany
|
||||
sven-mymonplugins@velt.biz
|
||||
|
||||
This file is part of "velt.biz - My Monitoring Plugins"
|
||||
a fork of "team(ix) Monitoring Plugins" in 2015
|
||||
URL: https://gogs.velt.biz/velt.biz/MyMonPlugins/
|
||||
"velt.biz - My Monitoring Plugins" is a fork of "team(ix) Monitoring Plugins" in
|
||||
2015
|
||||
|
||||
This file 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 file 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 file. If not, see <http://www.gnu.org/licenses/>.
|
||||
URL: https://git.velt.biz/Monitoring/MyMonPlugins/
|
||||
|
||||
|
|
254
check_apaches.py
254
check_apaches.py
|
@ -1,11 +1,11 @@
|
|||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
#####################################################################
|
||||
# (c) 2007-2011 by Sven Velt and team(ix) GmbH, Nuernberg, Germany #
|
||||
# sv@teamix.net #
|
||||
# (c) 2016 by Sven Velt, Germany #
|
||||
# sven-mymonplugins@velt.biz #
|
||||
# (c) 2016- by Sven Velt, Germany #
|
||||
# sven-mymonplugins@velt.biz #
|
||||
# #
|
||||
# This file is part of "velt.biz - My Monitoring Plugins" #
|
||||
# a fork of "team(ix) Monitoring Plugins" in 2015 #
|
||||
|
@ -28,102 +28,196 @@
|
|||
import os
|
||||
import re
|
||||
import sys
|
||||
import urllib2
|
||||
import urllib.request, urllib.error, urllib.parse
|
||||
|
||||
try:
|
||||
from monitoringplugin import MonitoringPlugin
|
||||
from MyMonPlugin import MonitoringPlugin
|
||||
except ImportError:
|
||||
print '=========================='
|
||||
print 'AIKS! Python import error!'
|
||||
print '==========================\n'
|
||||
print 'Could not find "monitoringplugin.py"!\n'
|
||||
print 'Did you download "%s"' % os.path.basename(sys.argv[0])
|
||||
print 'without "monitoringplugin.py"?\n'
|
||||
print 'Please go back to'
|
||||
print 'https://gogs.velt.biz/velt.biz/MyMonPlugins and download it,'
|
||||
print 'or even better:'
|
||||
print 'get a full archive at http://gogs.velt.biz/velt.biz/MyMonPlugins/releases'
|
||||
print 'or a master snapshot at http://gogs.velt.biz/velt.biz/MyMonPlugins/archive/master.tar.gz\n'
|
||||
print('==========================')
|
||||
print('AIKS! Python import error!')
|
||||
print('==========================\n')
|
||||
print('Could not find class "MonitoringPlugin"!\n')
|
||||
print('Did you download "%s"' % os.path.basename(sys.argv[0]))
|
||||
print('without "MyMonPlugin/"?\n')
|
||||
print('Please go back to')
|
||||
print('https://gogs.velt.biz/velt.biz/MyMonPlugins and:')
|
||||
print('- get a full archive at http://gogs.velt.biz/velt.biz/MyMonPlugins/releases')
|
||||
print('- or a master snapshot at http://gogs.velt.biz/velt.biz/MyMonPlugins/archive/master.tar.gz\n')
|
||||
sys.exit(127)
|
||||
|
||||
############################################################
|
||||
|
||||
plugin = MonitoringPlugin(pluginname='check_apaches', tagforstatusline='APACHE', description='Check Apache workers', version='0.1')
|
||||
class CheckApaches(MonitoringPlugin):
|
||||
|
||||
plugin.add_cmdlineoption('-H', '', 'host', 'Hostname/IP to check', default='localhost')
|
||||
plugin.add_cmdlineoption('-p', '', 'port', 'port to connect', default=None)
|
||||
plugin.add_cmdlineoption('-P', '', 'proto', 'protocol to use', default='http')
|
||||
plugin.add_cmdlineoption('-u', '', 'url', 'path to "server-status"', default='/server-status')
|
||||
plugin.add_cmdlineoption('-a', '', 'httpauth', 'HTTP Username and Password, separated by ":"')
|
||||
plugin.add_cmdlineoption('-w', '', 'warn', 'warning thresold', default='20')
|
||||
plugin.add_cmdlineoption('-c', '', 'crit', 'warning thresold', default='50')
|
||||
plugin.add_cmdlineoption('', '--statistics', 'statistics', 'Output worker statistics', action='store_true')
|
||||
apache_busy = None
|
||||
apache_idle = None
|
||||
apache_scoreboard = None
|
||||
apache_states = None
|
||||
data = None
|
||||
url = None
|
||||
|
||||
plugin.parse_cmdlineoptions()
|
||||
def analyze(self):
|
||||
try:
|
||||
self.apache_idle = int(re.search('Idle(?:Workers|Servers): (\d+)\n', self.data).group(1))
|
||||
self.apache_busy = int(re.search('Busy(?:Workers|Servers): (\d+)\n', self.data).group(1))
|
||||
except:
|
||||
self.back2nagios(2, 'Could not analyze data!')
|
||||
|
||||
if plugin.options.proto not in ['http', 'https']:
|
||||
plugin.back2nagios(3, 'Unknown protocol "' + plugin.options.proto + '"')
|
||||
self.apache_scoreboard = re.search('Scoreboard: (.*)\n', self.data)
|
||||
if self.apache_scoreboard:
|
||||
self.apache_states = {'_':0, 'S':0, 'R':0, 'W':0, 'K':0, 'D':0, 'C':0, 'L':0, 'G':0, 'I':0, '.':0,}
|
||||
for worker in self.apache_scoreboard.group(1):
|
||||
self.apache_states[worker] += 1
|
||||
pass
|
||||
|
||||
if not plugin.options.port:
|
||||
if plugin.options.proto == 'https':
|
||||
plugin.options.port = '443'
|
||||
else:
|
||||
plugin.options.port = '80'
|
||||
|
||||
url = plugin.options.proto + '://' + plugin.options.host + ':' + plugin.options.port + '/' + plugin.options.url + '?auto'
|
||||
plugin.verbose(1, 'Status URL: ' + url)
|
||||
def check_slots(self, target='open', warn='', crit=''):
|
||||
pd = {'label':'slots_open', 'unit':'', 'warn':warn, 'crit': crit, 'min':0}
|
||||
|
||||
if plugin.options.httpauth:
|
||||
httpauth = plugin.options.httpauth.split(':')
|
||||
if len(httpauth) != 2:
|
||||
plugin.back2nagios(3, 'Wrong format of authentication data! Need "USERNAME:PASSWORD", got "' + plugin.options.httpauth + '"')
|
||||
passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
|
||||
passman.add_password(None, url, httpauth[0], httpauth[1])
|
||||
authhandler = urllib2.HTTPBasicAuthHandler(passman)
|
||||
opener = urllib2.build_opener(authhandler)
|
||||
urllib2.install_opener(opener)
|
||||
if target == 'open':
|
||||
returncode = self.value_wc_to_returncode(self.apache_states['.'], warn, crit)
|
||||
output = '%d open slots' % self.apache_states['.']
|
||||
pd['value'] = self.apache_states['.']
|
||||
pd['label'] = 'slots_open'
|
||||
|
||||
try:
|
||||
data = urllib2.urlopen(url).read()
|
||||
except urllib2.HTTPError, e:
|
||||
plugin.back2nagios(2, 'Could not read data! ' + str(e))
|
||||
except urllib2.URLError, e:
|
||||
plugin.back2nagios(2, 'Could not connect to server!')
|
||||
return self.remember_check('slots', returncode, output, perfdata=[pd], target=target)
|
||||
|
||||
plugin.verbose(2, 'Got data:\n' + data)
|
||||
|
||||
try:
|
||||
idle = int(re.search('Idle(?:Workers|Servers): (\d+)\n', data).group(1))
|
||||
busy = int(re.search('Busy(?:Workers|Servers): (\d+)\n', data).group(1))
|
||||
except:
|
||||
plugin.back2nagios(2, 'Could not analyze data!')
|
||||
def check_worker(self, target='busy', warn='', crit=''):
|
||||
pd = {'label':'worker_busy', 'unit':'', 'warn':warn, 'crit': crit, 'min':0}
|
||||
|
||||
states = None
|
||||
if plugin.options.statistics:
|
||||
scoreboard = re.search('Scoreboard: (.*)\n', data)
|
||||
if scoreboard:
|
||||
states = {'_':0, 'S':0, 'R':0, 'W':0, 'K':0, 'D':0, 'C':0, 'L':0, 'G':0, 'I':0, '.':0,}
|
||||
for worker in scoreboard.group(1):
|
||||
states[worker] += 1
|
||||
plugin.add_multilineoutput(str(states['_']) + ' waiting for connection')
|
||||
plugin.add_multilineoutput(str(states['S']) + ' starting up')
|
||||
plugin.add_multilineoutput(str(states['R']) + ' reading request')
|
||||
plugin.add_multilineoutput(str(states['W']) + ' writing/sending reply')
|
||||
plugin.add_multilineoutput(str(states['K']) + ' keepalive')
|
||||
plugin.add_multilineoutput(str(states['D']) + ' looking up in DNS')
|
||||
plugin.add_multilineoutput(str(states['C']) + ' closing connection')
|
||||
plugin.add_multilineoutput(str(states['L']) + ' logging')
|
||||
plugin.add_multilineoutput(str(states['G']) + ' gracefully finishing')
|
||||
plugin.add_multilineoutput(str(states['I']) + ' idle cleanup of worker')
|
||||
plugin.add_multilineoutput(str(states['.']) + ' open slots(up to ServerLimit)')
|
||||
if target == 'busy':
|
||||
returncode = self.value_wc_to_returncode(self.apache_busy, warn, crit)
|
||||
output = '%d busy workers' % self.apache_busy
|
||||
pd['value'] = self.apache_busy
|
||||
pd = [pd]
|
||||
elif target == 'idle':
|
||||
returncode = self.value_wc_to_returncode(self.apache_idle, warn, crit)
|
||||
output = '%d idle workers' % self.apache_idle
|
||||
pd['value'] = self.apache_idle
|
||||
pd['label'] = 'worker_idle'
|
||||
pd = [pd]
|
||||
else:
|
||||
returncode = 3
|
||||
output = 'Target "%s" unknown' % target
|
||||
pd = None
|
||||
|
||||
returncode = plugin.value_wc_to_returncode(busy, plugin.options.warn, plugin.options.crit)
|
||||
|
||||
plugin.add_output(str(busy) + ' busy workers, ' + str(idle) + ' idle')
|
||||
return self.remember_check('worker', returncode, output, perfdata=pd, target=target)
|
||||
|
||||
plugin.add_returncode(returncode)
|
||||
|
||||
plugin.format_add_performancedata('busy', busy, '', warn=plugin.options.warn, crit=plugin.options.crit, min=0.0)
|
||||
plugin.format_add_performancedata('idle', idle, '')
|
||||
def get_server_status(self):
|
||||
if self.options.httpauth:
|
||||
httpauth = self.options.httpauth.split(':')
|
||||
if len(httpauth) != 2:
|
||||
self.back2nagios(3, 'Wrong format of authentication data! Need "USERNAME:PASSWORD", got "' + self.options.httpauth + '"')
|
||||
passman = urllib.request.HTTPPasswordMgrWithDefaultRealm()
|
||||
passman.add_password(None, url, httpauth[0], httpauth[1])
|
||||
authhandler = urllib.request.HTTPBasicAuthHandler(passman)
|
||||
opener = urllib.request.build_opener(authhandler)
|
||||
urllib.request.install_opener(opener)
|
||||
|
||||
plugin.exit()
|
||||
try:
|
||||
self.data = urllib.request.urlopen(self.url).read().decode()
|
||||
except urllib.error.HTTPError as e:
|
||||
self.back2nagios(2, 'Could not read data! ' + str(e))
|
||||
except urllib.error.URLError as e:
|
||||
self.back2nagios(2, 'Could not connect to server!')
|
||||
|
||||
pass
|
||||
|
||||
|
||||
def set_status_url(self):
|
||||
if self.options.url:
|
||||
self.url = self.options.url
|
||||
else:
|
||||
if self.options.proto not in ['http', 'https']:
|
||||
self.back2nagios(3, 'Unknown protocol "' + self.options.proto + '"')
|
||||
|
||||
if not self.options.port:
|
||||
if self.options.proto == 'https':
|
||||
self.options.port = '443'
|
||||
else:
|
||||
self.options.port = '80'
|
||||
|
||||
self.url = self.options.proto + '://' + self.options.host + ':' + self.options.port + '/' + self.options.uri + '?auto'
|
||||
|
||||
pass
|
||||
|
||||
############################################################
|
||||
|
||||
def main():
|
||||
plugin = CheckApaches(
|
||||
pluginname='check_apaches',
|
||||
tagforstatusline='APACHE',
|
||||
description='Check Apache workers',
|
||||
version='0.1',
|
||||
)
|
||||
|
||||
plugin.add_cmdlineoption('-H', '', 'host', 'Hostname/IP to check', default='localhost')
|
||||
plugin.add_cmdlineoption('-p', '', 'port', 'port to connect', default=None)
|
||||
plugin.add_cmdlineoption('-P', '', 'proto', 'protocol to use', default='http')
|
||||
plugin.add_cmdlineoption('-u', '', 'uri', 'path to "server-status"', default='/server-status')
|
||||
plugin.add_cmdlineoption('-U', '', 'url', 'complete URL to "server-status", overrides other options', default=None)
|
||||
plugin.add_cmdlineoption('-a', '', 'httpauth', 'HTTP Username and Password, separated by ":"')
|
||||
plugin.add_cmdlineoption('-w', '', 'warn', 'OBSOLETE: warning thresold', default='')
|
||||
plugin.add_cmdlineoption('-c', '', 'crit', 'OBSOLETE: warning thresold', default='')
|
||||
plugin.add_cmdlineoption('', '--statistics', 'statistics', 'Output worker statistics', action='store_true')
|
||||
|
||||
plugin.parse_cmdlineoptions()
|
||||
|
||||
|
||||
plugin.set_status_url()
|
||||
plugin.verbose(1, 'Status URL: ' + plugin.url)
|
||||
|
||||
plugin.get_server_status()
|
||||
plugin.verbose(2, 'Got data:')
|
||||
plugin.verbose(2, plugin.data)
|
||||
|
||||
plugin.analyze()
|
||||
|
||||
checks = plugin.args2checks()
|
||||
|
||||
# backward compatibility
|
||||
if len(checks) == 0:
|
||||
checks = [
|
||||
('worker','busy','20','50'),
|
||||
('worker','idle','20:','5:'),
|
||||
]
|
||||
|
||||
for quad in checks:
|
||||
(check, target, warn, crit) = tuple(quad)
|
||||
|
||||
if check == 'slots':
|
||||
result = plugin.check_slots(target, warn, crit)
|
||||
elif check == 'worker':
|
||||
result = plugin.check_worker(target, warn, crit)
|
||||
else:
|
||||
result = plugin.remember_check(check, plugin.RETURNCODE['UNKNOWN'], 'Unknown check "' + check + '"!')
|
||||
|
||||
plugin.verbose(5, result)
|
||||
|
||||
|
||||
|
||||
if plugin.options.statistics:
|
||||
plugin.add_multilineoutput(str(plugin.apache_states['_']) + ' waiting for connection')
|
||||
plugin.add_multilineoutput(str(plugin.apache_states['S']) + ' starting up')
|
||||
plugin.add_multilineoutput(str(plugin.apache_states['R']) + ' reading request')
|
||||
plugin.add_multilineoutput(str(plugin.apache_states['W']) + ' writing/sending reply')
|
||||
plugin.add_multilineoutput(str(plugin.apache_states['K']) + ' keepalive')
|
||||
plugin.add_multilineoutput(str(plugin.apache_states['D']) + ' looking up in DNS')
|
||||
plugin.add_multilineoutput(str(plugin.apache_states['C']) + ' closing connection')
|
||||
plugin.add_multilineoutput(str(plugin.apache_states['L']) + ' logging')
|
||||
plugin.add_multilineoutput(str(plugin.apache_states['G']) + ' gracefully finishing')
|
||||
plugin.add_multilineoutput(str(plugin.apache_states['I']) + ' idle cleanup of worker')
|
||||
plugin.add_multilineoutput(str(plugin.apache_states['.']) + ' open slots(up to ServerLimit)')
|
||||
|
||||
plugin.brain2output()
|
||||
plugin.exit()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
#vim: ts=4 sts=4 sw=4
|
||||
|
||||
|
|
177
check_apk.py
Executable file
177
check_apk.py
Executable file
|
@ -0,0 +1,177 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
#####################################################################
|
||||
# (c) 2016- by Sven Velt, Germany #
|
||||
# sven-mymonplugins@velt.biz #
|
||||
# #
|
||||
# This file is part of "velt.biz - My Monitoring Plugins" #
|
||||
# a fork of "team(ix) Monitoring Plugins" in 2015 #
|
||||
# URL: https://gogs.velt.biz/velt.biz/MyMonPlugins/ #
|
||||
# #
|
||||
# This file 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 file 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 file. If not, see <http://www.gnu.org/licenses/>. #
|
||||
#####################################################################
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
try:
|
||||
from MyMonPlugin import MonitoringPlugin
|
||||
except ImportError:
|
||||
print('==========================')
|
||||
print('AIKS! Python import error!')
|
||||
print('==========================\n')
|
||||
print('Could not find class "MonitoringPlugin"!\n')
|
||||
print('Did you download "%s"' % os.path.basename(sys.argv[0]))
|
||||
print('without "MyMonPlugin/"?\n')
|
||||
print('Please go back to')
|
||||
print('https://gogs.velt.biz/velt.biz/MyMonPlugins and:')
|
||||
print('- get a full archive at http://gogs.velt.biz/velt.biz/MyMonPlugins/releases')
|
||||
print('- or a master snapshot at http://gogs.velt.biz/velt.biz/MyMonPlugins/archive/master.tar.gz\n')
|
||||
sys.exit(127)
|
||||
|
||||
|
||||
plugin = MonitoringPlugin(
|
||||
pluginname='check_apk',
|
||||
tagforstatusline='APK',
|
||||
description='Check APK package manager for updates',
|
||||
version='0.1',
|
||||
)
|
||||
|
||||
plugin.add_cmdlineoption('-P', '--path-apk', 'apk', 'full path to apk', default='/sbin/apk')
|
||||
plugin.add_cmdlineoption('-S', '--sync-repo-index', 'sync_repo_index', 'sync repository index files at startup', default=False, action='store_true')
|
||||
plugin.add_cmdlineoption('', '--ignore-sync-failure', 'fail_on_sync_failure', 'ignore repo index sync failures', default=True, action='store_false')
|
||||
plugin.add_cmdlineoption('', '--sudo', 'sudo', 'call "apk" with sudo', default=False, action='store_true')
|
||||
|
||||
plugin.add_cmdlineoption('', '--mymonplugins-testmode', 'mymonplugins_testmode', None, default=False, action='store_true')
|
||||
|
||||
plugin.parse_cmdlineoptions()
|
||||
|
||||
##############################################################################
|
||||
##### Testmode
|
||||
|
||||
if plugin.options.mymonplugins_testmode:
|
||||
mymonplugins_testmode = {}
|
||||
|
||||
mymonplugins_testmode['apk update'] = '''fetch http://dl-cdn.alpinelinux.org/alpine/latest-stable/main/x86_64/APKINDEX.tar.gz
|
||||
fetch http://dl-cdn.alpinelinux.org/alpine/latest-stable/community/x86_64/APKINDEX.tar.gz
|
||||
v3.17.3-13-g98fa1f428e9 [http://dl-cdn.alpinelinux.org/alpine/latest-stable/main]
|
||||
v3.17.3-12-g492f704d069 [http://dl-cdn.alpinelinux.org/alpine/latest-stable/community]
|
||||
OK: 17824 distinct packages available
|
||||
'''.split('\n')
|
||||
|
||||
mymonplugins_testmode['apk -s upgrade'] = '''(1/6) Upgrading alpine-release (3.17.2-r0 -> 3.17.3-r0)
|
||||
(2/6) Upgrading libcrypto3 (3.0.8-r1 -> 3.0.8-r3)
|
||||
(3/6) Upgrading libssl3 (3.0.8-r1 -> 3.0.8-r3)
|
||||
(4/6) Upgrading alpine-base (3.17.2-r0 -> 3.17.3-r0)
|
||||
(5/6) Upgrading mkinitfs (3.7.0-r0 -> 3.7.0-r1)
|
||||
(6/6) Upgrading openssl (3.0.8-r1 -> 3.0.8-r3)
|
||||
OK: 258 MiB in 220 packages
|
||||
'''.split('\n')
|
||||
|
||||
##############################################################################
|
||||
|
||||
def run_command(cmdline, needs_sudo=False):
|
||||
tstart = time.time()
|
||||
if needs_sudo and plugin.options.sudo:
|
||||
new = ['sudo', '-n', '--']
|
||||
new.extend(cmdline)
|
||||
cmdline = new
|
||||
plugin.verbose(1, 'Running command line: %s' % subprocess.list2cmdline(cmdline))
|
||||
try:
|
||||
cmd = subprocess.Popen(
|
||||
cmdline,
|
||||
stdout = subprocess.PIPE,
|
||||
stderr = subprocess.PIPE
|
||||
)
|
||||
except OSError:
|
||||
plugin.back2nagios(plugin.RETURNCODE['UNKNOWN'], 'Could not execute command line: %s' % subprocess.list2cmdline(cmdline))
|
||||
|
||||
(sout,serr) = cmd.communicate()
|
||||
plugin.verbose(2, 'Runtime %.3fs' % (time.time() - tstart, ) )
|
||||
|
||||
sout = sout.rstrip().decode('utf-8').split('\n')
|
||||
if sout == ['']:
|
||||
sout = []
|
||||
serr = serr.rstrip().decode('utf-8').split('\n')
|
||||
if serr == ['']:
|
||||
serr = []
|
||||
|
||||
return( (sout, serr, cmd.returncode,) )
|
||||
|
||||
##############################################################################
|
||||
|
||||
if plugin.options.sync_repo_index:
|
||||
plugin.verbose(1, '-S/--sync_repo_index given')
|
||||
cmdline = [plugin.options.apk, 'update', '--no-progress',]
|
||||
(sout, serr, rc) = run_command(cmdline, needs_sudo=True)
|
||||
sout and plugin.verbose(3, sout, prefix='stdout: ')
|
||||
serr and plugin.verbose(3, serr, prefix='stderr: ')
|
||||
plugin.verbose(2, 'Return code: %d' % rc)
|
||||
if plugin.options.fail_on_sync_failure and (rc != 0 or 'ERROR:' in ' '.join(serr)):
|
||||
if 'Permission denied' in ' '.join(serr):
|
||||
plugin.back2nagios(plugin.RETURNCODE['CRITICAL'], 'Syncing of repository index files failed, permission denied. Do you need "--sudo"?', multiline=serr)
|
||||
plugin.back2nagios(plugin.RETURNCODE['CRITICAL'], 'Syncing of repository index files failed', multiline=serr)
|
||||
|
||||
##############################################################################
|
||||
|
||||
cmdline = [plugin.options.apk, 'upgrade', '--simulate', '--no-progress',]
|
||||
(sout, serr, rc) = run_command(cmdline)
|
||||
sout and plugin.verbose(3, sout, prefix='stdout: ')
|
||||
serr and plugin.verbose(3, serr, prefix='stderr: ')
|
||||
plugin.verbose(2, 'Return code: %d' % rc)
|
||||
|
||||
if plugin.options.sudo and 'sudo: ' in ' '.join(serr):
|
||||
# Running with sudo
|
||||
if rc == 1:
|
||||
# sudo RC 1: a password is required
|
||||
plugin.back2nagios(plugin.RETURNCODE['CRITICAL'], ' '.join(serr))
|
||||
if rc == 8:
|
||||
# RC 8: Transaction aborted due to unresolved shlibs.
|
||||
plugin.back2nagios(plugin.RETURNCODE['WARNING'], serr[-1], serr[:-1])
|
||||
elif rc not in [0, 6]:
|
||||
# RC 0: Packages to update
|
||||
# RC 6: Package(s) already installed
|
||||
plugin.back2nagios(plugin.RETURNCODE['WARNING'], 'Unknown returncode "%s", please contact the author of plugin or open an issue!' % rc)
|
||||
|
||||
action = {'Upgrading':[], 'Installing':[], 'Purging':[], }
|
||||
action_verb = {'Upgrading':'upgrade', 'Installing':'install', 'Purging':'purge', }
|
||||
|
||||
for line in sout[0:-1]:
|
||||
cols = line.split(' ')
|
||||
# Append package name to action type list
|
||||
action[cols[1]].append(cols[2])
|
||||
|
||||
if len(sout) == 1:
|
||||
plugin.remember_check('Updates', plugin.RETURNCODE['OK'], 'Everything uptodate')
|
||||
else:
|
||||
out = []
|
||||
multiline = []
|
||||
for act in list(action.keys()):
|
||||
pkgs = action.pop(act)
|
||||
pkgs.sort()
|
||||
l = len(pkgs)
|
||||
out.append('%s package%s to %s' % (l, l != 1 and 's' or '', action_verb[act]) )
|
||||
l and multiline.append('%s(%s): %s' % (act, l, ', '.join(pkgs)) )
|
||||
|
||||
out = ', '.join(out)
|
||||
|
||||
plugin.remember_check('Updates', plugin.RETURNCODE['CRITICAL'], out, multilineoutput=multiline)
|
||||
|
||||
# Exit
|
||||
plugin.brain2output()
|
||||
plugin.exit()
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
#!/usr/bin/env python2
|
||||
#!/usr/bin/env python3
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
#####################################################################
|
||||
# (c) 2016 by Sven Velt, Germany #
|
||||
# (c) 2016- by Sven Velt, Germany #
|
||||
# sven-mymonplugins@velt.biz #
|
||||
# #
|
||||
# This file is part of "velt.biz - My Monitoring Plugins" #
|
||||
|
@ -30,19 +30,18 @@ import sys
|
|||
import time
|
||||
|
||||
try:
|
||||
from monitoringplugin import MonitoringPlugin
|
||||
from MyMonPlugin import MonitoringPlugin
|
||||
except ImportError:
|
||||
print '=========================='
|
||||
print 'AIKS! Python import error!'
|
||||
print '==========================\n'
|
||||
print 'Could not find "monitoringplugin.py"!\n'
|
||||
print 'Did you download "%s"' % os.path.basename(sys.argv[0])
|
||||
print 'without "monitoringplugin.py"?\n'
|
||||
print 'Please go back to'
|
||||
print 'https://gogs.velt.biz/velt.biz/MyMonPlugins and download it,'
|
||||
print 'or even better:'
|
||||
print 'get a full archive at http://gogs.velt.biz/velt.biz/MyMonPlugins/releases'
|
||||
print 'or a master snapshot at http://gogs.velt.biz/velt.biz/MyMonPlugins/archive/master.tar.gz\n'
|
||||
print('==========================')
|
||||
print('AIKS! Python import error!')
|
||||
print('==========================\n')
|
||||
print('Could not find class "MonitoringPlugin"!\n')
|
||||
print('Did you download "%s"' % os.path.basename(sys.argv[0]))
|
||||
print('without "MyMonPlugin/"?\n')
|
||||
print('Please go back to')
|
||||
print('https://gogs.velt.biz/velt.biz/MyMonPlugins and:')
|
||||
print('- get a full archive at http://gogs.velt.biz/velt.biz/MyMonPlugins/releases')
|
||||
print('- or a master snapshot at http://gogs.velt.biz/velt.biz/MyMonPlugins/archive/master.tar.gz\n')
|
||||
sys.exit(127)
|
||||
|
||||
|
||||
|
@ -54,7 +53,7 @@ plugin = MonitoringPlugin(
|
|||
)
|
||||
|
||||
|
||||
plugin.add_cmdlineoption('-P', '--check-printers', 'check_printers', 'check printer queue', default=False, action='store_true' )
|
||||
plugin.add_cmdlineoption('-P', '--check-printers', 'check_printers', 'check printer', default=False, action='store_true' )
|
||||
plugin.add_cmdlineoption('-J', '--check-jobs', 'check_jobs', 'check job queue', default=False, action='store_true')
|
||||
plugin.add_cmdlineoption('-w', '', 'warn', 'warning thresold for old jobs (seconds)', default='3600')
|
||||
plugin.add_cmdlineoption('-c', '', 'crit', 'warning thresold for old jobs (seconds)', default='86400')
|
||||
|
@ -110,7 +109,7 @@ def check_printer_queue(output_printer_queue):
|
|||
def check_job_queue(output_job_queue):
|
||||
plugin.verbose(1, 'Checking job queue')
|
||||
m = re.compile('(\w{3} \d\d \w{3} \d{4} \d\d:\d\d:\d\d (AM|PM) \w{3,5})')
|
||||
nowsecs = long( time.time() )
|
||||
nowsecs = int( time.time() )
|
||||
|
||||
jobs_warn = []
|
||||
jobs_crit = []
|
||||
|
@ -122,7 +121,7 @@ def check_job_queue(output_job_queue):
|
|||
continue
|
||||
tstamp = time.strptime(f.group(1), '%a %d %b %Y %I:%M:%S %p %Z')
|
||||
|
||||
tsecs = long( time.mktime(tstamp) )
|
||||
tsecs = int( time.mktime(tstamp) )
|
||||
age = nowsecs - tsecs
|
||||
rc = plugin.value_wc_to_returncode(age, plugin.options.warn, plugin.options.crit)
|
||||
if rc == 1:
|
||||
|
@ -156,7 +155,7 @@ def call_cmd(cmdline):
|
|||
cmd = subprocess.Popen(cmdline, stdout=subprocess.PIPE, env=myenv)
|
||||
(sout, serr) = cmd.communicate()
|
||||
if sout:
|
||||
sout = sout.lstrip().rstrip().split('\n')
|
||||
sout = sout.lstrip().rstrip().decode('utf-8').split('\n')
|
||||
else:
|
||||
sout = []
|
||||
except OSError:
|
||||
|
@ -170,7 +169,7 @@ allchecks = not( plugin.options.check_printers or plugin.options.check_jobs )
|
|||
if allchecks or plugin.options.check_printers:
|
||||
(sout, serr, retcode) = call_cmd(['lpstat', '-a'])
|
||||
check_printer_queue(sout)
|
||||
if allchecks or plugin.options.check_jobs:
|
||||
if allchecks or plugin.options.check_jobs:
|
||||
(sout, serr, retcode) = call_cmd(['lpstat', '-o'])
|
||||
check_job_queue(sout)
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
#####################################################################
|
||||
# (c) 2006-2011 by Sven Velt and team(ix) GmbH, Nuernberg, Germany #
|
||||
# sv@teamix.net #
|
||||
# (c) 2016 by Sven Velt, Germany #
|
||||
# sven-mymonplugins@velt.biz #
|
||||
# (c) 2016- by Sven Velt, Germany #
|
||||
# sven-mymonplugins@velt.biz #
|
||||
# #
|
||||
# This file is part of "velt.biz - My Monitoring Plugins" #
|
||||
# a fork of "team(ix) Monitoring Plugins" in 2015 #
|
||||
|
@ -31,25 +31,24 @@ import struct
|
|||
import sys
|
||||
|
||||
try:
|
||||
from monitoringplugin import SNMPMonitoringPlugin
|
||||
from MyMonPlugin import MonitoringPlugin
|
||||
except ImportError:
|
||||
print '=========================='
|
||||
print 'AIKS! Python import error!'
|
||||
print '==========================\n'
|
||||
print 'Could not find "monitoringplugin.py"!\n'
|
||||
print 'Did you download "%s"' % os.path.basename(sys.argv[0])
|
||||
print 'without "monitoringplugin.py"?\n'
|
||||
print 'Please go back to'
|
||||
print 'https://gogs.velt.biz/velt.biz/MyMonPlugins and download it,'
|
||||
print 'or even better:'
|
||||
print 'get a full archive at http://gogs.velt.biz/velt.biz/MyMonPlugins/releases'
|
||||
print 'or a master snapshot at http://gogs.velt.biz/velt.biz/MyMonPlugins/archive/master.tar.gz\n'
|
||||
print('==========================')
|
||||
print('AIKS! Python import error!')
|
||||
print('==========================\n')
|
||||
print('Could not find class "MonitoringPlugin"!\n')
|
||||
print('Did you download "%s"' % os.path.basename(sys.argv[0]))
|
||||
print('without "MyMonPlugin/"?\n')
|
||||
print('Please go back to')
|
||||
print('https://gogs.velt.biz/velt.biz/MyMonPlugins and:')
|
||||
print('- get a full archive at http://gogs.velt.biz/velt.biz/MyMonPlugins/releases')
|
||||
print('- or a master snapshot at http://gogs.velt.biz/velt.biz/MyMonPlugins/archive/master.tar.gz\n')
|
||||
sys.exit(127)
|
||||
|
||||
|
||||
def get_ipv4_address(iface):
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
return socket.inet_ntoa(fcntl.ioctl(sock.fileno(), 0x8915, struct.pack('256s', iface[:15]))[20:24])
|
||||
return socket.inet_ntoa(fcntl.ioctl(sock.fileno(), 0x8915, struct.pack('256s', bytes(iface[:15], 'utf-8')))[20:24])
|
||||
|
||||
|
||||
plugin = MonitoringPlugin(pluginname='check_iface-dns', tagforstatusline='IFACE-DNS', description='Check interface address vs. DNS', version='0.1')
|
||||
|
@ -74,7 +73,8 @@ plugin.parse_cmdlineoptions()
|
|||
# Get IP from interface
|
||||
try:
|
||||
ip_iface = get_ipv4_address(plugin.options.iface)
|
||||
except IOError, (errno, strerror):
|
||||
except IOError as xxx_todo_changeme:
|
||||
(errno, strerror) = xxx_todo_changeme.args
|
||||
if errno == 19:
|
||||
plugin.back2nagios(2, 'Interface "%s" does not exist!' % plugin.options.iface)
|
||||
elif errno == 99:
|
||||
|
@ -120,7 +120,7 @@ else:
|
|||
else:
|
||||
plugin.add_multilineoutput('OK - "%s" resolves to "%s"' % (dns, ip_dns))
|
||||
|
||||
|
||||
|
||||
if len(failed_dns) == 0:
|
||||
plugin.add_returncode(0)
|
||||
plugin.add_output('All DNS objects have a correct IP')
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
#####################################################################
|
||||
# (c) 2016 by Sven Velt, Germany #
|
||||
# (c) 2016- by Sven Velt, Germany #
|
||||
# sven-mymonplugins@velt.biz #
|
||||
# #
|
||||
# This file is part of "velt.biz - My Monitoring Plugins" #
|
||||
|
@ -29,19 +29,18 @@ import socket
|
|||
import sys
|
||||
|
||||
try:
|
||||
from monitoringplugin import MonitoringPlugin
|
||||
from MyMonPlugin import MonitoringPlugin
|
||||
except ImportError:
|
||||
print '=========================='
|
||||
print 'AIKS! Python import error!'
|
||||
print '==========================\n'
|
||||
print 'Could not find "monitoringplugin.py"!\n'
|
||||
print 'Did you download "%s"' % os.path.basename(sys.argv[0])
|
||||
print 'without "monitoringplugin.py"?\n'
|
||||
print 'Please go back to'
|
||||
print 'https://gogs.velt.biz/velt.biz/MyMonPlugins and download it,'
|
||||
print 'or even better:'
|
||||
print 'get a full archive at http://gogs.velt.biz/velt.biz/MyMonPlugins/releases'
|
||||
print 'or a master snapshot at http://gogs.velt.biz/velt.biz/MyMonPlugins/archive/master.tar.gz\n'
|
||||
print('==========================')
|
||||
print('AIKS! Python import error!')
|
||||
print('==========================\n')
|
||||
print('Could not find class "MonitoringPlugin"!\n')
|
||||
print('Did you download "%s"' % os.path.basename(sys.argv[0]))
|
||||
print('without "MyMonPlugin/"?\n')
|
||||
print('Please go back to')
|
||||
print('https://gogs.velt.biz/velt.biz/MyMonPlugins and:')
|
||||
print('- get a full archive at http://gogs.velt.biz/velt.biz/MyMonPlugins/releases')
|
||||
print('- or a master snapshot at http://gogs.velt.biz/velt.biz/MyMonPlugins/archive/master.tar.gz\n')
|
||||
sys.exit(127)
|
||||
|
||||
|
||||
|
@ -83,7 +82,7 @@ if not os.access(plugin.options.socket, os.W_OK):
|
|||
plugin.back2nagios(3, 'Could not read from socket "%s"' % plugin.options.socket)
|
||||
# FIXME: End
|
||||
|
||||
cmd_svc='''GET services
|
||||
cmd_svc=b'''GET services
|
||||
OutputFormat: csv
|
||||
Stats: min latency
|
||||
Stats: max latency
|
||||
|
@ -93,7 +92,7 @@ Stats: max execution_time
|
|||
Stats: avg execution_time
|
||||
'''
|
||||
|
||||
cmd_hst='''GET hosts
|
||||
cmd_hst=b'''GET hosts
|
||||
OutputFormat: csv
|
||||
Stats: min latency
|
||||
Stats: max latency
|
||||
|
@ -116,7 +115,7 @@ try:
|
|||
s.settimeout(10)
|
||||
data = s.recv(32768)
|
||||
if data:
|
||||
answer += data
|
||||
answer += data.decode('utf-8')
|
||||
else:
|
||||
break
|
||||
except socket.timeout:
|
||||
|
@ -142,7 +141,7 @@ try:
|
|||
s.settimeout(10)
|
||||
data = s.recv(32768)
|
||||
if data:
|
||||
answer += data
|
||||
answer += data.decode('utf-8')
|
||||
else:
|
||||
break
|
||||
except socket.timeout:
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
#####################################################################
|
||||
# (c) 2010-2011 by Sven Velt and team(ix) GmbH, Nuernberg, Germany #
|
||||
# sv@teamix.net #
|
||||
# (c) 2016 by Sven Velt, Germany #
|
||||
# sven-mymonplugins@velt.biz #
|
||||
# (c) 2016- by Sven Velt, Germany #
|
||||
# sven-mymonplugins@velt.biz #
|
||||
# #
|
||||
# This file is part of "velt.biz - My Monitoring Plugins" #
|
||||
# a fork of "team(ix) Monitoring Plugins" in 2015 #
|
||||
|
@ -30,19 +30,18 @@ import re
|
|||
import sys
|
||||
|
||||
try:
|
||||
from monitoringplugin import MonitoringPlugin
|
||||
from MyMonPlugin import MonitoringPlugin
|
||||
except ImportError:
|
||||
print '=========================='
|
||||
print 'AIKS! Python import error!'
|
||||
print '==========================\n'
|
||||
print 'Could not find "monitoringplugin.py"!\n'
|
||||
print 'Did you download "%s"' % os.path.basename(sys.argv[0])
|
||||
print 'without "monitoringplugin.py"?\n'
|
||||
print 'Please go back to'
|
||||
print 'https://gogs.velt.biz/velt.biz/MyMonPlugins and download it,'
|
||||
print 'or even better:'
|
||||
print 'get a full archive at http://gogs.velt.biz/velt.biz/MyMonPlugins/releases'
|
||||
print 'or a master snapshot at http://gogs.velt.biz/velt.biz/MyMonPlugins/archive/master.tar.gz\n'
|
||||
print('==========================')
|
||||
print('AIKS! Python import error!')
|
||||
print('==========================\n')
|
||||
print('Could not find class "MonitoringPlugin"!\n')
|
||||
print('Did you download "%s"' % os.path.basename(sys.argv[0]))
|
||||
print('without "MyMonPlugin/"?\n')
|
||||
print('Please go back to')
|
||||
print('https://gogs.velt.biz/velt.biz/MyMonPlugins and:')
|
||||
print('- get a full archive at http://gogs.velt.biz/velt.biz/MyMonPlugins/releases')
|
||||
print('- or a master snapshot at http://gogs.velt.biz/velt.biz/MyMonPlugins/archive/master.tar.gz\n')
|
||||
sys.exit(127)
|
||||
|
||||
|
||||
|
@ -103,16 +102,13 @@ for version in versions:
|
|||
matcher = v4match
|
||||
|
||||
for proto in protos:
|
||||
filename = '/proc/net/%s%s' % (proto, version)
|
||||
f = file(filename)
|
||||
lines = f.readlines()
|
||||
|
||||
for line in lines:
|
||||
m = matcher.match(line)
|
||||
if m:
|
||||
port = int(m.group(2), 16)
|
||||
if port == plugin.options.port and m.group(3) not in ['00000000','00000000000000000000000000000000']:
|
||||
count += 1
|
||||
with open('/proc/net/%s%s' % (proto, version)) as fh:
|
||||
for line in fh:
|
||||
m = matcher.match(line)
|
||||
if m:
|
||||
port = int(m.group(2), 16)
|
||||
if port == plugin.options.port and m.group(3) not in ['00000000','00000000000000000000000000000000']:
|
||||
count += 1
|
||||
|
||||
|
||||
returncode = plugin.value_wc_to_returncode(count, plugin.options.warn, plugin.options.crit)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#!/usr/bin/env python2
|
||||
#!/usr/bin/env python3
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
#####################################################################
|
||||
# (c) 2016-2017 by Sven Velt, Germany #
|
||||
# sven-mymonplugins@velt.biz #
|
||||
# (c) 2016- by Sven Velt, Germany #
|
||||
# sven-mymonplugins@velt.biz #
|
||||
# #
|
||||
# This file is part of "velt.biz - My Monitoring Plugins" #
|
||||
# a fork of "team(ix) Monitoring Plugins" in 2015 #
|
||||
|
@ -23,24 +23,24 @@
|
|||
# along with this file. If not, see <http://www.gnu.org/licenses/>. #
|
||||
#####################################################################
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
try:
|
||||
from monitoringplugin import MonitoringPlugin
|
||||
from MyMonPlugin import MonitoringPlugin
|
||||
except ImportError:
|
||||
print '=========================='
|
||||
print 'AIKS! Python import error!'
|
||||
print '==========================\n'
|
||||
print 'Could not find "monitoringplugin.py"!\n'
|
||||
print 'Did you download "%s"' % os.path.basename(sys.argv[0])
|
||||
print 'without "monitoringplugin.py"?\n'
|
||||
print 'Please go back to'
|
||||
print 'https://gogs.velt.biz/velt.biz/MyMonPlugins and download it,'
|
||||
print 'or even better:'
|
||||
print 'get a full archive at http://gogs.velt.biz/velt.biz/MyMonPlugins/releases'
|
||||
print 'or a master snapshot at http://gogs.velt.biz/velt.biz/MyMonPlugins/archive/master.tar.gz\n'
|
||||
print('==========================')
|
||||
print('AIKS! Python import error!')
|
||||
print('==========================\n')
|
||||
print('Could not find class "MonitoringPlugin"!\n')
|
||||
print('Did you download "%s"' % os.path.basename(sys.argv[0]))
|
||||
print('without "MyMonPlugin/"?\n')
|
||||
print('Please go back to')
|
||||
print('https://gogs.velt.biz/velt.biz/MyMonPlugins and:')
|
||||
print('- get a full archive at http://gogs.velt.biz/velt.biz/MyMonPlugins/releases')
|
||||
print('- or a master snapshot at http://gogs.velt.biz/velt.biz/MyMonPlugins/archive/master.tar.gz\n')
|
||||
sys.exit(127)
|
||||
|
||||
|
||||
|
@ -98,10 +98,10 @@ def run_command(cmdline, needs_sudo=False):
|
|||
(sout,serr) = cmd.communicate()
|
||||
plugin.verbose(2, 'Runtime %.3fs' % (time.time() - tstart, ) )
|
||||
|
||||
sout = sout.rstrip().split('\n')
|
||||
sout = sout.rstrip().decode('utf-8').split('\n')
|
||||
if sout == ['']:
|
||||
sout = []
|
||||
serr = serr.rstrip().split('\n')
|
||||
serr = serr.rstrip().decode('utf-8').split('\n')
|
||||
if serr == ['']:
|
||||
serr = []
|
||||
|
||||
|
@ -145,7 +145,7 @@ elif rc not in [0, 6]:
|
|||
action = {'remove':[], 'update':[], 'install':[], 'configure':[]}
|
||||
arch = {}
|
||||
repo = {}
|
||||
downby = 0L
|
||||
downby = 0
|
||||
|
||||
for line in sout:
|
||||
cols = line.split(' ')
|
||||
|
@ -169,9 +169,9 @@ for line in sout:
|
|||
|
||||
# Count bytes to download
|
||||
if len(cols) == 5:
|
||||
downby += long(cols[4])
|
||||
downby += int(cols[4])
|
||||
else:
|
||||
downby += long(cols[5])
|
||||
downby += int(cols[5])
|
||||
|
||||
if len(sout) == 0:
|
||||
plugin.remember_check('Updates', plugin.RETURNCODE['OK'], 'Everything uptodate')
|
||||
|
@ -184,7 +184,7 @@ else:
|
|||
l = len(pkgs)
|
||||
out.append('%s package%s to %s' % (l, l != 1 and 's' or '', act) )
|
||||
l and multiline.append('%s(%s): %s' % (act, l, ', '.join(pkgs)) )
|
||||
for act in action.keys():
|
||||
for act in list(action.keys()):
|
||||
pkgs = action.pop(act)
|
||||
pkgs.sort()
|
||||
l = len(pkgs)
|
||||
|
@ -196,9 +196,9 @@ else:
|
|||
out += ' - %s to download' % plugin.value_to_human_binary(downby, 'B')
|
||||
|
||||
stats = 'Statistics: '
|
||||
for (k, v) in arch.iteritems():
|
||||
for (k, v) in arch.items():
|
||||
stats += '%sx %s, ' % (v, k)
|
||||
for (k, v) in repo.iteritems():
|
||||
for (k, v) in repo.items():
|
||||
stats += '%s from %s, ' % (v, k)
|
||||
multiline.append(stats[:-2])
|
||||
|
||||
|
|
Loading…
Reference in a new issue