)]}'
{"test/debug_logger.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"4616c5f22780f12c663ed1c6bfdeaca4d6243920","unresolved":true,"context_lines":[{"line_number":68,"context_line":"        return self._handle(record)"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"class FakeLogger(logging.Logger, CaptureLog):"},{"line_number":72,"context_line":"    # a thread safe fake logger"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    def __init__(self, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":1,"id":"577d7bd1_992054e6","line":71,"updated":"2021-06-23 21:33:32.000000000","message":"so here we\u0027re mixing in CaptureLog to a logger","commit_id":"2b21f85cb0793f4aa41be114f775d67bca6479fb"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"4616c5f22780f12c663ed1c6bfdeaca4d6243920","unresolved":true,"context_lines":[{"line_number":214,"context_line":"        try:"},{"line_number":215,"context_line":"            return object.__getattribute__(self, name)"},{"line_number":216,"context_line":"        except AttributeError:"},{"line_number":217,"context_line":"            return getattr(self.__dict__[\u0027logger\u0027], name)"},{"line_number":218,"context_line":""},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"def debug_logger(name\u003d\u0027test\u0027):"}],"source_content_type":"text/x-python","patch_set":1,"id":"ea1d9a77_715a2fc4","line":217,"updated":"2021-06-23 21:33:32.000000000","message":"this stupid LogAdapter just does a bunch of non-sense to forward the capture methods to to the logger\n\n... maybe it would be more consistent if we mixed in here instead of the DebugLogger?","commit_id":"2b21f85cb0793f4aa41be114f775d67bca6479fb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"38552c45d5b2ffbbc63f83fbfe6839f4c97cbd4c","unresolved":true,"context_lines":[{"line_number":214,"context_line":"        try:"},{"line_number":215,"context_line":"            return object.__getattribute__(self, name)"},{"line_number":216,"context_line":"        except AttributeError:"},{"line_number":217,"context_line":"            return getattr(self.__dict__[\u0027logger\u0027], name)"},{"line_number":218,"context_line":""},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"def debug_logger(name\u003d\u0027test\u0027):"}],"source_content_type":"text/x-python","patch_set":1,"id":"1501b2b6_ad648fe3","line":217,"in_reply_to":"ea1d9a77_715a2fc4","updated":"2021-06-24 10:09:04.000000000","message":"Maybe...it would need the ForwardingHandler trick again because LogAdapters don\u0027t have the handle(record) method that CaptureLog implements, adapters just have a process(msg) method so they don\u0027t get the structured record.\n\nBut, FakeLogger would then *not* have the log capturing, which should be ok I think? the only time we use a raw FakeLogger is to fake out syslog handler, where it is actually used as a LogHandler??? so not sure anything could access the captured logs anyway??\n\nThere\u0027s a few places where tests reach inside DebugLogAdapter to the FakeLogger using logger.logger (but they don\u0027t currently need to because of the method forwarding in DebugLogAdapter) so those tests would need fixing.\n\nOK, so I tried this in [1] and it looks ok. I\u0027ve left it as a follow on because (a) I don\u0027t want to slow down the dependent patch (delaying nondurable purge) and (b) we might want to go even further and move the stats capture out of FakeLogger too, so there\u0027s scope for hacking on [1] more.\n\n[1] https://review.opendev.org/c/openstack/swift/+/797735","commit_id":"2b21f85cb0793f4aa41be114f775d67bca6479fb"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"4616c5f22780f12c663ed1c6bfdeaca4d6243920","unresolved":true,"context_lines":[{"line_number":219,"context_line":""},{"line_number":220,"context_line":"def debug_logger(name\u003d\u0027test\u0027):"},{"line_number":221,"context_line":"    \"\"\"get a named adapted debug logger\"\"\""},{"line_number":222,"context_line":"    return DebugLogAdapter(DebugLogger(), name)"},{"line_number":223,"context_line":""},{"line_number":224,"context_line":""},{"line_number":225,"context_line":"class ForwardingLogHandler(logging.NullHandler):"}],"source_content_type":"text/x-python","patch_set":1,"id":"15aae4d0_59ec8e40","line":222,"updated":"2021-06-23 21:33:32.000000000","message":"I\u0027m pretty sure 99% of the times we get grab a debug logger we\u0027re getting the adapted version from here...","commit_id":"2b21f85cb0793f4aa41be114f775d67bca6479fb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"38552c45d5b2ffbbc63f83fbfe6839f4c97cbd4c","unresolved":true,"context_lines":[{"line_number":219,"context_line":""},{"line_number":220,"context_line":"def debug_logger(name\u003d\u0027test\u0027):"},{"line_number":221,"context_line":"    \"\"\"get a named adapted debug logger\"\"\""},{"line_number":222,"context_line":"    return DebugLogAdapter(DebugLogger(), name)"},{"line_number":223,"context_line":""},{"line_number":224,"context_line":""},{"line_number":225,"context_line":"class ForwardingLogHandler(logging.NullHandler):"}],"source_content_type":"text/x-python","patch_set":1,"id":"5a439e64_cb3d71e0","line":222,"in_reply_to":"15aae4d0_59ec8e40","updated":"2021-06-24 10:09:04.000000000","message":"AFAICT it\u0027s 100% :)","commit_id":"2b21f85cb0793f4aa41be114f775d67bca6479fb"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"4616c5f22780f12c663ed1c6bfdeaca4d6243920","unresolved":true,"context_lines":[{"line_number":236,"context_line":"        return self.handler_fn(record)"},{"line_number":237,"context_line":""},{"line_number":238,"context_line":""},{"line_number":239,"context_line":"class CaptureLogAdapter(utils.LogAdapter, CaptureLog):"},{"line_number":240,"context_line":"    \"\"\""},{"line_number":241,"context_line":"    A LogAdapter that is capable of capturing logs for inspection via accessor"},{"line_number":242,"context_line":"    methods."}],"source_content_type":"text/x-python","patch_set":1,"id":"100c1c38_27e91e07","line":239,"updated":"2021-06-23 21:33:32.000000000","message":"and here mix in CaptureLog to a LogAdapter","commit_id":"2b21f85cb0793f4aa41be114f775d67bca6479fb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"38552c45d5b2ffbbc63f83fbfe6839f4c97cbd4c","unresolved":true,"context_lines":[{"line_number":236,"context_line":"        return self.handler_fn(record)"},{"line_number":237,"context_line":""},{"line_number":238,"context_line":""},{"line_number":239,"context_line":"class CaptureLogAdapter(utils.LogAdapter, CaptureLog):"},{"line_number":240,"context_line":"    \"\"\""},{"line_number":241,"context_line":"    A LogAdapter that is capable of capturing logs for inspection via accessor"},{"line_number":242,"context_line":"    methods."}],"source_content_type":"text/x-python","patch_set":1,"id":"fc7d754a_ae66769c","line":239,"in_reply_to":"100c1c38_27e91e07","updated":"2021-06-24 10:09:04.000000000","message":"yeah, this is me trying to re-use code: we want the CaptureLog functionality to be available to a Logger in one case and to a LogAdapter in another. In the case of a LogAdapter I need to shim in a. handler to get a call to handle(). I can\u0027t do the same with FakeLogger because it doesn\u0027t support pluggable handlers (reasonably!).","commit_id":"2b21f85cb0793f4aa41be114f775d67bca6479fb"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"48a9a7e86fcd0f2dd42bfc88507be1449360e0b6","unresolved":true,"context_lines":[{"line_number":273,"context_line":"    instance."},{"line_number":274,"context_line":"    \"\"\""},{"line_number":275,"context_line":"    with mock.patch(\u0027swift.common.utils.LogAdapter\u0027, CaptureLogAdapter):"},{"line_number":276,"context_line":"        log_adapter \u003d utils.get_logger(conf, *args, **kwargs)"},{"line_number":277,"context_line":"    log_adapter.start_capture()"},{"line_number":278,"context_line":"    try:"},{"line_number":279,"context_line":"        yield log_adapter"}],"source_content_type":"text/x-python","patch_set":2,"id":"e0100c2e_5304d8fc","line":276,"updated":"2021-06-24 15:06:06.000000000","message":"i guess the big win here is we continue to use whatever is configured on the filesystem as far as logging goes - this isn\u0027t a replacement - it\u0027s addative.","commit_id":"40aace89f0070a06d1654edcfacadccb140c65b4"}],"test/probe/common.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"4616c5f22780f12c663ed1c6bfdeaca4d6243920","unresolved":true,"context_lines":[{"line_number":588,"context_line":"        finally:"},{"line_number":589,"context_line":"            # detach the log_adapter handler from the logger to avoid capturing"},{"line_number":590,"context_line":"            # subsequent logs to the adapted logger"},{"line_number":591,"context_line":"            log_adapter.stop_capture()"},{"line_number":592,"context_line":"        return daemon"},{"line_number":593,"context_line":""},{"line_number":594,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"9e998b7b_020e895c","line":591,"updated":"2021-06-23 21:33:32.000000000","message":"should this patch and start/stop be a standalone helper contextmanager - instead of boiler-plate embedded in this custom TestCase helper method?\n\nI guess it depends if we think we\u0027ll use CaptureLogAdapter anywhere outside of probe tests...","commit_id":"2b21f85cb0793f4aa41be114f775d67bca6479fb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"38552c45d5b2ffbbc63f83fbfe6839f4c97cbd4c","unresolved":true,"context_lines":[{"line_number":588,"context_line":"        finally:"},{"line_number":589,"context_line":"            # detach the log_adapter handler from the logger to avoid capturing"},{"line_number":590,"context_line":"            # subsequent logs to the adapted logger"},{"line_number":591,"context_line":"            log_adapter.stop_capture()"},{"line_number":592,"context_line":"        return daemon"},{"line_number":593,"context_line":""},{"line_number":594,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"19c42e24_ae1d5ae8","line":591,"in_reply_to":"9e998b7b_020e895c","updated":"2021-06-24 10:09:04.000000000","message":"ok, so something like\n\n  with capture_logger(conf, **kwargs) as log_adapter:\n      daemon \u003d klass(conf, log_adapter)\n      daemon.run_once(**kwargs)","commit_id":"2b21f85cb0793f4aa41be114f775d67bca6479fb"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"4616c5f22780f12c663ed1c6bfdeaca4d6243920","unresolved":true,"context_lines":[{"line_number":589,"context_line":"            # detach the log_adapter handler from the logger to avoid capturing"},{"line_number":590,"context_line":"            # subsequent logs to the adapted logger"},{"line_number":591,"context_line":"            log_adapter.stop_capture()"},{"line_number":592,"context_line":"        return daemon"},{"line_number":593,"context_line":""},{"line_number":594,"context_line":""},{"line_number":595,"context_line":"class ReplProbeTest(ProbeTest):"}],"source_content_type":"text/x-python","patch_set":1,"id":"bd406fde_398a49d7","line":592,"updated":"2021-06-23 21:33:32.000000000","message":"and the daemon.logger still let\u0027s you grap log lines off of it... +1","commit_id":"2b21f85cb0793f4aa41be114f775d67bca6479fb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"38552c45d5b2ffbbc63f83fbfe6839f4c97cbd4c","unresolved":true,"context_lines":[{"line_number":589,"context_line":"            # detach the log_adapter handler from the logger to avoid capturing"},{"line_number":590,"context_line":"            # subsequent logs to the adapted logger"},{"line_number":591,"context_line":"            log_adapter.stop_capture()"},{"line_number":592,"context_line":"        return daemon"},{"line_number":593,"context_line":""},{"line_number":594,"context_line":""},{"line_number":595,"context_line":"class ReplProbeTest(ProbeTest):"}],"source_content_type":"text/x-python","patch_set":1,"id":"f9d15772_32a1452c","line":592,"in_reply_to":"bd406fde_398a49d7","updated":"2021-06-24 10:09:04.000000000","message":"or in the case or reconstructor, daemon.logger.logger, because reconstructor also wraps its logger in a PrefixLogAdapter!! :)","commit_id":"2b21f85cb0793f4aa41be114f775d67bca6479fb"}]}
