check_nagiostats.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. #!/usr/bin/env python
  2. # -*- encoding: utf-8 -*-
  3. #####################################################################
  4. # (c) 2005-2011 by Sven Velt and team(ix) GmbH, Nuernberg, Germany #
  5. # sv@teamix.net #
  6. # #
  7. # This file is part of "team(ix) Monitoring Plugins" #
  8. # URL: http://oss.teamix.org/projects/monitoringplugins/ #
  9. # #
  10. # This file is free software: you can redistribute it and/or modify #
  11. # it under the terms of the GNU General Public License as published #
  12. # by the Free Software Foundation, either version 2 of the License, #
  13. # or (at your option) any later version. #
  14. # #
  15. # This file is distributed in the hope that it will be useful, but #
  16. # WITHOUT ANY WARRANTY; without even the implied warranty of #
  17. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
  18. # GNU General Public License for more details. #
  19. # #
  20. # You should have received a copy of the GNU General Public License #
  21. # along with this file. If not, see <http://www.gnu.org/licenses/>. #
  22. #####################################################################
  23. import os
  24. import shlex
  25. import subprocess
  26. import sys
  27. try:
  28. from monitoringplugin import MonitoringPlugin
  29. except ImportError:
  30. print '=========================='
  31. print 'AIKS! Python import error!'
  32. print '==========================\n'
  33. print 'Could not find "monitoringplugin.py"!\n'
  34. print 'Did you download "%s"' % os.path.basename(sys.argv[0])
  35. print 'without "monitoringplugin.py"?\n'
  36. print 'Please go back to'
  37. print 'http://oss.teamix.org/projects/monitoringplugins/ and download it,'
  38. print 'or even better:'
  39. print 'get a hole archive at http://oss.teamix.org/projects/monitoringplugins/files\n'
  40. sys.exit(127)
  41. plugin = MonitoringPlugin(pluginname='check_nagiostats', tagforstatusline='NAGIOSTATS', description='Check Nagios statistics', version='0.1')
  42. NAGIOSTATSs = ['/usr/sbin/nagios3stats', '/usr/local/nagios/bin/nagiostats']
  43. VARs = {
  44. 'PROGRUNTIME': { 'type':str, },
  45. 'PROGRUNTIMETT': { 'type':long, 'unit':'', },
  46. 'STATUSFILEAGE': { 'type':str, },
  47. 'STATUSFILEAGETT': { 'type':long, 'unit':'', },
  48. 'NAGIOSVERSION': { 'type':str, },
  49. 'NAGIOSPID': { 'type':str, },
  50. 'NAGIOSVERPID': { 'type':str, },
  51. 'TOTCMDBUF': { 'type':long, 'unit':'', },
  52. 'USEDCMDBUF': { 'type':long, 'unit':'', },
  53. 'HIGHCMDBUF': { 'type':long, 'unit':'', },
  54. 'NUMSERVICES': { 'type':long, 'unit':'', },
  55. 'NUMSVCOK': { 'type':long, 'unit':'', },
  56. 'NUMSVCWARN': { 'type':long, 'unit':'', },
  57. 'NUMSVCUNKN': { 'type':long, 'unit':'', },
  58. 'NUMSVCCRIT': { 'type':long, 'unit':'', },
  59. 'NUMSVCPROB': { 'type':long, 'unit':'', },
  60. 'NUMSVCCHECKED': { 'type':long, 'unit':'', },
  61. 'NUMSVCSCHEDULED': { 'type':long, 'unit':'', },
  62. 'NUMSVCFLAPPING': { 'type':long, 'unit':'', },
  63. 'NUMSVCDOWNTIME': { 'type':long, 'unit':'', },
  64. 'NUMHOSTS': { 'type':long, 'unit':'', },
  65. 'NUMHSTUP': { 'type':long, 'unit':'', },
  66. 'NUMHSTDOWN': { 'type':long, 'unit':'', },
  67. 'NUMHSTUNR': { 'type':long, 'unit':'', },
  68. 'NUMHSTPROB': { 'type':long, 'unit':'', },
  69. 'NUMHSTCHECKED': { 'type':long, 'unit':'', },
  70. 'NUMHSTSCHEDULED': { 'type':long, 'unit':'', },
  71. 'NUMHSTFLAPPING': { 'type':long, 'unit':'', },
  72. 'NUMHSTDOWNTIME': { 'type':long, 'unit':'', },
  73. 'NUMHSTACTCHK1M': { 'type':long, 'unit':'', },
  74. 'NUMHSTPSVCHK1M': { 'type':long, 'unit':'', },
  75. 'NUMSVCACTCHK1M': { 'type':long, 'unit':'', },
  76. 'NUMSVCPSVCHK1M': { 'type':long, 'unit':'', },
  77. 'NUMHSTACTCHK5M': { 'type':long, 'unit':'', },
  78. 'NUMHSTPSVCHK5M': { 'type':long, 'unit':'', },
  79. 'NUMSVCACTCHK5M': { 'type':long, 'unit':'', },
  80. 'NUMSVCPSVCHK5M': { 'type':long, 'unit':'', },
  81. 'NUMHSTACTCHK15M': { 'type':long, 'unit':'', },
  82. 'NUMHSTPSVCHK15M': { 'type':long, 'unit':'', },
  83. 'NUMSVCACTCHK15M': { 'type':long, 'unit':'', },
  84. 'NUMSVCPSVCHK15M': { 'type':long, 'unit':'', },
  85. 'NUMHSTACTCHK60M': { 'type':long, 'unit':'', },
  86. 'NUMHSTPSVCHK60M': { 'type':long, 'unit':'', },
  87. 'NUMSVCACTCHK60M': { 'type':long, 'unit':'', },
  88. 'NUMSVCPSVCHK60M': { 'type':long, 'unit':'', },
  89. 'AVGACTSVCLAT': { 'type':float, 'unit':'s', 'factor':0.001, },
  90. 'AVGACTSVCEXT': { 'type':float, 'unit':'s', 'factor':0.001, },
  91. 'AVGACTSVCPSC': { 'type':float, 'unit':'%', },
  92. 'AVGPSVSVCLAT': { 'type':float, 'unit':'s', 'factor':0.001, },
  93. 'AVGPSVSVCPSC': { 'type':float, 'unit':'%', },
  94. 'AVGSVCPSC': { 'type':float, 'unit':'%', },
  95. 'AVGACTHSTLAT': { 'type':float, 'unit':'s', 'factor':0.001, },
  96. 'AVGACTHSTEXT': { 'type':float, 'unit':'s', 'factor':0.001, },
  97. 'AVGACTHSTPSC': { 'type':float, 'unit':'%', },
  98. 'AVGPSVHSTLAT': { 'type':float, 'unit':'s', 'factor':0.001, },
  99. 'AVGPSVHSTPSC': { 'type':float, 'unit':'%', },
  100. 'AVGHSTPSC': { 'type':float, 'unit':'%', },
  101. 'MINACTSVCLAT': { 'type':float, 'unit':'s', 'factor':0.001, },
  102. 'MINACTSVCEXT': { 'type':float, 'unit':'s', 'factor':0.001, },
  103. 'MINACTSVCPSC': { 'type':float, 'unit':'%', },
  104. 'MINPSVSVCLAT': { 'type':float, 'unit':'s', 'factor':0.001, },
  105. 'MINPSVSVCPSC': { 'type':float, 'unit':'%', },
  106. 'MINSVCPSC': { 'type':float, 'unit':'%', },
  107. 'MINACTHSTLAT': { 'type':float, 'unit':'s', 'factor':0.001, },
  108. 'MINACTHSTEXT': { 'type':float, 'unit':'s', 'factor':0.001, },
  109. 'MINACTHSTPSC': { 'type':float, 'unit':'%', },
  110. 'MINPSVHSTLAT': { 'type':float, 'unit':'s', 'factor':0.001, },
  111. 'MINPSVHSTPSC': { 'type':float, 'unit':'%', },
  112. 'MINHSTPSC': { 'type':float, 'unit':'%', },
  113. 'MAXACTSVCLAT': { 'type':float, 'unit':'s', 'factor':0.001, },
  114. 'MAXACTSVCEXT': { 'type':float, 'unit':'s', 'factor':0.001, },
  115. 'MAXACTSVCPSC': { 'type':float, 'unit':'%', },
  116. 'MAXPSVSVCLAT': { 'type':float, 'unit':'s', 'factor':0.001, },
  117. 'MAXPSVSVCPSC': { 'type':float, 'unit':'%', },
  118. 'MAXSVCPSC': { 'type':float, 'unit':'%', },
  119. 'MAXACTHSTLAT': { 'type':float, 'unit':'s', 'factor':0.001, },
  120. 'MAXACTHSTEXT': { 'type':float, 'unit':'s', 'factor':0.001, },
  121. 'MAXACTHSTPSC': { 'type':float, 'unit':'%', },
  122. 'MAXPSVHSTLAT': { 'type':float, 'unit':'s', 'factor':0.001, },
  123. 'MAXPSVHSTPSC': { 'type':float, 'unit':'%', },
  124. 'MAXHSTPSC': { 'type':float, 'unit':'%', },
  125. 'NUMACTHSTCHECKS1M': { 'type':long, 'unit':'', },
  126. 'NUMOACTHSTCHECKS1M': { 'type':long, 'unit':'', },
  127. 'NUMCACHEDHSTCHECKS1M': { 'type':long, 'unit':'', },
  128. 'NUMSACTHSTCHECKS1M': { 'type':long, 'unit':'', },
  129. 'NUMPARHSTCHECKS1M': { 'type':long, 'unit':'', },
  130. 'NUMSERHSTCHECKS1M': { 'type':long, 'unit':'', },
  131. 'NUMPSVHSTCHECKS1M': { 'type':long, 'unit':'', },
  132. 'NUMACTSVCCHECKS1M': { 'type':long, 'unit':'', },
  133. 'NUMOACTSVCCHECKS1M': { 'type':long, 'unit':'', },
  134. 'NUMCACHEDSVCCHECKS1M': { 'type':long, 'unit':'', },
  135. 'NUMSACTSVCCHECKS1M': { 'type':long, 'unit':'', },
  136. 'NUMPSVSVCCHECKS1M': { 'type':long, 'unit':'', },
  137. 'NUMEXTCMDS1M': { 'type':long, 'unit':'', },
  138. 'NUMACTHSTCHECKS5M': { 'type':long, 'unit':'', },
  139. 'NUMOACTHSTCHECKS5M': { 'type':long, 'unit':'', },
  140. 'NUMCACHEDHSTCHECKS5M': { 'type':long, 'unit':'', },
  141. 'NUMSACTHSTCHECKS5M': { 'type':long, 'unit':'', },
  142. 'NUMPARHSTCHECKS5M': { 'type':long, 'unit':'', },
  143. 'NUMSERHSTCHECKS5M': { 'type':long, 'unit':'', },
  144. 'NUMPSVHSTCHECKS5M': { 'type':long, 'unit':'', },
  145. 'NUMACTSVCCHECKS5M': { 'type':long, 'unit':'', },
  146. 'NUMOACTSVCCHECKS5M': { 'type':long, 'unit':'', },
  147. 'NUMCACHEDSVCCHECKS5M': { 'type':long, 'unit':'', },
  148. 'NUMSACTSVCCHECKS5M': { 'type':long, 'unit':'', },
  149. 'NUMPSVSVCCHECKS5M': { 'type':long, 'unit':'', },
  150. 'NUMEXTCMDS5M': { 'type':long, 'unit':'', },
  151. 'NUMACTHSTCHECKS15M': { 'type':long, 'unit':'', },
  152. 'NUMOACTHSTCHECKS15M': { 'type':long, 'unit':'', },
  153. 'NUMCACHEDHSTCHECKS15M': { 'type':long, 'unit':'', },
  154. 'NUMSACTHSTCHECKS15M': { 'type':long, 'unit':'', },
  155. 'NUMPARHSTCHECKS15M': { 'type':long, 'unit':'', },
  156. 'NUMSERHSTCHECKS15M': { 'type':long, 'unit':'', },
  157. 'NUMPSVHSTCHECKS15M': { 'type':long, 'unit':'', },
  158. 'NUMACTSVCCHECKS15M': { 'type':long, 'unit':'', },
  159. 'NUMOACTSVCCHECKS15M': { 'type':long, 'unit':'', },
  160. 'NUMCACHEDSVCCHECKS15M': { 'type':long, 'unit':'', },
  161. 'NUMSACTSVCCHECKS15M': { 'type':long, 'unit':'', },
  162. 'NUMPSVSVCCHECKS15M': { 'type':long, 'unit':'', },
  163. 'NUMEXTCMDS15M': { 'type':long, 'unit':'', },
  164. }
  165. plugin.add_cmdlineoption('-C', '', 'checks', 'Use built-in checks (predefined lists of variables)', default='')
  166. plugin.add_cmdlineoption('-V', '', 'vars', 'List of "nagiostats" variables to check', default='')
  167. plugin.add_cmdlineoption('-n', '', 'nagiostats', 'Full path to nagiostat', default='')
  168. plugin.add_cmdlineoption('-w', '', 'warn', 'warning thresold', default='')
  169. plugin.add_cmdlineoption('-c', '', 'crit', 'warning thresold', default='')
  170. plugin.parse_cmdlineoptions()
  171. if not plugin.options.nagiostats:
  172. plugin.verbose(2, 'Auto-detecting path to "nagiostats"...')
  173. for nagiostats in NAGIOSTATSs:
  174. if os.path.exists(nagiostats):
  175. plugin.options.nagiostats = nagiostats
  176. plugin.verbose(2, 'Found it at "%s"' % nagiostats)
  177. break
  178. if not os.path.exists(plugin.options.nagiostats):
  179. plugin.back2nagios(3, 'Could not find "nagiostats"')
  180. if not plugin.options.checks and not plugin.options.vars:
  181. plugin.back2nagios(3, 'Need either "-C" or "-V"')
  182. # FIXME: Built var list out of -C
  183. if ',' in plugin.options.vars:
  184. plugin.verbose(2, 'Multiple variables detected')
  185. plugin.options.vars = plugin.options.vars.split(',')
  186. else:
  187. plugin.verbose(2, 'Single variable detected')
  188. plugin.options.vars = [plugin.options.vars, ]
  189. for var in plugin.options.vars:
  190. plugin.verbose(3, 'See if "%s" is a valid variable' % var)
  191. if var not in VARs:
  192. plugin.back2nagios(3, 'Unknown variable "%s"' % var)
  193. if ',' in plugin.options.warn:
  194. plugin.verbose(2, 'Multiple warning thresolds detected')
  195. plugin.options.warn = plugin.options.warn.split(',')
  196. else:
  197. plugin.verbose(2, 'Single warning thresold detected - use for all variables')
  198. plugin.options.warn = [plugin.options.warn, ] * len(plugin.options.vars)
  199. if ',' in plugin.options.crit:
  200. plugin.verbose(2, 'Multiple critical thresolds detected')
  201. plugin.options.crit = plugin.options.crit.split(',')
  202. else:
  203. plugin.verbose(2, 'Single critical thresold detected - use for all variables')
  204. plugin.options.crit = [plugin.options.crit, ] * len(plugin.options.vars)
  205. plugin.verbose(3, 'Length of vars: %s' % len(plugin.options.vars) )
  206. plugin.verbose(3, 'Length of warns: %s' % len(plugin.options.warn) )
  207. plugin.verbose(3, 'Length of crits: %s' % len(plugin.options.crit) )
  208. if not ( len(plugin.options.vars) == len(plugin.options.warn) == len(plugin.options.crit) ):
  209. plugin.back2nagios(3, 'Different length of -V, -w and -c')
  210. # Go!
  211. cmdline = '%s -m -d %s' % (plugin.options.nagiostats, ','.join(plugin.options.vars))
  212. plugin.verbose(1, 'Using command line: %s' % cmdline)
  213. cmdline = shlex.split(cmdline)
  214. try:
  215. cmd = subprocess.Popen(cmdline, stdout=subprocess.PIPE)
  216. outputs = cmd.communicate()[0].rstrip().split('\n')
  217. retcode = cmd.returncode
  218. except OSError:
  219. plugin.back2nagios(3, 'Could not execute "%s"' % cmdline)
  220. plugin.verbose(3, 'Returncode of "nagiostats": %s' % retcode)
  221. if retcode == 254:
  222. plugin.back2nagios(2, 'Could not read "status.dat"')
  223. elif retcode != 0:
  224. plugin.back2nagios(3, 'Unknown return code "%s" - please send output of "-vvv" command line to author!' % retcode)
  225. plugin.verbose(1, 'Asked for variable(s): %s' % ' '.join(plugin.options.vars) )
  226. plugin.verbose(1, 'Got response(s): %s' % ' '.join(outputs) )
  227. plugin.verbose(3, 'Length of vars: %s' % len(outputs) )
  228. plugin.verbose(3, 'Length of output: %s' % len(plugin.options.vars) )
  229. if len(outputs) != len(plugin.options.vars):
  230. plugin.back2nagios(3, 'Did not get expected infos')
  231. for idx in xrange(0, len(plugin.options.vars)):
  232. var = plugin.options.vars[idx]
  233. warn = plugin.options.warn[idx]
  234. crit = plugin.options.crit[idx]
  235. output = (VARs[var]['type'])(outputs[idx])
  236. if VARs[var]['type'] in [float, long, int]:
  237. factor = VARs[var].get('factor')
  238. if factor != None:
  239. output = output * factor
  240. returncode = plugin.value_wc_to_returncode(output, warn, crit)
  241. else:
  242. returncode = plugin.RETURNCODE['OK']
  243. perfdata = []
  244. if VARs[var].get('unit') != None:
  245. perfdata.append({'label':var, 'value':output, 'unit':VARs[var]['unit'], 'warn':warn, 'crit':crit,})
  246. plugin.remember_check(var, returncode, str(output), perfdata=perfdata)
  247. plugin.brain2output()
  248. plugin.exit()