Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion graphite_beacon/alerts.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def __str__(self):
"""String representation."""
return "%s (%s)" % (self.name, self.interval)

def configure(self, name=None, rules=None, query=None, **options):
def configure(self, name=None, rules=None, query=None, override=None, **options):
"""Configure the alert."""
self.name = name
if not name:
Expand All @@ -105,6 +105,8 @@ def configure(self, name=None, rules=None, query=None, **options):
assert query, "%s: Alert's query is invalid" % self.name
self.query = query

self.override = override

interval_raw = options.get('interval', self.reactor.options['interval'])
self.interval = TimeUnit.from_interval(interval_raw)

Expand Down
9 changes: 7 additions & 2 deletions graphite_beacon/handlers/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,22 @@ def init_handler(self):
self.whitelist = self.options.get('alerts_whitelist')
assert self.command_template, 'Command line command is not defined.'

def notify(self, level, *args, **kwargs):
def notify(self, level, alert, *args, **kwargs):
LOGGER.debug("Handler (%s) %s", self.name, level)

def get_alert_name(*args):
name = str(args[0])
# remove time characteristics e.g. (1minute)
return name.rsplit(' ', 1)[0].strip()

command_template = self.command_template
if alert.override and self.name in alert.override:
override = alert.override[self.name]
command_template = override.get('command', command_template)

# Run only for whitelisted names if specified
if not self.whitelist or get_alert_name(*args) in self.whitelist:
command = substitute_variables(self.command_template, level, *args, **kwargs)
command = substitute_variables(command_template, level, alert, *args, **kwargs)
subprocess.Popen(
command,
shell=True,
Expand Down
11 changes: 8 additions & 3 deletions graphite_beacon/handlers/hipchat.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,21 @@ def init_handler(self):
self.client = hc.AsyncHTTPClient()

@gen.coroutine
def notify(self, level, *args, **kwargs):
def notify(self, level, alert, *args, **kwargs):
LOGGER.debug("Handler (%s) %s", self.name, level)

room = self.room
if alert.override and self.name in alert.override:
override = alert.override[self.name]
room = override.get('room', room)

data = {
'message': self.get_short(level, *args, **kwargs).decode('UTF-8'),
'message': self.get_short(level, alert, *args, **kwargs).decode('UTF-8'),
'notify': True,
'color': self.colors.get(level, 'gray'),
'message_format': 'text',
}

yield self.client.fetch('{url}/v2/room/{room}/notification?auth_token={token}'.format(
url=self.options.get('url'), room=self.room, token=self.key), headers={
url=self.options.get('url'), room=room, token=self.key), headers={
'Content-Type': 'application/json'}, method='POST', body=json.dumps(data))
14 changes: 12 additions & 2 deletions graphite_beacon/handlers/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ def init_handler(self):
def notify(self, level, alert, value, target=None, ntype=None, rule=None):
LOGGER.debug("Handler (%s) %s", self.name, level)

url = self.url
params = self.params
method = self.method
if alert.override and self.name in alert.override:
override = alert.override[self.name]
url = override.get('url', url)
params = override.get('params', params)
method = override.get('method', method)

message = self.get_short(level, alert, value, target=target, ntype=ntype, rule=rule)
data = {'alert': alert.name, 'desc': message, 'level': level}
if target:
Expand All @@ -38,6 +47,7 @@ def notify(self, level, alert, value, target=None, ntype=None, rule=None):
data['graph_url'] = alert.get_graph_url(target)
data['value'] = value

data.update(self.params)
data.update(params)
body = urllib.urlencode(data)
yield self.client.fetch(self.url, method=self.method, body=body)
yield self.client.fetch(url, method=method, body=body)

27 changes: 19 additions & 8 deletions graphite_beacon/handlers/slack.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,17 @@ class SlackHandler(AbstractHandler):
'normal': ':white_check_mark:',
}

@staticmethod
def _make_channel_name(channel):
if channel and not channel.startswith(('#', '@')):
channel = '#' + channel
return channel

def init_handler(self):
self.webhook = self.options.get('webhook')
assert self.webhook, 'Slack webhook is not defined.'

