Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- '''
- check_rss v .35 - A simple Nagios plugin to check an RSS feed. Created to monitor status of cloud services.
- Requires feedparser and argparse python libraries. For Ubuntu you can install with "sudo apt-get install python-feedparser python-argparse"
- If you find it useful, feel free to leave me a comment/email at http://john.wesorick.com.
- Copyright 2011 John Wesorick (john.wesorick.com)
- 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 3 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, see <http://www.gnu.org/licenses/>.
- '''
- import feedparser
- import argparse
- import sys
- import datetime
- def main(argv=None):
- # Set up our arguments
- try:
- parser = argparse.ArgumentParser(description="check_rss v0.35 - A simple Nagios plugin to check an RSS feed. Created to monitor status of cloud services. ", epilog="notes: If you do not specify any warning or critical conditions, it will always return OK. This will only check the newest feed entry. Copyright 2011 John Wesorick (http://john.wesorick.com)")
- parser.add_argument('-H', dest='rssfeed', help='URL of RSS feed to monitor', action='store', required=True)
- parser.add_argument('-c', '--criticalif', dest='criticalif', help='Comma separated, quoted list of strings that will result in critical condition if PRESENT', action='store')
- parser.add_argument('-C', '--criticalnot', dest='criticalnot', help='Comma separated, quoted list of strings that will result in critical condition if MISSING', action='store')
- parser.add_argument('-w', '--warningif', dest='warningif', help='Comma separated, quoted list of strings that will result in warning condition if PRESENT', action='store')
- parser.add_argument('-W', '--warningnot', dest='warningnot', help='Comma separated, quoted list of strings that will result in warning condition if MISSING', action='store')
- parser.add_argument('-T', '--hours', dest='hours', help='Hours since last post. Will return critical if less than designated amount.', action='store')
- parser.add_argument('-t', '--titleonly', dest='titleonly', help='Search the titles only. The default is to search for strings matching in either the title or description', action='store_true', default=False)
- parser.add_argument('-p', '--perfdata', dest='perfdata', help='If used will keep very basic performance data (0 if OK, 1 if WARNING, 2 if CRITICAL, 3 if UNKNOWN)', action='store_true', default=False)
- parser.add_argument('-v', '--verbosity', dest='verbosity', help='Verbosity level. 0 = Only the title and time is returned. 1 = Title, time and link are returned. 2 = Title, time, link and description are returned (Default)', action='store', default='2')
- args = parser.parse_args()
- except:
- # Something didn't work. We will return an unknown.
- output = ': Invalid argument(s) {usage}'.format(usage=parser.format_usage())
- exitunknown(output)
- perfdata = args.perfdata
- # Parse our feed, getting title, description and link of newest entry.
- rssfeed = args.rssfeed
- if ( rssfeed.find('http://') != 0 ):
- rssfeed = 'http://{rssfeed}'.format(rssfeed=rssfeed)
- try:
- myfeed = feedparser.parse(rssfeed)
- feednumber = 0 #Grabs only the newest entry.
- title = myfeed['entries'][feednumber]['title']
- description = myfeed['entries'][feednumber]['description']
- link = myfeed['entries'][feednumber]['link']
- feeddate = myfeed['entries'][feednumber]['updated_parsed']
- except:
- output = ': Could not parse URL ({rssfeed})'.format(rssfeed=rssfeed)
- exitcritical(output, perfdata)
- # Get the difference in time from last post
- now = datetime.datetime.now()
- orderedfeeddate = datetime.datetime(feeddate.tm_year, feeddate.tm_mon, feeddate.tm_mday, feeddate.tm_hour, feeddate.tm_min)
- orderednowdate = datetime.datetime(now.year, now.month, now.day, now.hour, now.minute)
- timediff = orderednowdate - orderedfeeddate
- hourssinceposted = timediff.days * 24 + timediff.seconds / 60 / 60
- # We will form our response here based on the verbosity levels. This makes the logic below a lot easier.
- if (args.verbosity == '0' ):
- output = ': Posted {hourssinceposted} hrs ago ; {title}'.format(hourssinceposted=hourssinceposted, title=title.encode('utf-8'))
- elif (args.verbosity == '1' ):
- output = ': Posted {hourssinceposted} hrs ago ; Title: {title} ; Link: {link}'.format(hourssinceposted=hourssinceposted, title=title.encode('utf-8'), link=link)
- elif (args.verbosity == '2' ):
- output = ': Posted {hourssinceposted} hrs ago ; Title: {title} ; Description: {description} ; Link: {link}'.format(hourssinceposted=hourssinceposted, title=title.encode('utf-8'), description=description.encode('utf-8'), link=link)
- # Check for strings that match, resulting in critical status
- if ( args.criticalif ):
- criticalif = args.criticalif.lower().split(',')
- for search in criticalif:
- if ( args.titleonly == True ):
- if ( title.lower().find(search) >= 0 ):
- exitcritical(output, perfdata)
- else:
- if ( title.lower().find(search) >= 0 or description.lower().find(search) >= 0 ):
- exitcritical(output, perfdata)
- # Check for strings that are missing, resulting in critical status
- if ( args.criticalnot ):
- stringmatched = False
- criticalnot = args.criticalnot.lower().split(',')
- for search in criticalnot:
- if ( args.titleonly == True ):
- if ( title.lower().find(search) >= 0 ):
- stringmatched = True
- break
- else:
- if ( title.lower().find(search) >= 0 or description.lower().find(search) >= 0 ):
- stringmatched = True
- break
- if not stringmatched:
- print description.lower()
- exitcritical(output, perfdata)
- # Check for time difference (in hours), resulting in critical status
- if ( args.hours ):
- if ( int(hourssinceposted) <= int(args.hours) ):
- exitcritical(output, perfdata)
- # Check for strings that match, resulting in warning status
- if ( args.warningif ):
- warningif = args.warningif.lower().split(',')
- for search in warningif:
- if ( args.titleonly == True ):
- if ( title.lower().find(search) >= 0 ):
- exitwarning(output, perfdata)
- else:
- if ( title.lower().find(search) >= 0 or description.lower().find(search) >= 0 ):
- exitwarning(output, perfdata)
- # Check for strings that are missing, resulting in warning status
- if ( args.warningnot ):
- stringmatched = False
- warningnot = args.warningnot.lower().split(',')
- for search in criticalnot:
- if ( args.titleonly == True ):
- if ( title.lower().find(search) >= 0 ):
- stringmatched = True
- break
- else:
- if ( title.lower().find(search) >= 0 or description.lower().find(search) >= 0 ):
- stringmatched = True
- break
- if not stringmatched:
- print description.lower()
- exitwarning(output, perfdata)
- # If we made it this far, we must be ok
- exitok(output, perfdata)
- def exitok(output, perfdata):
- if ( perfdata ):
- print "OK{output}|'RSS'=0;1;2;0;2".format(output=output)
- else:
- print 'OK{output}'.format(output=output)
- sys.exit(0)
- def exitwarning(output, perfdata):
- if ( perfdata ):
- print "WARNING{output}|'RSS'=1;1;2;0;2".format(output=output)
- else:
- print 'WARNING{output}'.format(output=output)
- sys.exit(1)
- def exitcritical(output, perfdata):
- if ( perfdata ):
- print "CRITICAL{output}|'RSS'=2;1;2;0;2".format(output=output)
- else:
- print 'CRITICAL{output}'.format(output=output)
- sys.exit(2)
- def exitunknown(output):
- sys.exit(3)
- if __name__ == '__main__':
- result = main(sys.argv)
- sys.exit(result)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement