def test_history_no_errors_boundary(self): down = Status.get_by_slug("down") up = Status.get_by_slug("up") now = datetime(2011, 4, 5) event = Event(status=down, service=self.service, start=now, message="HEY") event.put() history = self.service.history(5, up, start=date(2011, 4, 5)) self.assertEquals(history[0]["information"], False)
def test_history_current_status(self): down = Status.get_by_slug("down") up = Status.get_by_slug("up") now = datetime(2011, 4, 4, 12, 51) event = Event(status=down, service=self.service, start=now, message="HEY") event.put() history, = self.service.history(1, up, start=date(2011, 4, 5)) self.assertEquals(history["information"], True)
def post(self, version): if (self.valid_version(version)): name = self.request.get('name', default_value=None) description = self.request.get('description', default_value=None) image = self.request.get('image', default_value=None) level = self.request.get('level', default_value=None) severity = Level.get_severity(level) if name and description and severity and image: slug = slugify.slugify(name) status = Status.get_by_slug(slug) # Update existing resource if status: status.description = description status.severity = severity status.image = image status.name = name status.put() self.json(status.rest(self.base_url(version))) # Create new service else: status = Status(name=name, slug=slug, description=description, severity=severity, image=image) status.put() self.json(status.rest(self.base_url(version))) else: self.error(400, "Bad Data") else: self.error(404, "API Version %s not supported" % version)
def serverisdown (service): # Create a new event with the given status and given service service = Service.get_by_slug(service) status = Status.get_by_slug("down") e = Event(service=service, status=status, message="The server could not be reached") e.put()
def call_api(service, data): '''Submit service status to API''' service = Service.get_by_slug(service) status = Status.get_by_slug(data['status']) e = Event(service=service, status=status, message=data['message']) print json.dumps(data, sort_keys=True, skipkeys=True) e.put()
def post(self, version, status_slug): if (self.valid_version(version)): status = Status.get_by_slug(status_slug) if status: name = self.request.get('name', default_value=None) image = self.request.get('image', default_value=None) description = self.request.get('description', default_value=None) level = self.request.get('level', default_value=None) severity = Level.get_severity(level) if description: status.description = description if image: status.image = image if name: status.name = name if severity: status.severity = severity if description or name or image or severity: status.put() self.json(status.rest(self.base_url(version))) else: self.error(404, "Status %s not found" % status_slug) else: self.error(404, "API Version %s not supported" % version)
def serverisup (service): # Create a new event with the given status and given service service = Service.get_by_slug(service) status = Status.get_by_slug("up") e = Event(service=service, status=status, message="The server is responding.") e.put()
def serverisdown(service): # Create a new event with the given status and given service service = Service.get_by_slug(service) status = Status.get_by_slug("down") e = Event(service=service, status=status, message="The server could not be reached") e.put()
def serverisup(service): # Create a new event with the given status and given service service = Service.get_by_slug(service) status = Status.get_by_slug("up") e = Event(service=service, status=status, message="The server is responding.") e.put()
def get(self, version, status_slug): if not self.valid_version(version): self.error(404, "API Version %s not supported" % version) return status = Status.get_by_slug(status_slug) if not status: self.error(404, "No status with the slug %s found" % status_slug) return self.json(status.rest(self.base_url(version)))
def update_status(service_slug, status_type, message): service = Service.get_by_slug(service_slug) status = Status.get_by_slug(status_type) cur_event = service.events.order('-start').fetch(1) if cur_event and cur_event[0].status.slug != status.slug: e = Event(service=service, status=status, message=message) e.put() invalidate_cache()
def get(self, version, status_slug): logging.debug("CurrentStatusHandler#get") if (self.valid_version(version)): status = Status.get_by_slug(status_slug) if (status): self.json(status.rest(self.base_url(version))) else: self.error(404, "No status %s for Service %s" % status_slug) else: self.error(404, "API Version %s not supported" % version)
def get(self, slug): status = Status.get_by_slug(slug) if not status: self.not_found() return td = { "statuses_selected": True, "status": status, } td.update(site.default_template_data()) self.render(td, 'admin/status_delete.html')
def post(self, version, service_slug): if not self.valid_version(version): self.error(404, "API Version %s not supported" % version) return status_slug = self.request.get("status", default_value=None) message = self.request.get("message", default_value=None) informational = self.request.get("informational", default_value=None) if not message: self.error(400, "Event message is required") return service = Service.get_by_slug(service_slug) if not service: self.error(404, "Service %s not found" % service_slug) return if not status_slug: event = service.current_event() if event: status = event.status else: status = Status.get_default() else: status = Status.get_by_slug(status_slug) if not status: self.error(404, "Status %s not found" % status_slug) return e = Event(status=status, service=service, message=message) e.informational = informational and informational == "true" e.put() # Queue up a task that calls the Twitter API to make a tweet. if self.request.get('tweet'): logging.info( 'Attempting to post a tweet for the latest event via async GAE task queue.' ) taskqueue.add(url='/admin/tweet', params={ 'service_name': service.name, 'status_name': status.name, 'message': message }) invalidate_cache() self.json(e.rest(self.base_url(version)))
def post(self, version, status_slug): if not self.valid_version(version): self.error(404, "API Version %s not supported" % version) return status = Status.get_by_slug(status_slug) if not status: self.error(404, "No status with the slug %s found" % status_slug) return name = self.request.get('name', default_value=None) image_slug = self.request.get('image', default_value=None) image = None default = self.request.get('default', default_value=None) description = self.request.get('description', default_value=None) if image_slug is not None: image = Image.get_by_slug(image_slug) if image is None: self.error( 400, "An Image with the " "slug %s doesn't exist" % image_slug) return status.image = image.path if description is not None: status.description = description if default is not None and default in ["false", "true"]: # Reset default status if default == "true": for stat in Status.all().filter("default", True): stat.default = False stat.put() status.default = default == "true" if name is not None: status.name = name if description or name or image or default: status.put() invalidate_cache() self.json(status.rest(self.base_url(version)))
def test_history_order_late_month(self): start = date(2011, 4, 5) up = Status.get_by_slug("up") history = self.service.history(5, up, start=start) history_days = [h["day"] for h in history] expected = [ date(2011, 4, 4), date(2011, 4, 3), date(2011, 4, 2), date(2011, 4, 1), date(2011, 3, 31), ] self.assertEquals(history_days, expected)
def test_history_order_late_month(self): start = date(2011, 4, 5) up = Status.get_by_slug("up") history = self.service.history(5, up, start=start) history_days = [ h["day"] for h in history ] expected = [ date(2011, 4, 4), date(2011, 4, 3), date(2011, 4, 2), date(2011, 4, 1), date(2011, 3, 31), ] self.assertEquals(history_days, expected)
def post(self, version): if not self.valid_version(version): self.error(404, "API Version %s not supported" % version) return name = self.request.get('name', default_value=None) description = self.request.get('description', default_value=None) image_slug = self.request.get('image', default_value=None) default = self.request.get('default', default_value="false") if default not in ["true", "false"]: self.error(400, "Default must be true or false") return if not name or not description or not image_slug: self.error(400, "Bad Data") return slug = slugify.slugify(name) status = Status.get_by_slug(slug) image = Image.get_by_slug(image_slug) if status is not None: self.error(400, "A Status with the slug %s already exists" % slug) return if image is None: msg = "An Image with the slug %s doesn't exist" % image_slug self.error(400, msg) return # Reset default status if default == "true": for stat in Status.all().filter("default", True): stat.default = False stat.put() default = default == "true" status = Status(name=name, slug=slug, description=description, image=image.path, default=default) status.put() invalidate_cache() self.response.set_status(201) self.json(status.rest(self.base_url(version)))
def post(self, version, status_slug): if not self.valid_version(version): self.error(404, "API Version %s not supported" % version) return status = Status.get_by_slug(status_slug) if not status: self.error(404, "No status with the slug %s found" % status_slug) return name = self.request.get('name', default_value=None) image_slug = self.request.get('image', default_value=None) image = None default = self.request.get('default', default_value=None) description = self.request.get('description', default_value=None) if image_slug is not None: image = Image.get_by_slug(image_slug) if image is None: self.error(400, "An Image with the " "slug %s doesn't exist" % image_slug) return status.image = image.path if description is not None: status.description = description if default is not None and default in ["false", "true"]: # Reset default status if default == "true": for stat in Status.all().filter("default", True): stat.default = False stat.put() status.default = default == "true" if name is not None: status.name = name if description or name or image or default: status.put() invalidate_cache() self.json(status.rest(self.base_url(version)))
def test_history_order(self): start = date(2011, 4, 13) up = Status.get_by_slug("up") history = self.service.history(5, up, start=start) self.assertEquals(len(history), 5) history_days = [h["day"] for h in history] expected = [ date(2011, 4, 12), date(2011, 4, 11), date(2011, 4, 10), date(2011, 4, 9), date(2011, 4, 8), ] self.assertEquals(history_days, expected)
def test_history_order(self): start = date(2011, 4, 13) up = Status.get_by_slug("up") history = self.service.history(5, up, start=start) self.assertEquals(len(history), 5) history_days = [ h["day"] for h in history ] expected = [ date(2011, 4, 12), date(2011, 4, 11), date(2011, 4, 10), date(2011, 4, 9), date(2011, 4, 8), ] self.assertEquals(history_days, expected)
def delete(self, version, status_slug): if not self.valid_version(version): self.error(404, "API Version %s not supported" % version) return status = Status.get_by_slug(status_slug) if not status: self.error(404, "Status %s not found" % status_slug) return # We may want to think more about this delete_multi(Event.query().filter(Event.status == status)) status.delete() self.json(status.rest(self.base_url(version)))
def post(self, version, service_slug): if not self.valid_version(version): self.error(404, "API Version %s not supported" % version) return status_slug = self.request.get("status", default_value=None) message = self.request.get("message", default_value=None) informational = self.request.get("informational", default_value=None) if not message: self.error(400, "Event message is required") return service = Service.get_by_slug(service_slug) if not service: self.error(404, "Service %s not found" % service_slug) return if not status_slug: event = service.current_event() if event: status = event.status else: status = Status.get_default() else: status = Status.get_by_slug(status_slug) if not status: self.error(404, "Status %s not found" % status_slug) return e = Event(status=status, service=service, message=message) e.informational = informational and informational == "true" e.put() # Queue up a task that calls the Twitter API to make a tweet. if self.request.get('tweet'): logging.info('Attempting to post a tweet for the latest event via async GAE task queue.') taskqueue.add(url='/admin/tweet', params={'service_name': service.name, 'status_name': status.name, 'message': message}) #TODO - insert Hipchat notification here logging.info('*** Sending update to Hipchat room') taskqueue.add(url='/admin/hipchat', params={'service_name': service.name, 'status_name': status.name, 'message': message}) invalidate_cache() self.json(e.rest(self.base_url(version)))
def _save_result(self, site, level, message): service = Service.gql('WHERE name = :1', site).get() if not service: return status = Status.get_by_slug(level) if not status: self.response.out.write("Status %s not found" % site) return e = Event(status=status, service=service, message=message) e.informational = False e.put() api.invalidate_cache()
def check_service(self, service, tries_count=0, last_status_slug="", options=None, schedule=True): if not options: options = {} self.log("Checking %(service_name)s" % {"service_name": service.name}) check = self.check_host(options) if check["is_ok"]: tries_count = 0 status_slug = "up" countdown = settings.CHECK_SERVICES_NORMAL_CHECK_INTERVAL else: countdown = settings.CHECK_SERVICES_ERROR_CHECK_INTERVAL tries_count = int(tries_count) + 1 self.log( "Check count: %(count)s, limit is %(limit)s" % {"count": tries_count, "limit": settings.CHECK_SERVICES_MAX_TRIES} ) if check["is_unknown"]: status_slug = "unknown" else: status_slug = "down" if tries_count >= settings.CHECK_SERVICES_MAX_TRIES or check["is_ok"]: if not last_status_slug: last_event = service.current_event() if last_event: last_status_slug = last_event.status.slug else: last_status_slug = Status.get_default().slug if last_status_slug != status_slug: status = Status.get_by_slug(status_slug) logging.info( "%(service_name)s is : %(status)s (was %(last_status)s)" % {"service_name": service.name, "status": status_slug, "last_status": last_status_slug} ) self.update_service(service, status, check["message"]) self.log("invalidate_cache") api.invalidate_cache() self.notify_admin(service, status, check["notification_message"]) last_status_slug = status_slug if schedule: self.schedule_check(service.slug, countdown, tries_count, last_status_slug)
def delete(self, version, status_slug): if not self.valid_version(version): self.error(404, "API Version %s not supported" % version) return status = Status.get_by_slug(status_slug) if not status: self.error(404, "Status %s not found" % status_slug) return # We may want to think more about this events = Event.all().filter('status =', status).fetch(1000) for event in events: event.delete() status.delete() self.json(status.rest(self.base_url(version)))
def test_history_order_early_month(self): start = date(2011, 4, 2) up = Status.get_by_slug("up") history = self.service.history(5, up, start=start) history_days = [ h["day"] for h in history ] expected = [ date(2011, 4, 1), date(2011, 3, 31), date(2011, 3, 30), date(2011, 3, 29), date(2011, 3, 28), ] self.assertEquals(history_days, expected) for h in history: self.assertFalse(h["information"])
def test_history_order_early_month(self): start = date(2011, 4, 2) up = Status.get_by_slug("up") history = self.service.history(5, up, start=start) history_days = [h["day"] for h in history] expected = [ date(2011, 4, 1), date(2011, 3, 31), date(2011, 3, 30), date(2011, 3, 29), date(2011, 3, 28), ] self.assertEquals(history_days, expected) for h in history: self.assertFalse(h["information"])
def delete(self, version, status_slug): logging.debug("StatusInstanceHandler#delete slug=%s" % status_slug) if (self.valid_version(version)): status = Status.get_by_slug(status_slug) if status: # We may want to think more about this events = Event.all().filter('status =', status).fetch(1000) for event in events: event.delete() status.delete() self.json(status.rest(self.base_url(version))) else: self.error(404, "Status %s not found" % service_slug) else: self.error(404, "API Version %s not supported" % version)
def get(self, slug): status = Status.get_by_slug(slug) if not status: self.not_found() return td = { "statuses_selected": True, "status": status, "action": "edit", "url": "/admin/api/v1/statuses/" + slug, "description": status.description, "name": status.name, "image_url": status.image, "images": Image.all().fetch(200), "default": status.default, } td.update(site.default_template_data()) self.render(td, 'admin/status_edit.html')
def post(self, version, service_slug): logging.debug("EventsListHandler#post") if (self.valid_version(version)): status_slug = self.request.get("status", default_value=None) message = self.request.get("message", default_value=None) informational = self.request.get("informational", default_value=None) if message: service = Service.get_by_slug(service_slug) if service: if not status_slug: event = service.current_event() if event: status = event.status else: status = Status.default() else: status = Status.get_by_slug(status_slug) if status: e = Event(status=status, service=service, message=message) e.informational = informational and informational == "true" e.put() self.json(e.rest(self.base_url(version))) else: self.error(404, "Status %s not found" % status_slug) else: self.error(404, "Service %s not found" % service_slug) else: self.error(400, "Event message is required") else: self.error(404, "API Version %s not supported" % version)
def post(self, version, service_slug): if not self.valid_version(version): self.error(404, "API Version %s not supported" % version) return status_slug = self.request.get("status", default_value=None) message = self.request.get("message", default_value=None) informational = self.request.get("informational", default_value=None) if not message: self.error(400, "Event message is required") return service = Service.get_by_slug(service_slug) if not service: self.error(404, "Service %s not found" % service_slug) return if not status_slug: event = service.current_event() if event: status = event.status else: status = Status.get_default() else: status = Status.get_by_slug(status_slug) if not status: self.error(404, "Status %s not found" % status_slug) return e = Event(status=status, service=service, message=message) e.informational = informational and informational == "true" e.put() invalidate_cache() self.json(e.rest(self.base_url(version)))
def run(self): logging.info("Update each status") # For each status for status in Status.all().fetch(100): # Set the status to default status.default = False # Update the status url status.image = "icons/fugue/" + status.image + ".png" # Save the status status.put() # Get the up status and make it default default_status = Status.get_by_slug("up") if default_status is None: logging.error("Could not find the up status") return default_status.default = True default_status.put() logging.info("Set up status as the default")
def run(self): logging.info("Update each status") # For each status for status in Status.query().fetch(100): # Set the status to default status.default = False # Update the status url status.image = "icons/fugue/" + status.image + ".png" # Save the status status.put() # Get the up status and make it default default_status = Status.get_by_slug("up") if default_status is None: logging.error("Could not find the up status") return default_status.default = True default_status.put() logging.info("Set up status as the default")
def test_history_count(self): up = Status.get_by_slug("up") history = self.service.history(10, up, start=date(2011, 4, 5)) self.assertEquals(len(history), 10)
from google.appengine.ext import db from models import Status, Service, Event from datetime import datetime, timedelta, date #foo = Service(name="Service Foo", slug="service-foo", # description="Scalable and reliable foo service across the globe") #foo.put() #bar = Service(name="Service Bar", slug="service-bar", description="Scalable and reliable foo service") #bar.put() #delete = Service(name="Delete Me", slug="delete", description="Delete Me Please") #delete.put() bar = Service.get_by_slug("service-bar") cat = Status.get_by_slug("down") dates = [ datetime(2010, 6, 5), datetime(2010, 6, 10), datetime(2010, 7, 16), datetime(2010, 7, 17), datetime(2010, 8, 31), datetime(2010, 8, 30), datetime(2010, 9, 1), datetime(2010, 9, 2), ] for d in dates: e = Event(service=bar, status=cat, message="Error on date %s" % d.isoformat(), start=d)
from google.appengine.ext import db from models import Status, Service, Event from datetime import datetime, timedelta, date # Create the default statuses Status.install_defaults() # Create Services service = { "name": "Service Foo", "slug": "service-foo", "description": "Scalable and reliable foo service across the globe", } services = [] for i in "ABCDEFGHIJ": foo = Service(name=service["name"] + i, slug=service["slug"] + i, description=service["description"]) foo.put() services.append(foo) # Given one service a bunch of events foo = services[0] bad = Status.get_by_slug("down") for i in range(10): Event(service=foo, status=bad, message="Event %s" % i).put()
def post(self, version, service_slug): if not self.valid_version(version): self.error(404, "API Version %s not supported" % version) return status_slug = self.request.get("status", default_value=None) message = self.request.get("message", default_value=None) informational = self.request.get("informational", default_value=None) if not message: self.error(400, "Event message is required") return service = Service.get_by_slug(service_slug) if not service: self.error(404, "Service %s not found" % service_slug) return last_event = service.current_event() if last_event: old_status = last_event.status if not status_slug: if last_event: status = old_status else: status = Status.get_default() else: status = Status.get_by_slug(status_slug) if not status: self.error(404, "Status %s not found" % status_slug) return e = Event(status=status, service=service, message=message) e.informational = informational and informational == "true" e.put() # Queue up a task that calls the Twitter API to make a tweet. if self.request.get('tweet'): logging.info('Attempting to post a tweet for the latest event via async GAE task queue.') taskqueue.add(url='/admin/tweet', params={'service_name': service.name, 'status_name': status.name, 'message': message}) # Queue up tasks for notifing subscribers via XMPP if service.subscriptions: for subscription in service.subscriptions.filter("type =","xmpp"): mobile = Mobile.all().filter('subscription = ', subscription).get() if mobile: mobile_number = mobile.number else: mobile_number = False params={'address': subscription.address, 'service': service.key(), 'oldstatus': old_status.key(), 'number': mobile_number} logging.info("Adding deferred task: %s %s" % ( subscription.type, params)) taskqueue.add(url='/notify/' + subscription.type, params=params) else: logging.info("No subscriptions for %s" % service.name) invalidate_cache() self.json(e.rest(self.base_url(version)))