Merge lp:~facundo/ubuntuone-client/ignore-nonutf8-filenames into lp:ubuntuone-client
- ignore-nonutf8-filenames
- Merge into trunk
Proposed by
Facundo Batista
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Facundo Batista | ||||
Approved revision: | 450 | ||||
Merged at revision: | not available | ||||
Proposed branch: | lp:~facundo/ubuntuone-client/ignore-nonutf8-filenames | ||||
Merge into: | lp:ubuntuone-client | ||||
Diff against target: |
511 lines (+225/-35) 6 files modified
data/source_ubuntuone-client.py (+2/-0) tests/syncdaemon/test_dbus.py (+17/-0) tests/syncdaemon/test_eq_inotify.py (+158/-35) ubuntuone/syncdaemon/dbus_interface.py (+14/-0) ubuntuone/syncdaemon/event_queue.py (+25/-0) ubuntuone/syncdaemon/logger.py (+9/-0) |
||||
To merge this branch: | bzr merge lp:~facundo/ubuntuone-client/ignore-nonutf8-filenames | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
dobey (community) | Approve | ||
Natalia Bidart (community) | Approve | ||
Review via email: mp+22238@code.launchpad.net |
Commit message
Ignore all the events from disk when file/dir name is not valid.
Description of the change
Ignore all the events from disk when file/dir name is not valid.
This introduces a new event, FS_INVALID_NAME, and a new specific log to include only alerts when this happens (which are also logged in main log file).
Also, when this event happens, the DBus interface generates a signal to make the system aware of this.
Tests included for everything.
To post a comment you must log in.
- 450. By Facundo Batista
-
Docstring
Revision history for this message
dobey (dobey) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'data/source_ubuntuone-client.py' |
2 | --- data/source_ubuntuone-client.py 2009-10-06 13:50:37 +0000 |
3 | +++ data/source_ubuntuone-client.py 2010-03-26 18:31:32 +0000 |
4 | @@ -27,6 +27,7 @@ |
5 | # things we may want to collect for the report |
6 | u1_client_log = os.path.join(u1_log_path, "syncdaemon.log") |
7 | u1_except_log = os.path.join(u1_log_path, "syncdaemon-exceptions.log") |
8 | +u1_invalidnames_log = os.path.join(u1_log_path, "syncdaemon-invalid-names.log") |
9 | u1_oauth_log = os.path.join(u1_log_path, "oauth-login.log") |
10 | u1_u1sync_log = os.path.join(u1_log_path, "u1sync.log") |
11 | u1_sd_conf = os.path.join("etc", "xdg", "ubuntuone", "syncdaemon.conf") |
12 | @@ -37,6 +38,7 @@ |
13 | def add_info(report): |
14 | """add report info""" |
15 | attach_file_if_exists(report, u1_except_log) |
16 | + attach_file_if_exists(report, u1_invalidnames_log) |
17 | attach_file_if_exists(report, u1_oauth_log) |
18 | attach_file_if_exists(report, u1_usersd_conf) |
19 | attach_file_if_exists(report, u1_sd_conf) |
20 | |
21 | === modified file 'tests/syncdaemon/test_dbus.py' |
22 | --- tests/syncdaemon/test_dbus.py 2010-03-10 22:12:06 +0000 |
23 | +++ tests/syncdaemon/test_dbus.py 2010-03-26 18:31:32 +0000 |
24 | @@ -1133,6 +1133,23 @@ |
25 | self.event_q.push(event_name, *args) |
26 | return d |
27 | |
28 | + def test_invalid_filename(self): |
29 | + """Test the FS_INVALID_NAME signal.""" |
30 | + d = defer.Deferred() |
31 | + |
32 | + def handler(dirname, filename): |
33 | + """Handler for InvalidName signal.""" |
34 | + self.assertTrue(isinstance(dirname, unicode)) |
35 | + self.assertTrue(isinstance(filename, str)) |
36 | + d.callback(True) |
37 | + |
38 | + match = self.bus.add_signal_receiver(handler, |
39 | + signal_name='InvalidName', |
40 | + byte_arrays=True) |
41 | + self.signal_receivers.add(match) |
42 | + self.main.event_q.push('FS_INVALID_NAME', u'test/dir', 'testpath') |
43 | + return d |
44 | + |
45 | def test_share_changed(self): |
46 | """ Test the ShareChanged signal. """ |
47 | share_path = os.path.join(self.main.shares_dir, 'share') |
48 | |
49 | === modified file 'tests/syncdaemon/test_eq_inotify.py' |
50 | --- tests/syncdaemon/test_eq_inotify.py 2010-03-15 17:05:49 +0000 |
51 | +++ tests/syncdaemon/test_eq_inotify.py 2010-03-26 18:31:32 +0000 |
52 | @@ -31,6 +31,18 @@ |
53 | from tests.syncdaemon.test_eventqueue import BaseEQTestCase |
54 | |
55 | |
56 | +class DontHitMe(object): |
57 | + """We shouldn't be called.""" |
58 | + |
59 | + def __init__(self, test_instance): |
60 | + self.test_instance = test_instance |
61 | + |
62 | + def handle_default(self, *a, **k): |
63 | + """Something here? Error!""" |
64 | + self.test_inst.finished_error("Don't hit me! Received %s %s" % (a, k)) |
65 | + |
66 | + |
67 | + |
68 | class WatchTests(BaseEQTestCase): |
69 | """Test the EQ API to add and remove watchs.""" |
70 | |
71 | @@ -393,20 +405,13 @@ |
72 | open(fromfile, "w").close() |
73 | symlpath = os.path.join(testdir, "syml") |
74 | |
75 | - class DontHitMe(object): |
76 | - """we shouldn't be called""" |
77 | - # class-closure, cannot use self, pylint: disable-msg=E0213 |
78 | - def handle_default(innerself, *a): |
79 | - """Something here? Error!""" |
80 | - self.finished_error("don't hit me! received %s" % (a,)) |
81 | - |
82 | def confirm(): |
83 | """check result.""" |
84 | self.finished_ok() |
85 | |
86 | # set up everything and freeze |
87 | self.eq.inotify_add_watch(testdir) |
88 | - self.eq.subscribe(DontHitMe()) |
89 | + self.eq.subscribe(DontHitMe(self)) |
90 | |
91 | os.symlink(fromfile, symlpath) |
92 | reactor.callLater(.1, confirm) |
93 | @@ -1026,13 +1031,6 @@ |
94 | testfile = os.path.join(testdir, "bar") |
95 | os.mkdir(testdir) |
96 | |
97 | - class DontHitMe(object): |
98 | - """we shouldn't be called""" |
99 | - # class-closure, cannot use self, pylint: disable-msg=E0213 |
100 | - def handle_default(innerself, *a): |
101 | - """Something here? Error!""" |
102 | - self.finished_error("don't hit me! received %s" % (a,)) |
103 | - |
104 | def freeze_commit(): |
105 | """release and check result.""" |
106 | d = self.eq.freeze_commit([("FS_DIR_DELETE", "foobar")]) |
107 | @@ -1046,7 +1044,7 @@ |
108 | |
109 | # set up everything and freeze |
110 | self.eq.inotify_add_watch(testdir) |
111 | - self.eq.subscribe(DontHitMe()) |
112 | + self.eq.subscribe(DontHitMe(self)) |
113 | self.eq.freeze_begin(testdir) |
114 | |
115 | open(testfile, "w").close() |
116 | @@ -1132,15 +1130,6 @@ |
117 | class MutedSignalsTests(BaseTwisted): |
118 | """Test that EQ filter some signals on demand.""" |
119 | |
120 | - class DontHitMe(object): |
121 | - """we shouldn't be called""" |
122 | - # class-closure, cannot use self, pylint: disable-msg=E0213 |
123 | - def __init__(innerself, obj): |
124 | - innerself.obj = obj |
125 | - def handle_default(innerself, *a): |
126 | - """Something here? Error!""" |
127 | - innerself.obj.finished_error("don't hit me! received %s" % (a,)) |
128 | - |
129 | def check_filter(self, _=None): |
130 | self.assertFalse(self.eq._processor._to_mute._cnt) |
131 | self.finished_ok() |
132 | @@ -1179,7 +1168,7 @@ |
133 | self.eq.add_to_mute_filter("FS_FILE_CLOSE_NOWRITE", testfile) |
134 | |
135 | self.eq.inotify_add_watch(self.root_dir) |
136 | - self.eq.subscribe(self.DontHitMe(self)) |
137 | + self.eq.subscribe(DontHitMe(self)) |
138 | |
139 | # generate the event |
140 | open(testfile) |
141 | @@ -1194,7 +1183,7 @@ |
142 | self.eq.add_to_mute_filter("FS_FILE_CLOSE_NOWRITE", testfile) |
143 | |
144 | self.eq.inotify_add_watch(self.root_dir) |
145 | - self.eq.subscribe(self.DontHitMe(self)) |
146 | + self.eq.subscribe(DontHitMe(self)) |
147 | |
148 | # generate the event |
149 | fh.close() |
150 | @@ -1209,7 +1198,7 @@ |
151 | self.eq.add_to_mute_filter("FS_FILE_CLOSE_WRITE", testfile) |
152 | |
153 | self.eq.inotify_add_watch(self.root_dir) |
154 | - self.eq.subscribe(self.DontHitMe(self)) |
155 | + self.eq.subscribe(DontHitMe(self)) |
156 | |
157 | # generate the event |
158 | open(testfile, "w").close() |
159 | @@ -1222,7 +1211,7 @@ |
160 | self.eq.add_to_mute_filter("FS_DIR_CREATE", testdir) |
161 | |
162 | self.eq.inotify_add_watch(self.root_dir) |
163 | - self.eq.subscribe(self.DontHitMe(self)) |
164 | + self.eq.subscribe(DontHitMe(self)) |
165 | |
166 | # generate the event |
167 | os.mkdir(testdir) |
168 | @@ -1236,7 +1225,7 @@ |
169 | self.eq.add_to_mute_filter("FS_FILE_DELETE", testfile) |
170 | |
171 | self.eq.inotify_add_watch(self.root_dir) |
172 | - self.eq.subscribe(self.DontHitMe(self)) |
173 | + self.eq.subscribe(DontHitMe(self)) |
174 | |
175 | # generate the event |
176 | os.remove(testfile) |
177 | @@ -1250,7 +1239,7 @@ |
178 | self.eq.add_to_mute_filter("FS_DIR_DELETE", testdir) |
179 | |
180 | self.eq.inotify_add_watch(self.root_dir) |
181 | - self.eq.subscribe(self.DontHitMe(self)) |
182 | + self.eq.subscribe(DontHitMe(self)) |
183 | |
184 | # generate the event |
185 | os.rmdir(testdir) |
186 | @@ -1269,7 +1258,7 @@ |
187 | self.eq.add_to_mute_filter("FS_FILE_MOVE", fromfile, tofile) |
188 | |
189 | self.eq.inotify_add_watch(self.root_dir) |
190 | - self.eq.subscribe(self.DontHitMe(self)) |
191 | + self.eq.subscribe(DontHitMe(self)) |
192 | |
193 | # generate the event |
194 | os.rename(fromfile, tofile) |
195 | @@ -1288,7 +1277,7 @@ |
196 | self.eq.add_to_mute_filter("FS_DIR_MOVE", fromdir, todir) |
197 | |
198 | self.eq.inotify_add_watch(self.root_dir) |
199 | - self.eq.subscribe(self.DontHitMe(self)) |
200 | + self.eq.subscribe(DontHitMe(self)) |
201 | |
202 | # generate the event |
203 | os.rename(fromdir, todir) |
204 | @@ -1307,7 +1296,7 @@ |
205 | self.eq.add_to_mute_filter("FS_FILE_MOVE", fromfile, tofile) |
206 | |
207 | self.eq.inotify_add_watch(self.root_dir) |
208 | - self.eq.subscribe(self.DontHitMe(self)) |
209 | + self.eq.subscribe(DontHitMe(self)) |
210 | |
211 | # generate the event |
212 | os.rename(fromfile, tofile) |
213 | @@ -1325,7 +1314,7 @@ |
214 | self.eq.add_to_mute_filter("FS_FILE_CLOSE_WRITE", tofile) |
215 | |
216 | self.eq.inotify_add_watch(root_dir) |
217 | - self.eq.subscribe(self.DontHitMe(self)) |
218 | + self.eq.subscribe(DontHitMe(self)) |
219 | |
220 | # generate the event |
221 | os.rename(fromfile, tofile) |
222 | @@ -1727,6 +1716,140 @@ |
223 | return self._deferred |
224 | |
225 | |
226 | +class NonUTF8NamesTests(BaseTwisted): |
227 | + """Test the non-utf8 name handling.""" |
228 | + |
229 | + invalid_name = "invalid \xff\xff name" |
230 | + |
231 | + def test_file_open(self): |
232 | + """Test invalid_filename after open a file.""" |
233 | + testfile = os.path.join(self.root_dir, self.invalid_name) |
234 | + open(testfile, "w").close() |
235 | + |
236 | + self.eq.inotify_add_watch(self.root_dir) |
237 | + should_events = [ |
238 | + ('FS_INVALID_NAME', self.root_dir, self.invalid_name), # open |
239 | + ('FS_INVALID_NAME', self.root_dir, self.invalid_name), # close no w |
240 | + ] |
241 | + self.eq.subscribe(DynamicHitMe(should_events, self)) |
242 | + |
243 | + # generate the event |
244 | + open(testfile) |
245 | + return self._deferred |
246 | + |
247 | + def test_file_close_nowrite(self): |
248 | + """Test invalid_filename after a close no write.""" |
249 | + testfile = os.path.join(self.root_dir, self.invalid_name) |
250 | + open(testfile, "w").close() |
251 | + fh = open(testfile) |
252 | + |
253 | + self.eq.inotify_add_watch(self.root_dir) |
254 | + should_events = [ |
255 | + ('FS_INVALID_NAME', self.root_dir, self.invalid_name), # close no w |
256 | + ] |
257 | + self.eq.subscribe(DynamicHitMe(should_events, self)) |
258 | + |
259 | + # generate the event |
260 | + fh.close() |
261 | + return self._deferred |
262 | + |
263 | + def test_file_create_close_write(self): |
264 | + """Test invalid_filename after a create, open and close write.""" |
265 | + testfile = os.path.join(self.root_dir, self.invalid_name) |
266 | + |
267 | + self.eq.inotify_add_watch(self.root_dir) |
268 | + should_events = [ |
269 | + ('FS_INVALID_NAME', self.root_dir, self.invalid_name), # create |
270 | + ('FS_INVALID_NAME', self.root_dir, self.invalid_name), # open |
271 | + ('FS_INVALID_NAME', self.root_dir, self.invalid_name), # close w |
272 | + ] |
273 | + self.eq.subscribe(DynamicHitMe(should_events, self)) |
274 | + |
275 | + # generate the event |
276 | + open(testfile, "w").close() |
277 | + return self._deferred |
278 | + |
279 | + def test_dir_create(self): |
280 | + """Test invalid_filename after a dir create.""" |
281 | + testdir = os.path.join(self.root_dir, self.invalid_name) |
282 | + |
283 | + self.eq.inotify_add_watch(self.root_dir) |
284 | + should_events = [ |
285 | + ('FS_INVALID_NAME', self.root_dir, self.invalid_name), # create |
286 | + ] |
287 | + self.eq.subscribe(DynamicHitMe(should_events, self)) |
288 | + |
289 | + # generate the event |
290 | + os.mkdir(testdir) |
291 | + return self._deferred |
292 | + |
293 | + def test_file_delete(self): |
294 | + """Test invalid_filename after a file delete.""" |
295 | + testfile = os.path.join(self.root_dir, self.invalid_name) |
296 | + open(testfile, "w").close() |
297 | + |
298 | + self.eq.inotify_add_watch(self.root_dir) |
299 | + should_events = [ |
300 | + ('FS_INVALID_NAME', self.root_dir, self.invalid_name), # delete |
301 | + ] |
302 | + self.eq.subscribe(DynamicHitMe(should_events, self)) |
303 | + |
304 | + # generate the event |
305 | + os.remove(testfile) |
306 | + return self._deferred |
307 | + |
308 | + def test_dir_delete(self): |
309 | + """Test invalid_filename after a dir delete.""" |
310 | + testdir = os.path.join(self.root_dir, self.invalid_name) |
311 | + os.mkdir(testdir) |
312 | + |
313 | + self.eq.inotify_add_watch(self.root_dir) |
314 | + should_events = [ |
315 | + ('FS_INVALID_NAME', self.root_dir, self.invalid_name), # delete |
316 | + ] |
317 | + self.eq.subscribe(DynamicHitMe(should_events, self)) |
318 | + |
319 | + # generate the event |
320 | + os.rmdir(testdir) |
321 | + return self._deferred |
322 | + |
323 | + def test_file_move_to(self): |
324 | + """Test invalid_filename after moving a file into a watched dir.""" |
325 | + fromfile = os.path.join(self.root_dir, self.invalid_name) |
326 | + open(fromfile, "w").close() |
327 | + destdir = os.path.join(self.root_dir, "watched_dir") |
328 | + os.mkdir(destdir) |
329 | + destfile = os.path.join(destdir, self.invalid_name) |
330 | + |
331 | + self.eq.inotify_add_watch(destdir) |
332 | + should_events = [ |
333 | + ('FS_INVALID_NAME', destdir, self.invalid_name), # move to |
334 | + ] |
335 | + self.eq.subscribe(DynamicHitMe(should_events, self)) |
336 | + |
337 | + # generate the event |
338 | + os.rename(fromfile, destfile) |
339 | + return self._deferred |
340 | + |
341 | + def test_file_move_from(self): |
342 | + """Test invalid_filename after moving a file from a watched dir.""" |
343 | + fromdir = os.path.join(self.root_dir, "watched_dir") |
344 | + os.mkdir(fromdir) |
345 | + fromfile = os.path.join(fromdir, self.invalid_name) |
346 | + open(fromfile, "w").close() |
347 | + destfile = os.path.join(self.root_dir, self.invalid_name) |
348 | + |
349 | + self.eq.inotify_add_watch(fromdir) |
350 | + should_events = [ |
351 | + ('FS_INVALID_NAME', fromdir, self.invalid_name), # move from |
352 | + ] |
353 | + self.eq.subscribe(DynamicHitMe(should_events, self)) |
354 | + |
355 | + # generate the event |
356 | + os.rename(fromfile, destfile) |
357 | + return self._deferred |
358 | + |
359 | + |
360 | def test_suite(): |
361 | # pylint: disable-msg=C0111 |
362 | return unittest.TestLoader().loadTestsFromName(__name__) |
363 | |
364 | === modified file 'ubuntuone/syncdaemon/dbus_interface.py' |
365 | --- ubuntuone/syncdaemon/dbus_interface.py 2010-03-23 22:48:19 +0000 |
366 | +++ ubuntuone/syncdaemon/dbus_interface.py 2010-03-26 18:31:32 +0000 |
367 | @@ -285,6 +285,11 @@ |
368 | """ Fire a D-BUS signal, notifying an upload has finished. """ |
369 | pass |
370 | |
371 | + @dbus.service.signal(DBUS_IFACE_STATUS_NAME, signature='say') |
372 | + def InvalidName(self, dirname, filename): |
373 | + """Fire a D-BUS signal, notifying an invalid file or dir name.""" |
374 | + pass |
375 | + |
376 | @dbus.service.signal(DBUS_IFACE_STATUS_NAME) |
377 | def StatusChanged(self, status): |
378 | """ Fire a D-BUS signal, notifying that the status of the |
379 | @@ -333,6 +338,10 @@ |
380 | 'size': '0'} |
381 | self.ContentQueueChanged(message) |
382 | |
383 | + def emit_invalid_name(self, dirname, filename): |
384 | + """Emits the signal.""" |
385 | + self.InvalidName(unicode(dirname), str(filename)) |
386 | + |
387 | def emit_status_changed(self, state): |
388 | """Emits the signal.""" |
389 | state_dict = {'name':state.name, |
390 | @@ -551,6 +560,11 @@ |
391 | upload_error=str(error)) |
392 | self.dbus_iface.status.emit_signal_error('UploadFinished', args) |
393 | |
394 | + def handle_FS_INVALID_NAME(self, dirname, filename): |
395 | + """Handle FS_INVALID_NAME.""" |
396 | + self.handle_default('FS_INVALID_NAME', dirname, filename) |
397 | + self.dbus_iface.status.emit_invalid_name(dirname, filename) |
398 | + |
399 | def handle_SYS_STATE_CHANGED(self, state): |
400 | """ handle SYS_STATE_CHANGED """ |
401 | self.handle_default('SYS_STATE_CHANGED', state) |
402 | |
403 | === modified file 'ubuntuone/syncdaemon/event_queue.py' |
404 | --- ubuntuone/syncdaemon/event_queue.py 2010-03-24 12:44:39 +0000 |
405 | +++ ubuntuone/syncdaemon/event_queue.py 2010-03-26 18:31:32 +0000 |
406 | @@ -41,6 +41,7 @@ |
407 | 'FS_DIR_DELETE': ('path',), |
408 | 'FS_FILE_MOVE': ('path_from', 'path_to',), |
409 | 'FS_DIR_MOVE': ('path_from', 'path_to',), |
410 | + 'FS_INVALID_NAME': ('dirname', 'filename',), |
411 | |
412 | 'AQ_FILE_NEW_OK': ('marker', 'new_id'), |
413 | 'AQ_FILE_NEW_ERROR': ('marker', 'error'), |
414 | @@ -184,6 +185,23 @@ |
415 | DEFAULT_HANDLER = "handle_default" # receives (event_name, *args, **kwargs) |
416 | |
417 | |
418 | +def validate_filename(real_func): |
419 | + """Decorator that validates the filename.""" |
420 | + def func(self, event): |
421 | + """If valid, executes original function.""" |
422 | + try: |
423 | + # validate UTF-8 |
424 | + event.name.decode("utf8") |
425 | + except UnicodeDecodeError: |
426 | + dirname = event.path.decode("utf8") |
427 | + self.invnames_log.info("%s in %r: path %r", event.maskname, |
428 | + dirname, event.name) |
429 | + self.eq.push('FS_INVALID_NAME', dirname, event.name) |
430 | + else: |
431 | + real_func(self, event) |
432 | + return func |
433 | + |
434 | + |
435 | class MuteFilter(object): |
436 | """Stores what needs to be muted.""" |
437 | def __init__(self): |
438 | @@ -294,6 +312,8 @@ |
439 | """ |
440 | def __init__(self, eq, ignore_config=None): |
441 | self.log = logging.getLogger('ubuntuone.SyncDaemon.GeneralINotProc') |
442 | + self.invnames_log = logging.getLogger( |
443 | + 'ubuntuone.SyncDaemon.InvalidNames') |
444 | self.eq = eq |
445 | self.held_event = None |
446 | self.timer = None |
447 | @@ -351,11 +371,13 @@ |
448 | self.push_event(self.held_event) |
449 | self.held_event = None |
450 | |
451 | + @validate_filename |
452 | def process_IN_OPEN(self, event): |
453 | """Filter IN_OPEN to make it happen only in files.""" |
454 | if not (event.mask & evtcodes.IN_ISDIR): |
455 | self.push_event(event) |
456 | |
457 | + @validate_filename |
458 | def process_IN_CLOSE_NOWRITE(self, event): |
459 | """Filter IN_CLOSE_NOWRITE to make it happen only in files.""" |
460 | if not (event.mask & evtcodes.IN_ISDIR): |
461 | @@ -369,6 +391,7 @@ |
462 | |
463 | """ |
464 | |
465 | + @validate_filename |
466 | def process_IN_MOVED_FROM(self, event): |
467 | """Capture the MOVED_FROM to maybe syntethize FILE_MOVED.""" |
468 | if self.held_event is not None: |
469 | @@ -409,6 +432,7 @@ |
470 | |
471 | return False |
472 | |
473 | + @validate_filename |
474 | def process_IN_MOVED_TO(self, event): |
475 | """Capture the MOVED_TO to maybe syntethize FILE_MOVED.""" |
476 | if self.held_event is not None: |
477 | @@ -476,6 +500,7 @@ |
478 | if not self._to_mute.pop(event_data): |
479 | self.eq.push(*event_data) |
480 | |
481 | + @validate_filename |
482 | def process_default(self, event): |
483 | """Push the event into the EventQueue.""" |
484 | if self.held_event is not None: |
485 | |
486 | === modified file 'ubuntuone/syncdaemon/logger.py' |
487 | --- ubuntuone/syncdaemon/logger.py 2010-02-15 17:19:53 +0000 |
488 | +++ ubuntuone/syncdaemon/logger.py 2010-03-26 18:31:32 +0000 |
489 | @@ -334,6 +334,7 @@ |
490 | |
491 | LOGFILENAME = os.path.join(LOGFOLDER, 'syncdaemon.log') |
492 | EXLOGFILENAME = os.path.join(LOGFOLDER, 'syncdaemon-exceptions.log') |
493 | +INVALIDLOGFILENAME = os.path.join(LOGFOLDER, 'syncdaemon-invalid-names.log') |
494 | |
495 | LOGBACKUP = 5 # the number of log files to keep around |
496 | |
497 | @@ -397,6 +398,14 @@ |
498 | inotify_logger.setLevel(logging.ERROR) |
499 | inotify_logger.propagate = False |
500 | |
501 | +# invalid filenames log |
502 | +invnames_logger = logging.getLogger("ubuntuone.SyncDaemon.InvalidNames") |
503 | +invnames_logger.setLevel(_DEBUG_LOG_LEVEL) |
504 | +invnames_handler = CustomRotatingFileHandler(filename=INVALIDLOGFILENAME) |
505 | +invnames_handler.setFormatter(basic_formatter) |
506 | +invnames_handler.setLevel(logging.INFO) |
507 | +invnames_logger.addHandler(invnames_handler) |
508 | + |
509 | |
510 | def configure_logging(level, maxBytes, backupCount): |
511 | """configure level, maxBytes and backupCount in all handlers""" |
Nice!