Skip to content

Commit

Permalink
Merge pull request #31 from mogproject/topic-limit-len-output-#30
Browse files Browse the repository at this point in the history
Topic limit len output #30
  • Loading branch information
mogproject committed Jul 27, 2015
2 parents 5712208 + e022807 commit bd9d084
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/easy_alert/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.0.6'
__version__ = '0.0.7'
1 change: 0 additions & 1 deletion src/easy_alert/i18n/messages_en.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
MSG_SSH_ALERT = u'Failed to connect to the following servers using SSH from %(server_id)r.\n\n%(result)s\n\n=='

MSG_CMD_ALERT_FORMAT = u"""[%(level)s] Failed health check: %(name)s
command: %(command)r
actual : {code:%(code)d, stdout:%(stdout)r, stderr:%(stderr)r}
expect : {code:%(expect_code)s, stdout:%(expect_stdout)r, stderr:%(expect_stderr)r}"""
MSG_CMD_ALERT_TITLE = u'Detected Health Check Error'
Expand Down
1 change: 0 additions & 1 deletion src/easy_alert/i18n/messages_ja.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
MSG_SSH_ALERT = u'サーバ %(server_id)s から、以下のサーバに対する SSH 疎通確認に失敗しました。\n\n%(result)s\n\n以上'

