-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Alarms options group partially described.
- Loading branch information
Showing
6 changed files
with
220 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Alarms | ||
====== | ||
|
||
.. automodule:: uwsgiconf.options.alarms | ||
:members: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -50,6 +50,7 @@ API | |
:maxdepth: 3 | ||
|
||
config | ||
grp_alarms | ||
grp_applications | ||
grp_caching | ||
grp_locks | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
from uwsgiconf import Section | ||
|
||
|
||
def test_alarms_basics(assert_lines): | ||
|
||
assert_lines([ | ||
'alarm-msg-size = 10000', | ||
], Section().alarms.set_basic_params(msg_size=10000)) | ||
|
||
assert_lines([ | ||
'alarm-list = true', | ||
], Section().alarms.print_alarms()) | ||
|
||
|
||
def test_alarms_registration(assert_lines): | ||
|
||
alarms = Section().alarms | ||
assert_lines([ | ||
'alarm = my cmd:some', | ||
], alarms.register_alarm(alarms.cls_alarm_command('my', 'some'))) | ||
|
||
alarms = Section().alarms | ||
assert_lines([ | ||
'alarm = mysig signal:17', | ||
], alarms.register_alarm(alarms.cls_alarm_signal('mysig', 17))) | ||
|
||
alarms = Section().alarms | ||
assert_lines([ | ||
'alarm = tomule mule:2', | ||
], alarms.register_alarm(alarms.cls_alarm_mule('tomule', 2))) | ||
|
||
alarms = Section().alarms | ||
assert_lines([ | ||
'plugin = alarm_curl', | ||
'alarm = test2 curl:http://192.168.173.6:9191/argh;auth_pass=foobar;auth_user=topogigio', | ||
], alarms.register_alarm( | ||
alarms.cls_alarm_curl( | ||
'test2', 'http://192.168.173.6:9191/argh', | ||
auth_user='topogigio', auth_pass='foobar'))) | ||
|
||
alarms = Section().alarms | ||
assert_lines([ | ||
'plugin = alarm_xmpp', | ||
'alarm = jab xmpp:idle@some.com;12345;one@some.com,two@some.com', | ||
], alarms.register_alarm( | ||
alarms.cls_alarm_xmpp('jab', 'idle@some.com', '12345', ['one@some.com', 'two@some.com']))) | ||
|
||
|
||
def test_alarms_on_log(assert_lines): | ||
|
||
alarms = Section().alarms | ||
|
||
alarm1 = alarms.cls_alarm_command('mycom', 'some') | ||
alarm2 = alarms.cls_alarm_signal('mysig', 27) | ||
|
||
assert_lines([ | ||
'alarm = mycom cmd:some', | ||
'alarm = mysig signal:27', | ||
'alarm-log = mycom,mysig some text', | ||
], alarms.alarm_on_log([alarm1, alarm2], 'some text')) | ||
|
||
assert_lines([ | ||
'not-alarm-log = mycom other', | ||
], alarms.alarm_on_log(alarm1, 'other', skip=True)) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
from operator import attrgetter | ||
|
||
from ..base import OptionsGroup, ParametrizedValue | ||
from ..utils import listify, filter_locals, make_key_val_string | ||
|
||
|
||
class Alarm(ParametrizedValue): | ||
|
||
def __init__(self, alias, *args, **kwargs): | ||
self.alias = alias or '' | ||
super(Alarm, self).__init__(*args) | ||
|
||
|
||
class AlarmCommand(Alarm): | ||
"""Run a shell command, passing the log line to its stdin.""" | ||
|
||
name = 'cmd' | ||
|
||
def __init__(self, alias, command): | ||
super(AlarmCommand, self).__init__(alias, command) | ||
|
||
|
||
class AlarmSignal(Alarm): | ||
"""Raise an uWSGI signal.""" | ||
|
||
name = 'signal' | ||
|
||
def __init__(self, alias, sig_num): | ||
super(AlarmSignal, self).__init__(alias, sig_num) | ||
|
||
|
||
class AlarmMule(Alarm): | ||
"""Send the log line to a mule waiting for messages.""" | ||
|
||
name = 'mule' | ||
|
||
def __init__(self, alias, mule_id): | ||
super(AlarmMule, self).__init__(alias, mule_id) | ||
|
||
|
||
class AlarmCurl(Alarm): | ||
"""Send the log line to a cURL-able URL.""" | ||
|
||
name = 'curl' | ||
requires_plugin = 'alarm_curl' | ||
args_joiner = ';' | ||
|
||
def __init__( | ||
self, alias, url, method=None, ssl=None, ssl_insecure=None, | ||
auth_user=None, auth_pass=None, | ||
timeout=None, conn_timeout=None, | ||
mail_from=None, mail_to=None, subject=None): | ||
|
||
opts = make_key_val_string( | ||
filter_locals(locals(), drop=['alias', 'url']), | ||
bool_keys=['ssl', 'ssl_insecure'], | ||
items_separator=self.args_joiner, | ||
) | ||
super(AlarmCurl, self).__init__(alias, url, opts) | ||
|
||
|
||
class AlarmXmpp(Alarm): | ||
"""Send the log line via XMPP/jabber.""" | ||
|
||
name = 'xmpp' | ||
requires_plugin = 'alarm_xmpp' | ||
args_joiner = ';' | ||
|
||
def __init__(self, alias, jid, password, recipients): | ||
super(AlarmXmpp, self).__init__(alias, jid, password, ','.join(listify(recipients))) | ||
|
||
|
||
class Alarms(OptionsGroup): | ||
"""Alarms. | ||
This subsystem allows the developer/sysadmin to "announce" | ||
special conditions of an app via various channels. | ||
* http://uwsgi-docs.readthedocs.io/en/latest/AlarmSubsystem.html | ||
""" | ||
|
||
cls_alarm_command = AlarmCommand | ||
cls_alarm_signal = AlarmSignal | ||
cls_alarm_mule = AlarmMule | ||
cls_alarm_curl = AlarmCurl | ||
cls_alarm_xmpp = AlarmXmpp | ||
|
||
def __init__(self, *args, **kwargs): | ||
self._alarms = [] | ||
super(Alarms, self).__init__(*args, **kwargs) | ||
|
||
def set_basic_params(self, msg_size=None, cheap=None, anti_loop_timeout=None): | ||
""" | ||
:param int msg_size: Set the max size of an alarm message in bytes. Default: 8192. | ||
:param bool cheap: Use main alarm thread rather than create dedicated | ||
threads for curl-based alarms | ||
:param int anti_loop_timeout: Tune the anti-loop alarm system. Default: 3 seconds. | ||
""" | ||
self._set('alarm-msg-size', msg_size) | ||
self._set('alarm-cheap', cheap, cast=bool) | ||
self._set('alarm-freq', anti_loop_timeout) | ||
|
||
return self._section | ||
|
||
def print_alarms(self): | ||
"""Print out enabled alarms.""" | ||
|
||
self._set('alarm-list', True, cast=bool) | ||
|
||
return self._section | ||
|
||
def register_alarm(self, alarm): | ||
"""Register (create) an alarm. | ||
:param Alarm|list[Alarms] alarm: Alarm. | ||
""" | ||
for alarm in listify(alarm): | ||
if alarm not in self._alarms: | ||
self._set('alarm', alarm, multi=True) | ||
self._alarms.append(alarm) | ||
|
||
return self._section | ||
|
||
def alarm_on_log(self, alarm, matcher, skip=False): | ||
"""Raise (or skip) the specified alarm when a log line matches the specified regexp. | ||
:param Alarm|list[Alarms] alarm: Alarm. | ||
:param str|unicode matcher: Regular expression to match log line. | ||
:param bool skip: | ||
""" | ||
self.register_alarm(alarm) | ||
|
||
value = '%s %s' % ( | ||
','.join(map(attrgetter('alias'), listify(alarm))), | ||
matcher) | ||
|
||
self._set('not-alarm-log' if skip else 'alarm-log', value) | ||
|
||
return self._section |