Fix typecheck idiom in cmk/gui/{plugins,wato}
[check_mk.git] / cmk / gui / wato / pages / pattern_editor.py
blobe3084347e2263b1e6469b40663bb2afed70d60fe
1 #!/usr/bin/env python
2 # -*- encoding: utf-8; py-indent-offset: 4 -*-
3 # +------------------------------------------------------------------+
4 # | ____ _ _ __ __ _ __ |
5 # | / ___| |__ ___ ___| | __ | \/ | |/ / |
6 # | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
7 # | | |___| | | | __/ (__| < | | | | . \ |
8 # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
9 # | |
10 # | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
11 # +------------------------------------------------------------------+
13 # This file is part of Check_MK.
14 # The official homepage is at http://mathias-kettner.de/check_mk.
16 # check_mk is free software; you can redistribute it and/or modify it
17 # under the terms of the GNU General Public License as published by
18 # the Free Software Foundation in version 2. check_mk is distributed
19 # in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
20 # out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 # PARTICULAR PURPOSE. See the GNU General Public License for more de-
22 # tails. You should have received a copy of the GNU General Public
23 # License along with GNU Make; see the file COPYING. If not, write
24 # to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
25 # Boston, MA 02110-1301 USA.
26 """Mode for trying out the logwatch patterns"""
28 import re
30 import cmk.gui.watolib as watolib
31 import cmk.gui.table as table
32 import cmk.gui.forms as forms
33 from cmk.gui.htmllib import HTML
34 from cmk.gui.i18n import _
35 from cmk.gui.globals import html
36 from cmk.gui.exceptions import MKUserError
38 from cmk.gui.plugins.wato import (
39 WatoMode,
40 mode_registry,
41 global_buttons,
45 @mode_registry.register
46 class ModePatternEditor(WatoMode):
47 @classmethod
48 def name(cls):
49 return "pattern_editor"
51 @classmethod
52 def permissions(cls):
53 return ["pattern_editor"]
55 def _from_vars(self):
56 self._hostname = html.var('host', '')
57 # TODO: validate all fields
58 self._item = html.var('file', '')
59 self._match_txt = html.var('match', '')
61 self._host = watolib.Folder.current().host(self._hostname)
63 if self._hostname and not self._host:
64 raise MKUserError(None, _("This host does not exist."))
66 def title(self):
67 if not self._hostname and not self._item:
68 return _("Logfile Pattern Analyzer")
69 elif not self._hostname:
70 return _("Logfile Patterns of Logfile %s on all Hosts") % (self._item)
71 elif not self._item:
72 return _("Logfile Patterns of Host %s") % (self._hostname)
73 return _("Logfile Patterns of Logfile %s on Host %s") % (self._item, self._hostname)
75 def buttons(self):
76 global_buttons()
77 if self._host:
78 if self._item:
79 title = _("Show Logfile")
80 else:
81 title = _("Host Logfiles")
83 html.context_button(
84 title,
85 html.makeuri_contextless([("host", self._hostname), ("file", self._item)],
86 filename="logwatch.py"), 'logwatch')
88 html.context_button(_('Edit Logfile Rules'), watolib.folder_preserving_link([
89 ('mode', 'edit_ruleset'),
90 ('varname', 'logwatch_rules')
91 ]),
92 'edit'
95 def page(self):
96 html.help(_('On this page you can test the defined logfile patterns against a custom text, '
97 'for example a line from a logfile. Using this dialog it is possible to analyze '
98 'and debug your whole set of logfile patterns.'))
100 self._show_try_form()
101 self._show_patterns()
103 def _show_try_form(self):
104 html.begin_form('try')
105 forms.header(_('Try Pattern Match'))
106 forms.section(_('Hostname'))
107 html.text_input('host')
108 forms.section(_('Logfile'))
109 html.text_input('file')
110 forms.section(_('Text to match'))
111 html.help(_('You can insert some text (e.g. a line of the logfile) to test the patterns defined '
112 'for this logfile. All patterns for this logfile are listed below. Matching patterns '
113 'will be highlighted after clicking the "Try out" button.')
115 html.text_input('match', cssclass='match', size=100)
116 forms.end()
117 html.button('_try', _('Try out'))
118 html.del_var('folder') # Never hand over the folder here
119 html.hidden_fields()
120 html.end_form()
122 def _show_patterns(self):
123 import cmk.gui.logwatch as logwatch
124 collection = watolib.SingleRulesetRecursively("logwatch_rules")
125 collection.load()
126 ruleset = collection.get("logwatch_rules")
128 html.h3(_('Logfile Patterns'))
129 if ruleset.is_empty():
130 html.open_div(class_="info")
131 html.write_text('There are no logfile patterns defined. You may create '
132 'logfile patterns using the <a href="%s">Rule Editor</a>.' %
133 watolib.folder_preserving_link([
134 ('mode', 'edit_ruleset'),
135 ('varname', 'logwatch_rules'),
137 html.close_div()
139 # Loop all rules for this ruleset
140 already_matched = False
141 abs_rulenr = 0
142 for folder, rulenr, rule in ruleset.get_rules():
143 # Check if this rule applies to the given host/service
144 if self._hostname:
145 # If hostname (and maybe filename) try match it
146 rule_matches = rule.matches_host_and_item(watolib.Folder.current(), self._hostname,
147 self._item)
148 elif self._item:
149 # If only a filename is given
150 rule_matches = rule.matches_item()
151 else:
152 # If no host/file given match all rules
153 rule_matches = True
155 html.begin_foldable_container(
156 "rule",
157 "%s" % abs_rulenr,
158 True,
159 HTML("<b>Rule #%d</b>" % (abs_rulenr + 1)),
160 indent=False)
161 table.begin("pattern_editor_rule_%d" % abs_rulenr, sortable=False)
162 abs_rulenr += 1
164 # TODO: What's this?
165 pattern_list = rule.value
166 if isinstance(pattern_list, dict):
167 pattern_list = pattern_list["reclassify_patterns"]
169 # Each rule can hold no, one or several patterns. Loop them all here
170 for state, pattern, comment in pattern_list:
171 match_class = ''
172 disp_match_txt = ''
173 match_img = ''
174 if rule_matches:
175 # Applies to the given host/service
176 reason_class = 'reason'
178 matched = re.search(pattern, self._match_txt)
179 if matched:
181 # Prepare highlighted search txt
182 match_start = matched.start()
183 match_end = matched.end()
184 disp_match_txt = html.render_text(self._match_txt[:match_start]) \
185 + html.render_span(self._match_txt[match_start:match_end], class_="match")\
186 + html.render_text(self._match_txt[match_end:])
188 if already_matched == False:
189 # First match
190 match_class = 'match first'
191 match_img = 'match'
192 match_title = _('This logfile pattern matches first and will be used for '
193 'defining the state of the given line.')
194 already_matched = True
195 else:
196 # subsequent match
197 match_class = 'match'
198 match_img = 'imatch'
199 match_title = _('This logfile pattern matches but another matched first.')
200 else:
201 match_img = 'nmatch'
202 match_title = _('This logfile pattern does not match the given string.')
203 else:
204 # rule does not match
205 reason_class = 'noreason'
206 match_img = 'nmatch'
207 match_title = _('The rule conditions do not match.')
209 table.row(css=reason_class)
210 table.cell(_('Match'))
211 html.icon(match_title, "rule%s" % match_img)
213 cls = ''
214 if match_class == 'match first':
215 cls = 'svcstate state%d' % logwatch.level_state(state)
216 table.cell(_('State'), logwatch.level_name(state), css=cls)
217 table.cell(_('Pattern'), html.render_tt(pattern))
218 table.cell(_('Comment'), html.render_text(comment))
219 table.cell(_('Matched line'), disp_match_txt)
221 table.row(fixed=True)
222 table.cell(colspan=5)
223 edit_url = watolib.folder_preserving_link([
224 ("mode", "edit_rule"),
225 ("varname", "logwatch_rules"),
226 ("rulenr", rulenr),
227 ("host", self._hostname),
228 ("item", watolib.mk_repr(self._item)),
229 ("rule_folder", folder.path()),
231 html.icon_button(edit_url, _("Edit this rule"), "edit")
233 table.end()
234 html.end_foldable_container()