check_cups.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #!/usr/bin/env python2
  2. # -*- encoding: utf-8 -*-
  3. #####################################################################
  4. # (c) 2016 by Sven Velt, Germany #
  5. # sven-mymonplugins@velt.biz #
  6. # #
  7. # This file is part of "velt.biz - My Monitoring Plugins" #
  8. # a fork of "team(ix) Monitoring Plugins" in 2015 #
  9. # URL: https://gogs.velt.biz/velt.biz/MyMonPlugins/ #
  10. # #
  11. # This file is free software: you can redistribute it and/or modify #
  12. # it under the terms of the GNU General Public License as published #
  13. # by the Free Software Foundation, either version 2 of the License, #
  14. # or (at your option) any later version. #
  15. # #
  16. # This file is distributed in the hope that it will be useful, but #
  17. # WITHOUT ANY WARRANTY; without even the implied warranty of #
  18. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
  19. # GNU General Public License for more details. #
  20. # #
  21. # You should have received a copy of the GNU General Public License #
  22. # along with this file. If not, see <http://www.gnu.org/licenses/>. #
  23. #####################################################################
  24. import datetime
  25. import re
  26. import subprocess
  27. import sys
  28. import time
  29. try:
  30. from monitoringplugin import MonitoringPlugin
  31. except ImportError:
  32. print '=========================='
  33. print 'AIKS! Python import error!'
  34. print '==========================\n'
  35. print 'Could not find "monitoringplugin.py"!\n'
  36. print 'Did you download "%s"' % os.path.basename(sys.argv[0])
  37. print 'without "monitoringplugin.py"?\n'
  38. print 'Please go back to'
  39. print 'https://gogs.velt.biz/velt.biz/MyMonPlugins and download it,'
  40. print 'or even better:'
  41. print 'get a full archive at http://gogs.velt.biz/velt.biz/MyMonPlugins/releases'
  42. print 'or a master snapshot at http://gogs.velt.biz/velt.biz/MyMonPlugins/archive/master.tar.gz\n'
  43. sys.exit(127)
  44. plugin = MonitoringPlugin(
  45. pluginname='check_cups',
  46. tagforstatusline='CUPS',
  47. description='Check CUPS jobs and printer queues',
  48. version='0.1',
  49. )
  50. plugin.add_cmdlineoption('-P', '--check-printers', 'check_printers', 'check printer queue', default=False, action='store_true' )
  51. plugin.add_cmdlineoption('-J', '--check-jobs', 'check_jobs', 'check job queue', default=False, action='store_true')
  52. plugin.add_cmdlineoption('-w', '', 'warn', 'warning thresold for old jobs (seconds)', default='3600')
  53. plugin.add_cmdlineoption('-c', '', 'crit', 'warning thresold for old jobs (seconds)', default='86400')
  54. plugin.add_cmdlineoption('', '--mymontools-testmode', 'mymontools_testmode', None, default=False, action='store_true')
  55. plugin.parse_cmdlineoptions()
  56. ##############################################################################
  57. ##### Testmode
  58. if plugin.options.mymontools_testmode:
  59. # Because we need tzlocal from dateutil.tz
  60. mymontools_testmode = {}
  61. mymontools_testmode['lpstat -a'] = '''Printer_One accepting requests since 1970-01-01T00:00:00 CEST
  62. Printer_Two accepting requests since 2016-01-01T00:00:00 CEST
  63. Printer_Three accepting requests since 2116-01-01T00:00:00 CEST
  64. Printer_Rejecting not accepting requests since 2016-02-01T00:00:00 CEST -
  65. Rejecting Jobs'''.split('\n')
  66. from dateutil.tz import tzlocal
  67. mymontools_testmode['lpstat -o'] = '''Printer_One-1234 username 12345 1970-01-01T00:00:00 CEST
  68. Printer_Two-1234 username 12345 %s''' % datetime.datetime.now(tzlocal()).strftime('%FT%T %Z')
  69. mymontools_testmode['lpstat -o'] = mymontools_testmode['lpstat -o'].split('\n')
  70. ##############################################################################
  71. def check_printer_queue(output_printer_queue):
  72. lidx = 0
  73. printers = []
  74. printers_bad = []
  75. while lidx < len(output_printer_queue):
  76. printer = output_printer_queue[lidx].split(' ')[0]
  77. if output_printer_queue[lidx].find('not accepting') > 0:
  78. reason = output_printer_queue[(lidx+1)].replace('\t', '').lstrip().rstrip()
  79. printers_bad.append( (printer, reason,) )
  80. lidx += 1
  81. printers.append( printer )
  82. lidx += 1
  83. plugin.remember_check('All Printers', 0, '%d printer%s found' % (len(printers), len(printers) != 1 and 's' or ''), perfdata=[ {'label':'printers', 'value':len(printers), 'unit':''}, ] )
  84. for p in printers_bad:
  85. plugin.remember_check('%s' % p[0], 1, p[1])
  86. ##############################################################################
  87. def check_job_queue(output_job_queue):
  88. try:
  89. import dateutil.parser
  90. from dateutil.tz import tzlocal
  91. except ImportError:
  92. print('Python module "dateutil" required, please install!')
  93. sys.exit(3)
  94. m = re.compile('(\d{4}\D\d{2}\D\d{2}\D\d{2}\D\d{2}\D\d{2}\D\w{3,5})')
  95. nowsecs = long( time.time() )
  96. jobs_warn = []
  97. jobs_crit = []
  98. for line in output_job_queue:
  99. f = m.search(line)
  100. if not f:
  101. continue
  102. tstamp = dateutil.parser.parse(f.group(0))
  103. tsecs = long( tstamp.strftime('%s') )
  104. rc = plugin.value_wc_to_returncode((nowsecs-tsecs), plugin.options.warn, plugin.options.crit)
  105. if rc == 1:
  106. jobs_warn.append(line)
  107. elif rc == 2:
  108. jobs_crit.append(line)
  109. jobs = len(output_job_queue)
  110. jobs_old = len(jobs_warn) + len(jobs_crit)
  111. perfdata = []
  112. perfdata.append( { 'label':'jobs', 'value':'%d' % jobs, 'unit':'', } )
  113. perfdata.append( { 'label':'jobs_old', 'value':'%d' % jobs_old, 'unit':'', } )
  114. plugin.remember_check('Jobs', 0, '%d job%s found' % (jobs, jobs != 1 and 's' or ''), perfdata=perfdata )
  115. for j in jobs_crit:
  116. plugin.remember_check('Job %s' % j.split(' ')[0], 2, m.search(j).group(0) )
  117. for j in jobs_warn:
  118. plugin.remember_check('Job %s' % j.split(' ')[0], 1, m.search(j).group(0) )
  119. ##############################################################################
  120. def call_cmd(cmdline):
  121. if plugin.options.mymontools_testmode:
  122. return (mymontools_testmode.get(' '.join(cmdline)), '', 0)
  123. try:
  124. cmd = subprocess.Popen(cmdline, stdout=subprocess.PIPE)
  125. (sout, serr) = cmd.communicate()
  126. if sout:
  127. sout = sout.lstrip().rstrip().split('\n')
  128. else:
  129. sout = []
  130. except OSError:
  131. plugin.back2nagios(3, 'Could not execute "%s"' % ' '.join(cmdline))
  132. return (sout, serr, cmd.returncode)
  133. ##############################################################################
  134. allchecks = not( plugin.options.check_printers or plugin.options.check_jobs )
  135. if allchecks or plugin.options.check_printers:
  136. (sout, serr, retcode) = call_cmd(['lpstat', '-a'])
  137. check_printer_queue(sout)
  138. if allchecks or plugin.options.check_jobs:
  139. (sout, serr, retcode) = call_cmd(['lpstat', '-o'])
  140. check_job_queue(sout)
  141. # Exit
  142. plugin.brain2output()
  143. plugin.exit()