mirror of
https://github.com/getredash/redash.git
synced 2025-12-25 01:03:20 -05:00
Merge pull request #644 from toyama0919/feature/alert-to-hipchat
Feature: send alert notifications to HipChat or web hook
This commit is contained in:
@@ -621,19 +621,26 @@ class Alert(ModelTimestampsMixin, BaseModel):
|
||||
def all(cls):
|
||||
return cls.select(Alert, User, Query).join(Query).switch(Alert).join(User)
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
'id': self.id,
|
||||
'name': self.name,
|
||||
'query': self.query.to_dict(),
|
||||
'user': self.user.to_dict(),
|
||||
'options': self.options,
|
||||
'state': self.state,
|
||||
'last_triggered_at': self.last_triggered_at,
|
||||
'updated_at': self.updated_at,
|
||||
'created_at': self.created_at
|
||||
def to_dict(self, full=True):
|
||||
d = {
|
||||
'id': self.id,
|
||||
'name': self.name,
|
||||
'options': self.options,
|
||||
'state': self.state,
|
||||
'last_triggered_at': self.last_triggered_at,
|
||||
'updated_at': self.updated_at,
|
||||
'created_at': self.created_at
|
||||
}
|
||||
|
||||
if full:
|
||||
d['query'] = self.query.to_dict()
|
||||
d['user'] = self.user.to_dict()
|
||||
else:
|
||||
d['query_id'] = self._data['query']
|
||||
d['user_id'] = self._data['user']
|
||||
|
||||
return d
|
||||
|
||||
def evaluate(self):
|
||||
data = json.loads(self.query.latest_query_data.data)
|
||||
# todo: safe guard for empty
|
||||
|
||||
@@ -104,6 +104,13 @@ MAIL_ASCII_ATTACHMENTS = parse_boolean(os.environ.get('REDASH_MAIL_ASCII_ATTACHM
|
||||
|
||||
HOST = os.environ.get('REDASH_HOST', '')
|
||||
|
||||
HIPCHAT_API_TOKEN = os.environ.get('REDASH_HIPCHAT_API_TOKEN', None)
|
||||
HIPCHAT_ROOM_ID = os.environ.get('REDASH_HIPCHAT_ROOM_ID', None)
|
||||
|
||||
WEBHOOK_ENDPOINT = os.environ.get('REDASH_WEBHOOK_ENDPOINT', None)
|
||||
WEBHOOK_USERNAME = os.environ.get('REDASH_WEBHOOK_USERNAME', None)
|
||||
WEBHOOK_PASSWORD = os.environ.get('REDASH_WEBHOOK_PASSWORD', None)
|
||||
|
||||
# CORS settings for the Query Result API (and possbily future external APIs).
|
||||
# In most cases all you need to do is set REDASH_CORS_ACCESS_CONTROL_ALLOW_ORIGIN
|
||||
# to the calling domain (or domains in a comma separated list).
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
import time
|
||||
import logging
|
||||
import signal
|
||||
import traceback
|
||||
from flask.ext.mail import Message
|
||||
import redis
|
||||
import hipchat
|
||||
import requests
|
||||
import json
|
||||
from redash.utils import json_dumps
|
||||
from requests.auth import HTTPBasicAuth
|
||||
from celery import Task
|
||||
from celery.result import AsyncResult
|
||||
from celery.utils.log import get_task_logger
|
||||
@@ -252,24 +258,21 @@ def check_alerts_for_query(self, query_id):
|
||||
continue
|
||||
|
||||
# message = Message
|
||||
recipients = [s.email for s in alert.subscribers()]
|
||||
logger.debug("Notifying: %s", recipients)
|
||||
html = """
|
||||
Check <a href="{host}/alerts/{alert_id}">alert</a> / check <a href="{host}/queries/{query_id}">query</a>.
|
||||
""".format(host=settings.HOST, alert_id=alert.id, query_id=query.id)
|
||||
|
||||
with app.app_context():
|
||||
message = Message(recipients=recipients,
|
||||
subject="[{1}] {0}".format(alert.name, new_state.upper()),
|
||||
html=html)
|
||||
notify_mail(alert, html, new_state, app)
|
||||
|
||||
mail.send(message)
|
||||
if settings.HIPCHAT_API_TOKEN:
|
||||
notify_hipchat(alert, html, new_state)
|
||||
|
||||
if settings.WEBHOOK_ENDPOINT:
|
||||
notify_webhook(alert, query, html, new_state)
|
||||
|
||||
def signal_handler(*args):
|
||||
raise InterruptException
|
||||
|
||||
|
||||
@celery.task(bind=True, base=BaseTask, track_started=True)
|
||||
def execute_query(self, query, data_source_id, metadata):
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
@@ -325,7 +328,41 @@ def execute_query(self, query, data_source_id, metadata):
|
||||
def record_event(event):
|
||||
models.Event.record(event)
|
||||
|
||||
|
||||
@celery.task(base=BaseTask)
|
||||
def version_check():
|
||||
run_version_check()
|
||||
|
||||
def notify_hipchat(alert, html, new_state):
|
||||
try:
|
||||
hipchat_client = hipchat.HipChat(token=settings.HIPCHAT_API_TOKEN)
|
||||
message = '[' + new_state.upper() + '] ' + alert.name + '<br />' + html
|
||||
hipchat_client.message_room(settings.HIPCHAT_ROOM_ID, settings.NAME, message, message_format='html')
|
||||
except:
|
||||
logger.exception("hipchat send ERROR.")
|
||||
|
||||
def notify_mail(alert, html, new_state, app):
|
||||
recipients = [s.email for s in alert.subscribers()]
|
||||
logger.debug("Notifying: %s", recipients)
|
||||
try:
|
||||
with app.app_context():
|
||||
message = Message(recipients=recipients,
|
||||
subject="[{1}] {0}".format(alert.name, new_state.upper()),
|
||||
html=html)
|
||||
mail.send(message)
|
||||
except:
|
||||
logger.exception("mail send ERROR.")
|
||||
|
||||
def notify_webhook(alert, query, html, new_state):
|
||||
try:
|
||||
data = {
|
||||
'event': 'alert_state_change',
|
||||
'alert': alert.to_dict(full=False),
|
||||
'url_base': settings.HOST
|
||||
}
|
||||
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:
|
||||
logger.exception("webhook send ERROR.")
|
||||
|
||||
@@ -34,3 +34,4 @@ pycrypto==2.6.1
|
||||
funcy==1.5
|
||||
raven==5.6.0
|
||||
semver==2.2.1
|
||||
python-simple-hipchat==0.4.0
|
||||
|
||||
Reference in New Issue
Block a user