def render_template(self, template): if template is None: return "" data = self.query_rel.latest_query_data.data host = base_url(self.query_rel.org) col_name = self.options["column"] if data["rows"] and col_name in data["rows"][0]: result_value = data["rows"][0][col_name] else: result_value = None context = { "ALERT_NAME": self.name, "ALERT_URL": "{host}/alerts/{alert_id}".format(host=host, alert_id=self.id), "ALERT_STATUS": self.state.upper(), "ALERT_CONDITION": self.options["op"], "ALERT_THRESHOLD": self.options["value"], "QUERY_NAME": self.query_rel.name, "QUERY_URL": "{host}/queries/{query_id}".format( host=host, query_id=self.query_rel.id ), "QUERY_RESULT_VALUE": result_value, "QUERY_RESULT_ROWS": data["rows"], "QUERY_RESULT_COLS": data["columns"], } return mustache_render(template, context)
def send_failure_report(user_id): user = models.User.get_by_id(user_id) errors = [ json_loads(e) for e in redis_connection.lrange(key(user_id), 0, -1) ] if errors: errors.reverse() occurrences = Counter((e.get("id"), e.get("message")) for e in errors) unique_errors = {(e.get("id"), e.get("message")): e for e in errors} context = { "failures": [{ "id": v.get("id"), "name": v.get("name"), "failed_at": v.get("failed_at"), "failure_reason": v.get("message"), "failure_count": occurrences[k], "comment": comment_for(v), } for k, v in unique_errors.items()], "base_url": base_url(user.org), } subject = "Redash failed to execute {} of your scheduled queries".format( len(unique_errors.keys())) html, text = [ render_template("emails/failures.{}".format(f), context) for f in ["html", "txt"] ] send_mail.delay([user.email], subject, html, text) redis_connection.delete(key(user_id))
def send_failure_report(user_id): user = models.User.get_by_id(user_id) errors = [ json_loads(e) for e in redis_connection.lrange(key(user_id), 0, -1) ] if errors: errors.reverse() occurrences = Counter((e.get('id'), e.get('message')) for e in errors) unique_errors = {(e.get('id'), e.get('message')): e for e in errors} context = { 'failures': [{ 'id': v.get('id'), 'name': v.get('name'), 'failed_at': v.get('failed_at'), 'failure_reason': v.get('message'), 'failure_count': occurrences[k], 'comment': comment_for(v) } for k, v in unique_errors.items()], 'base_url': base_url(user.org) } html = render_template('emails/failures.html', **context) text = render_template('emails/failures.txt', **context) subject = "Redash failed to execute {} of your scheduled queries".format( len(unique_errors.keys())) send_mail.delay([user.email], subject, html, text) redis_connection.delete(key(user_id))
def check_alerts_for_query(self, query_id): from redash.wsgi import app logger.debug("Checking query %d for alerts", query_id) query = models.Query.get_by_id(query_id) for alert in query.alerts: alert.query = query new_state = alert.evaluate() passed_rearm_threshold = False if alert.rearm and alert.last_triggered_at: passed_rearm_threshold = alert.last_triggered_at + datetime.timedelta(seconds=alert.rearm) < utils.utcnow() if new_state != alert.state or (alert.state == models.Alert.TRIGGERED_STATE and passed_rearm_threshold ): logger.info("Alert %d new state: %s", alert.id, new_state) old_state = alert.state alert.update_instance(state=new_state, last_triggered_at=utils.utcnow()) if old_state == models.Alert.UNKNOWN_STATE and new_state == models.Alert.OK_STATE: logger.debug("Skipping notification (previous state was unknown and now it's ok).") continue host = base_url(alert.query.org) for subscription in alert.subscriptions: try: subscription.notify(alert, query, subscription.user, new_state, app, host) except Exception as e: logger.warn("Exception: {}".format(e))
def check_alerts_for_query(self, query_id): from redash.wsgi import app logger.debug("Checking query %d for alerts", query_id) query = models.Query.get_by_id(query_id) for alert in query.alerts: alert.query = query new_state = alert.evaluate() passed_rearm_threshold = False if alert.rearm and alert.last_triggered_at: passed_rearm_threshold = alert.last_triggered_at + datetime.timedelta(seconds=alert.rearm) < utils.utcnow() if new_state != alert.state or (alert.state == models.Alert.TRIGGERED_STATE and passed_rearm_threshold ): logger.info("Alert %d new state: %s", alert.id, new_state) old_state = alert.state alert.update_instance(state=new_state, last_triggered_at=utils.utcnow()) if old_state == models.Alert.UNKNOWN_STATE and new_state == models.Alert.OK_STATE: logger.debug("Skipping notification (previous state was unknown and now it's ok).") continue # message = Message html = """ Check <a href="{host}/alerts/{alert_id}">alert</a> / check <a href="{host}/queries/{query_id}">query</a>. """.format(host=base_url(alert.query.org), alert_id=alert.id, query_id=query.id) notify_mail(alert, html, new_state, app) if settings.HIPCHAT_API_TOKEN: notify_hipchat(alert, html, new_state) if settings.WEBHOOK_ENDPOINT: notify_webhook(alert, query, html, new_state)
def notify_subscriptions(alert, new_state): host = utils.base_url(alert.query_rel.org) for subscription in alert.subscriptions: try: subscription.notify(alert, alert.query_rel, subscription.user, new_state, current_app, host) except Exception as e: logger.exception("Error with processing destination")
def notify_webhook(alert, query, html, new_state): try: data = { 'event': 'alert_state_change', 'alert': alert.to_dict(full=False), 'url_base': base_url(query.org) } headers = {'Content-Type': 'application/json'} auth = HTTPBasicAuth(settings.WEBHOOK_USERNAME, settings.WEBHOOK_PASSWORD) if settings.WEBHOOK_USERNAME else None resp = requests.post(settings.WEBHOOK_ENDPOINT, data=json_dumps(data), auth=auth, headers=headers) if resp.status_code != 200: logger.error("webhook send ERROR. status_code => {status}".format(status=resp.status_code)) except Exception: logger.exception("webhook send ERROR.")
def notify_webhook(alert, query, html, new_state): try: data = { 'event': 'alert_state_change', 'alert': alert.to_dict(full=False), 'url_base': base_url(query.org) } headers = {'Content-Type': 'application/json'} auth = HTTPBasicAuth( settings.WEBHOOK_USERNAME, settings.WEBHOOK_PASSWORD) if settings.WEBHOOK_USERNAME else None resp = requests.post(settings.WEBHOOK_ENDPOINT, data=json_dumps(data), auth=auth, headers=headers) if resp.status_code != 200: logger.error("webhook send ERROR. status_code => {status}".format( status=resp.status_code)) except Exception: logger.exception("webhook send ERROR.")
def check_alerts_for_query(self, query_id): from redash.wsgi import app logger.debug("Checking query %d for alerts", query_id) query = models.Query.get_by_id(query_id) for alert in query.alerts: alert.query = query new_state = alert.evaluate() passed_rearm_threshold = False if alert.rearm and alert.last_triggered_at: passed_rearm_threshold = alert.last_triggered_at + datetime.timedelta( seconds=alert.rearm) < utils.utcnow() if new_state != alert.state or (alert.state == models.Alert.TRIGGERED_STATE and passed_rearm_threshold): logger.info("Alert %d new state: %s", alert.id, new_state) old_state = alert.state alert.update_instance(state=new_state, last_triggered_at=utils.utcnow()) if old_state == models.Alert.UNKNOWN_STATE and new_state == models.Alert.OK_STATE: logger.debug( "Skipping notification (previous state was unknown and now it's ok)." ) continue # message = Message html = """ Check <a href="{host}/alerts/{alert_id}">alert</a> / check <a href="{host}/queries/{query_id}">query</a>. """.format(host=base_url(alert.query.org), alert_id=alert.id, query_id=query.id) notify_mail(alert, html, new_state, app) if settings.HIPCHAT_API_TOKEN: notify_hipchat(alert, html, new_state) if settings.WEBHOOK_ENDPOINT: notify_webhook(alert, query, html, new_state)
def _get_job_data(self, query): job_data = super(BigQuery, self)._get_job_data(query) labels = {"App": "redash"} # Add the Owner label with the current user's email address if self._query_user is not None: labels["Owner"] = self._query_user.email # Add all the parsed query metadata as labels to the job parsed_annotation = parse_annotated_query(query) labels.update(parsed_annotation) # Add a full URL to the query for the "Name" label if "Query ID" in parsed_annotation: host = base_url(current_org) labels["Name"] = "{host}/queries/{query_id}".format( host=host, query_id=parsed_annotation["Query ID"]) if labels: job_data["labels"] = labels return job_data
def render_template(self, template): if template is None: return '' data = self.query_rel.latest_query_data.data host = base_url(self.query_rel.org) col_name = self.options['column'] if data['rows'] and col_name in data['rows'][0]: result_value = data['rows'][0][col_name] else: result_value = None context = { 'ALERT_NAME': self.name, 'ALERT_URL': '{host}/alerts/{alert_id}'.format(host=host, alert_id=self.id), 'ALERT_STATUS': self.state.upper(), 'ALERT_CONDITION': self.options['op'], 'ALERT_THRESHOLD': self.options['value'], 'QUERY_NAME': self.query_rel.name, 'QUERY_URL': '{host}/queries/{query_id}'.format(host=host, query_id=self.query_rel.id), 'QUERY_RESULT_VALUE': result_value, 'QUERY_RESULT_ROWS': data['rows'], 'QUERY_RESULT_COLS': data['columns'], } return mustache_render(template, context)
def reset_link_for_user(user): token = invite_token(user) invite_url = "{}/reset/{}".format(base_url(user.org), token) return invite_url
def verify_link_for_user(user): token = invite_token(user) verify_url = "{}/verify/{}".format(base_url(user.org), token) return verify_url