author | Tero Marttila <terom@fixme.fi> |
Sat, 06 Nov 2010 16:01:42 +0200 | |
changeset 66 | eb0545ec03e7 |
parent 57 | 31e7421e98af |
permissions | -rw-r--r-- |
21
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
1 |
import re |
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
2 |
|
48
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
3 |
class BaseFilter (object) : |
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
4 |
""" |
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
5 |
A filter object matches incoming lines, to determine how they are handled, classify them, and optionally reformat them |
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
6 |
""" |
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
7 |
|
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
8 |
# the LogWatchModule event to send |
57 | 9 |
label = None |
48
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
10 |
|
57 | 11 |
def __init__ (self, label) : |
12 |
self.label = label |
|
21
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
13 |
|
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
14 |
def test (self, line) : |
48
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
15 |
""" |
53 | 16 |
Match against the given line. See match() for return codes |
17 |
""" |
|
21
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
18 |
|
53 | 19 |
raise NotImplementedError() |
20 |
||
21 |
def match (self, msg) : |
|
22 |
""" |
|
23 |
Match against the given SyslogMessage, and return one of: |
|
48
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
24 |
None - filter did not match, continue |
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
25 |
False - filter matched, line should be dropped |
57 | 26 |
(label, <str>) |
27 |
- filter matched, pass formatted output with given label |
|
48
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
28 |
""" |
53 | 29 |
|
30 |
# default to a full-line match |
|
31 |
return self.test(str(msg)) |
|
48
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
32 |
|
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
33 |
class FullFilter (BaseFilter) : |
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
34 |
""" |
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
35 |
A trivial filter that matches every possible line as-is |
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
36 |
""" |
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
37 |
|
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
38 |
def test (self, line) : |
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
39 |
# pass through |
57 | 40 |
return self.label, line |
48
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
41 |
|
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
42 |
class NullFilter (BaseFilter) : |
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
43 |
""" |
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
44 |
A filter that drops every line matching a given regexp |
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
45 |
""" |
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
46 |
|
53 | 47 |
def __init__ (self, pattern, flags=0) : |
57 | 48 |
# don't need an label |
48
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
49 |
|
21
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
50 |
self.regexp = re.compile(pattern, flags) |
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
51 |
|
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
52 |
def test (self, line) : |
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
53 |
match = self.regexp.search(line) |
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
54 |
|
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
55 |
if match : |
48
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
56 |
# drop |
21
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
57 |
return False |
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
58 |
|
48
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
59 |
class SimpleFilter (BaseFilter) : |
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
60 |
""" |
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
61 |
A simple filter that passes through any lines that match, optionally reformatting them with the given string |
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
62 |
pattern, using the regexp match groups as parameters. |
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
63 |
""" |
21
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
64 |
|
57 | 65 |
def __init__ (self, label, pattern, format=None) : |
66 |
super(SimpleFilter, self).__init__(label) |
|
48
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
67 |
|
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
68 |
# store |
21
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
69 |
self.regexp = re.compile(pattern) |
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
70 |
self.format = format |
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
71 |
|
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
72 |
def test (self, line) : |
48
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
73 |
# match |
21
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
74 |
match = self.regexp.search(line) |
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
75 |
|
48
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
76 |
if not match : |
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
77 |
# continue |
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
78 |
return None |
21
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
79 |
|
48
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
80 |
# reformat? |
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
81 |
if self.format : |
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
82 |
# format with regexp match groups |
57 | 83 |
return self.label, self.format % match.groupdict() |
48
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
84 |
|
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
85 |
else : |
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
86 |
# match as-is |
57 | 87 |
return self.label, line |
21
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
88 |
|
53 | 89 |
class SyslogFilter (BaseFilter) : |
90 |
""" |
|
91 |
A more advanced filter that can match against fields in the syslog message. |
|
92 |
""" |
|
93 |
||
94 |
def __init__ (self, label, pattern=None, program=None, drop=False, format=None, re_flags=0) : |
|
95 |
""" |
|
96 |
Filter using the given criteria: |
|
97 |
||
98 |
label - label match output with given label |
|
99 |
||
100 |
pattern - match message content against given regexp |
|
101 |
program - (optional) case-insensitive match against message tag's program component |
|
102 |
May also be False to indicate no tag |
|
103 |
||
104 |
drop - drop this message if this matches |
|
105 |
format - (optional) format output with given format string |
|
106 |
||
107 |
re_flags - (optional) flags for regular expression |
|
108 |
""" |
|
109 |
||
110 |
# XXX: super(SyslogFilter, self).__init__(label) |
|
111 |
self.label = label |
|
112 |
||
113 |
# store |
|
55 | 114 |
if pattern : |
115 |
self.regexp = re.compile(pattern, re_flags) |
|
116 |
else : |
|
117 |
self.regexp = None |
|
118 |
||
53 | 119 |
self.program = program |
120 |
||
121 |
self.drop = drop |
|
122 |
self.format = format |
|
123 |
||
124 |
def match (self, msg) : |
|
125 |
""" |
|
126 |
Evaluate match on given message |
|
127 |
""" |
|
128 |
||
129 |
# use the SyslogMessage's match method |
|
130 |
match = msg.match(self.regexp, self.program) |
|
131 |
||
132 |
# handle result |
|
133 |
if match is False : |
|
134 |
# nack |
|
135 |
return None |
|
136 |
||
137 |
elif self.drop : |
|
138 |
# halt processing |
|
139 |
return False |
|
140 |
||
141 |
elif self.format : |
|
142 |
# the messages properties |
|
143 |
params = msg.properties() |
|
144 |
||
145 |
# the regexp'd matched params |
|
146 |
params.update(match) |
|
147 |
||
148 |
# formatted output |
|
149 |
return self.label, self.format % params |
|
150 |
||
151 |
else : |
|
152 |
# boring output |
|
153 |
return self.label, str(msg) |
|
154 |
||
155 |
||
48
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
156 |
# matches a timestamp prefix |
21
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
157 |
_timestamp = "\w{3} [0-9 ]\d \d{2}:\d{2}:\d{2}" |
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
158 |
|
48
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
159 |
|
55 | 160 |
# match all lines, but doesn't include the timestamp |
161 |
all = SyslogFilter('all', |
|
162 |
format = "%(hostname)s %(message)s" |
|
21
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
163 |
) |
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
164 |
|
48
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
165 |
# match sudo invocations, reformatting them nicely |
53 | 166 |
sudo = SyslogFilter('sudo', |
167 |
program = "sudo", |
|
56 | 168 |
pattern = r"^\s*(?P<username>\S+) : TTY=(?P<tty>\S+) ; PWD=(?P<pwd>.+?) ; USER=(?P<target_user>\S+) ; COMMAND=(?P<command>.*)", |
53 | 169 |
format = "%(username)s:%(tty)s - %(target_user)s@%(hostname)s:%(pwd)s - %(command)r", |
21
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
170 |
) |
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
171 |
|
48
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
172 |
# match accepted ssh logins |
55 | 173 |
ssh = SyslogFilter('ssh', |
174 |
program = "sshd", |
|
56 | 175 |
pattern = r"^\s*Accepted password for (?P<username>\S+) from (?P<ip>\S+) port (?P<port>\S+) (?P<proto>\S+)", |
55 | 176 |
format = "SSH login for %(username)s@%(hostname)s from %(ip)s:%(port)s", |
21
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
177 |
) |
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
178 |
|
55 | 179 |
# drops all output from cron |
56 | 180 |
# XXX: what about the same from su? |
66 | 181 |
cron_killer = SyslogFilter('cron', |
55 | 182 |
program = "cron", |
183 |
drop = True, |
|
21
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
184 |
) |
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
185 |
|
48
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
186 |
# drops `su nobody` output (from cron) |
66 | 187 |
su_nobody_killer = SyslogFilter('su-nobody', |
56 | 188 |
program = "su", |
189 |
pattern = r"^(Successful su for nobody by root|\+ \?\?\? root:nobody)$", |
|
190 |
re_flags = re.IGNORECASE, |
|
191 |
drop = True |
|
21
aa6df8f9c44a
add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff
changeset
|
192 |
) |
48
ba101beeb062
work on logwatch docs, small tweaks
Tero Marttila <terom@fixme.fi>
parents:
40
diff
changeset
|
193 |