Merge lp:~mterry/duplicity/levelName into lp:duplicity/0.6

Proposed by Michael Terry
Status: Merged
Approved by: Kenneth Loafman
Approved revision: 725
Merged at revision: 734
Proposed branch: lp:~mterry/duplicity/levelName
Merge into: lp:duplicity/0.6
Diff against target: 82 lines (+17/-20)
1 file modified
duplicity/log.py (+17/-20)
To merge this branch: bzr merge lp:~mterry/duplicity/levelName
Reviewer Review Type Date Requested Status
duplicity-team Pending
Review via email: mp+62226@code.launchpad.net

Description of the change

I found this while messing with the Ubuntu One backend, because apparently one of the ubuntuone modules sets a log level using logging.addLevelName (as duplicity does).

While that's probably not something the ubuntuone module should be doing, reading the documentation for the logging module (http://docs.python.org/library/logging.html), I realized that any old piece of code anywhere could add level names, overriding ours (as ubuntuone did).

That's not wise, so I adjusted the logging code to be more careful of that and use our own mapping always.

To post a comment you must log in.
lp:~mterry/duplicity/levelName updated
725. By Michael Terry

fix MachineFilter logic to match new level name code

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'duplicity/log.py'
2--- duplicity/log.py 2011-03-06 15:12:33 +0000
3+++ duplicity/log.py 2011-05-31 18:07:33 +0000
4@@ -3,6 +3,7 @@
5 # Copyright 2002 Ben Escoto <ben@emerose.org>
6 # Copyright 2007 Kenneth Loafman <kenneth@loafman.com>
7 # Copyright 2008 Michael Terry <mike@mterry.name>
8+# Copyright 2011 Canonical Ltd
9 #
10 # This file is part of duplicity.
11 #
12@@ -46,6 +47,14 @@
13 more severe"""
14 return DupToLoggerLevel(verb)
15
16+def LevelName(level):
17+ level = LoggerToDupLevel(level)
18+ if level >= 9: return "DEBUG"
19+ elif level >= 5: return "INFO"
20+ elif level >= 3: return "NOTICE"
21+ elif level >= 1: return "WARNING"
22+ else: return "ERROR"
23+
24 def Log(s, verb_level, code=1, extra=None, force_print=False):
25 """Write s to stderr if verbosity level low enough"""
26 global _logger
27@@ -201,6 +210,7 @@
28 global _logger
29 logging.LogRecord.__init__(self, *args, **kwargs)
30 self.controlLine = controlLine
31+ self.levelName = LevelName(self.levelno)
32
33 class DupLogger(logging.Logger):
34 """Custom logger that creates special code-bearing records"""
35@@ -229,18 +239,6 @@
36 logging.setLoggerClass(DupLogger)
37 _logger = logging.getLogger("duplicity")
38
39- # Set up our special level names
40- logging.addLevelName(DupToLoggerLevel(0), "ERROR")
41- logging.addLevelName(DupToLoggerLevel(1), "WARNING")
42- logging.addLevelName(DupToLoggerLevel(2), "WARNING")
43- logging.addLevelName(DupToLoggerLevel(3), "NOTICE")
44- logging.addLevelName(DupToLoggerLevel(4), "NOTICE")
45- logging.addLevelName(DupToLoggerLevel(5), "INFO")
46- logging.addLevelName(DupToLoggerLevel(6), "INFO")
47- logging.addLevelName(DupToLoggerLevel(7), "INFO")
48- logging.addLevelName(DupToLoggerLevel(8), "INFO")
49- logging.addLevelName(DupToLoggerLevel(9), "DEBUG")
50-
51 # Default verbosity allows notices and above
52 setverbosity(NOTICE)
53
54@@ -258,7 +256,11 @@
55 processes."""
56 def __init__(self):
57 # 'message' will be appended by format()
58- logging.Formatter.__init__(self, "%(levelname)s %(controlLine)s")
59+ # Note that we use our own, custom-created 'levelName' instead of the
60+ # standard 'levelname'. This is because the standard 'levelname' can
61+ # be adjusted by any library anywhere in our stack without us knowing.
62+ # But we control 'levelName'.
63+ logging.Formatter.__init__(self, "%(levelName)s %(controlLine)s")
64
65 def format(self, record):
66 s = logging.Formatter.format(self, record)
67@@ -274,13 +276,8 @@
68 class MachineFilter(logging.Filter):
69 """Filter that only allows levels that are consumable by other processes."""
70 def filter(self, record):
71- # We only want to allow records that have level names. If the level
72- # does not have an associated name, there will be a space as the
73- # logging module expands levelname to "Level %d". This will confuse
74- # consumers. Even if we dropped the space, random levels may not
75- # mean anything to consumers.
76- s = logging.getLevelName(record.levelno)
77- return s.find(' ') == -1
78+ # We only want to allow records that have our custom level names
79+ return hasattr(record, 'levelName')
80
81 def add_fd(fd):
82 """Add stream to which to write machine-readable logging"""

Subscribers

People subscribed via source and target branches

to all changes: