check_nagiostats.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. #!/usr/bin/python
  2. import os
  3. import shlex
  4. import subprocess
  5. from monitoringplugin import MonitoringPlugin
  6. plugin = MonitoringPlugin(pluginname='check_nagiostats', tagforstatusline='NAGIOSTATS', description='Check Nagios statistics', version='0.1')
  7. NAGIOSTATSs = ['/usr/sbin/nagios3stats', '/usr/local/nagios/bin/nagiostats']
  8. VARs = {
  9. 'PROGRUNTIME': { 'type':str, },
  10. 'PROGRUNTIMETT': { 'type':long, 'unit':'', },
  11. 'STATUSFILEAGE': { 'type':str, },
  12. 'STATUSFILEAGETT': { 'type':long, 'unit':'', },
  13. 'NAGIOSVERSION': { 'type':str, },
  14. 'NAGIOSPID': { 'type':str, },
  15. 'NAGIOSVERPID': { 'type':str, },
  16. 'TOTCMDBUF': { 'type':long, 'unit':'', },
  17. 'USEDCMDBUF': { 'type':long, 'unit':'', },
  18. 'HIGHCMDBUF': { 'type':long, 'unit':'', },
  19. 'NUMSERVICES': { 'type':long, 'unit':'', },
  20. 'NUMSVCOK': { 'type':long, 'unit':'', },
  21. 'NUMSVCWARN': { 'type':long, 'unit':'', },
  22. 'NUMSVCUNKN': { 'type':long, 'unit':'', },
  23. 'NUMSVCCRIT': { 'type':long, 'unit':'', },
  24. 'NUMSVCPROB': { 'type':long, 'unit':'', },
  25. 'NUMSVCCHECKED': { 'type':long, 'unit':'', },
  26. 'NUMSVCSCHEDULED': { 'type':long, 'unit':'', },
  27. 'NUMSVCFLAPPING': { 'type':long, 'unit':'', },
  28. 'NUMSVCDOWNTIME': { 'type':long, 'unit':'', },
  29. 'NUMHOSTS': { 'type':long, 'unit':'', },
  30. 'NUMHSTUP': { 'type':long, 'unit':'', },
  31. 'NUMHSTDOWN': { 'type':long, 'unit':'', },
  32. 'NUMHSTUNR': { 'type':long, 'unit':'', },
  33. 'NUMHSTPROB': { 'type':long, 'unit':'', },
  34. 'NUMHSTCHECKED': { 'type':long, 'unit':'', },
  35. 'NUMHSTSCHEDULED': { 'type':long, 'unit':'', },
  36. 'NUMHSTFLAPPING': { 'type':long, 'unit':'', },
  37. 'NUMHSTDOWNTIME': { 'type':long, 'unit':'', },
  38. 'NUMHSTACTCHK1M': { 'type':long, 'unit':'', },
  39. 'NUMHSTPSVCHK1M': { 'type':long, 'unit':'', },
  40. 'NUMSVCACTCHK1M': { 'type':long, 'unit':'', },
  41. 'NUMSVCPSVCHK1M': { 'type':long, 'unit':'', },
  42. 'NUMHSTACTCHK5M': { 'type':long, 'unit':'', },
  43. 'NUMHSTPSVCHK5M': { 'type':long, 'unit':'', },
  44. 'NUMSVCACTCHK5M': { 'type':long, 'unit':'', },
  45. 'NUMSVCPSVCHK5M': { 'type':long, 'unit':'', },
  46. 'NUMHSTACTCHK15M': { 'type':long, 'unit':'', },
  47. 'NUMHSTPSVCHK15M': { 'type':long, 'unit':'', },
  48. 'NUMSVCACTCHK15M': { 'type':long, 'unit':'', },
  49. 'NUMSVCPSVCHK15M': { 'type':long, 'unit':'', },
  50. 'NUMHSTACTCHK60M': { 'type':long, 'unit':'', },
  51. 'NUMHSTPSVCHK60M': { 'type':long, 'unit':'', },
  52. 'NUMSVCACTCHK60M': { 'type':long, 'unit':'', },
  53. 'NUMSVCPSVCHK60M': { 'type':long, 'unit':'', },
  54. 'AVGACTSVCLAT': { 'type':float, 'unit':'s', 'factor':0.001, },
  55. 'AVGACTSVCEXT': { 'type':float, 'unit':'s', 'factor':0.001, },
  56. 'AVGACTSVCPSC': { 'type':float, 'unit':'%', },
  57. 'AVGPSVSVCLAT': { 'type':float, 'unit':'s', 'factor':0.001, },
  58. 'AVGPSVSVCPSC': { 'type':float, 'unit':'%', },
  59. 'AVGSVCPSC': { 'type':float, 'unit':'%', },
  60. 'AVGACTHSTLAT': { 'type':float, 'unit':'s', 'factor':0.001, },
  61. 'AVGACTHSTEXT': { 'type':float, 'unit':'s', 'factor':0.001, },
  62. 'AVGACTHSTPSC': { 'type':float, 'unit':'%', },
  63. 'AVGPSVHSTLAT': { 'type':float, 'unit':'s', 'factor':0.001, },
  64. 'AVGPSVHSTPSC': { 'type':float, 'unit':'%', },
  65. 'AVGHSTPSC': { 'type':float, 'unit':'%', },
  66. 'MINACTSVCLAT': { 'type':float, 'unit':'s', 'factor':0.001, },
  67. 'MINACTSVCEXT': { 'type':float, 'unit':'s', 'factor':0.001, },
  68. 'MINACTSVCPSC': { 'type':float, 'unit':'%', },
  69. 'MINPSVSVCLAT': { 'type':float, 'unit':'s', 'factor':0.001, },
  70. 'MINPSVSVCPSC': { 'type':float, 'unit':'%', },
  71. 'MINSVCPSC': { 'type':float, 'unit':'%', },
  72. 'MINACTHSTLAT': { 'type':float, 'unit':'s', 'factor':0.001, },
  73. 'MINACTHSTEXT': { 'type':float, 'unit':'s', 'factor':0.001, },
  74. 'MINACTHSTPSC': { 'type':float, 'unit':'%', },
  75. 'MINPSVHSTLAT': { 'type':float, 'unit':'s', 'factor':0.001, },
  76. 'MINPSVHSTPSC': { 'type':float, 'unit':'%', },
  77. 'MINHSTPSC': { 'type':float, 'unit':'%', },
  78. 'MAXACTSVCLAT': { 'type':float, 'unit':'s', 'factor':0.001, },
  79. 'MAXACTSVCEXT': { 'type':float, 'unit':'s', 'factor':0.001, },
  80. 'MAXACTSVCPSC': { 'type':float, 'unit':'%', },
  81. 'MAXPSVSVCLAT': { 'type':float, 'unit':'s', 'factor':0.001, },
  82. 'MAXPSVSVCPSC': { 'type':float, 'unit':'%', },
  83. 'MAXSVCPSC': { 'type':float, 'unit':'%', },
  84. 'MAXACTHSTLAT': { 'type':float, 'unit':'s', 'factor':0.001, },
  85. 'MAXACTHSTEXT': { 'type':float, 'unit':'s', 'factor':0.001, },
  86. 'MAXACTHSTPSC': { 'type':float, 'unit':'%', },
  87. 'MAXPSVHSTLAT': { 'type':float, 'unit':'s', 'factor':0.001, },
  88. 'MAXPSVHSTPSC': { 'type':float, 'unit':'%', },
  89. 'MAXHSTPSC': { 'type':float, 'unit':'%', },
  90. 'NUMACTHSTCHECKS1M': { 'type':long, 'unit':'', },
  91. 'NUMOACTHSTCHECKS1M': { 'type':long, 'unit':'', },
  92. 'NUMCACHEDHSTCHECKS1M': { 'type':long, 'unit':'', },
  93. 'NUMSACTHSTCHECKS1M': { 'type':long, 'unit':'', },
  94. 'NUMPARHSTCHECKS1M': { 'type':long, 'unit':'', },
  95. 'NUMSERHSTCHECKS1M': { 'type':long, 'unit':'', },
  96. 'NUMPSVHSTCHECKS1M': { 'type':long, 'unit':'', },
  97. 'NUMACTSVCCHECKS1M': { 'type':long, 'unit':'', },
  98. 'NUMOACTSVCCHECKS1M': { 'type':long, 'unit':'', },
  99. 'NUMCACHEDSVCCHECKS1M': { 'type':long, 'unit':'', },
  100. 'NUMSACTSVCCHECKS1M': { 'type':long, 'unit':'', },
  101. 'NUMPSVSVCCHECKS1M': { 'type':long, 'unit':'', },
  102. 'NUMEXTCMDS1M': { 'type':long, 'unit':'', },
  103. 'NUMACTHSTCHECKS5M': { 'type':long, 'unit':'', },
  104. 'NUMOACTHSTCHECKS5M': { 'type':long, 'unit':'', },
  105. 'NUMCACHEDHSTCHECKS5M': { 'type':long, 'unit':'', },
  106. 'NUMSACTHSTCHECKS5M': { 'type':long, 'unit':'', },
  107. 'NUMPARHSTCHECKS5M': { 'type':long, 'unit':'', },
  108. 'NUMSERHSTCHECKS5M': { 'type':long, 'unit':'', },
  109. 'NUMPSVHSTCHECKS5M': { 'type':long, 'unit':'', },
  110. 'NUMACTSVCCHECKS5M': { 'type':long, 'unit':'', },
  111. 'NUMOACTSVCCHECKS5M': { 'type':long, 'unit':'', },
  112. 'NUMCACHEDSVCCHECKS5M': { 'type':long, 'unit':'', },
  113. 'NUMSACTSVCCHECKS5M': { 'type':long, 'unit':'', },
  114. 'NUMPSVSVCCHECKS5M': { 'type':long, 'unit':'', },
  115. 'NUMEXTCMDS5M': { 'type':long, 'unit':'', },
  116. 'NUMACTHSTCHECKS15M': { 'type':long, 'unit':'', },
  117. 'NUMOACTHSTCHECKS15M': { 'type':long, 'unit':'', },
  118. 'NUMCACHEDHSTCHECKS15M': { 'type':long, 'unit':'', },
  119. 'NUMSACTHSTCHECKS15M': { 'type':long, 'unit':'', },
  120. 'NUMPARHSTCHECKS15M': { 'type':long, 'unit':'', },
  121. 'NUMSERHSTCHECKS15M': { 'type':long, 'unit':'', },
  122. 'NUMPSVHSTCHECKS15M': { 'type':long, 'unit':'', },
  123. 'NUMACTSVCCHECKS15M': { 'type':long, 'unit':'', },
  124. 'NUMOACTSVCCHECKS15M': { 'type':long, 'unit':'', },
  125. 'NUMCACHEDSVCCHECKS15M': { 'type':long, 'unit':'', },
  126. 'NUMSACTSVCCHECKS15M': { 'type':long, 'unit':'', },
  127. 'NUMPSVSVCCHECKS15M': { 'type':long, 'unit':'', },
  128. 'NUMEXTCMDS15M': { 'type':long, 'unit':'', },
  129. }
  130. plugin.add_cmdlineoption('-C', '', 'checks', 'Use built-in checks (predefined lists of variables)', default='')
  131. plugin.add_cmdlineoption('-V', '', 'vars', 'List of "nagiostats" variables to check', default='')
  132. plugin.add_cmdlineoption('-n', '', 'nagiostats', 'Full path to nagiostat', default='')
  133. plugin.add_cmdlineoption('-w', '', 'warn', 'warning thresold', default='')
  134. plugin.add_cmdlineoption('-c', '', 'crit', 'warning thresold', default='')
  135. plugin.parse_cmdlineoptions()
  136. if not plugin.options.nagiostats:
  137. plugin.verbose(2, 'Auto-detecting path to "nagiostats"...')
  138. for nagiostats in NAGIOSTATSs:
  139. if os.path.exists(nagiostats):
  140. plugin.options.nagiostats = nagiostats
  141. plugin.verbose(2, 'Found it at "%s"' % nagiostats)
  142. break
  143. if not os.path.exists(plugin.options.nagiostats):
  144. plugin.back2nagios(3, 'Could not find "nagiostats"')
  145. if not plugin.options.checks and not plugin.options.vars:
  146. plugin.back2nagios(3, 'Need either "-C" or "-V"')
  147. # FIXME: Built var list out of -C
  148. if ',' in plugin.options.vars:
  149. plugin.verbose(2, 'Multiple variables detected')
  150. plugin.options.vars = plugin.options.vars.split(',')
  151. else:
  152. plugin.verbose(2, 'Single variable detected')
  153. plugin.options.vars = [plugin.options.vars, ]
  154. for var in plugin.options.vars:
  155. plugin.verbose(3, 'See if "%s" is a valid variable' % var)
  156. if var not in VARs:
  157. plugin.back2nagios(3, 'Unknown variable "%s"' % var)
  158. if ',' in plugin.options.warn:
  159. plugin.verbose(2, 'Multiple warning thresolds detected')
  160. plugin.options.warn = plugin.options.warn.split(',')
  161. else:
  162. plugin.verbose(2, 'Single warning thresold detected - use for all variables')
  163. plugin.options.warn = [plugin.options.warn, ] * len(plugin.options.vars)
  164. if ',' in plugin.options.crit:
  165. plugin.verbose(2, 'Multiple critical thresolds detected')
  166. plugin.options.crit = plugin.options.crit.split(',')
  167. else:
  168. plugin.verbose(2, 'Single critical thresold detected - use for all variables')
  169. plugin.options.crit = [plugin.options.crit, ] * len(plugin.options.vars)
  170. plugin.verbose(3, 'Length of vars: %s' % len(plugin.options.vars) )
  171. plugin.verbose(3, 'Length of warns: %s' % len(plugin.options.warn) )
  172. plugin.verbose(3, 'Length of crits: %s' % len(plugin.options.crit) )
  173. if not ( len(plugin.options.vars) == len(plugin.options.warn) == len(plugin.options.crit) ):
  174. plugin.back2nagios(3, 'Different length of -V, -w and -c')
  175. # Go!
  176. cmdline = '%s -m -d %s' % (plugin.options.nagiostats, ','.join(plugin.options.vars))
  177. plugin.verbose(1, 'Using command line: %s' % cmdline)
  178. cmdline = shlex.split(cmdline)
  179. try:
  180. cmd = subprocess.Popen(cmdline, stdout=subprocess.PIPE)
  181. outputs = cmd.communicate()[0].rstrip().split('\n')
  182. retcode = cmd.returncode
  183. except OSError:
  184. plugin.back2nagios(3, 'Could not execute "%s"' % cmdline)
  185. plugin.verbose(3, 'Returncode of "nagiostats": %s' % retcode)
  186. if retcode == 254:
  187. plugin.back2nagios(2, 'Could not read "status.dat"')
  188. elif retcode != 0:
  189. plugin.back2nagios(3, 'Unknown return code "%s" - please send output of "-vvv" command line to author!' % retcode)
  190. plugin.verbose(1, 'Asked for variable(s): %s' % ' '.join(plugin.options.vars) )
  191. plugin.verbose(1, 'Got response(s): %s' % ' '.join(outputs) )
  192. plugin.verbose(3, 'Length of vars: %s' % len(outputs) )
  193. plugin.verbose(3, 'Length of output: %s' % len(plugin.options.vars) )
  194. if len(outputs) != len(plugin.options.vars):
  195. plugin.back2nagios(3, 'Did not get expected infos')
  196. for idx in xrange(0, len(plugin.options.vars)):
  197. var = plugin.options.vars[idx]
  198. warn = plugin.options.warn[idx]
  199. crit = plugin.options.crit[idx]
  200. output = (VARs[var]['type'])(outputs[idx])
  201. if VARs[var]['type'] in [float, long, int]:
  202. factor = VARs[var].get('factor')
  203. if factor != None:
  204. output = output * factor
  205. returncode = plugin.value_wc_to_returncode(output, warn, crit)
  206. else:
  207. returncode = plugin.RETURNCODE['OK']
  208. perfdata = []
  209. if VARs[var].get('unit') != None:
  210. perfdata.append({'label':var, 'value':output, 'unit':VARs[var]['unit'], 'warn':warn, 'crit':crit,})
  211. plugin.remember_check(var, returncode, str(output), perfdata=perfdata)
  212. plugin.brain2output()
  213. plugin.exit()