MSG_CMD_ALERT_FORMAT = u"""[%(level)s] %(name)s のヘルスチェックに失敗
command: %(command)r
actual : {code:%(code)d, stdout:%(stdout)r, stderr:%(stderr)r}
expect : {code:%(expect_code)s, stdout:%(expect_stdout)r, stderr:%(expect_stderr)r}"""
MSG_CMD_ALERT_TITLE = u'ヘルスチェック異常を検知しました'
Expand Down
18 changes: 10 additions & 8 deletions src/easy_alert/watcher/command_watcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@ class CommandWatcher(Watcher):
expect_code : expected exit code number
expect_stdout : expected stdout pattern in regexp
expect_stderr : expected stderr pattern in regexp
max_output_len : maximum length for each stdout/stderr
Any of {expect_code, expect_stdout, expect_stderr} is required.
"""

DEFAULT_MAX_OUTPUT_LEN = 1024

def __init__(self, command_setting):
if not isinstance(command_setting, list):
raise SettingError('CommandWatcher settings not a list: %s' % command_setting)
Expand All @@ -36,9 +39,6 @@ def __init__(self, command_setting):
name = s['name']
level_str = s['level']
level = [l for l in Level.seq if l.get_keyword() == level_str]
if not level:
raise SettingError('CommandWatcher invalid level: %s' % level_str)
level = level[0]
command = s['command']
expect_code = s.get('expect_code')
if expect_code:
Expand All @@ -49,15 +49,18 @@ def __init__(self, command_setting):
expect_stderr = s.get('expect_stderr')
if expect_stderr:
expect_stderr = re.compile(expect_stderr)
max_output_len = int(s.get('max_output_len', self.DEFAULT_MAX_OUTPUT_LEN))
except KeyError as e:
raise SettingError('CommandWatcher not found config key: %s' % e)
except Exception as e:
raise SettingError('CommandWatcher settings syntax error: %s' % e)

if not level:
raise SettingError('CommandWatcher invalid level: %s' % level_str)
if not any([expect_code, expect_stdout, expect_stderr]):
raise SettingError('CommandWatcher any of expect_code, expect_stdout or expect_stderr should be set.')

settings.append((name, level, command, expect_code, expect_stdout, expect_stderr))
settings.append((name, level[0], command, expect_code, expect_stdout, expect_stderr, max_output_len))

super(CommandWatcher, self).__init__(settings=settings)

Expand All @@ -68,16 +71,15 @@ def watch(self):
start_time = datetime.now()

result = []
for name, level, command, expect_code, expect_stdout, expect_stderr in self.settings:
for name, level, command, expect_code, expect_stdout, expect_stderr, max_output_len in self.settings:
code, stdout, stderr = self._execute_external_command(command)
if self._should_alert(code, stdout, stderr, expect_code, expect_stdout, expect_stderr):
message = MSG_CMD_ALERT_FORMAT % {
'level': level.get_text(),
'name': name,
'command': command,
'code': code,
'stdout': stdout,
'stderr': stderr,
'stdout': stdout[:max_output_len],
'stderr': stderr[:max_output_len],
'expect_code': expect_code,
'expect_stdout': expect_stdout.pattern if expect_stdout else None,
'expect_stderr': expect_stderr.pattern if expect_stderr else None,
Expand Down
2 changes: 1 addition & 1 deletion src/easy_alert/watcher/watcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ def watch(self):
"""abstract method"""

def after_success(self):
pass
"""do nothing in default"""
50 changes: 50 additions & 0 deletions tests/easy_alert/watcher/test_command_watcher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import sys
import logging
import re
from easy_alert.setting.setting_error import SettingError
from easy_alert.watcher.command_watcher import CommandWatcher
from easy_alert.entity.level import Level

if sys.version_info < (2, 7):
import unittest2 as unittest
else:
import unittest


class TestCommandWatcher(unittest.TestCase):
def test_init_error(self):
def assert_err(setting, expected):
with self.assertRaises(SettingError) as cm:
CommandWatcher(setting)
self.assertEqual(cm.exception.args[0], expected)

assert_err('xxx', 'CommandWatcher settings not a list: xxx')
assert_err({}, 'CommandWatcher settings not a list: {}')
assert_err([[]], 'CommandWatcher settings not a dict: []')
assert_err([{}], "CommandWatcher not found config key: 'name'")
assert_err([{'name': 'name'}], "CommandWatcher not found config key: 'level'")
assert_err([{'name': 'name', 'level': 'error'}], "CommandWatcher not found config key: 'command'")
assert_err([{'name': 'name', 'level': 'xxx', 'command': 'echo'}], "CommandWatcher invalid level: xxx")
assert_err([{'name': 'name', 'level': 'error', 'command': 'echo'}],
"CommandWatcher any of expect_code, expect_stdout or expect_stderr should be set.")
assert_err([{'name': 'name', 'level': 'error', 'command': 'echo', 'expect_code': 'a'}],
"CommandWatcher settings syntax error: invalid literal for int() with base 10: 'a'")
assert_err([{'name': 'name', 'level': 'error', 'command': 'echo', 'expect_stdout': '.['}],
"CommandWatcher settings syntax error: unexpected end of regular expression")
assert_err([{'name': 'name', 'level': 'error', 'command': 'echo', 'expect_stderr': '.['}],
"CommandWatcher settings syntax error: unexpected end of regular expression")
assert_err([{'name': 'name', 'level': 'error', 'command': 'echo', 'max_output_len': 'a'}],
"CommandWatcher settings syntax error: invalid literal for int() with base 10: 'a'")

def test_init_normal(self):
s = [
{'name': 'n1', 'level': 'warn', 'command': 'echo abcdefgh', 'expect_code': 0, 'expect_stdout': 'cde'},
{'name': 'n2', 'level': 'error', 'command': 'echo abcdefgh', 'expect_code': 0, 'expect_stdout': 'cdf'},
{'name': 'n3', 'level': 'warn', 'command': 'echo abcdefgh', 'expect_code': 1, 'expect_stdout': 'cde',
'max_output_len': 5},
]
self.assertEqual(CommandWatcher(s).settings, [
('n1', Level(logging.WARN), 'echo abcdefgh', 0, re.compile('cde'), None, 1024),
('n2', Level(logging.ERROR), 'echo abcdefgh', 0, re.compile('cdf'), None, 1024),
('n3', Level(logging.WARN), 'echo abcdefgh', 1, re.compile('cde'), None, 5),
])

0 comments on commit bd9d084

Please sign in to comment.