Merge lp:~clay-gerrard/swift/bench_logger_fix into lp:~hudson-openstack/swift/trunk

Proposed by clayg
Status: Merged
Approved by: Chuck Thier
Approved revision: 159
Merged at revision: 156
Proposed branch: lp:~clay-gerrard/swift/bench_logger_fix
Merge into: lp:~hudson-openstack/swift/trunk
Diff against target: 127 lines (+52/-13)
3 files modified
bin/swift-bench (+5/-4)
swift/common/middleware/catch_errors.py (+5/-1)
swift/common/utils.py (+42/-8)
To merge this branch: bzr merge lp:~clay-gerrard/swift/bench_logger_fix
Reviewer Review Type Date Requested Status
Chuck Thier (community) Approve
clayg Needs Resubmitting
Review via email: mp+45194@code.launchpad.net

Commit message

reworked tnx logging

Description of the change

fixed import of missing NamedLogger in bin/swift-bench
fixed LogAdapter.tnx_id so that it works with multiple calls to get_logger
fixed common.middleware.catch_errors to reuse self.app.logger if it can
renamed x-cf-trans-id to x-swift-tnx-id

To post a comment you must log in.
Revision history for this message
gholt (gholt) wrote :

bin/swift-bench:130:80: E501 line too long (86 characters)

Revision history for this message
gholt (gholt) wrote :

Kinda whiny, but wouldn't the change to catch_errors be cleaner as:
    self.logger = getattr(app, 'logger', get_logger(conf))

Also minor: During an upgrade some transaction ids won't get logged for a short time as one server is upgraded and expecting new x-swift-txn-id headers and an old server is still sending x-cf-trans-id headers.

Revision history for this message
clayg (clay-gerrard) wrote :

I guess you *could* use getattr now that the NamedFormatter is looking for the threadlocal variable on the LogAdapter *class* - but if you do it that way get_logger gets called everytime. Which before would cause get_logger.handler's formatter to be set as a new formatter with a new reference to different "adapted_logger" object that couldn't reference the instance variable... I'd rather avoid the issue in the future and leave it as the "ugly" try/except.

I hadn't considered the rolling upgrade across the cluster. I'm tempted to update the code to read 'x-swift-tnx-id' AND 'x-cf-trans-id', but only write 'x-swift-tnx-id'??? After the 1.1 release I'll take it out completely. We'll see how it looks...

Revision history for this message
clayg (clay-gerrard) wrote :

Hrmm... I don't think it "looks" that bad, except when I get rid of x-cf-trans-id common.utils.get_txn_id will look kinda silly? Still I'm not sure how much this really helps, since it works both ways. As one server is upgraded and sending x-swift-txn-id headers and an old server is still expecting x-cf-trans-id headers. But I don't know if I really want to read and WRITE both headers?

Revision history for this message
gholt (gholt) wrote :

So really, neither of my suggestions are very helpful. You can ignore them.

159. By clayg

revert x-cf-trans-id rename

Revision history for this message
clayg (clay-gerrard) wrote :

so... this is me admitting defeat.

I guess it's not worth the trouble to rename x-cf-trans-id to x-swift-txn-id :(

review: Needs Resubmitting
Revision history for this message
Chuck Thier (cthier) wrote :