self.channel = self.options.get('channel')
if self.channel and not self.channel.startswith(('#', '@')):
self.channel = '#' + self.channel
self.channel = self._make_channel_name(self.options.get('channel'))
self.username = self.options.get('username')
self.client = hc.AsyncHTTPClient()

Expand All @@ -41,16 +45,23 @@ def get_message(self, level, alert, value, target=None, ntype=None, rule=None):
level=level, reactor=self.reactor, alert=alert, value=value, target=target).strip()

@gen.coroutine
def notify(self, level, *args, **kwargs):
def notify(self, level, alert, *args, **kwargs):
LOGGER.debug("Handler (%s) %s", self.name, level)

message = self.get_message(level, *args, **kwargs)
channel = self.channel
username = self.username
if alert.override and self.name in alert.override:
override = alert.override[self.name]
channel = self._make_channel_name(override.get('channel', channel))
username = override.get('username', username)

message = self.get_message(level, alert, *args, **kwargs)
data = dict()
data['username'] = self.username
data['username'] = username
data['text'] = message
data['icon_emoji'] = self.emoji.get(level, ':warning:')
if self.channel:
data['channel'] = self.channel
if channel:
data['channel'] = channel

body = json.dumps(data)
yield self.client.fetch(
Expand Down
23 changes: 16 additions & 7 deletions graphite_beacon/handlers/smtp.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,22 @@ def init_handler(self):
self.options['to'] = [self.options['to']]

@gen.coroutine
def notify(self, level, *args, **kwargs):
def notify(self, level, alert, *args, **kwargs):
LOGGER.debug("Handler (%s) %s", self.name, level)

msg = self.get_message(level, *args, **kwargs)
msg['Subject'] = self.get_short(level, *args, **kwargs)
msg['From'] = self.options['from']
msg['To'] = ", ".join(self.options['to'])
sender = self.options['from']
to = self.options['to']
if alert.override and self.name in alert.override:
override = alert.override[self.name]
sender = override.get('from', sender)
to = override.get('to', to)
if not isinstance(to, (list, tuple)):
to = [to]

msg = self.get_message(level, alert, *args, **kwargs)
msg['Subject'] = self.get_short(level, alert, *args, **kwargs)
msg['From'] = sender
msg['To'] = ", ".join(to)

smtp = SMTP()
yield smtp_connect(smtp, self.options['host'], self.options['port']) # pylint: disable=no-value-for-parameter
Expand All @@ -53,8 +62,8 @@ def notify(self, level, *args, **kwargs):
self.options['password'])

try:
LOGGER.debug("Send message to: %s", ", ".join(self.options['to']))
smtp.sendmail(self.options['from'], self.options['to'], msg.as_string())
LOGGER.debug("Send message to: %s", ", ".join(to))
smtp.sendmail(sender, to, msg.as_string())
finally:
smtp.quit()

Expand Down
12 changes: 9 additions & 3 deletions graphite_beacon/handlers/victorops.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,19 @@ def init_handler(self):
assert self.url, 'REST Endpoint is not defined'

self.routing_key = self.options.get('routing_key', 'everyone')
self.url = urljoin(self.url, self.routing_key)


self.client = hc.AsyncHTTPClient()

@gen.coroutine
def notify(self, level, alert, value, target=None, ntype=None, rule=None):
LOGGER.debug("Handler (%s) %s", self.name, level)
url = self.url
routing_key = self.routing_key
if alert.override and self.name in alert.override:
override = alert.override[self.name]
url = override.get('url', url)
routing_key = override.get('routing_key', routing_key)
url = urljoin(url, routing_key)

message = self.get_short(level, alert, value, target=target, ntype=ntype, rule=rule)
data = {'entity_display_name': alert.name, 'state_message': message, 'message_type': level}
Expand All @@ -36,4 +42,4 @@ def notify(self, level, alert, value, target=None, ntype=None, rule=None):
data['rule'] = rule['raw']
body = json.dumps(data)
headers = {'Content-Type': 'application/json;'}
yield self.client.fetch(self.url, method="POST", body=body, headers=headers)
yield self.client.fetch(url, method="POST", body=body, headers=headers)