| Éric Lemoine | 6a1abe9 | 2016-11-03 14:02:43 +0000 | [diff] [blame] | 1 | # -*- coding: utf-8 -*- | 
|  | 2 |  | 
|  | 3 | import re | 
|  | 4 |  | 
|  | 5 | _valid_dimension_re = re.compile(r'^[a-z0-9_/-]+$') | 
|  | 6 | _disallowed_dimensions = ('name', 'value', 'hostname', 'member', | 
|  | 7 | 'no_alerting', 'tag_fields') | 
|  | 8 |  | 
|  | 9 |  | 
|  | 10 | def message_matcher(alarm, triggers): | 
|  | 11 | """ | 
|  | 12 | Return an Heka message matcher expression for a given alarm and a | 
|  | 13 | dict of triggers. | 
|  | 14 |  | 
|  | 15 | For example the function may return this: | 
|  | 16 |  | 
|  | 17 | Fields[name] == 'cpu_idle' || Fields[name] = 'cpu_wait' | 
|  | 18 | """ | 
|  | 19 | matchers = set() | 
|  | 20 | for trigger_name in alarm.get('triggers', []): | 
|  | 21 | trigger = triggers.get(trigger_name) | 
|  | 22 | if trigger and trigger.get('enabled', True): | 
|  | 23 | for rule in trigger.get('rules', []): | 
|  | 24 | matcher = "Fields[name] == '{}'".format(rule['metric']) | 
|  | 25 | matchers.add(matcher) | 
|  | 26 | return ' || '.join(matchers) | 
|  | 27 |  | 
|  | 28 |  | 
|  | 29 | def dimensions(alarm): | 
|  | 30 | """ | 
|  | 31 | Return a dict alarm dimensions. Each dimension is validated, and an | 
|  | 32 | Exception is raised if a dimension is invalid. | 
|  | 33 |  | 
|  | 34 | Valid characters are a-z, 0-9, _, - and /. | 
|  | 35 | """ | 
|  | 36 | dimensions = alarm.get('dimension', {}) | 
|  | 37 | for name, value in dimensions.items(): | 
|  | 38 | if name in _disallowed_dimensions: | 
|  | 39 | raise Exception( | 
|  | 40 | '{} is not allowed as a dimension name'.format(name)) | 
|  | 41 | if not _valid_dimension_re.match(name): | 
|  | 42 | raise Exception( | 
|  | 43 | 'Dimension name {} includes disallowed chars'.format(name)) | 
|  | 44 | if not _valid_dimension_re.match(value): | 
|  | 45 | raise Exception( | 
|  | 46 | 'Dimension value {} includes disallowed chars'.format(value)) | 
|  | 47 | return dimensions |