Thanks for taking care of this clay

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/swift-bench'
2--- bin/swift-bench 2011-01-04 23:34:43 +0000
3+++ bin/swift-bench 2011-01-05 21:29:07 +0000
4@@ -22,7 +22,7 @@
5 from optparse import OptionParser
6
7 from swift.common.bench import BenchController
8-from swift.common.utils import readconf, NamedLogger
9+from swift.common.utils import readconf, LogAdapter, NamedFormatter
10
11 # The defaults should be sufficient to run swift-bench on a SAIO
12 CONF_DEFAULTS = {
13@@ -124,10 +124,11 @@
14 'critical': logging.CRITICAL}.get(
15 options.log_level.lower(), logging.INFO))
16 loghandler = logging.StreamHandler()
17- logformat = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
18+ logger.addHandler(loghandler)
19+ logger = LogAdapter(logger)
20+ logformat = NamedFormatter('swift-bench', logger,
21+ fmt='%(server)s %(asctime)s %(levelname)s %(message)s')
22 loghandler.setFormatter(logformat)
23- logger.addHandler(loghandler)
24- logger = NamedLogger(logger, 'swift-bench')
25
26 controller = BenchController(logger, options)
27 controller.run()
28
29=== modified file 'swift/common/middleware/catch_errors.py'
30--- swift/common/middleware/catch_errors.py 2011-01-04 23:34:43 +0000
31+++ swift/common/middleware/catch_errors.py 2011-01-05 21:29:07 +0000
32@@ -26,7 +26,11 @@
33
34 def __init__(self, app, conf):
35 self.app = app
36- self.logger = get_logger(conf)
37+ # if the application already has a logger we should use that one
38+ self.logger = getattr(app, 'logger', None)
39+ if not self.logger:
40+ # and only call get_logger if we have to
41+ self.logger = get_logger(conf)
42
43 def __call__(self, env, start_response):
44 try:
45
46=== modified file 'swift/common/utils.py'
47--- swift/common/utils.py 2011-01-04 23:34:43 +0000
48+++ swift/common/utils.py 2011-01-05 21:29:07 +0000
49@@ -284,11 +284,15 @@
50
51
52 class LogAdapter(object):
53- """Cheesy version of the LoggerAdapter available in Python 3"""
54+ """
55+ A Logger like object which performs some reformatting on calls to
56+ :meth:`exception`. Can be used to store a threadlocal transaction id.
57+ """
58+
59+ _txn_id = threading.local()
60
61 def __init__(self, logger):
62 self.logger = logger
63- self._txn_id = threading.local()
64 for proxied_method in ('debug', 'log', 'warn', 'warning', 'error',
65 'critical', 'info'):
66 setattr(self, proxied_method, getattr(logger, proxied_method))
67@@ -334,18 +338,45 @@
68
69
70 class NamedFormatter(logging.Formatter):
71- def __init__(self, server, logger):
72- logging.Formatter.__init__(self)
73+ """
74+ NamedFormatter is used to add additional information to log messages.
75+ Normally it will simply add the server name as an attribute on the
76+ LogRecord and the default format string will include it at the
77+ begining of the log message. Additionally, if the transaction id is
78+ available and not already included in the message, NamedFormatter will
79+ add it.
80+
81+ NamedFormatter may be initialized with a format string which makes use
82+ of the standard LogRecord attributes. In addition the format string
83+ may include the following mapping key:
84+
85+ +----------------+---------------------------------------------+
86+ | Format | Description |
87+ +================+=============================================+
88+ | %(server)s | Name of the swift server doing logging |
89+ +----------------+---------------------------------------------+
90+
91+ :param server: the swift server name, a string.
92+ :param logger: a Logger or :class:`LogAdapter` instance, additional
93+ context may be pulled from attributes on this logger if
94+ available.
95+ :param fmt: the format string used to construct the message, if none is
96+ supplied it defaults to ``"%(server)s %(message)s"``
97+ """
98+
99+ def __init__(self, server, logger,
100+ fmt="%(server)s %(message)s"):
101+ logging.Formatter.__init__(self, fmt)
102 self.server = server
103 self.logger = logger
104
105 def format(self, record):
106+ record.server = self.server
107 msg = logging.Formatter.format(self, record)
108 if self.logger.txn_id and (record.levelno != logging.INFO or
109 self.logger.txn_id not in msg):
110- return '%s %s (txn: %s)' % (self.server, msg, self.logger.txn_id)
111- else:
112- return '%s %s' % (self.server, msg)
113+ msg = "%s (txn: %s)" % (msg, self.logger.txn_id)
114+ return msg
115
116
117 def get_logger(conf, name=None, log_to_console=False):
118@@ -386,7 +417,10 @@
119 root_logger.setLevel(
120 getattr(logging, conf.get('log_level', 'INFO').upper(), logging.INFO))
121 adapted_logger = LogAdapter(root_logger)
122- get_logger.handler.setFormatter(NamedFormatter(name, adapted_logger))
123+ formatter = NamedFormatter(name, adapted_logger)
124+ get_logger.handler.setFormatter(formatter)
125+ if hasattr(get_logger, 'console'):
126+ get_logger.console.setFormatter(formatter)
127 return adapted_logger
128
129