)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e6df311bac282d96055b00037a8324cedb49d04a","unresolved":true,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"proxy-logging: Add real-time transfer bytes counters"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Currently we can get one proxy-logging transfer stat emission over the duration of the upload/download. We want another stat coming out of proxy-logging: something that gets emitted periodically as bytes are actually sent/received so we can get reasonably accurate point-in-time breakdowns of bandwidth usage."},{"line_number":10,"context_line":""},{"line_number":11,"context_line":"Change-Id: Ideecd0aa58ddf091c9f25f15022a9066088f532b"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":6,"id":"6cd3da6b_98f38a45","line":9,"updated":"2024-11-19 18:58:22.000000000","message":"please fix line wrapping on this commit message\n\nhttps://wiki.openstack.org/wiki/GitCommitMessages#Summary_of_Git_commit_message_structure\n\nthis should say something about the \"is_s3_req\" stuff if that\u0027s *also* going on in this patch","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"proxy-logging: Add real-time transfer bytes counters"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Currently we can get one proxy-logging transfer stat emission over the duration of the upload/download. We want another stat coming out of proxy-logging: something that gets emitted periodically as bytes are actually sent/received so we can get reasonably accurate point-in-time breakdowns of bandwidth usage."},{"line_number":10,"context_line":""},{"line_number":11,"context_line":"Change-Id: Ideecd0aa58ddf091c9f25f15022a9066088f532b"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":6,"id":"1d1545f7_10061f70","line":9,"in_reply_to":"6cd3da6b_98f38a45","updated":"2024-11-22 20:30:38.000000000","message":"using a different patch per our discussion","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"735abc7928e73bf5b3f3464946fe04633df6fb42","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"3216970f_0f9e488b","updated":"2024-10-07 17:15:03.000000000","message":"I don\u0027t understand the proxy env back propogation and it doesn\u0027t appear to be tested; see `_do_test_object_proxy_index_logging` in `test.unit.common.mw.s3api.test_obj` for some examples of how to test s3api+proxy-logging behavior","commit_id":"93971c11c36809e4f15deb33704f4929c44ec3ab"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"4482de8bc114592c02fcfd43902415a818c55b47","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"df6152f5_62693041","updated":"2024-10-07 15:23:05.000000000","message":"recheck","commit_id":"93971c11c36809e4f15deb33704f4929c44ec3ab"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"88385b4cb0bf4ad1b773fc44366c408fde5ed0b7","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"0f1b51e4_d22650fe","updated":"2024-10-29 17:29:39.000000000","message":"the main idea here is a means for right-most-subrequest-proxy-logging instance to communicate the path of the actual swift request to left-most-userrequest-proxy-logging instance.\n\nOriginally I had thought that s3api could \"just\" set the sw_req.path in the user_req.environ BEFORE sending it down to swift; but because of how s3-compatible check_signature callbacks work (they get the access_key_id from the PATH_INFO and replace ith with the *real* swift account name) - even s3api doesn\u0027t know the sw_req.path on the way in!\n\nThe best course of action seems to be to allow the right-most-subrequest-proxy-logging instance to annotate a mutable key in the user_req.env (that\u0027s carefully namespaced under `swift.` and propogated properly in `wsgi.make_env`) such that the left-most-userrequest-proxy-logging instance can reliably discover ALL the subrequest/swift paths that were spawned off this user-request including/importantly any s3api user-requests that get translated to swift subrequests.\n\nThis could become a more general pattern that could eventually even replace the `s3api.swift_backend_path` pattern and make s3api\u0027s life easier.\n\nThis new general primative shouldn\u0027t relay on s3api setting up the mutable message passting structure - the left-most-userrequest-proxy-logging instance should just *always* setup the subrequest_tracking list and the right-most-subrequest-proxy-logging instance should always annotate the the swift.subrequest_tracking list even if the request was already flagged w/ `swift.proxy_access_log_made`","commit_id":"cdb1cdf7df5bdc8bfcf782b7efa622976eb0df1b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"34996bc75ca6f593d928381298d4af325195443c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"f99b071e_c81b6500","updated":"2024-11-14 14:41:23.000000000","message":"I need to spend more time to understand what\u0027s happening in the callback handler, but leaving some initial comments.","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e6df311bac282d96055b00037a8324cedb49d04a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"41624ce5_766ffd44","updated":"2024-11-19 18:58:22.000000000","message":"WSGI is mind-bending, and we\u0027re WAY down in the weeds - we did some high bandwidth discussion and came up with reasonable actions - GL!  Yan is the best!","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d21278b9a94cd7c6739dd5897408c28bc9120615","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"3d9595bb_9ebf6d12","updated":"2024-11-15 19:40:40.000000000","message":"i haven\u0027t fully groked this - it seems like Al had some questions about the implementation - i glanced at a couple things and wanted to share some early impressions since I\u0027m assuming this will get another revision.","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3c9db4b292eacdc99e65c8934ed5e7d5148bdd8b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"548d10fe_18a9b9a4","updated":"2024-11-29 16:33:28.000000000","message":"Leaving some comments but not yet reviewed the tests.\n\nI\u0027m not sure the modification of swift.backend_path is correct.\n\nI\u0027m finding it easier to grok now the callback has been broken out to a class etc","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c836907958e81fc6029007ffa68113095eb48b82","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":11,"id":"40baeef6_72be54c1","updated":"2024-12-11 15:35:43.000000000","message":"I played with in my vsaio. I definitely see the \u0027real time\u0027 bytes metrics. But I noticed a couple fo inconsistencies in the metrics names. One is easy to fix - wsgi quoting issue. \n\nThe other issue relates to the use of the container part of the swift_request_path, and the fix for that is not so obvious to me. Having played with this I now have a better understanding as to why it is not sufficient to update the labels with only the account (because leftmost proxy logging also does not know the container for an s3 request)...but the container that the rightmost proxy logging observes is not necessarily correct either. We\u0027ll need to think more on that.","commit_id":"1af3d28b70a02ca2ed62f9252b527b1efb018b60"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":13,"id":"ba38804e_8eb4ee05","updated":"2025-01-17 21:20:47.000000000","message":"I 100% support the idea that the NEW BETTER structure that works *on the way in* (before we read a single byte) should *replace* the old/busted `swift.backend_path` that only works on the way out after we\u0027ve already got the response.  Please split that into a prefactor and add the new xfer metrics in a (hopefully smaller/simpler) follow-on.\n\nFWIW, I think you might be able to mostly leave `s3api.backend_path` alone and \"just fix\" the one and only place in s3api we set `swift.backend_path` to instead rely on the fact that left-most proxy-logging will have installed the `swift.log_path_parts` structure and we can parse the `s3api.backend_path` to fill that in.\n\n... *except* currently that happens *after* processing the request:\n\nhttps://github.com/NVIDIA/swift/blob/master/swift/common/middleware/s3api/s3api.py#L350-L370\n\nSO, if you want the \"correct\" bucket+segments to be available for input_bytes labels (which honestly might be debateable) you would have to update the \"correct bucket\" before you know the account!?\n\nMaybe the best place for the \"fix bucket in swift.log_path_parts on the way in\" would be in `to_swift_req`\n\n```\n    def to_swift_req(self, method, container, obj, query\u003dNone,\n                     body\u003dNone, headers\u003dNone):\n        \"\"\"\n        Create a Swift request based on this request\u0027s environment.\n        \"\"\"\n        if self.account is None:\n            account \u003d swob.str_to_wsgi(self.access_key)\n        else:\n            account \u003d self.account\n        if container:\n            # we want input_bytes container label to match logging\n            # and this is right more often that wrong?\n            self.environ[\u0027swift.log_path_parts\u0027][1] \u003d container\n```\n\nBut, the neat thing about just fixing `s3api.backend_path` to update the new-interface and getting rid of `swift.backend_path` in a *pre-factor* is that we don\u0027t have the requirement on the lazy-account-back-propagation-for-input-bytes requirement yet - so it\u0027s POSSIBLE no one would even notice that input_bytes labels *always* use the client request bucket/container while output_bytes will randomly pick some different path segments cause s3api changes them too late for input_bytes metrics!\n\nOR if someone DOES notice \"hey why aren\u0027t the output_bytes using EXACTLY the same labels we calculated for input_bytes\" we could just fix the input_bytes labels to consistently use the labels we calculate on the way in - even if logging and response stats labels are doing their crazy s3api.backend_path manipulation non-sense for now.\n\nWhen we get around to adding an s3 label to proxy-logging metrics maybe we can also think about how/when s3api can/should insert an upload_id label to \"all\" the proxy logging metrics consistently on the way in.  Maybe a `swift.log_ctx` dict!?","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"14cf8a0f380dfd1b62c64e3ae94d323a6c4d23ef","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":13,"id":"9fe2fcfe_3a1da621","updated":"2025-01-15 15:01:49.000000000","message":"swift.path_parts seems to be working, but I found another issue around the consistency of labels for the same request (see inline).\n\nI\u0027m growing to dislike swift.backend_path more and more:\n\n* AFAICT swift.backend_path is only used for s3api to communicate alternate log paths back to proxy logging. \n\n* It is set by s3api after the request has been handled, so cannot be used for metrics issued while the request body is being read. This leads to the metric label inconsistency. That was partly necessary because the account may not have been fixed up by auth until after the request was handled. But this patch is introducing a new mechanism to report the account back to proxy_logging that is independent of s3api.\n\n* It is relevant when s3api redirects a request to a segments container and SRE think they would rather have the logs show the segments container. But with native MPU s3api will lose sight of that anyway. Maybe we make mpu middleware set swift.backend_path, but the segments container will be a hidden internal container. It might be better to use extensible log_info to pass upload ids to proxy-logging? Perhaps we should revisit the need for logging different container names in the leftmost log line?\n\nTo preserve current log behaviour, we could maybe drop swift.backend_path and just use the new swift.path_parts to patch up the container and obj as well as the account:\n\n* s3api sets/overwrites container and obj parts as it sees fit e.g. with the segments container, *before* issuing the swift-request, so that the parts are available to an input byte counter.\n\n* rightmost proxy-logging sets account\n\n* proxy-logging deduces populates the acc and cont metric labels dynamically from swift.path_parts in the BufferXferEmitCallback after swift.path_parts has been patched up by s3api and proxy-logging.\n\n* proxy-logging uses swift.path_parts instead of swift.backend_path elsewhere","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c18d9096100c33d4b60c2528df7faba203435a4f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":18,"id":"9ad08ef6_0cb25d54","updated":"2025-03-06 18:38:33.000000000","message":"@Yan I think this is shaping up nicely, and I suspect that once we pull the scope back to *only* bytes xfer, and clean up some unused pieces, then the patch will be quite compact.\n\nSome (all) of the methods that moved to functions probably don\u0027t *need* to be functions anymore. That doesn\u0027t mean that they *shouldn\u0027t* be functions, but the patch could be *smaller* if they were reverted. There could be a follow-on to refactor to functions if it is felt desirable - maybe it will become *necessary* when we migrate existing metrics to use the base_labels.","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"f0911cf71c5cc9a15735dd29c759e86744afdb44","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":37,"id":"80bde4c4_91ea8d3e","updated":"2025-05-13 15:33:56.000000000","message":"recheck","commit_id":"9b76f1ea04924cd50bb5538a4f70f9dc905fd09c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":38,"id":"edb59c75_06c934e4","updated":"2025-05-19 15:40:26.000000000","message":"There\u0027s some parts of the patch that don\u0027t seem necessary - in some cases not necessary at all, and in some cases (SubsetDict) not until we move on to other use cases for base_labels. I\u0027d encourage always self-evaluating patches to question if every change is really needed - because reviewers WILL do that ;-)\n\nI think there is a gap in account resource handling, when the resource type needs to be evaluated in the rightmost middleware.\n\nSome of the tests could be more compact. Please keep them focussed on the new behavior and look for any opportunities to provide some common shared test setup helper functions.","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":43,"id":"4acee0d7_51b01a66","updated":"2025-06-04 18:08:30.000000000","message":"I\u0027m part way through review but stopping for the ay so pushing the comments I have so far","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f3ce9d72fdeef6e34b742f3b73a6959f25a2cbe4","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":44,"id":"0e9eed2d_b9d91ef0","updated":"2025-06-04 18:10:43.000000000","message":"...also, some suggestions here https://review.opendev.org/c/openstack/swift/+/951800 but please review before squashing!","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":44,"id":"233ee905_0af547e9","updated":"2025-06-05 11:46:42.000000000","message":"There\u0027s a bug in the stats reporting: the final stat is not emitted unless it happens to occur at or after the next_emit_time.\n\nThere\u0027s some repeated patterns/unnecessary code in the tests which I have called out a few times but please audit *all* the tests to clean them up in the same way.","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"10b9971a338bf501dac283cf9af2e6055bdfd30c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":53,"id":"90f3b74c_fb5c0d4d","updated":"2025-07-15 16:23:29.000000000","message":"recheck","commit_id":"b7ff6ff1646c1a19f3e7054bd597c97db6449ae7"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"dfeb47c6dcf70affb33b15bedd666be9abd61143","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":55,"id":"45f824d5_8499d558","updated":"2025-07-16 20:48:39.000000000","message":"recheck","commit_id":"8aaf69b82928a4f55cb48f2b87a2563258e8e6ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1432c12767bfa249bb2d1d29e769cd306b817b23","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":57,"id":"820b154c_3055150c","updated":"2025-07-17 14:31:02.000000000","message":"The bug still exists w.r.t. not reporting the final bytes of a read (unless they happen to be read at exactly the right moment).\n\nI changed a test to highlight this https://review.opendev.org/c/openstack/swift/+/955290 - there is a test in there that will fail until the bug is fixed.\n\n(there\u0027s also some cleanup for another test)\n\nI\u0027m seeing more unrelated changes creeping in, and in some cases they have broken tests. Please review your own patches and ask yourself \"is every line of change here necessary to achieve the goal of this patch?\". Every unnecessary change is a burden on reviewers, a change to the version history, and potentially a bug.\n\nSometimes unrelated drive-by changes are ok when they are simple, obvious, *improvements*. Good judgement applies, but be wary.","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed52e6f601100413157c728b3379848ae27d2538","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":58,"id":"3486b50a_4d0f206e","updated":"2025-07-24 09:38:58.000000000","message":"The ``eof`` has been added to the callback but the callers aren\u0027t passing it?\n\nI\u0027m still seeing unnecessary changes in test_proxy_logging.py","commit_id":"4641e0ca4aa3481f0bd66d4af9ff4a61e5267946"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"39f2ccece4cf04b118f66a5b48358098d758c9b7","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":64,"id":"604a3100_60803cf5","updated":"2025-08-06 15:02:22.000000000","message":"@shreeyad this latest patchset looks like what Tim suggested w.r.t. adding a subclass for InputProxy. I left a few comments on the detail.","commit_id":"89f2c7a2e176b641d2b0d2c5cd17c1c0e47747bb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"fbfb2a73e3030a8ddeecea098b1d17d6043d82a1","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":65,"id":"497008a5_2b2af198","updated":"2025-08-07 12:33:31.000000000","message":"The CallbackInputProxy pattern is good, but there\u0027s ambiguity in whether the callback should return the chunk. The docstring says it should, but the code isn\u0027t doing it.","commit_id":"d8a8d7e051e290790b5e8df57fca28166015a6c8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"94af435e5e843a4093f95790290a679681a01ea5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":66,"id":"036e4508_8fa0c71f","updated":"2025-08-08 17:38:52.000000000","message":"I\u0027ve left some suggestions here 956947: sq: bytes xfer stats test fixups | https://review.opendev.org/c/openstack/swift/+/956947, please squash if you see fit.\n\nI\u0027ve run out of time today but will continue to review next week","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"b13aaec32653c7cb6d0b7c00ede2b860498b0144","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":67,"id":"80777baf_c0e3c0a3","updated":"2025-08-25 06:44:46.000000000","message":"Done a code pass, was going to do some vsaio testing before I posted anything, but got a question inline.. thought I\u0027d send it up now, incase I don\u0027t get to finish testing on my vsaio until the morning.","commit_id":"752531a59abaad6978e1e3ed6e0f0c47abd10472"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"61ae00f41d0471a942b50efc4484f8a283c956e2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":67,"id":"85ca6c64_1b5b0d03","updated":"2025-08-20 14:02:28.000000000","message":"I\u0027ve become comfortable with the bucket-in-host parsing happening in proxy logging. I\u0027ve also become convinced that the container label should be the client given container.\n\nMy remaining comments, from earlier reviews, are polishing/nits.","commit_id":"752531a59abaad6978e1e3ed6e0f0c47abd10472"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c21f8ce79fd1904a2a8ea1a8f3a5eeedd48c8ff8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":67,"id":"df25db60_5e7b2d94","updated":"2025-08-11 13:37:44.000000000","message":"I\u0027ve dumped some captured stats for a swift API SLO upload and an s3api MPU here https://paste.openstack.org/show/bDgxSh58Lca6mup9KGbq/. The numbers all make sense (total bytes is sum of streaming bytes etc). But it has reminded me of the glaring inconsistency between the container label used for part upload streaming (\u0027container\u0027) vs total bytes (\u0027container+segments\u0027). Meaning that the sum of all streaming bytes a \u0027container\u0027 won\u0027t equal the sum of all total bytes stats to the same \u0027container\u0027.\n\nThat\u0027s because this patch has made the choice to make proxy-logging always populate the container field (rather than deferring to s3api). This is the opposite to the previous choice when implementing swift.backend_path, so, for the same  part upload, we have streaming bytes labeled with the user container and total bytes labeled with the +segments container. \n\nFor this patch to do that we\u0027ve had to bleed the s3api bucket-in-host parsing into proxy-logging, which isn\u0027t great.\n\nWe are going to want to make the streaming and total bytes labels uniform at some point, and if we choose to settle on container+segments then we don\u0027t need the s3api bucket-in-host parsing in the proxy-logging after all (we just delegate populating the container field in base_labels to s3api).\n\nAnd even if we do want to normalise on always labeling with the user container, I still wonder if we\u0027d be better delegating to s3api to populate the base_labels fields, rather then proxy-logging becoming increasingly aware of s3api features.\n\nAlso, (and this is evident in https://paste.openstack.org/show/bDgxSh58Lca6mup9KGbq/), it\u0027s odd that the rightmost proxy-logging is also labeling subrequest part uploads with the user container despite them going to the +segments container.\n\nWhat do we actually want the stats to tell us? Is it:\n\nleftmost logging: \n- Z \u003d number of bytes apparently in/out of the user container (including those that internally are redirected to/from parts).\n\nrightmost logging:\n- X \u003d number of bytes actually in/out of the user container (not including those that internally are redirected to/from parts).\n- Y \u003d number of bytes actually in/out of the parts container.\n\nwhere X + Y \u003d Z","commit_id":"752531a59abaad6978e1e3ed6e0f0c47abd10472"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"a5da64bad6adc61d078a6df64c1eba017f139f03","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":67,"id":"79738fc8_55f8e88c","updated":"2025-08-11 02:02:28.000000000","message":"recheck","commit_id":"752531a59abaad6978e1e3ed6e0f0c47abd10472"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"61ae00f41d0471a942b50efc4484f8a283c956e2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":67,"id":"6dd81921_56f779e6","in_reply_to":"df25db60_5e7b2d94","updated":"2025-08-20 14:02:28.000000000","message":"On reflection, there\u0027s good reason to have the leftmost proxy-logging parse the bucket-in-host urls: other (downstream) middlewares may benefit from having base_labels populated as early as possible. We already have a downstream middleware that is parsing bucket in host, so consolidating this in proxy-logging will help reduce code.\n\nAlso, in discussion with other devs, we decided that the metrics SHOULD be labeled with the client given container (so buckets, not bucket+segments) and that we should head in that direction (so subsequent to this patch, fix the end-of-request metrics to be consistent with this patch).","commit_id":"752531a59abaad6978e1e3ed6e0f0c47abd10472"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"37a14d43fdbd6d6681d7e180153e2f52cc8b7404","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":68,"id":"4d850c68_d1981856","updated":"2025-08-29 08:08:08.000000000","message":"Just running through local tests in my SAIO before I up my vote.. just thought I\u0027d at least change it because Tim answered my question 😊","commit_id":"9a96b6ebd540c99922dadbb74af70e67827b3d6a"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"06f7960d403f7ab5bac00a15336ee3290aac8288","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":70,"id":"b4e9ae70_901ff64c","updated":"2025-09-02 20:38:32.000000000","message":"recheck","commit_id":"ee8afcbbe64c15b5bf236f6fcbaa62df8c880319"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"df4f4ce15898bcf8fefe4bed4c3f528f447938ba","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":70,"id":"e8ea1811_1bb6eb4d","updated":"2025-09-03 01:41:42.000000000","message":"recheck","commit_id":"ee8afcbbe64c15b5bf236f6fcbaa62df8c880319"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"87bed46ce8464d6ca1cb66101b3caaa24803fc1c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":70,"id":"feb3c7e6_8ca45a41","updated":"2025-09-02 21:39:53.000000000","message":"recheck","commit_id":"ee8afcbbe64c15b5bf236f6fcbaa62df8c880319"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"5afbe5f80e500e63c1f1ffcf22caa6c803b0d01b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":72,"id":"caca1673_99ee98b6","updated":"2025-09-03 18:50:02.000000000","message":"recheck","commit_id":"c0005760b717a22f5fb5e6f8de0201936b651254"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"cf7c6e298905660fd8de85fad8aceb076d0284d5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":74,"id":"f1f8e546_e46fb4d9","updated":"2025-09-03 19:28:42.000000000","message":"recheck","commit_id":"7075a5885497cfd1115b58457bffb292b10a8aee"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"48d792f9cecc76402d4e76367a5338fab8aaf4de","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":75,"id":"07185f00_06d0ccf1","updated":"2025-09-03 20:46:15.000000000","message":"recheck","commit_id":"e4bac03afdc5b67284407a8a585eea20d624cddb"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"8b3c3c2174c1f853a1096f055ddd7b0c2bee19af","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":80,"id":"1c63fe76_0a667e74","updated":"2025-10-08 21:15:06.000000000","message":"recheck","commit_id":"0a724c02fbdf5c065f6d0a72b6ed2753379ee095"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"76643d87c6df6f4e4763013d011e0eb171b67d10","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":84,"id":"6a80e787_a22ac7ff","updated":"2025-10-13 15:54:33.000000000","message":"test import needs updating","commit_id":"042e31fd0d5e282c830fd7ca2186e4a7aec31533"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ae3cfeb983e350d48a0a2849a43fb4445136bbb2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":85,"id":"4780cebb_43dd0b17","updated":"2025-10-13 16:43:36.000000000","message":"only +1 because I\u0027m co-author, needs another core to review","commit_id":"eb6137934faf92bb74fe2607c6ea52fbb87b72be"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"fd08a6b9075fc5125bb65152f0ac612e74508e53","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":88,"id":"a30d5bd2_4e4acc0b","updated":"2025-11-03 04:33:51.000000000","message":"Tested this in my vsaio, I really like it.\n\nThere is some reservations on whether we should be tracking currnt throughput via a guage or progress via a counter. But I guess we can get this the current thoughput with some maths or how we display it.. heck maybe that\u0027s not what we want it for. Eaither way, I do like the way it periodically gives us stats on where it\u0027s up to.. kudos!\n\nTalks about counter vs guages is defintely out of scope and could be a follow up.","commit_id":"dcd5a265f6f36551e0bc0feac0e08bfdd09301a3"}],"etc/proxy-server.conf-sample":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":1110,"context_line":"# configured for virtual-hosted style requests. This option should be a"},{"line_number":1111,"context_line":"# comma-separated list of host names, exactly the same as that set for the"},{"line_number":1112,"context_line":"# s3api middleware."},{"line_number":1113,"context_line":"# storage_domain \u003d"},{"line_number":1114,"context_line":""},{"line_number":1115,"context_line":"# Note: Put before both ratelimit and auth in the pipeline."},{"line_number":1116,"context_line":"[filter:bulk]"}],"source_content_type":"application/octet-stream","patch_set":44,"id":"63f71915_d43179c0","line":1113,"updated":"2025-06-05 11:46:42.000000000","message":"please add doc for ``statsd_emit_buffer_xfer_bytes_ms`` conf option","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9237818e7872731319b58e2ec2b6f7976543e67d","unresolved":false,"context_lines":[{"line_number":1110,"context_line":"# configured for virtual-hosted style requests. This option should be a"},{"line_number":1111,"context_line":"# comma-separated list of host names, exactly the same as that set for the"},{"line_number":1112,"context_line":"# s3api middleware."},{"line_number":1113,"context_line":"# storage_domain \u003d"},{"line_number":1114,"context_line":""},{"line_number":1115,"context_line":"# Note: Put before both ratelimit and auth in the pipeline."},{"line_number":1116,"context_line":"[filter:bulk]"}],"source_content_type":"application/octet-stream","patch_set":44,"id":"3fd3b982_dc356bb7","line":1113,"in_reply_to":"63f71915_d43179c0","updated":"2025-06-25 20:41:54.000000000","message":"Acknowledged","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1432c12767bfa249bb2d1d29e769cd306b817b23","unresolved":true,"context_lines":[{"line_number":1112,"context_line":"# s3api middleware."},{"line_number":1113,"context_line":"# storage_domain \u003d"},{"line_number":1114,"context_line":"#"},{"line_number":1115,"context_line":"# statsd_emit_buffer_xfer_bytes_ms conf option:"},{"line_number":1116,"context_line":"# An integer value in milliseconds for how often we should emit"},{"line_number":1117,"context_line":"# statsd real-time buffer transfer bytes counter metrics for WSGI input or output."},{"line_number":1118,"context_line":"# Negative value or -1 for not emitting such metrics."}],"source_content_type":"application/octet-stream","patch_set":57,"id":"5311e990_0ed475c5","line":1115,"updated":"2025-07-17 14:31:02.000000000","message":"the convention is that sample conf files is for the actual option to come after the descriptive text, and for it to have its default value.\n\nSo line 1115 should be at line 1120 and be:\n\n```\nstatsd_emit_buffer_xfer_bytes_ms \u003d -1\n```","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9c175fca54bd4eec0f0d2e996f5cb2bb4fce3870","unresolved":false,"context_lines":[{"line_number":1112,"context_line":"# s3api middleware."},{"line_number":1113,"context_line":"# storage_domain \u003d"},{"line_number":1114,"context_line":"#"},{"line_number":1115,"context_line":"# statsd_emit_buffer_xfer_bytes_ms conf option:"},{"line_number":1116,"context_line":"# An integer value in milliseconds for how often we should emit"},{"line_number":1117,"context_line":"# statsd real-time buffer transfer bytes counter metrics for WSGI input or output."},{"line_number":1118,"context_line":"# Negative value or -1 for not emitting such metrics."}],"source_content_type":"application/octet-stream","patch_set":57,"id":"d31fac5c_0d1c4569","line":1115,"in_reply_to":"5311e990_0ed475c5","updated":"2025-07-21 21:19:09.000000000","message":"Acknowledged","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1432c12767bfa249bb2d1d29e769cd306b817b23","unresolved":true,"context_lines":[{"line_number":1115,"context_line":"# statsd_emit_buffer_xfer_bytes_ms conf option:"},{"line_number":1116,"context_line":"# An integer value in milliseconds for how often we should emit"},{"line_number":1117,"context_line":"# statsd real-time buffer transfer bytes counter metrics for WSGI input or output."},{"line_number":1118,"context_line":"# Negative value or -1 for not emitting such metrics."},{"line_number":1119,"context_line":"# 0 for always emitting such metrics on every input or output call. Default is -1."},{"line_number":1120,"context_line":"#"},{"line_number":1121,"context_line":"# Note: Put before both ratelimit and auth in the pipeline."}],"source_content_type":"application/octet-stream","patch_set":57,"id":"559f1ac9_775a71a1","line":1118,"range":{"start_line":1118,"start_character":2,"end_line":1118,"end_character":22},"updated":"2025-07-17 14:31:02.000000000","message":"nit: tautology! -1 *is* a negative value","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9c175fca54bd4eec0f0d2e996f5cb2bb4fce3870","unresolved":false,"context_lines":[{"line_number":1115,"context_line":"# statsd_emit_buffer_xfer_bytes_ms conf option:"},{"line_number":1116,"context_line":"# An integer value in milliseconds for how often we should emit"},{"line_number":1117,"context_line":"# statsd real-time buffer transfer bytes counter metrics for WSGI input or output."},{"line_number":1118,"context_line":"# Negative value or -1 for not emitting such metrics."},{"line_number":1119,"context_line":"# 0 for always emitting such metrics on every input or output call. Default is -1."},{"line_number":1120,"context_line":"#"},{"line_number":1121,"context_line":"# Note: Put before both ratelimit and auth in the pipeline."}],"source_content_type":"application/octet-stream","patch_set":57,"id":"733a9793_1d22b171","line":1118,"range":{"start_line":1118,"start_character":2,"end_line":1118,"end_character":22},"in_reply_to":"559f1ac9_775a71a1","updated":"2025-07-21 21:19:09.000000000","message":"Acknowledged","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1432c12767bfa249bb2d1d29e769cd306b817b23","unresolved":true,"context_lines":[{"line_number":1116,"context_line":"# An integer value in milliseconds for how often we should emit"},{"line_number":1117,"context_line":"# statsd real-time buffer transfer bytes counter metrics for WSGI input or output."},{"line_number":1118,"context_line":"# Negative value or -1 for not emitting such metrics."},{"line_number":1119,"context_line":"# 0 for always emitting such metrics on every input or output call. Default is -1."},{"line_number":1120,"context_line":"#"},{"line_number":1121,"context_line":"# Note: Put before both ratelimit and auth in the pipeline."},{"line_number":1122,"context_line":"[filter:bulk]"}],"source_content_type":"application/octet-stream","patch_set":57,"id":"bec27dca_f4c3f63f","line":1119,"updated":"2025-07-17 14:31:02.000000000","message":"please line wrap the paragraph","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9c175fca54bd4eec0f0d2e996f5cb2bb4fce3870","unresolved":false,"context_lines":[{"line_number":1116,"context_line":"# An integer value in milliseconds for how often we should emit"},{"line_number":1117,"context_line":"# statsd real-time buffer transfer bytes counter metrics for WSGI input or output."},{"line_number":1118,"context_line":"# Negative value or -1 for not emitting such metrics."},{"line_number":1119,"context_line":"# 0 for always emitting such metrics on every input or output call. Default is -1."},{"line_number":1120,"context_line":"#"},{"line_number":1121,"context_line":"# Note: Put before both ratelimit and auth in the pipeline."},{"line_number":1122,"context_line":"[filter:bulk]"}],"source_content_type":"application/octet-stream","patch_set":57,"id":"4b989c65_92a03cae","line":1119,"in_reply_to":"bec27dca_f4c3f63f","updated":"2025-07-21 21:19:09.000000000","message":"Acknowledged","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"144e64fa36b2a06eef9c238f2ce7f42c529efe6f","unresolved":true,"context_lines":[{"line_number":1107,"context_line":"#"},{"line_number":1108,"context_line":"# The proxy_logging middleware attempts to translate s3api request paths to"},{"line_number":1109,"context_line":"# swift paths. To do so it needs to know which, if any, storage domains are"},{"line_number":1110,"context_line":"# configured for virtual-hosted style requests. This option should be a"},{"line_number":1111,"context_line":"# comma-separated list of host names, exactly the same as that set for the"},{"line_number":1112,"context_line":"# s3api middleware."},{"line_number":1113,"context_line":"# storage_domain \u003d"},{"line_number":1114,"context_line":"#"},{"line_number":1115,"context_line":"# An integer value in milliseconds for how often we should emit statsd"}],"source_content_type":"application/octet-stream","patch_set":61,"id":"23735b6b_8dc3b53d","line":1112,"range":{"start_line":1110,"start_character":48,"end_line":1112,"end_character":19},"updated":"2025-07-25 17:44:50.000000000","message":"Interesting... I don\u0027t much like tightly-coupled cross-middleware config options.\n\nWe can\u0027t just punt to s3api and the auth middlewares to get us a sane swift path? I thought that was part of the appeal of the change in `wsgi.py`...\n\nIs the trouble that we might read the whole request body in s3api before sending anything further down the pipeline or something? Maybe we need to do something like [that wacky `authenticate` thing](https://github.com/openstack/swift/blob/2.35.0/swift/common/middleware/s3api/s3request.py#L1662) we do for `s3_acl` requests...\n\nWhat are the implications for `domain_remap` requests?","commit_id":"74e88a1633605f28d0d5eb95d1c889616245a54f"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"504f1547325aa77e6e44f5dea300a57dda4ba0e4","unresolved":false,"context_lines":[{"line_number":1107,"context_line":"#"},{"line_number":1108,"context_line":"# The proxy_logging middleware attempts to translate s3api request paths to"},{"line_number":1109,"context_line":"# swift paths. To do so it needs to know which, if any, storage domains are"},{"line_number":1110,"context_line":"# configured for virtual-hosted style requests. This option should be a"},{"line_number":1111,"context_line":"# comma-separated list of host names, exactly the same as that set for the"},{"line_number":1112,"context_line":"# s3api middleware."},{"line_number":1113,"context_line":"# storage_domain \u003d"},{"line_number":1114,"context_line":"#"},{"line_number":1115,"context_line":"# An integer value in milliseconds for how often we should emit statsd"}],"source_content_type":"application/octet-stream","patch_set":61,"id":"82c3f3d2_96f97a2b","line":1112,"range":{"start_line":1110,"start_character":48,"end_line":1112,"end_character":19},"in_reply_to":"212e6411_e4325266","updated":"2025-09-03 19:00:05.000000000","message":"Done","commit_id":"74e88a1633605f28d0d5eb95d1c889616245a54f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"198b984c59b8a6fd4ba03b46d765c424b2ef8250","unresolved":true,"context_lines":[{"line_number":1107,"context_line":"#"},{"line_number":1108,"context_line":"# The proxy_logging middleware attempts to translate s3api request paths to"},{"line_number":1109,"context_line":"# swift paths. To do so it needs to know which, if any, storage domains are"},{"line_number":1110,"context_line":"# configured for virtual-hosted style requests. This option should be a"},{"line_number":1111,"context_line":"# comma-separated list of host names, exactly the same as that set for the"},{"line_number":1112,"context_line":"# s3api middleware."},{"line_number":1113,"context_line":"# storage_domain \u003d"},{"line_number":1114,"context_line":"#"},{"line_number":1115,"context_line":"# An integer value in milliseconds for how often we should emit statsd"}],"source_content_type":"application/octet-stream","patch_set":61,"id":"212e6411_e4325266","line":1112,"range":{"start_line":1110,"start_character":48,"end_line":1112,"end_character":19},"in_reply_to":"23735b6b_8dc3b53d","updated":"2025-07-28 14:00:11.000000000","message":"@Tim\n\u003e We can\u0027t just punt to s3api and the auth middlewares to get us a sane swift path? I thought that was part of the appeal of the change in wsgi.py...\n\nwe could, I think, have s3api populate cont \u0026 obj. I just don\u0027t think we have a clear sense of which is better/worse: sharing config between middlewares vs sharing implementation/data structures. \n\nI know we backed away from assuming auth middlewares would populate the `base_labels[account]`.\n\nI don\u0027t think we want to leave ``cont``, ``obj`` to be populated by the rightmost proxy_logging in case s3api changes the path. So we would be relying on s3api populating base_labels. I *think* I\u0027d be ok with that, given that we already rely on s3api setting swift.backend_path.","commit_id":"74e88a1633605f28d0d5eb95d1c889616245a54f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"dd22723e4051ebb7784730a82b60fb9630d3e2ba","unresolved":true,"context_lines":[{"line_number":1103,"context_line":"# Template used to format access logs. All words surrounded by curly brackets"},{"line_number":1104,"context_line":"# will be substituted with the appropriate values. For more information, see"},{"line_number":1105,"context_line":"# https://docs.openstack.org/swift/latest/logs.html"},{"line_number":1106,"context_line":"\u003c\u003c\u003c\u003c\u003c\u003c\u003c PATCH SET (30df98 proxy-logging: Add real-time transfer bytes counters)"},{"line_number":1107,"context_line":"# log_msg_template \u003d {client_ip} {remote_addr} {end_time.datetime} {method} {path} {protocol} {status_int} {referer} {user_agent} {auth_token} {bytes_recvd} {bytes_sent} {client_etag} {transaction_id} {headers} {request_time} {source} {log_info} {start_time} {end_time} {policy_index}"},{"line_number":1108,"context_line":"#"},{"line_number":1109,"context_line":"# The proxy_logging middleware attempts to translate s3api request paths to"}],"source_content_type":"application/octet-stream","patch_set":70,"id":"95d5dbb4_ea3d6613","line":1106,"updated":"2025-09-03 16:14:08.000000000","message":"here\u0027s the git conflict markers!","commit_id":"ee8afcbbe64c15b5bf236f6fcbaa62df8c880319"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"c508fad486daafb491a681d4a06784779fc36512","unresolved":false,"context_lines":[{"line_number":1103,"context_line":"# Template used to format access logs. All words surrounded by curly brackets"},{"line_number":1104,"context_line":"# will be substituted with the appropriate values. For more information, see"},{"line_number":1105,"context_line":"# https://docs.openstack.org/swift/latest/logs.html"},{"line_number":1106,"context_line":"\u003c\u003c\u003c\u003c\u003c\u003c\u003c PATCH SET (30df98 proxy-logging: Add real-time transfer bytes counters)"},{"line_number":1107,"context_line":"# log_msg_template \u003d {client_ip} {remote_addr} {end_time.datetime} {method} {path} {protocol} {status_int} {referer} {user_agent} {auth_token} {bytes_recvd} {bytes_sent} {client_etag} {transaction_id} {headers} {request_time} {source} {log_info} {start_time} {end_time} {policy_index}"},{"line_number":1108,"context_line":"#"},{"line_number":1109,"context_line":"# The proxy_logging middleware attempts to translate s3api request paths to"}],"source_content_type":"application/octet-stream","patch_set":70,"id":"7c931866_c14b0be0","line":1106,"in_reply_to":"95d5dbb4_ea3d6613","updated":"2025-09-03 18:49:18.000000000","message":"Done","commit_id":"ee8afcbbe64c15b5bf236f6fcbaa62df8c880319"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f719d84280a8c3c93378a84805a52e9720b34b4e","unresolved":true,"context_lines":[{"line_number":1115,"context_line":"# real-time buffer transfer bytes counter metrics for WSGI input or output."},{"line_number":1116,"context_line":"# Negative value for not emitting such metrics. 0 for always emitting such"},{"line_number":1117,"context_line":"# metrics on every input or output call. Default is -1."},{"line_number":1118,"context_line":"# statsd_emit_buffer_xfer_bytes_ms \u003d -1"},{"line_number":1119,"context_line":"#"},{"line_number":1120,"context_line":"# Note: Put before both ratelimit and auth in the pipeline."},{"line_number":1121,"context_line":"[filter:bulk]"}],"source_content_type":"application/octet-stream","patch_set":75,"id":"e804ebec_7e196381","line":1118,"updated":"2025-09-24 22:04:31.000000000","message":"Do we have any recommendations for \"reasonable\" positive values for this? I\u0027m guessing 1 would still be rather aggressive; what do we think about 10? Or even 100, or 1,000 -- the resolution on scrapes tends to be what, like 10s?","commit_id":"e4bac03afdc5b67284407a8a585eea20d624cddb"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"bb73cfefbee08032ad27edd00b6f5c0e9da82f79","unresolved":false,"context_lines":[{"line_number":1115,"context_line":"# real-time buffer transfer bytes counter metrics for WSGI input or output."},{"line_number":1116,"context_line":"# Negative value for not emitting such metrics. 0 for always emitting such"},{"line_number":1117,"context_line":"# metrics on every input or output call. Default is -1."},{"line_number":1118,"context_line":"# statsd_emit_buffer_xfer_bytes_ms \u003d -1"},{"line_number":1119,"context_line":"#"},{"line_number":1120,"context_line":"# Note: Put before both ratelimit and auth in the pipeline."},{"line_number":1121,"context_line":"[filter:bulk]"}],"source_content_type":"application/octet-stream","patch_set":75,"id":"846171d2_d1c10355","line":1118,"in_reply_to":"e804ebec_7e196381","updated":"2025-10-10 18:27:29.000000000","message":"Default is 1, anything above that should be reasonable. We can recommend a higher value if needed!","commit_id":"e4bac03afdc5b67284407a8a585eea20d624cddb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f1ff6fe03b84a9459586a4e497449e251685f176","unresolved":true,"context_lines":[{"line_number":1139,"context_line":"# real-time buffer transfer bytes counter metrics for WSGI input or output."},{"line_number":1140,"context_line":"# Negative value for not emitting such metrics. 0 for always emitting such"},{"line_number":1141,"context_line":"# metrics on every input or output call. Default is -1."},{"line_number":1142,"context_line":"# statsd_emit_buffer_xfer_bytes_ms \u003d -1"},{"line_number":1143,"context_line":"#"},{"line_number":1144,"context_line":"# Note: Put before both ratelimit and auth in the pipeline."},{"line_number":1145,"context_line":"[filter:bulk]"}],"source_content_type":"application/octet-stream","patch_set":86,"id":"fc02a366_6ab52097","line":1142,"updated":"2025-10-28 10:48:24.000000000","message":"sorry to drop this at such a late stage in review, but Clay asked me why the conf value is msecs (and not float secs) ... and I think he\u0027s right!\n\nI think that all other time conf options are expressed in secs, so it\u0027s confusing to have this new one NOT be seconds, and also unnecessary.\n\nWas there a reason that msecs was chosen as the unit? We may need Yan to comment.","commit_id":"1a081d4e3f01893c0bd898b1b877b9a95b1339b3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"28e694101f4c34119d225ed95d41eeda3a786d68","unresolved":false,"context_lines":[{"line_number":1139,"context_line":"# real-time buffer transfer bytes counter metrics for WSGI input or output."},{"line_number":1140,"context_line":"# Negative value for not emitting such metrics. 0 for always emitting such"},{"line_number":1141,"context_line":"# metrics on every input or output call. Default is -1."},{"line_number":1142,"context_line":"# statsd_emit_buffer_xfer_bytes_ms \u003d -1"},{"line_number":1143,"context_line":"#"},{"line_number":1144,"context_line":"# Note: Put before both ratelimit and auth in the pipeline."},{"line_number":1145,"context_line":"[filter:bulk]"}],"source_content_type":"application/octet-stream","patch_set":86,"id":"65ad51ff_a356a70e","line":1142,"in_reply_to":"fc02a366_6ab52097","updated":"2025-10-28 21:29:27.000000000","message":"Updated config per our discussion","commit_id":"1a081d4e3f01893c0bd898b1b877b9a95b1339b3"}],"swift/common/middleware/proxy_logging.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"735abc7928e73bf5b3f3464946fe04633df6fb42","unresolved":true,"context_lines":[{"line_number":206,"context_line":"            raise ValueError(\u0027Cannot interpolate log_msg_template: %s\u0027 % e)"},{"line_number":207,"context_line":""},{"line_number":208,"context_line":"    def method_from_req(self, req):"},{"line_number":209,"context_line":"        return req.environ.get(\u0027swift.orig_req_method\u0027, req.method)"},{"line_number":210,"context_line":""},{"line_number":211,"context_line":"    def req_already_logged(self, env):"},{"line_number":212,"context_line":"        return env.get(\u0027swift.proxy_access_log_made\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"f4bb7a89_bdaba6b2","side":"PARENT","line":209,"updated":"2024-10-07 17:15:03.000000000","message":"i support making methods into functions whereever we can!","commit_id":"947277842cbc0893b4e8790da611ad96a28fce17"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"cf087b0546a525a7c0b6b9144552345ff5068d98","unresolved":false,"context_lines":[{"line_number":206,"context_line":"            raise ValueError(\u0027Cannot interpolate log_msg_template: %s\u0027 % e)"},{"line_number":207,"context_line":""},{"line_number":208,"context_line":"    def method_from_req(self, req):"},{"line_number":209,"context_line":"        return req.environ.get(\u0027swift.orig_req_method\u0027, req.method)"},{"line_number":210,"context_line":""},{"line_number":211,"context_line":"    def req_already_logged(self, env):"},{"line_number":212,"context_line":"        return env.get(\u0027swift.proxy_access_log_made\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"631d1171_adbcdb5c","side":"PARENT","line":209,"in_reply_to":"f4bb7a89_bdaba6b2","updated":"2024-10-11 15:22:05.000000000","message":"Acknowledged","commit_id":"947277842cbc0893b4e8790da611ad96a28fce17"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"735abc7928e73bf5b3f3464946fe04633df6fb42","unresolved":true,"context_lines":[{"line_number":507,"context_line":"        path_env \u003d req.environ.get(\u0027PATH_INFO\u0027, None)"},{"line_number":508,"context_line":"        proxy_env \u003d req.environ.get(\u0027backpropagate_proxy_env\u0027, None)"},{"line_number":509,"context_line":"        if proxy_env is not None and path_env is not None:"},{"line_number":510,"context_line":"            proxy_env[\u0027PATH_INFO\u0027] \u003d path_env"},{"line_number":511,"context_line":""},{"line_number":512,"context_line":"        if xfer_labels is not None:"},{"line_number":513,"context_line":"            statsd_emit_callback \u003d self.get_buffer_xfer_emit_callback("}],"source_content_type":"text/x-python","patch_set":2,"id":"a5aac084_e1e7373d","line":510,"updated":"2024-10-07 17:15:03.000000000","message":"why are WE re-writing the request PATH_INFO!?  And isn\u0027t PATH_INFO normally just a string; i thougth `backpropogate_proxy_env` was a dict/environ.","commit_id":"93971c11c36809e4f15deb33704f4929c44ec3ab"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"6578bf38dcfbbb449948bb15e330a17d5db773cf","unresolved":false,"context_lines":[{"line_number":507,"context_line":"        path_env \u003d req.environ.get(\u0027PATH_INFO\u0027, None)"},{"line_number":508,"context_line":"        proxy_env \u003d req.environ.get(\u0027backpropagate_proxy_env\u0027, None)"},{"line_number":509,"context_line":"        if proxy_env is not None and path_env is not None:"},{"line_number":510,"context_line":"            proxy_env[\u0027PATH_INFO\u0027] \u003d path_env"},{"line_number":511,"context_line":""},{"line_number":512,"context_line":"        if xfer_labels is not None:"},{"line_number":513,"context_line":"            statsd_emit_callback \u003d self.get_buffer_xfer_emit_callback("}],"source_content_type":"text/x-python","patch_set":2,"id":"230ef872_5e5ef660","line":510,"in_reply_to":"a5aac084_e1e7373d","updated":"2024-10-11 15:33:16.000000000","message":"Acknowledged","commit_id":"93971c11c36809e4f15deb33704f4929c44ec3ab"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"88385b4cb0bf4ad1b773fc44366c408fde5ed0b7","unresolved":true,"context_lines":[{"line_number":373,"context_line":"                raise ValueError"},{"line_number":374,"context_line":"        except ValueError:"},{"line_number":375,"context_line":"            acc, cont, obj \u003d None, None, None"},{"line_number":376,"context_line":"        return acc, cont, obj"},{"line_number":377,"context_line":""},{"line_number":378,"context_line":"    def get_metric_name_type(self, req):"},{"line_number":379,"context_line":"        swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"}],"source_content_type":"text/x-python","patch_set":4,"id":"02c34699_094ea3de","side":"PARENT","line":376,"updated":"2024-10-29 17:29:39.000000000","message":"this \"method\" doesn\u0027t even *use* `self`!  Much better as a pure function - kudos!","commit_id":"09df3927ca90d4aa215f3c6fb0cbfbdf63ab12fd"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"770fc5ba81f79fd485837068bcefe7f8e5d99a74","unresolved":false,"context_lines":[{"line_number":373,"context_line":"                raise ValueError"},{"line_number":374,"context_line":"        except ValueError:"},{"line_number":375,"context_line":"            acc, cont, obj \u003d None, None, None"},{"line_number":376,"context_line":"        return acc, cont, obj"},{"line_number":377,"context_line":""},{"line_number":378,"context_line":"    def get_metric_name_type(self, req):"},{"line_number":379,"context_line":"        swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"}],"source_content_type":"text/x-python","patch_set":4,"id":"1c7f6590_15e997eb","side":"PARENT","line":376,"in_reply_to":"02c34699_094ea3de","updated":"2024-11-01 15:35:26.000000000","message":"Acknowledged","commit_id":"09df3927ca90d4aa215f3c6fb0cbfbdf63ab12fd"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"88385b4cb0bf4ad1b773fc44366c408fde5ed0b7","unresolved":true,"context_lines":[{"line_number":152,"context_line":"            policy_index is not None and \\"},{"line_number":153,"context_line":"            POLICIES.get_by_index(policy_index) is not None:"},{"line_number":154,"context_line":"        labels[\u0027policy\u0027] \u003d policy_index"},{"line_number":155,"context_line":"    return labels"},{"line_number":156,"context_line":""},{"line_number":157,"context_line":""},{"line_number":158,"context_line":"class ProxyLoggingMiddleware(object):"}],"source_content_type":"text/x-python","patch_set":4,"id":"ad8d9a36_43b40be8","line":155,"updated":"2024-10-29 17:29:39.000000000","message":"i almost always support turning methods into functions - kudos!","commit_id":"cdb1cdf7df5bdc8bfcf782b7efa622976eb0df1b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"770fc5ba81f79fd485837068bcefe7f8e5d99a74","unresolved":false,"context_lines":[{"line_number":152,"context_line":"            policy_index is not None and \\"},{"line_number":153,"context_line":"            POLICIES.get_by_index(policy_index) is not None:"},{"line_number":154,"context_line":"        labels[\u0027policy\u0027] \u003d policy_index"},{"line_number":155,"context_line":"    return labels"},{"line_number":156,"context_line":""},{"line_number":157,"context_line":""},{"line_number":158,"context_line":"class ProxyLoggingMiddleware(object):"}],"source_content_type":"text/x-python","patch_set":4,"id":"ee69a89e_b696674c","line":155,"in_reply_to":"ad8d9a36_43b40be8","updated":"2024-11-01 15:35:26.000000000","message":"Acknowledged","commit_id":"cdb1cdf7df5bdc8bfcf782b7efa622976eb0df1b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"88385b4cb0bf4ad1b773fc44366c408fde5ed0b7","unresolved":true,"context_lines":[{"line_number":464,"context_line":"                update_path \u003d None"},{"line_number":465,"context_line":"                proxy_env \u003d req.environ.get(\u0027backpropagate_proxy_env\u0027, {})"},{"line_number":466,"context_line":"                if proxy_env:"},{"line_number":467,"context_line":"                    update_path \u003d proxy_env.get(\u0027swift.backend_path\u0027, None)"},{"line_number":468,"context_line":"                if update_path:"},{"line_number":469,"context_line":"                    req.environ[\u0027swift.backend_path\u0027] \u003d update_path"},{"line_number":470,"context_line":"                swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"}],"source_content_type":"text/x-python","patch_set":4,"id":"52939a8f_5df3dd71","line":467,"updated":"2024-10-29 17:29:39.000000000","message":"why the redirection/double-nesting?  Does the missing `swift.backend_path` mean this wasn\u0027t an s3api request?","commit_id":"cdb1cdf7df5bdc8bfcf782b7efa622976eb0df1b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"770fc5ba81f79fd485837068bcefe7f8e5d99a74","unresolved":false,"context_lines":[{"line_number":464,"context_line":"                update_path \u003d None"},{"line_number":465,"context_line":"                proxy_env \u003d req.environ.get(\u0027backpropagate_proxy_env\u0027, {})"},{"line_number":466,"context_line":"                if proxy_env:"},{"line_number":467,"context_line":"                    update_path \u003d proxy_env.get(\u0027swift.backend_path\u0027, None)"},{"line_number":468,"context_line":"                if update_path:"},{"line_number":469,"context_line":"                    req.environ[\u0027swift.backend_path\u0027] \u003d update_path"},{"line_number":470,"context_line":"                swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"}],"source_content_type":"text/x-python","patch_set":4,"id":"0da834d0_ab42c8c9","line":467,"in_reply_to":"52939a8f_5df3dd71","updated":"2024-11-01 15:35:26.000000000","message":"if swift.backend_path is None, probably subrequest-proxy-logging isn\u0027t configured. Otherwise should exist","commit_id":"cdb1cdf7df5bdc8bfcf782b7efa622976eb0df1b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"88385b4cb0bf4ad1b773fc44366c408fde5ed0b7","unresolved":true,"context_lines":[{"line_number":466,"context_line":"                if proxy_env:"},{"line_number":467,"context_line":"                    update_path \u003d proxy_env.get(\u0027swift.backend_path\u0027, None)"},{"line_number":468,"context_line":"                if update_path:"},{"line_number":469,"context_line":"                    req.environ[\u0027swift.backend_path\u0027] \u003d update_path"},{"line_number":470,"context_line":"                swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"},{"line_number":471,"context_line":"                acc, cont, _ \u003d get_aco_from_path(swift_path)"},{"line_number":472,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"2d6a5f97_7ea7572b","line":469,"updated":"2024-10-29 17:29:39.000000000","message":"if this *was* a s3api request why can\u0027t s3api just ensure that the `update_path` is *already* in the `req.environ` so that proxy_logging doesn\u0027t have to do it on it\u0027s behalf?","commit_id":"cdb1cdf7df5bdc8bfcf782b7efa622976eb0df1b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"770fc5ba81f79fd485837068bcefe7f8e5d99a74","unresolved":true,"context_lines":[{"line_number":466,"context_line":"                if proxy_env:"},{"line_number":467,"context_line":"                    update_path \u003d proxy_env.get(\u0027swift.backend_path\u0027, None)"},{"line_number":468,"context_line":"                if update_path:"},{"line_number":469,"context_line":"                    req.environ[\u0027swift.backend_path\u0027] \u003d update_path"},{"line_number":470,"context_line":"                swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"},{"line_number":471,"context_line":"                acc, cont, _ \u003d get_aco_from_path(swift_path)"},{"line_number":472,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"cced6441_6c06a4b8","line":469,"in_reply_to":"2d6a5f97_7ea7572b","updated":"2024-11-01 15:35:26.000000000","message":"Good point. Updated according to your suggestion","commit_id":"cdb1cdf7df5bdc8bfcf782b7efa622976eb0df1b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"cb15c832481ae6c0f7b946721addefada72f84b3","unresolved":false,"context_lines":[{"line_number":466,"context_line":"                if proxy_env:"},{"line_number":467,"context_line":"                    update_path \u003d proxy_env.get(\u0027swift.backend_path\u0027, None)"},{"line_number":468,"context_line":"                if update_path:"},{"line_number":469,"context_line":"                    req.environ[\u0027swift.backend_path\u0027] \u003d update_path"},{"line_number":470,"context_line":"                swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"},{"line_number":471,"context_line":"                acc, cont, _ \u003d get_aco_from_path(swift_path)"},{"line_number":472,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"75d2aecb_3e8752f2","line":469,"in_reply_to":"cced6441_6c06a4b8","updated":"2024-11-01 15:35:41.000000000","message":"Acknowledged","commit_id":"cdb1cdf7df5bdc8bfcf782b7efa622976eb0df1b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"88385b4cb0bf4ad1b773fc44366c408fde5ed0b7","unresolved":true,"context_lines":[{"line_number":513,"context_line":"        req_path \u003d req.environ.get(\u0027PATH_INFO\u0027, None)"},{"line_number":514,"context_line":"        proxy_env \u003d req.environ.get(\u0027backpropagate_proxy_env\u0027, None)"},{"line_number":515,"context_line":"        if proxy_env is not None and req_path is not None:"},{"line_number":516,"context_line":"            proxy_env[\u0027swift.backend_path\u0027] \u003d req_path"},{"line_number":517,"context_line":""},{"line_number":518,"context_line":"        if xfer_labels is not None:"},{"line_number":519,"context_line":"            statsd_emit_callback \u003d self.get_buffer_xfer_emit_callback("}],"source_content_type":"text/x-python","patch_set":4,"id":"fed42dbf_7c338190","line":516,"updated":"2024-10-29 17:29:39.000000000","message":"this doesn\u0027t seem like something that proxy_logging should have to do - is this in *second* right-most instance of proxy-logging?!","commit_id":"cdb1cdf7df5bdc8bfcf782b7efa622976eb0df1b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"770fc5ba81f79fd485837068bcefe7f8e5d99a74","unresolved":false,"context_lines":[{"line_number":513,"context_line":"        req_path \u003d req.environ.get(\u0027PATH_INFO\u0027, None)"},{"line_number":514,"context_line":"        proxy_env \u003d req.environ.get(\u0027backpropagate_proxy_env\u0027, None)"},{"line_number":515,"context_line":"        if proxy_env is not None and req_path is not None:"},{"line_number":516,"context_line":"            proxy_env[\u0027swift.backend_path\u0027] \u003d req_path"},{"line_number":517,"context_line":""},{"line_number":518,"context_line":"        if xfer_labels is not None:"},{"line_number":519,"context_line":"            statsd_emit_callback \u003d self.get_buffer_xfer_emit_callback("}],"source_content_type":"text/x-python","patch_set":4,"id":"34717e12_f2c0f4aa","line":516,"in_reply_to":"fed42dbf_7c338190","updated":"2024-11-01 15:35:26.000000000","message":"Indeed. If proxy_env exists, this should be the subrequest-proxy-logging instance","commit_id":"cdb1cdf7df5bdc8bfcf782b7efa622976eb0df1b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"34996bc75ca6f593d928381298d4af325195443c","unresolved":true,"context_lines":[{"line_number":135,"context_line":"                         acc\u003dNone, cont\u003dNone, policy_index\u003dNone,"},{"line_number":136,"context_line":"                         subreq_paths\u003dNone):"},{"line_number":137,"context_line":"    server_type \u003d get_metric_name_type(req)"},{"line_number":138,"context_line":"    if server_type is None:"},{"line_number":139,"context_line":"        return None"},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"    labels \u003d {"}],"source_content_type":"text/x-python","patch_set":6,"id":"1e019d44_aa3670d5","line":138,"updated":"2024-11-14 14:41:23.000000000","message":"``stat_type`` cannot be None from ``get_metric_name_type``?","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":135,"context_line":"                         acc\u003dNone, cont\u003dNone, policy_index\u003dNone,"},{"line_number":136,"context_line":"                         subreq_paths\u003dNone):"},{"line_number":137,"context_line":"    server_type \u003d get_metric_name_type(req)"},{"line_number":138,"context_line":"    if server_type is None:"},{"line_number":139,"context_line":"        return None"},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"    labels \u003d {"}],"source_content_type":"text/x-python","patch_set":6,"id":"5e15f267_42aeab17","line":138,"in_reply_to":"1e019d44_aa3670d5","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"83aaeaa742cdf60cda754faeb378c1f60824bdd3","unresolved":true,"context_lines":[{"line_number":140,"context_line":""},{"line_number":141,"context_line":"    labels \u003d {"},{"line_number":142,"context_line":"        \u0027type\u0027: server_type,"},{"line_number":143,"context_line":"        \u0027method\u0027: (method if method in valid_methods"},{"line_number":144,"context_line":"                   else \u0027BAD_METHOD\u0027),"},{"line_number":145,"context_line":"    }"},{"line_number":146,"context_line":"    if status_int:"}],"source_content_type":"text/x-python","patch_set":6,"id":"c1501398_dd46c136","line":143,"range":{"start_line":143,"start_character":19,"end_line":143,"end_character":52},"updated":"2024-11-19 18:48:36.000000000","message":"this could be evaluated by the caller to this function and that then avoids passing in ``valid_methods``","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":140,"context_line":""},{"line_number":141,"context_line":"    labels \u003d {"},{"line_number":142,"context_line":"        \u0027type\u0027: server_type,"},{"line_number":143,"context_line":"        \u0027method\u0027: (method if method in valid_methods"},{"line_number":144,"context_line":"                   else \u0027BAD_METHOD\u0027),"},{"line_number":145,"context_line":"    }"},{"line_number":146,"context_line":"    if status_int:"}],"source_content_type":"text/x-python","patch_set":6,"id":"2914f784_18359d52","line":143,"range":{"start_line":143,"start_character":19,"end_line":143,"end_character":52},"in_reply_to":"c1501398_dd46c136","updated":"2024-11-22 20:30:38.000000000","message":"keeping valid_methods close to statsd_metric_labels logic for now as the class implementation seems easier to understand","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"34996bc75ca6f593d928381298d4af325195443c","unresolved":true,"context_lines":[{"line_number":155,"context_line":"        labels[\u0027policy\u0027] \u003d policy_index"},{"line_number":156,"context_line":"    if subreq_paths:"},{"line_number":157,"context_line":"        for path in subreq_paths:"},{"line_number":158,"context_line":"            if path \u003d\u003d \u0027S3\u0027:"},{"line_number":159,"context_line":"                labels[\u0027client\u0027] \u003d \u0027S3\u0027"},{"line_number":160,"context_line":"                break"},{"line_number":161,"context_line":"    return labels"}],"source_content_type":"text/x-python","patch_set":6,"id":"36051ac8_24e69e25","line":158,"updated":"2024-11-14 14:41:23.000000000","message":"the use of ``path`` here is odd when in fact we\u0027re looking for a ``source`` string","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":155,"context_line":"        labels[\u0027policy\u0027] \u003d policy_index"},{"line_number":156,"context_line":"    if subreq_paths:"},{"line_number":157,"context_line":"        for path in subreq_paths:"},{"line_number":158,"context_line":"            if path \u003d\u003d \u0027S3\u0027:"},{"line_number":159,"context_line":"                labels[\u0027client\u0027] \u003d \u0027S3\u0027"},{"line_number":160,"context_line":"                break"},{"line_number":161,"context_line":"    return labels"}],"source_content_type":"text/x-python","patch_set":6,"id":"73cc3f68_f7bfd11c","line":158,"in_reply_to":"36051ac8_24e69e25","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"34996bc75ca6f593d928381298d4af325195443c","unresolved":true,"context_lines":[{"line_number":158,"context_line":"            if path \u003d\u003d \u0027S3\u0027:"},{"line_number":159,"context_line":"                labels[\u0027client\u0027] \u003d \u0027S3\u0027"},{"line_number":160,"context_line":"                break"},{"line_number":161,"context_line":"    return labels"},{"line_number":162,"context_line":""},{"line_number":163,"context_line":""},{"line_number":164,"context_line":"class ProxyLoggingMiddleware(object):"}],"source_content_type":"text/x-python","patch_set":6,"id":"77e896ef_69caffc8","line":161,"updated":"2024-11-14 14:41:23.000000000","message":"I think this function always returns a dict with at least two keys","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":158,"context_line":"            if path \u003d\u003d \u0027S3\u0027:"},{"line_number":159,"context_line":"                labels[\u0027client\u0027] \u003d \u0027S3\u0027"},{"line_number":160,"context_line":"                break"},{"line_number":161,"context_line":"    return labels"},{"line_number":162,"context_line":""},{"line_number":163,"context_line":""},{"line_number":164,"context_line":"class ProxyLoggingMiddleware(object):"}],"source_content_type":"text/x-python","patch_set":6,"id":"decedd07_d6093cb8","line":161,"in_reply_to":"77e896ef_69caffc8","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"34996bc75ca6f593d928381298d4af325195443c","unresolved":true,"context_lines":[{"line_number":213,"context_line":"            conf.get(\u0027reveal_sensitive_prefix\u0027, 16))"},{"line_number":214,"context_line":"        self.check_log_msg_template_validity()"},{"line_number":215,"context_line":"        statsd_emit_buffer_xfer_bytes_ms \u003d int("},{"line_number":216,"context_line":"            conf.get(\u0027statsd_emit_buffer_xfer_bytes_ms\u0027, -1))"},{"line_number":217,"context_line":"        if statsd_emit_buffer_xfer_bytes_ms \u003c 0:"},{"line_number":218,"context_line":"            self.emit_buffer_xfer_bytes_sec \u003d -1"},{"line_number":219,"context_line":"        elif statsd_emit_buffer_xfer_bytes_ms \u003d\u003d 0:"}],"source_content_type":"text/x-python","patch_set":6,"id":"0bd85d30_212cf045","line":216,"updated":"2024-11-14 14:41:23.000000000","message":"is there a reason to have this be a ms value rather than float seconds?","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3c9db4b292eacdc99e65c8934ed5e7d5148bdd8b","unresolved":false,"context_lines":[{"line_number":213,"context_line":"            conf.get(\u0027reveal_sensitive_prefix\u0027, 16))"},{"line_number":214,"context_line":"        self.check_log_msg_template_validity()"},{"line_number":215,"context_line":"        statsd_emit_buffer_xfer_bytes_ms \u003d int("},{"line_number":216,"context_line":"            conf.get(\u0027statsd_emit_buffer_xfer_bytes_ms\u0027, -1))"},{"line_number":217,"context_line":"        if statsd_emit_buffer_xfer_bytes_ms \u003c 0:"},{"line_number":218,"context_line":"            self.emit_buffer_xfer_bytes_sec \u003d -1"},{"line_number":219,"context_line":"        elif statsd_emit_buffer_xfer_bytes_ms \u003d\u003d 0:"}],"source_content_type":"text/x-python","patch_set":6,"id":"303ffd1c_b7a9059e","line":216,"in_reply_to":"0b21a0fe_d57c7d08","updated":"2024-11-29 16:33:28.000000000","message":"OIC, so avoid user specifying a float value that is less than 1ms. Makes sense.","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":true,"context_lines":[{"line_number":213,"context_line":"            conf.get(\u0027reveal_sensitive_prefix\u0027, 16))"},{"line_number":214,"context_line":"        self.check_log_msg_template_validity()"},{"line_number":215,"context_line":"        statsd_emit_buffer_xfer_bytes_ms \u003d int("},{"line_number":216,"context_line":"            conf.get(\u0027statsd_emit_buffer_xfer_bytes_ms\u0027, -1))"},{"line_number":217,"context_line":"        if statsd_emit_buffer_xfer_bytes_ms \u003c 0:"},{"line_number":218,"context_line":"            self.emit_buffer_xfer_bytes_sec \u003d -1"},{"line_number":219,"context_line":"        elif statsd_emit_buffer_xfer_bytes_ms \u003d\u003d 0:"}],"source_content_type":"text/x-python","patch_set":6,"id":"0b21a0fe_d57c7d08","line":216,"in_reply_to":"0bd85d30_212cf045","updated":"2024-11-22 20:30:38.000000000","message":"using milliseconds seems would be easier for user to understand the precision this config option would support","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"34996bc75ca6f593d928381298d4af325195443c","unresolved":true,"context_lines":[{"line_number":410,"context_line":"                                            bytes_received + bytes_sent)"},{"line_number":411,"context_line":""},{"line_number":412,"context_line":"        subreq_paths \u003d req.environ.get(\u0027swift.subrequest_paths\u0027)"},{"line_number":413,"context_line":"        labels \u003d statsd_metric_labels("},{"line_number":414,"context_line":"            req, self.valid_methods, method, status_int\u003dstatus_int,"},{"line_number":415,"context_line":"            acc\u003dacc, cont\u003dcont, policy_index\u003dpolicy_index,"},{"line_number":416,"context_line":"            subreq_paths\u003dsubreq_paths)"}],"source_content_type":"text/x-python","patch_set":6,"id":"65ea3862_0407de16","line":413,"range":{"start_line":413,"start_character":17,"end_line":413,"end_character":37},"updated":"2024-11-14 14:41:23.000000000","message":"why move this method out of the class and then have to pass it an attribute of the class? what was wrong with it being a method of the class that could access ``self.valid_methods``, just like the following two methods do?","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":410,"context_line":"                                            bytes_received + bytes_sent)"},{"line_number":411,"context_line":""},{"line_number":412,"context_line":"        subreq_paths \u003d req.environ.get(\u0027swift.subrequest_paths\u0027)"},{"line_number":413,"context_line":"        labels \u003d statsd_metric_labels("},{"line_number":414,"context_line":"            req, self.valid_methods, method, status_int\u003dstatus_int,"},{"line_number":415,"context_line":"            acc\u003dacc, cont\u003dcont, policy_index\u003dpolicy_index,"},{"line_number":416,"context_line":"            subreq_paths\u003dsubreq_paths)"}],"source_content_type":"text/x-python","patch_set":6,"id":"7bcca932_f78240be","line":413,"range":{"start_line":413,"start_character":17,"end_line":413,"end_character":37},"in_reply_to":"18e1dffd_d3a50b68","updated":"2024-11-22 20:30:38.000000000","message":"updated to use a callback-handler-class per our discussion. keeping valid_methods close to statsd_metric_labels logic for now as the class implementation seems easier to understand","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e6df311bac282d96055b00037a8324cedb49d04a","unresolved":true,"context_lines":[{"line_number":410,"context_line":"                                            bytes_received + bytes_sent)"},{"line_number":411,"context_line":""},{"line_number":412,"context_line":"        subreq_paths \u003d req.environ.get(\u0027swift.subrequest_paths\u0027)"},{"line_number":413,"context_line":"        labels \u003d statsd_metric_labels("},{"line_number":414,"context_line":"            req, self.valid_methods, method, status_int\u003dstatus_int,"},{"line_number":415,"context_line":"            acc\u003dacc, cont\u003dcont, policy_index\u003dpolicy_index,"},{"line_number":416,"context_line":"            subreq_paths\u003dsubreq_paths)"}],"source_content_type":"text/x-python","patch_set":6,"id":"18e1dffd_d3a50b68","line":413,"range":{"start_line":413,"start_character":17,"end_line":413,"end_character":37},"in_reply_to":"65ea3862_0407de16","updated":"2024-11-19 18:58:22.000000000","message":"one reason this moved is because we want to call it from a different place/class\n\n... except the callback/closure is in the same class\n\nbut if we had a need to call the \"get_statsd_metrics_labels\" from proxy-logging mw class OR the callback-handler-class you might want it to be a module level function.","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"83aaeaa742cdf60cda754faeb378c1f60824bdd3","unresolved":true,"context_lines":[{"line_number":410,"context_line":"                                            bytes_received + bytes_sent)"},{"line_number":411,"context_line":""},{"line_number":412,"context_line":"        subreq_paths \u003d req.environ.get(\u0027swift.subrequest_paths\u0027)"},{"line_number":413,"context_line":"        labels \u003d statsd_metric_labels("},{"line_number":414,"context_line":"            req, self.valid_methods, method, status_int\u003dstatus_int,"},{"line_number":415,"context_line":"            acc\u003dacc, cont\u003dcont, policy_index\u003dpolicy_index,"},{"line_number":416,"context_line":"            subreq_paths\u003dsubreq_paths)"}],"source_content_type":"text/x-python","patch_set":6,"id":"14c645ed_c9f6a0a4","line":413,"range":{"start_line":413,"start_character":17,"end_line":413,"end_character":37},"in_reply_to":"65ea3862_0407de16","updated":"2024-11-19 18:48:36.000000000","message":"we discussed this more...a valid reason to move a method to the module level is so that it can be called from other classes. If the callback handler becomes a *class* then that would be the case.\n\nAlso, as noted above, I think the need for valid_methods to be passed can perhaps be avoided anyway.","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"34996bc75ca6f593d928381298d4af325195443c","unresolved":true,"context_lines":[{"line_number":434,"context_line":""},{"line_number":435,"context_line":"    def statsd_metric_name(self, req, status_int, method):"},{"line_number":436,"context_line":"        stat_type \u003d get_metric_name_type(req)"},{"line_number":437,"context_line":"        if stat_type is None:"},{"line_number":438,"context_line":"            return None"},{"line_number":439,"context_line":"        stat_method \u003d method if method in self.valid_methods \\"},{"line_number":440,"context_line":"            else \u0027BAD_METHOD\u0027"}],"source_content_type":"text/x-python","patch_set":6,"id":"9d46c3c1_911197a1","line":437,"updated":"2024-11-14 14:41:23.000000000","message":"``stat_type`` cannot be None from ``get_metric_name_type``?","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":434,"context_line":""},{"line_number":435,"context_line":"    def statsd_metric_name(self, req, status_int, method):"},{"line_number":436,"context_line":"        stat_type \u003d get_metric_name_type(req)"},{"line_number":437,"context_line":"        if stat_type is None:"},{"line_number":438,"context_line":"            return None"},{"line_number":439,"context_line":"        stat_method \u003d method if method in self.valid_methods \\"},{"line_number":440,"context_line":"            else \u0027BAD_METHOD\u0027"}],"source_content_type":"text/x-python","patch_set":6,"id":"db46edad_ef12d0f7","line":437,"in_reply_to":"9d46c3c1_911197a1","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"34996bc75ca6f593d928381298d4af325195443c","unresolved":true,"context_lines":[{"line_number":466,"context_line":"            next_emit_time \u003d 0"},{"line_number":467,"context_line":""},{"line_number":468,"context_line":"        def buffer_xfer_emit_callback(buffer_len):"},{"line_number":469,"context_line":"            if CallbackParameters.labels is None:"},{"line_number":470,"context_line":"                return"},{"line_number":471,"context_line":""},{"line_number":472,"context_line":"            if CallbackParameters.labels.get(\u0027account\u0027, None) is None:"}],"source_content_type":"text/x-python","patch_set":6,"id":"3c547dfd_e03bfa0e","line":469,"updated":"2024-11-14 14:41:23.000000000","message":"can this ever be true. IIUC labels is always a dict","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":466,"context_line":"            next_emit_time \u003d 0"},{"line_number":467,"context_line":""},{"line_number":468,"context_line":"        def buffer_xfer_emit_callback(buffer_len):"},{"line_number":469,"context_line":"            if CallbackParameters.labels is None:"},{"line_number":470,"context_line":"                return"},{"line_number":471,"context_line":""},{"line_number":472,"context_line":"            if CallbackParameters.labels.get(\u0027account\u0027, None) is None:"}],"source_content_type":"text/x-python","patch_set":6,"id":"d5db1c30_a1db7442","line":469,"in_reply_to":"3c547dfd_e03bfa0e","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"50cfce9a3e0bacd0e5a159d88d1a76c3079ff742","unresolved":true,"context_lines":[{"line_number":469,"context_line":"            if CallbackParameters.labels is None:"},{"line_number":470,"context_line":"                return"},{"line_number":471,"context_line":""},{"line_number":472,"context_line":"            if CallbackParameters.labels.get(\u0027account\u0027, None) is None:"},{"line_number":473,"context_line":"                method \u003d method_from_req(req)"},{"line_number":474,"context_line":""},{"line_number":475,"context_line":"                subreq_paths \u003d req.environ.get(\u0027swift.subrequest_paths\u0027)"}],"source_content_type":"text/x-python","patch_set":6,"id":"9f5bebed_b4655743","line":472,"updated":"2024-11-19 17:50:47.000000000","message":"this is essentially just testing if this is the first time we\u0027re calling the callback (i.e. we haven\u0027t filled in our labels yet, which has to be deferred until the first read - so that the subrequest proxy-logging has every oppertunity to figure out the swift path and add it to the req.environ","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":469,"context_line":"            if CallbackParameters.labels is None:"},{"line_number":470,"context_line":"                return"},{"line_number":471,"context_line":""},{"line_number":472,"context_line":"            if CallbackParameters.labels.get(\u0027account\u0027, None) is None:"},{"line_number":473,"context_line":"                method \u003d method_from_req(req)"},{"line_number":474,"context_line":""},{"line_number":475,"context_line":"                subreq_paths \u003d req.environ.get(\u0027swift.subrequest_paths\u0027)"}],"source_content_type":"text/x-python","patch_set":6,"id":"27c16436_402c0279","line":472,"in_reply_to":"9f5bebed_b4655743","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"34996bc75ca6f593d928381298d4af325195443c","unresolved":true,"context_lines":[{"line_number":483,"context_line":"                CallbackParameters.labels \u003d statsd_metric_labels("},{"line_number":484,"context_line":"                    req, valid_methods, method, status_int\u003dstatus_int,"},{"line_number":485,"context_line":"                    acc\u003dacc, cont\u003dcont, policy_index\u003dpolicy_index,"},{"line_number":486,"context_line":"                    subreq_paths\u003dsubreq_paths)"},{"line_number":487,"context_line":""},{"line_number":488,"context_line":"            if self.emit_buffer_xfer_bytes_sec \u003e\u003d 0:"},{"line_number":489,"context_line":"                CallbackParameters.emit_bytes +\u003d buffer_len"}],"source_content_type":"text/x-python","patch_set":6,"id":"20b67c04_b400eb51","line":486,"updated":"2024-11-14 14:41:23.000000000","message":"IIUC this ``if`` clause may mutate the labels while the InputProxy is iterating the bytes?? can you add some comments to explain what is happening and why?","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":483,"context_line":"                CallbackParameters.labels \u003d statsd_metric_labels("},{"line_number":484,"context_line":"                    req, valid_methods, method, status_int\u003dstatus_int,"},{"line_number":485,"context_line":"                    acc\u003dacc, cont\u003dcont, policy_index\u003dpolicy_index,"},{"line_number":486,"context_line":"                    subreq_paths\u003dsubreq_paths)"},{"line_number":487,"context_line":""},{"line_number":488,"context_line":"            if self.emit_buffer_xfer_bytes_sec \u003e\u003d 0:"},{"line_number":489,"context_line":"                CallbackParameters.emit_bytes +\u003d buffer_len"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a7b1819_22dae1af","line":486,"in_reply_to":"20b67c04_b400eb51","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"34996bc75ca6f593d928381298d4af325195443c","unresolved":true,"context_lines":[{"line_number":485,"context_line":"                    acc\u003dacc, cont\u003dcont, policy_index\u003dpolicy_index,"},{"line_number":486,"context_line":"                    subreq_paths\u003dsubreq_paths)"},{"line_number":487,"context_line":""},{"line_number":488,"context_line":"            if self.emit_buffer_xfer_bytes_sec \u003e\u003d 0:"},{"line_number":489,"context_line":"                CallbackParameters.emit_bytes +\u003d buffer_len"},{"line_number":490,"context_line":"                now \u003d time.time()"},{"line_number":491,"context_line":"                if self.emit_buffer_xfer_bytes_sec \u003d\u003d 0 or \\"}],"source_content_type":"text/x-python","patch_set":6,"id":"f6d36b91_e8ba0760","line":488,"updated":"2024-11-14 14:41:23.000000000","message":"so the callback is actually a no-op if ``self.emit_buffer_xfer_bytes_sec \u003c 0``\n\ncan we short-circuit and not install a callback in that case?","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":485,"context_line":"                    acc\u003dacc, cont\u003dcont, policy_index\u003dpolicy_index,"},{"line_number":486,"context_line":"                    subreq_paths\u003dsubreq_paths)"},{"line_number":487,"context_line":""},{"line_number":488,"context_line":"            if self.emit_buffer_xfer_bytes_sec \u003e\u003d 0:"},{"line_number":489,"context_line":"                CallbackParameters.emit_bytes +\u003d buffer_len"},{"line_number":490,"context_line":"                now \u003d time.time()"},{"line_number":491,"context_line":"                if self.emit_buffer_xfer_bytes_sec \u003d\u003d 0 or \\"}],"source_content_type":"text/x-python","patch_set":6,"id":"4abde193_3b91b9fa","line":488,"in_reply_to":"f6d36b91_e8ba0760","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"34996bc75ca6f593d928381298d4af325195443c","unresolved":true,"context_lines":[{"line_number":512,"context_line":"        req \u003d Request(env)"},{"line_number":513,"context_line":"        method \u003d method_from_req(req)"},{"line_number":514,"context_line":""},{"line_number":515,"context_line":"        subreq_paths \u003d req.environ.get(\u0027swift.subrequest_paths\u0027, None)"},{"line_number":516,"context_line":"        if subreq_paths is None:"},{"line_number":517,"context_line":"            req.environ[\u0027swift.subrequest_paths\u0027] \u003d [None]"},{"line_number":518,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":6,"id":"00505400_91f8534a","line":515,"range":{"start_line":515,"start_character":63,"end_line":515,"end_character":69},"updated":"2024-11-14 14:41:23.000000000","message":"there\u0027s no need for the ``None``, ``dict.get()`` will return ``None`` by default","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":512,"context_line":"        req \u003d Request(env)"},{"line_number":513,"context_line":"        method \u003d method_from_req(req)"},{"line_number":514,"context_line":""},{"line_number":515,"context_line":"        subreq_paths \u003d req.environ.get(\u0027swift.subrequest_paths\u0027, None)"},{"line_number":516,"context_line":"        if subreq_paths is None:"},{"line_number":517,"context_line":"            req.environ[\u0027swift.subrequest_paths\u0027] \u003d [None]"},{"line_number":518,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":6,"id":"49bd894a_3f85eb6f","line":515,"range":{"start_line":515,"start_character":63,"end_line":515,"end_character":69},"in_reply_to":"00505400_91f8534a","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"34996bc75ca6f593d928381298d4af325195443c","unresolved":true,"context_lines":[{"line_number":513,"context_line":"        method \u003d method_from_req(req)"},{"line_number":514,"context_line":""},{"line_number":515,"context_line":"        subreq_paths \u003d req.environ.get(\u0027swift.subrequest_paths\u0027, None)"},{"line_number":516,"context_line":"        if subreq_paths is None:"},{"line_number":517,"context_line":"            req.environ[\u0027swift.subrequest_paths\u0027] \u003d [None]"},{"line_number":518,"context_line":"        else:"},{"line_number":519,"context_line":"            req_path \u003d req.environ.get(\u0027PATH_INFO\u0027, None)"}],"source_content_type":"text/x-python","patch_set":6,"id":"2a7329aa_42e20bc6","line":516,"updated":"2024-11-14 14:41:23.000000000","message":"this means it is the left most proxy_logging instance?","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":513,"context_line":"        method \u003d method_from_req(req)"},{"line_number":514,"context_line":""},{"line_number":515,"context_line":"        subreq_paths \u003d req.environ.get(\u0027swift.subrequest_paths\u0027, None)"},{"line_number":516,"context_line":"        if subreq_paths is None:"},{"line_number":517,"context_line":"            req.environ[\u0027swift.subrequest_paths\u0027] \u003d [None]"},{"line_number":518,"context_line":"        else:"},{"line_number":519,"context_line":"            req_path \u003d req.environ.get(\u0027PATH_INFO\u0027, None)"}],"source_content_type":"text/x-python","patch_set":6,"id":"0ad4d5a4_07bf9e8c","line":516,"in_reply_to":"2a7329aa_42e20bc6","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"34996bc75ca6f593d928381298d4af325195443c","unresolved":true,"context_lines":[{"line_number":516,"context_line":"        if subreq_paths is None:"},{"line_number":517,"context_line":"            req.environ[\u0027swift.subrequest_paths\u0027] \u003d [None]"},{"line_number":518,"context_line":"        else:"},{"line_number":519,"context_line":"            req_path \u003d req.environ.get(\u0027PATH_INFO\u0027, None)"},{"line_number":520,"context_line":"            if req_path is not None:"},{"line_number":521,"context_line":"                subreq_paths[0] \u003d req_path"},{"line_number":522,"context_line":"            req_source \u003d req.environ.get(\u0027swift.source\u0027, None)"}],"source_content_type":"text/x-python","patch_set":6,"id":"a41d03df_15ac4602","line":519,"range":{"start_line":519,"start_character":23,"end_line":519,"end_character":57},"updated":"2024-11-14 14:41:23.000000000","message":"this is available as ``req.path_info``","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":516,"context_line":"        if subreq_paths is None:"},{"line_number":517,"context_line":"            req.environ[\u0027swift.subrequest_paths\u0027] \u003d [None]"},{"line_number":518,"context_line":"        else:"},{"line_number":519,"context_line":"            req_path \u003d req.environ.get(\u0027PATH_INFO\u0027, None)"},{"line_number":520,"context_line":"            if req_path is not None:"},{"line_number":521,"context_line":"                subreq_paths[0] \u003d req_path"},{"line_number":522,"context_line":"            req_source \u003d req.environ.get(\u0027swift.source\u0027, None)"}],"source_content_type":"text/x-python","patch_set":6,"id":"72429342_fc4bf9bf","line":519,"range":{"start_line":519,"start_character":23,"end_line":519,"end_character":57},"in_reply_to":"a41d03df_15ac4602","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"34996bc75ca6f593d928381298d4af325195443c","unresolved":true,"context_lines":[{"line_number":518,"context_line":"        else:"},{"line_number":519,"context_line":"            req_path \u003d req.environ.get(\u0027PATH_INFO\u0027, None)"},{"line_number":520,"context_line":"            if req_path is not None:"},{"line_number":521,"context_line":"                subreq_paths[0] \u003d req_path"},{"line_number":522,"context_line":"            req_source \u003d req.environ.get(\u0027swift.source\u0027, None)"},{"line_number":523,"context_line":"            if req_source is not None:"},{"line_number":524,"context_line":"                subreq_paths.append(req_source)"}],"source_content_type":"text/x-python","patch_set":6,"id":"7673da87_a0569792","line":521,"range":{"start_line":521,"start_character":16,"end_line":521,"end_character":31},"updated":"2024-11-14 14:41:23.000000000","message":"the handling of None\u0027s means that in theory index 0 may not be populated by a path...but might then be populated by a source?","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":518,"context_line":"        else:"},{"line_number":519,"context_line":"            req_path \u003d req.environ.get(\u0027PATH_INFO\u0027, None)"},{"line_number":520,"context_line":"            if req_path is not None:"},{"line_number":521,"context_line":"                subreq_paths[0] \u003d req_path"},{"line_number":522,"context_line":"            req_source \u003d req.environ.get(\u0027swift.source\u0027, None)"},{"line_number":523,"context_line":"            if req_source is not None:"},{"line_number":524,"context_line":"                subreq_paths.append(req_source)"}],"source_content_type":"text/x-python","patch_set":6,"id":"f707fbb6_124fe385","line":521,"range":{"start_line":521,"start_character":16,"end_line":521,"end_character":31},"in_reply_to":"7673da87_a0569792","updated":"2024-11-22 20:30:38.000000000","message":"updated per our discussion","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"34996bc75ca6f593d928381298d4af325195443c","unresolved":true,"context_lines":[{"line_number":521,"context_line":"                subreq_paths[0] \u003d req_path"},{"line_number":522,"context_line":"            req_source \u003d req.environ.get(\u0027swift.source\u0027, None)"},{"line_number":523,"context_line":"            if req_source is not None:"},{"line_number":524,"context_line":"                subreq_paths.append(req_source)"},{"line_number":525,"context_line":""},{"line_number":526,"context_line":"        swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"},{"line_number":527,"context_line":"        acc, cont, _ \u003d get_aco_from_path(swift_path)"}],"source_content_type":"text/x-python","patch_set":6,"id":"2165ac24_20591baf","line":524,"updated":"2024-11-14 14:41:23.000000000","message":"IIUC ``subreq_paths`` is a list whose first element *may* be the most recent request or subrequest path, and following elements are source strings? We then use that list to set swift.backend_path to the first element and search the list for an occurrence of \u0027S3\u0027.\n\nI\u0027d like to suggest using a more explicit items in the \u0027swift.\u0027 namespace of the req.environ, for example:\n\n```\n  \u0027swift.subreq_path\u0027: None,\n  \u0027swift.subreq_sources\u0027: []\n```\n\nor even simpler:\n\n```\n  \u0027swift.subreq_path\u0027: None,\n  \u0027swift.s3_request\u0027: False\n```\n\nAlso, w.r.t. naming, IIUC the path value is not necessarily taken from a *sub-request*: not all client requests result in sub-requests, and even those that do may also reach the rightmost proxy_logging, so the path isn\u0027t necessarily a *subrequest* path. However, I think source is only set for a genuine subrequest.","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e6df311bac282d96055b00037a8324cedb49d04a","unresolved":true,"context_lines":[{"line_number":521,"context_line":"                subreq_paths[0] \u003d req_path"},{"line_number":522,"context_line":"            req_source \u003d req.environ.get(\u0027swift.source\u0027, None)"},{"line_number":523,"context_line":"            if req_source is not None:"},{"line_number":524,"context_line":"                subreq_paths.append(req_source)"},{"line_number":525,"context_line":""},{"line_number":526,"context_line":"        swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"},{"line_number":527,"context_line":"        acc, cont, _ \u003d get_aco_from_path(swift_path)"}],"source_content_type":"text/x-python","patch_set":6,"id":"50fc3402_55210d3e","line":524,"in_reply_to":"2165ac24_20591baf","updated":"2024-11-19 18:58:22.000000000","message":"in retrospect, we think this will need to be a mutable.\n\npart of the question has to do with the \"is_s3_req\" interfaces that\u0027s ALSO in this patch (?!)\n\nthe subrequest_path that the left most proxy-logging sets up to be copied through s3api\u0027s swift requests (and sub-requests) *does* need to be \"copy-by-reference\" so that the \"get_statds_metric_labels\" callback can *find* the correct account label from the path of the swift-request.","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":521,"context_line":"                subreq_paths[0] \u003d req_path"},{"line_number":522,"context_line":"            req_source \u003d req.environ.get(\u0027swift.source\u0027, None)"},{"line_number":523,"context_line":"            if req_source is not None:"},{"line_number":524,"context_line":"                subreq_paths.append(req_source)"},{"line_number":525,"context_line":""},{"line_number":526,"context_line":"        swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"},{"line_number":527,"context_line":"        acc, cont, _ \u003d get_aco_from_path(swift_path)"}],"source_content_type":"text/x-python","patch_set":6,"id":"6ed8b837_300e5489","line":524,"in_reply_to":"50fc3402_55210d3e","updated":"2024-11-22 20:30:38.000000000","message":"updated subrequest_path per our discussion","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"34996bc75ca6f593d928381298d4af325195443c","unresolved":true,"context_lines":[{"line_number":532,"context_line":"            acc\u003dacc, cont\u003dcont, policy_index\u003dNone,"},{"line_number":533,"context_line":"            subreq_paths\u003dsubreq_paths)"},{"line_number":534,"context_line":""},{"line_number":535,"context_line":"        if xfer_labels is not None:"},{"line_number":536,"context_line":"            statsd_emit_callback \u003d self.get_buffer_xfer_emit_callback("},{"line_number":537,"context_line":"                req, self.valid_methods, xfer_metric_name, xfer_labels)"},{"line_number":538,"context_line":"            input_proxy \u003d InputProxy("}],"source_content_type":"text/x-python","patch_set":6,"id":"21f723b1_2864f6d1","line":535,"updated":"2024-11-14 14:41:23.000000000","message":"``statsd_metric_labels`` always returns a dict?","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":532,"context_line":"            acc\u003dacc, cont\u003dcont, policy_index\u003dNone,"},{"line_number":533,"context_line":"            subreq_paths\u003dsubreq_paths)"},{"line_number":534,"context_line":""},{"line_number":535,"context_line":"        if xfer_labels is not None:"},{"line_number":536,"context_line":"            statsd_emit_callback \u003d self.get_buffer_xfer_emit_callback("},{"line_number":537,"context_line":"                req, self.valid_methods, xfer_metric_name, xfer_labels)"},{"line_number":538,"context_line":"            input_proxy \u003d InputProxy("}],"source_content_type":"text/x-python","patch_set":6,"id":"93eea72e_60ef08cc","line":535,"in_reply_to":"21f723b1_2864f6d1","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"34996bc75ca6f593d928381298d4af325195443c","unresolved":true,"context_lines":[{"line_number":539,"context_line":"                env[\u0027wsgi.input\u0027],"},{"line_number":540,"context_line":"                statsd_emit_callback)"},{"line_number":541,"context_line":"        else:"},{"line_number":542,"context_line":"            input_proxy \u003d InputProxy(env[\u0027wsgi.input\u0027])"},{"line_number":543,"context_line":"        env[\u0027wsgi.input\u0027] \u003d input_proxy"},{"line_number":544,"context_line":"        start_time \u003d time.time()"},{"line_number":545,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"ad4972b4_5c135c87","line":542,"updated":"2024-11-14 14:41:23.000000000","message":"it\u0027s a shame we can\u0027t have ``self.get_buffer_xfer_emit_callback`` return None is the callback isn\u0027t needed and then write::\n\n```\ninput_proxy \u003d InputProxy(env[\u0027wsgi.input\u0027], self.get_buffer_xfer_emit_callback(...))\n```\n\n(see related comment in utils)","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":539,"context_line":"                env[\u0027wsgi.input\u0027],"},{"line_number":540,"context_line":"                statsd_emit_callback)"},{"line_number":541,"context_line":"        else:"},{"line_number":542,"context_line":"            input_proxy \u003d InputProxy(env[\u0027wsgi.input\u0027])"},{"line_number":543,"context_line":"        env[\u0027wsgi.input\u0027] \u003d input_proxy"},{"line_number":544,"context_line":"        start_time \u003d time.time()"},{"line_number":545,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"6eba28c3_53fd01d1","line":542,"in_reply_to":"ad4972b4_5c135c87","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3c9db4b292eacdc99e65c8934ed5e7d5148bdd8b","unresolved":true,"context_lines":[{"line_number":135,"context_line":"                         acc\u003dNone, cont\u003dNone, policy_index\u003dNone):"},{"line_number":136,"context_line":"    server_type \u003d get_metric_name_type(req)"},{"line_number":137,"context_line":"    if server_type is None:"},{"line_number":138,"context_line":"        return None"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":"    labels \u003d {"},{"line_number":141,"context_line":"        \u0027type\u0027: server_type,"}],"source_content_type":"text/x-python","patch_set":9,"id":"ff773e69_7a4da261","line":138,"updated":"2024-11-29 16:33:28.000000000","message":"this line cannot be reached, server_type will never be None\n\nSee https://review.opendev.org/c/openstack/swift/+/928080/3/swift/common/middleware/proxy_logging.py\n\nI realise this is just moved code but I think it is worth fixing, because it testing-for-None is propagating through the code unnecessarily: ``statsd_metric_labels`` also cannot return None.\n\nUpdate: I realised that this is moving code from the parent patch https://review.opendev.org/c/openstack/swift/+/917711 that has not yet merged, so it would be helpful to update the parent patch to avoid this issue attracting repeated comments. Thanks!","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"ec749a90b62e4614dfbbd965ec77307a011e0994","unresolved":false,"context_lines":[{"line_number":135,"context_line":"                         acc\u003dNone, cont\u003dNone, policy_index\u003dNone):"},{"line_number":136,"context_line":"    server_type \u003d get_metric_name_type(req)"},{"line_number":137,"context_line":"    if server_type is None:"},{"line_number":138,"context_line":"        return None"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":"    labels \u003d {"},{"line_number":141,"context_line":"        \u0027type\u0027: server_type,"}],"source_content_type":"text/x-python","patch_set":9,"id":"080d5bed_8ce608b2","line":138,"in_reply_to":"ff773e69_7a4da261","updated":"2024-12-10 16:29:15.000000000","message":"Acknowledged","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3c9db4b292eacdc99e65c8934ed5e7d5148bdd8b","unresolved":true,"context_lines":[{"line_number":139,"context_line":""},{"line_number":140,"context_line":"    labels \u003d {"},{"line_number":141,"context_line":"        \u0027type\u0027: server_type,"},{"line_number":142,"context_line":"        \u0027method\u0027: (method if method in valid_methods"},{"line_number":143,"context_line":"                   else \u0027BAD_METHOD\u0027),"},{"line_number":144,"context_line":"    }"},{"line_number":145,"context_line":"    if status_int:"},{"line_number":146,"context_line":"        labels[\u0027status\u0027] \u003d status_int"}],"source_content_type":"text/x-python","patch_set":9,"id":"72a20370_1dcf3036","line":143,"range":{"start_line":142,"start_character":19,"end_line":143,"end_character":36},"updated":"2024-11-29 16:33:28.000000000","message":"There are 3 places where this is evaluated. It could be done once and ``stat_method`` passed as an arg rather than passing both ``valid_methods`` and ``method`` as args in several places.","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"ec749a90b62e4614dfbbd965ec77307a011e0994","unresolved":false,"context_lines":[{"line_number":139,"context_line":""},{"line_number":140,"context_line":"    labels \u003d {"},{"line_number":141,"context_line":"        \u0027type\u0027: server_type,"},{"line_number":142,"context_line":"        \u0027method\u0027: (method if method in valid_methods"},{"line_number":143,"context_line":"                   else \u0027BAD_METHOD\u0027),"},{"line_number":144,"context_line":"    }"},{"line_number":145,"context_line":"    if status_int:"},{"line_number":146,"context_line":"        labels[\u0027status\u0027] \u003d status_int"}],"source_content_type":"text/x-python","patch_set":9,"id":"e6d1a122_6873a323","line":143,"range":{"start_line":142,"start_character":19,"end_line":143,"end_character":36},"in_reply_to":"72a20370_1dcf3036","updated":"2024-12-10 16:29:15.000000000","message":"Acknowledged","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3c9db4b292eacdc99e65c8934ed5e7d5148bdd8b","unresolved":true,"context_lines":[{"line_number":168,"context_line":"        self.next_emit_time \u003d 0"},{"line_number":169,"context_line":""},{"line_number":170,"context_line":"    def __call__(self, buffer_len):"},{"line_number":171,"context_line":"        if self.labels.get(\u0027account\u0027, None) is None:"},{"line_number":172,"context_line":"            method \u003d method_from_req(self.req)"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"            swift_request_paths \u003d self.req.environ.get("}],"source_content_type":"text/x-python","patch_set":9,"id":"d55f5371_bac87d97","line":171,"range":{"start_line":171,"start_character":11,"end_line":171,"end_character":51},"updated":"2024-11-29 16:33:28.000000000","message":"do we ever want to emit labelled metrics when the account is unknown? If not, it might be clearer to have labels be None until the account *is* known","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"ec749a90b62e4614dfbbd965ec77307a011e0994","unresolved":false,"context_lines":[{"line_number":168,"context_line":"        self.next_emit_time \u003d 0"},{"line_number":169,"context_line":""},{"line_number":170,"context_line":"    def __call__(self, buffer_len):"},{"line_number":171,"context_line":"        if self.labels.get(\u0027account\u0027, None) is None:"},{"line_number":172,"context_line":"            method \u003d method_from_req(self.req)"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"            swift_request_paths \u003d self.req.environ.get("}],"source_content_type":"text/x-python","patch_set":9,"id":"b98057d6_9bd01c8d","line":171,"range":{"start_line":171,"start_character":11,"end_line":171,"end_character":51},"in_reply_to":"d55f5371_bac87d97","updated":"2024-12-10 16:29:15.000000000","message":"updated per other comment to only update the existing labels","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3c9db4b292eacdc99e65c8934ed5e7d5148bdd8b","unresolved":true,"context_lines":[{"line_number":173,"context_line":""},{"line_number":174,"context_line":"            swift_request_paths \u003d self.req.environ.get("},{"line_number":175,"context_line":"                \u0027swift.swift_request_paths\u0027)"},{"line_number":176,"context_line":"            if swift_request_paths[0]:"},{"line_number":177,"context_line":"                self.req.environ[\u0027swift.backend_path\u0027] \u003d swift_request_paths[0]"},{"line_number":178,"context_line":"            swift_path \u003d self.req.environ.get(\u0027swift.backend_path\u0027,"},{"line_number":179,"context_line":"                                              self.req.path)"}],"source_content_type":"text/x-python","patch_set":9,"id":"41c04bc6_b1630cce","line":176,"range":{"start_line":176,"start_character":12,"end_line":176,"end_character":37},"updated":"2024-11-29 16:33:28.000000000","message":"using ``req.environ.get`` allows for the key to NOT be in the environ, but then line 176 assumes that it always is. It would be safer to write:\n\n```\nif swift_request_paths:\n```","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"ec749a90b62e4614dfbbd965ec77307a011e0994","unresolved":false,"context_lines":[{"line_number":173,"context_line":""},{"line_number":174,"context_line":"            swift_request_paths \u003d self.req.environ.get("},{"line_number":175,"context_line":"                \u0027swift.swift_request_paths\u0027)"},{"line_number":176,"context_line":"            if swift_request_paths[0]:"},{"line_number":177,"context_line":"                self.req.environ[\u0027swift.backend_path\u0027] \u003d swift_request_paths[0]"},{"line_number":178,"context_line":"            swift_path \u003d self.req.environ.get(\u0027swift.backend_path\u0027,"},{"line_number":179,"context_line":"                                              self.req.path)"}],"source_content_type":"text/x-python","patch_set":9,"id":"de590e80_5c95f6c9","line":176,"range":{"start_line":176,"start_character":12,"end_line":176,"end_character":37},"in_reply_to":"41c04bc6_b1630cce","updated":"2024-12-10 16:29:15.000000000","message":"Acknowledged","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3c9db4b292eacdc99e65c8934ed5e7d5148bdd8b","unresolved":true,"context_lines":[{"line_number":174,"context_line":"            swift_request_paths \u003d self.req.environ.get("},{"line_number":175,"context_line":"                \u0027swift.swift_request_paths\u0027)"},{"line_number":176,"context_line":"            if swift_request_paths[0]:"},{"line_number":177,"context_line":"                self.req.environ[\u0027swift.backend_path\u0027] \u003d swift_request_paths[0]"},{"line_number":178,"context_line":"            swift_path \u003d self.req.environ.get(\u0027swift.backend_path\u0027,"},{"line_number":179,"context_line":"                                              self.req.path)"},{"line_number":180,"context_line":"            acc, cont, _ \u003d get_aco_from_path(swift_path)"}],"source_content_type":"text/x-python","patch_set":9,"id":"54bc1d7a_ea7ac5da","line":177,"range":{"start_line":177,"start_character":16,"end_line":177,"end_character":79},"updated":"2024-11-29 16:33:28.000000000","message":"I\u0027m really not sure this is correct - IIUC the rightmost proxy_logging has now become the authority for swift.backend_path whereas currently s3api middleware decides what swift.backend_path should be.\n\nFor example, during a multipart upload, s3api deliberately sets swift.backend_path to be something other than the possible last backend request [1] whereas IIUC with this change it will always be the last subrequest.\n\n[1] https://github.com/openstack/swift/blob/46e7da97c6e620ba2998872901ed44055714e699/swift/common/middleware/s3api/controllers/multi_upload.py#L124","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"ec749a90b62e4614dfbbd965ec77307a011e0994","unresolved":false,"context_lines":[{"line_number":174,"context_line":"            swift_request_paths \u003d self.req.environ.get("},{"line_number":175,"context_line":"                \u0027swift.swift_request_paths\u0027)"},{"line_number":176,"context_line":"            if swift_request_paths[0]:"},{"line_number":177,"context_line":"                self.req.environ[\u0027swift.backend_path\u0027] \u003d swift_request_paths[0]"},{"line_number":178,"context_line":"            swift_path \u003d self.req.environ.get(\u0027swift.backend_path\u0027,"},{"line_number":179,"context_line":"                                              self.req.path)"},{"line_number":180,"context_line":"            acc, cont, _ \u003d get_aco_from_path(swift_path)"}],"source_content_type":"text/x-python","patch_set":9,"id":"a0ca5f7e_d1062624","line":177,"range":{"start_line":177,"start_character":16,"end_line":177,"end_character":79},"in_reply_to":"54bc1d7a_ea7ac5da","updated":"2024-12-10 16:29:15.000000000","message":"Good point, Al. Updated to not change swift.backend_path","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3c9db4b292eacdc99e65c8934ed5e7d5148bdd8b","unresolved":true,"context_lines":[{"line_number":177,"context_line":"                self.req.environ[\u0027swift.backend_path\u0027] \u003d swift_request_paths[0]"},{"line_number":178,"context_line":"            swift_path \u003d self.req.environ.get(\u0027swift.backend_path\u0027,"},{"line_number":179,"context_line":"                                              self.req.path)"},{"line_number":180,"context_line":"            acc, cont, _ \u003d get_aco_from_path(swift_path)"},{"line_number":181,"context_line":""},{"line_number":182,"context_line":"            status_int \u003d self.labels.get(\u0027status\u0027, None)"},{"line_number":183,"context_line":"            policy_index \u003d self.labels.get(\u0027policy\u0027, None)"}],"source_content_type":"text/x-python","patch_set":9,"id":"b6430cf1_4a4d73ad","line":180,"updated":"2024-11-29 16:33:28.000000000","message":"I think it is still possible for account to be None here, if for example the s3api returns a response early without any swift_request propagating to the right-most proxy-logging, which I believe can happen if the request fails the up-front s3api auth parsing (e.g. credentials have expired)","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"ec749a90b62e4614dfbbd965ec77307a011e0994","unresolved":false,"context_lines":[{"line_number":177,"context_line":"                self.req.environ[\u0027swift.backend_path\u0027] \u003d swift_request_paths[0]"},{"line_number":178,"context_line":"            swift_path \u003d self.req.environ.get(\u0027swift.backend_path\u0027,"},{"line_number":179,"context_line":"                                              self.req.path)"},{"line_number":180,"context_line":"            acc, cont, _ \u003d get_aco_from_path(swift_path)"},{"line_number":181,"context_line":""},{"line_number":182,"context_line":"            status_int \u003d self.labels.get(\u0027status\u0027, None)"},{"line_number":183,"context_line":"            policy_index \u003d self.labels.get(\u0027policy\u0027, None)"}],"source_content_type":"text/x-python","patch_set":9,"id":"bf123283_7a842553","line":180,"in_reply_to":"b6430cf1_4a4d73ad","updated":"2024-12-10 16:29:15.000000000","message":"Acknowledged","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3c9db4b292eacdc99e65c8934ed5e7d5148bdd8b","unresolved":true,"context_lines":[{"line_number":181,"context_line":""},{"line_number":182,"context_line":"            status_int \u003d self.labels.get(\u0027status\u0027, None)"},{"line_number":183,"context_line":"            policy_index \u003d self.labels.get(\u0027policy\u0027, None)"},{"line_number":184,"context_line":"            self.labels \u003d statsd_metric_labels("},{"line_number":185,"context_line":"                self.req, self.valid_methods, method, status_int\u003dstatus_int,"},{"line_number":186,"context_line":"                acc\u003dacc, cont\u003dcont, policy_index\u003dpolicy_index)"},{"line_number":187,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"357c9b32_2473a4fb","line":184,"range":{"start_line":184,"start_character":26,"end_line":184,"end_character":46},"updated":"2024-11-29 16:33:28.000000000","message":"I\u0027m curious that is constructing a new labels dict rather than updating the existing one. My understanding is that, with an s3api request, the account might be the *only* missing field when the request is first handled by the left-most proxy-logging, so I understand that we *need* to extract account from the backend path here. But I was expecting to see \n\n``self.labels[\u0027account\u0027] \u003d \u0027acc\u0027``\n\nIt looks like container might also change...but do we really want to also update the *container* label based on the backend path??\n\nIf the subrequest is reading or writing to a hidden versions container, do we really want the labels container to be the hidden container vs the user namespace container?","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"ec749a90b62e4614dfbbd965ec77307a011e0994","unresolved":false,"context_lines":[{"line_number":181,"context_line":""},{"line_number":182,"context_line":"            status_int \u003d self.labels.get(\u0027status\u0027, None)"},{"line_number":183,"context_line":"            policy_index \u003d self.labels.get(\u0027policy\u0027, None)"},{"line_number":184,"context_line":"            self.labels \u003d statsd_metric_labels("},{"line_number":185,"context_line":"                self.req, self.valid_methods, method, status_int\u003dstatus_int,"},{"line_number":186,"context_line":"                acc\u003dacc, cont\u003dcont, policy_index\u003dpolicy_index)"},{"line_number":187,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"bdfd3ff0_d5b7ebd9","line":184,"range":{"start_line":184,"start_character":26,"end_line":184,"end_character":46},"in_reply_to":"357c9b32_2473a4fb","updated":"2024-12-10 16:29:15.000000000","message":"Ack. seems that we only need to update acc, cont, type","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3c9db4b292eacdc99e65c8934ed5e7d5148bdd8b","unresolved":true,"context_lines":[{"line_number":187,"context_line":""},{"line_number":188,"context_line":"        self.emit_bytes +\u003d buffer_len"},{"line_number":189,"context_line":"        now \u003d time.time()"},{"line_number":190,"context_line":"        if self.emit_buffer_xfer_bytes_sec \u003d\u003d 0 or \\"},{"line_number":191,"context_line":"                self.next_emit_time \u003c\u003d now:"},{"line_number":192,"context_line":"            self.statsd.update_stats("},{"line_number":193,"context_line":"                self.metric_name,"}],"source_content_type":"text/x-python","patch_set":9,"id":"2f9b4b3e_4ad6e811","line":190,"updated":"2024-11-29 16:33:28.000000000","message":"see comment line 180 - should this also be conditional on a re-check that labels now has a non-None account field?","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"ec749a90b62e4614dfbbd965ec77307a011e0994","unresolved":false,"context_lines":[{"line_number":187,"context_line":""},{"line_number":188,"context_line":"        self.emit_bytes +\u003d buffer_len"},{"line_number":189,"context_line":"        now \u003d time.time()"},{"line_number":190,"context_line":"        if self.emit_buffer_xfer_bytes_sec \u003d\u003d 0 or \\"},{"line_number":191,"context_line":"                self.next_emit_time \u003c\u003d now:"},{"line_number":192,"context_line":"            self.statsd.update_stats("},{"line_number":193,"context_line":"                self.metric_name,"}],"source_content_type":"text/x-python","patch_set":9,"id":"964fb10a_a089b391","line":190,"in_reply_to":"2f9b4b3e_4ad6e811","updated":"2024-12-10 16:29:15.000000000","message":"Acknowledged","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3c9db4b292eacdc99e65c8934ed5e7d5148bdd8b","unresolved":true,"context_lines":[{"line_number":468,"context_line":"                labels\u003dlabels,"},{"line_number":469,"context_line":"            )"},{"line_number":470,"context_line":""},{"line_number":471,"context_line":"    def statsd_metric_name(self, req, status_int, method):"},{"line_number":472,"context_line":"        stat_type \u003d get_metric_name_type(req)"},{"line_number":473,"context_line":"        stat_method \u003d method if method in self.valid_methods \\"},{"line_number":474,"context_line":"            else \u0027BAD_METHOD\u0027"}],"source_content_type":"text/x-python","patch_set":9,"id":"f3ae2c69_29fa72d4","line":471,"range":{"start_line":471,"start_character":50,"end_line":471,"end_character":56},"updated":"2024-11-29 16:33:28.000000000","message":"this could accept stat_method as an arg and then be a function","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"ec749a90b62e4614dfbbd965ec77307a011e0994","unresolved":false,"context_lines":[{"line_number":468,"context_line":"                labels\u003dlabels,"},{"line_number":469,"context_line":"            )"},{"line_number":470,"context_line":""},{"line_number":471,"context_line":"    def statsd_metric_name(self, req, status_int, method):"},{"line_number":472,"context_line":"        stat_type \u003d get_metric_name_type(req)"},{"line_number":473,"context_line":"        stat_method \u003d method if method in self.valid_methods \\"},{"line_number":474,"context_line":"            else \u0027BAD_METHOD\u0027"}],"source_content_type":"text/x-python","patch_set":9,"id":"f562ccf4_878dcc29","line":471,"range":{"start_line":471,"start_character":50,"end_line":471,"end_character":56},"in_reply_to":"f3ae2c69_29fa72d4","updated":"2024-12-10 16:29:15.000000000","message":"Acknowledged","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3c9db4b292eacdc99e65c8934ed5e7d5148bdd8b","unresolved":true,"context_lines":[{"line_number":474,"context_line":"            else \u0027BAD_METHOD\u0027"},{"line_number":475,"context_line":"        return \u0027.\u0027.join((stat_type, stat_method, str(status_int)))"},{"line_number":476,"context_line":""},{"line_number":477,"context_line":"    def statsd_metric_name_policy(self, req, status_int, method, policy_index):"},{"line_number":478,"context_line":"        if policy_index is None:"},{"line_number":479,"context_line":"            return None"},{"line_number":480,"context_line":"        stat_type \u003d get_metric_name_type(req)"}],"source_content_type":"text/x-python","patch_set":9,"id":"425ac18f_ec894bc0","line":477,"range":{"start_line":477,"start_character":57,"end_line":477,"end_character":63},"updated":"2024-11-29 16:33:28.000000000","message":"pass in stat_method and then this can be a function too 😊","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"ec749a90b62e4614dfbbd965ec77307a011e0994","unresolved":false,"context_lines":[{"line_number":474,"context_line":"            else \u0027BAD_METHOD\u0027"},{"line_number":475,"context_line":"        return \u0027.\u0027.join((stat_type, stat_method, str(status_int)))"},{"line_number":476,"context_line":""},{"line_number":477,"context_line":"    def statsd_metric_name_policy(self, req, status_int, method, policy_index):"},{"line_number":478,"context_line":"        if policy_index is None:"},{"line_number":479,"context_line":"            return None"},{"line_number":480,"context_line":"        stat_type \u003d get_metric_name_type(req)"}],"source_content_type":"text/x-python","patch_set":9,"id":"86769d17_f4cf760c","line":477,"range":{"start_line":477,"start_character":57,"end_line":477,"end_character":63},"in_reply_to":"425ac18f_ec894bc0","updated":"2024-12-10 16:29:15.000000000","message":"Acknowledged","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3c9db4b292eacdc99e65c8934ed5e7d5148bdd8b","unresolved":true,"context_lines":[{"line_number":493,"context_line":""},{"line_number":494,"context_line":"    def get_buffer_xfer_emit_callback(self, req, metric_name, labels):"},{"line_number":495,"context_line":"        if self.emit_buffer_xfer_bytes_sec \u003c 0:"},{"line_number":496,"context_line":"            return None"},{"line_number":497,"context_line":"        return BufferXferEmitCallback(req, metric_name, labels,"},{"line_number":498,"context_line":"                                      self.valid_methods, self.statsd,"},{"line_number":499,"context_line":"                                      self.emit_buffer_xfer_bytes_sec)"}],"source_content_type":"text/x-python","patch_set":9,"id":"c77e586b_0e7409e3","line":496,"updated":"2024-11-29 16:33:28.000000000","message":"ok, so I think I may have suggested this pattern of \u0027don\u0027t even have a callback if it won\u0027t emit anything\u0027, but now I can see that emit_buffer_xfer_bytes_sec is going to be passed into the callback *anyway*...\n\n...and then at line 604 you\u0027ve had to write \n```\nif statsd_emit_callback is not None\n```\n\nwhich could be avoided if the callback just no-op\u0027d when ``emit_buffer_xfer_bytes_sec \u003c 0``\n\nI still think it is good that InputProxy doesn\u0027t require a callback function","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"ec749a90b62e4614dfbbd965ec77307a011e0994","unresolved":false,"context_lines":[{"line_number":493,"context_line":""},{"line_number":494,"context_line":"    def get_buffer_xfer_emit_callback(self, req, metric_name, labels):"},{"line_number":495,"context_line":"        if self.emit_buffer_xfer_bytes_sec \u003c 0:"},{"line_number":496,"context_line":"            return None"},{"line_number":497,"context_line":"        return BufferXferEmitCallback(req, metric_name, labels,"},{"line_number":498,"context_line":"                                      self.valid_methods, self.statsd,"},{"line_number":499,"context_line":"                                      self.emit_buffer_xfer_bytes_sec)"}],"source_content_type":"text/x-python","patch_set":9,"id":"4a86eaaf_5a381a6d","line":496,"in_reply_to":"c77e586b_0e7409e3","updated":"2024-12-10 16:29:15.000000000","message":"Acknowledged","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3c9db4b292eacdc99e65c8934ed5e7d5148bdd8b","unresolved":true,"context_lines":[{"line_number":495,"context_line":"        if self.emit_buffer_xfer_bytes_sec \u003c 0:"},{"line_number":496,"context_line":"            return None"},{"line_number":497,"context_line":"        return BufferXferEmitCallback(req, metric_name, labels,"},{"line_number":498,"context_line":"                                      self.valid_methods, self.statsd,"},{"line_number":499,"context_line":"                                      self.emit_buffer_xfer_bytes_sec)"},{"line_number":500,"context_line":""},{"line_number":501,"context_line":"    def __call__(self, env, start_response):"}],"source_content_type":"text/x-python","patch_set":9,"id":"febd2d60_0ad0d999","line":498,"range":{"start_line":498,"start_character":38,"end_line":498,"end_character":56},"updated":"2024-11-29 16:33:28.000000000","message":"``stat_method``","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"ec749a90b62e4614dfbbd965ec77307a011e0994","unresolved":false,"context_lines":[{"line_number":495,"context_line":"        if self.emit_buffer_xfer_bytes_sec \u003c 0:"},{"line_number":496,"context_line":"            return None"},{"line_number":497,"context_line":"        return BufferXferEmitCallback(req, metric_name, labels,"},{"line_number":498,"context_line":"                                      self.valid_methods, self.statsd,"},{"line_number":499,"context_line":"                                      self.emit_buffer_xfer_bytes_sec)"},{"line_number":500,"context_line":""},{"line_number":501,"context_line":"    def __call__(self, env, start_response):"}],"source_content_type":"text/x-python","patch_set":9,"id":"2682f267_340cf18f","line":498,"range":{"start_line":498,"start_character":38,"end_line":498,"end_character":56},"in_reply_to":"febd2d60_0ad0d999","updated":"2024-12-10 16:29:15.000000000","message":"Acknowledged","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3c9db4b292eacdc99e65c8934ed5e7d5148bdd8b","unresolved":true,"context_lines":[{"line_number":515,"context_line":"        start_response_args \u003d [None]"},{"line_number":516,"context_line":""},{"line_number":517,"context_line":"        req \u003d Request(env)"},{"line_number":518,"context_line":"        method \u003d method_from_req(req)"},{"line_number":519,"context_line":""},{"line_number":520,"context_line":"        swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"},{"line_number":521,"context_line":"        acc, cont, _ \u003d get_aco_from_path(swift_path)"}],"source_content_type":"text/x-python","patch_set":9,"id":"88144c24_1313f0d2","line":518,"updated":"2024-11-29 16:33:28.000000000","message":"here we could have:\n\n```\nstat_method \u003d method if method in self.valid_methods else \u0027BAD_METHOD\u0027\n```","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"ec749a90b62e4614dfbbd965ec77307a011e0994","unresolved":false,"context_lines":[{"line_number":515,"context_line":"        start_response_args \u003d [None]"},{"line_number":516,"context_line":""},{"line_number":517,"context_line":"        req \u003d Request(env)"},{"line_number":518,"context_line":"        method \u003d method_from_req(req)"},{"line_number":519,"context_line":""},{"line_number":520,"context_line":"        swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"},{"line_number":521,"context_line":"        acc, cont, _ \u003d get_aco_from_path(swift_path)"}],"source_content_type":"text/x-python","patch_set":9,"id":"98a5ac15_497c752a","line":518,"in_reply_to":"88144c24_1313f0d2","updated":"2024-12-10 16:29:15.000000000","message":"Acknowledged","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3c9db4b292eacdc99e65c8934ed5e7d5148bdd8b","unresolved":true,"context_lines":[{"line_number":522,"context_line":""},{"line_number":523,"context_line":"        xfer_metric_name \u003d \u0027swift_proxy_request_body_input_bytes\u0027"},{"line_number":524,"context_line":"        xfer_labels \u003d statsd_metric_labels("},{"line_number":525,"context_line":"            req, self.valid_methods, method, status_int\u003dNone,"},{"line_number":526,"context_line":"            acc\u003dacc, cont\u003dcont, policy_index\u003dNone)"},{"line_number":527,"context_line":""},{"line_number":528,"context_line":"        statsd_emit_callback \u003d self.get_buffer_xfer_emit_callback("}],"source_content_type":"text/x-python","patch_set":9,"id":"8429ad01_b7ae79aa","line":525,"range":{"start_line":525,"start_character":17,"end_line":525,"end_character":43},"updated":"2024-11-29 16:33:28.000000000","message":"``stat_method``","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"ec749a90b62e4614dfbbd965ec77307a011e0994","unresolved":false,"context_lines":[{"line_number":522,"context_line":""},{"line_number":523,"context_line":"        xfer_metric_name \u003d \u0027swift_proxy_request_body_input_bytes\u0027"},{"line_number":524,"context_line":"        xfer_labels \u003d statsd_metric_labels("},{"line_number":525,"context_line":"            req, self.valid_methods, method, status_int\u003dNone,"},{"line_number":526,"context_line":"            acc\u003dacc, cont\u003dcont, policy_index\u003dNone)"},{"line_number":527,"context_line":""},{"line_number":528,"context_line":"        statsd_emit_callback \u003d self.get_buffer_xfer_emit_callback("}],"source_content_type":"text/x-python","patch_set":9,"id":"02d262c9_02d5fb15","line":525,"range":{"start_line":525,"start_character":17,"end_line":525,"end_character":43},"in_reply_to":"8429ad01_b7ae79aa","updated":"2024-12-10 16:29:15.000000000","message":"Acknowledged","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3c9db4b292eacdc99e65c8934ed5e7d5148bdd8b","unresolved":true,"context_lines":[{"line_number":568,"context_line":""},{"line_number":569,"context_line":"            policy_index \u003d get_policy_index(req.headers, resp_headers)"},{"line_number":570,"context_line":"            labels \u003d statsd_metric_labels("},{"line_number":571,"context_line":"                req, self.valid_methods, method, status_int\u003dwire_status_int,"},{"line_number":572,"context_line":"                acc\u003dacc, cont\u003dcont, policy_index\u003dpolicy_index)"},{"line_number":573,"context_line":""},{"line_number":574,"context_line":"            # Log timing information for time-to-first-byte (GET requests only)"}],"source_content_type":"text/x-python","patch_set":9,"id":"d172f5a1_7da5d51b","line":571,"range":{"start_line":571,"start_character":21,"end_line":571,"end_character":47},"updated":"2024-11-29 16:33:28.000000000","message":"``stat_method``","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"ec749a90b62e4614dfbbd965ec77307a011e0994","unresolved":false,"context_lines":[{"line_number":568,"context_line":""},{"line_number":569,"context_line":"            policy_index \u003d get_policy_index(req.headers, resp_headers)"},{"line_number":570,"context_line":"            labels \u003d statsd_metric_labels("},{"line_number":571,"context_line":"                req, self.valid_methods, method, status_int\u003dwire_status_int,"},{"line_number":572,"context_line":"                acc\u003dacc, cont\u003dcont, policy_index\u003dpolicy_index)"},{"line_number":573,"context_line":""},{"line_number":574,"context_line":"            # Log timing information for time-to-first-byte (GET requests only)"}],"source_content_type":"text/x-python","patch_set":9,"id":"21c8c924_927c5c67","line":571,"range":{"start_line":571,"start_character":21,"end_line":571,"end_character":47},"in_reply_to":"d172f5a1_7da5d51b","updated":"2024-12-10 16:29:15.000000000","message":"Acknowledged","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c836907958e81fc6029007ffa68113095eb48b82","unresolved":true,"context_lines":[{"line_number":201,"context_line":"            acc, cont, _ \u003d get_aco_from_path(swift_path)"},{"line_number":202,"context_line":""},{"line_number":203,"context_line":"            self.labels[\u0027account\u0027] \u003d acc"},{"line_number":204,"context_line":"            self.labels[\u0027container\u0027] \u003d cont"},{"line_number":205,"context_line":"            self.labels[\u0027type\u0027] \u003d get_metric_name_type(self.req, swift_path)"},{"line_number":206,"context_line":""},{"line_number":207,"context_line":"        self.emit_bytes +\u003d buffer_len"}],"source_content_type":"text/x-python","patch_set":11,"id":"3476e84e_f1778068","line":204,"updated":"2024-12-11 15:35:43.000000000","message":"I think this is wrong. This cont, derived from the swift_request_path at the backend, is sometimes different than the one used for other labelled metrics for the same request. For example, with an s3api multipart download, the backend container is \u003ccont\u003e+segments, so I see inconsistently labelled metrics.\n\ne.g. sampled metrics for a single request:\n\n```\nswift_proxy_response_body_output_bytes:1114112|c|#account:AUTH_test,container:test%2Bsegments,method:GET,policy:0,status:200,type:object,user_reqctx:subrequest\nswift_proxy_response_body_output_bytes:1179648|c|#account:AUTH_test,container:test+segments,method:GET,policy:0,status:206,type:object\n\nswift_proxy_request_timing:80.0724|ms|#account:AUTH_test,container:test%2Bsegments,method:GET,policy:0,status:200,type:object,user_reqctx:subrequest\nswift_proxy_request_body_bytes:0|c|#account:AUTH_test,container:test%2Bsegments,method:GET,policy:0,status:200,type:object,user_reqctx:subrequest\nswift_proxy_response_body_bytes:8388608|c|#account:AUTH_test,container:test%2Bsegments,method:GET,policy:0,status:200,type:object,user_reqctx:subrequest\n\nswift_proxy_request_timing:106.6575|ms|#account:AUTH_test,container:test,method:GET,policy:0,status:206,type:object\nswift_proxy_request_body_bytes:0|c|#account:AUTH_test,container:test,method:GET,policy:0,status:206,type:object\nswift_proxy_response_body_bytes:8388608|c|#account:AUTH_test,container:test,method:GET,policy:0,status:206,type:object\n```\n\nNote how both the normal and subrequest metrics for ``body_output_bytes``  have ``container:test%2Bsegments``, whereas the normal metrics for ``request_body_bytes`` has ``container:test``\n\nAlso note that the final log messages for this request has container\u003dtest\n\n```\nDec 11 09:30:22 vagrant proxy-server: 127.0.0.1 127.0.0.1 11/Dec/2024/14/30/22 GET /test/1GB%3FpartNumber%3D1 HTTP/1.0 206 - aws-cli/1.33.34%20md/Botocore%231.34.152%20ua/2.0%20os/linux%235.4.0-90-generic%20md/arch%23aarch64%20lang/python%233.8.10%20md/pyimpl%23CPython%20cfg/retry-mode%23legacy%20botocore/1.34.152 - - 8388608 - txa143e51c79dd43aeb07bc-006759a1fe - 0.1067 - - 1733927422.732774734 1733927422.839432240 0 AUTH_test test 1GB\nDec 11 09:30:22 vagrant proxy-server: STDERR: 127.0.0.1 - - [11/Dec/2024 14:30:22] \"GET /test/1GB?partNumber\u003d1 HTTP/1.1\" 206 8389136 0.108359 (txn: txa143e51c79dd43aeb07bc-006759a1fe)\n```","commit_id":"1af3d28b70a02ca2ed62f9252b527b1efb018b60"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"95af8f10f32e2f8430669825672d1b9701c15cf6","unresolved":false,"context_lines":[{"line_number":201,"context_line":"            acc, cont, _ \u003d get_aco_from_path(swift_path)"},{"line_number":202,"context_line":""},{"line_number":203,"context_line":"            self.labels[\u0027account\u0027] \u003d acc"},{"line_number":204,"context_line":"            self.labels[\u0027container\u0027] \u003d cont"},{"line_number":205,"context_line":"            self.labels[\u0027type\u0027] \u003d get_metric_name_type(self.req, swift_path)"},{"line_number":206,"context_line":""},{"line_number":207,"context_line":"        self.emit_bytes +\u003d buffer_len"}],"source_content_type":"text/x-python","patch_set":11,"id":"8a4a75fa_bf0fe80e","line":204,"in_reply_to":"3476e84e_f1778068","updated":"2025-01-03 16:33:48.000000000","message":"Thanks Al! changed per our discussion","commit_id":"1af3d28b70a02ca2ed62f9252b527b1efb018b60"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c836907958e81fc6029007ffa68113095eb48b82","unresolved":true,"context_lines":[{"line_number":504,"context_line":"        if swift_request_paths is None:"},{"line_number":505,"context_line":"            env[\u0027swift.swift_request_paths\u0027] \u003d [None]"},{"line_number":506,"context_line":"        else:"},{"line_number":507,"context_line":"            req_path \u003d env.get(\u0027PATH_INFO\u0027, None)"},{"line_number":508,"context_line":"            if req_path is not None:"},{"line_number":509,"context_line":"                swift_request_paths[0] \u003d req_path"},{"line_number":510,"context_line":""},{"line_number":511,"context_line":"        if self.req_already_logged(env):"},{"line_number":512,"context_line":"            return self.app(env, start_response)"}],"source_content_type":"text/x-python","patch_set":11,"id":"28eb22f1_b4d13bc1","line":509,"range":{"start_line":507,"start_character":12,"end_line":509,"end_character":49},"updated":"2024-12-11 15:35:43.000000000","message":"I watched the stats while doing an S3api multipart download, where the backend path is to the +segments container, and noticed a difference between the request and subrequest metrics labels:\n\n```\nswift_proxy_response_body_output_bytes:589824|c|#account:AUTH_test,container:test%2Bsegments,method:GET,policy:0,status:200,type:object,user_reqctx:subrequest\nswift_proxy_response_body_output_bytes:589824|c|#account:AUTH_test,container:test+segments,method:GET,policy:0,status:206,type:object\n\n```\n\nIn the subrequest context the container has been wsgi_quoted, but not in the request context. I think that is because here the swift_request_path is set to the *unquoted* \u0027PATH_INFO\u0027, but elsewhere when a labels is constructed the req.path property is used which *is quoted*. We should use the quoted ``req.path`` here too - just needs the Request constructor to be moved up before this from line 518.","commit_id":"1af3d28b70a02ca2ed62f9252b527b1efb018b60"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"95af8f10f32e2f8430669825672d1b9701c15cf6","unresolved":false,"context_lines":[{"line_number":504,"context_line":"        if swift_request_paths is None:"},{"line_number":505,"context_line":"            env[\u0027swift.swift_request_paths\u0027] \u003d [None]"},{"line_number":506,"context_line":"        else:"},{"line_number":507,"context_line":"            req_path \u003d env.get(\u0027PATH_INFO\u0027, None)"},{"line_number":508,"context_line":"            if req_path is not None:"},{"line_number":509,"context_line":"                swift_request_paths[0] \u003d req_path"},{"line_number":510,"context_line":""},{"line_number":511,"context_line":"        if self.req_already_logged(env):"},{"line_number":512,"context_line":"            return self.app(env, start_response)"}],"source_content_type":"text/x-python","patch_set":11,"id":"655187ff_f67891a3","line":509,"range":{"start_line":507,"start_character":12,"end_line":509,"end_character":49},"in_reply_to":"28eb22f1_b4d13bc1","updated":"2025-01-03 16:33:48.000000000","message":"Acknowledged","commit_id":"1af3d28b70a02ca2ed62f9252b527b1efb018b60"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":372,"context_line":"                raise ValueError"},{"line_number":373,"context_line":"        except ValueError:"},{"line_number":374,"context_line":"            acc, cont, obj \u003d None, None, None"},{"line_number":375,"context_line":"        return acc, cont, obj"},{"line_number":376,"context_line":""},{"line_number":377,"context_line":"    def get_metric_name_type(self, req):"},{"line_number":378,"context_line":"        swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"}],"source_content_type":"text/x-python","patch_set":13,"id":"8a30bf90_3bc21e71","side":"PARENT","line":375,"updated":"2025-01-17 21:20:47.000000000","message":"I don\u0027t know why this interface worked this way; but as a method maybe it made sense - where as moving it up a module level function IMHO makes it more likely to be attractive for use outside of the context of this class: in which case there\u0027s a higher-bar for the interface/doc-string/testing\n\nWhile generally I prefer functions to methods - that\u0027s partly b/c they tend to have easier to understand interfaces with less side-effects, better doc-strings, and easier to write/read tests for.\n\nI wouldn\u0027t say it\u0027s only/always virtuous to pull any method that doesn\u0027t use `self` out a module level function as-is w/o considering the interface, documentation and testing.","commit_id":"a2748293d30a3795835c76ee75becddfd20196e2"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"2cf84e04dade1b637fc97428392dddc14d0eff30","unresolved":false,"context_lines":[{"line_number":372,"context_line":"                raise ValueError"},{"line_number":373,"context_line":"        except ValueError:"},{"line_number":374,"context_line":"            acc, cont, obj \u003d None, None, None"},{"line_number":375,"context_line":"        return acc, cont, obj"},{"line_number":376,"context_line":""},{"line_number":377,"context_line":"    def get_metric_name_type(self, req):"},{"line_number":378,"context_line":"        swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"}],"source_content_type":"text/x-python","patch_set":13,"id":"ee6cbac2_3ee43af2","side":"PARENT","line":375,"in_reply_to":"8a30bf90_3bc21e71","updated":"2025-02-24 16:22:27.000000000","message":"Acknowledged","commit_id":"a2748293d30a3795835c76ee75becddfd20196e2"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":383,"context_line":"            return \u0027container\u0027"},{"line_number":384,"context_line":"        if acc:"},{"line_number":385,"context_line":"            return \u0027account\u0027"},{"line_number":386,"context_line":"        return req.environ.get(\u0027swift.source\u0027) or \u0027UNKNOWN\u0027"},{"line_number":387,"context_line":""},{"line_number":388,"context_line":"    def statsd_metric_name(self, req, status_int, method):"},{"line_number":389,"context_line":"        stat_type \u003d self.get_metric_name_type(req)"}],"source_content_type":"text/x-python","patch_set":13,"id":"e61dc7c9_66815dfc","side":"PARENT","line":386,"updated":"2025-01-17 21:20:47.000000000","message":"oic, this is the main reason for the interface:\n\n```\n(acct, cont, obj)\n(acct, cont, None)\n(acct, None, None)\n(None, None, None)\n```\n\nso maybe that interface is fine/reasonable if it\u0027s documented and well tested","commit_id":"a2748293d30a3795835c76ee75becddfd20196e2"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"2cf84e04dade1b637fc97428392dddc14d0eff30","unresolved":false,"context_lines":[{"line_number":383,"context_line":"            return \u0027container\u0027"},{"line_number":384,"context_line":"        if acc:"},{"line_number":385,"context_line":"            return \u0027account\u0027"},{"line_number":386,"context_line":"        return req.environ.get(\u0027swift.source\u0027) or \u0027UNKNOWN\u0027"},{"line_number":387,"context_line":""},{"line_number":388,"context_line":"    def statsd_metric_name(self, req, status_int, method):"},{"line_number":389,"context_line":"        stat_type \u003d self.get_metric_name_type(req)"}],"source_content_type":"text/x-python","patch_set":13,"id":"61636ecb_997b6aaa","side":"PARENT","line":386,"in_reply_to":"e61dc7c9_66815dfc","updated":"2025-02-24 16:22:27.000000000","message":"Acknowledged","commit_id":"a2748293d30a3795835c76ee75becddfd20196e2"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":116,"context_line":"        if not valid_api_version(version):"},{"line_number":117,"context_line":"            raise ValueError"},{"line_number":118,"context_line":"    except ValueError:"},{"line_number":119,"context_line":"        acc, cont, obj \u003d None, None, None"},{"line_number":120,"context_line":"    return acc, cont, obj"},{"line_number":121,"context_line":""},{"line_number":122,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"15482afd_6a52f8d8","line":119,"updated":"2025-01-17 21:20:47.000000000","message":"Are we only/always using this to indicate essentially an \"error\" condition than it\u0027s not POSSIBLE to pull acc, cont, obj from this path?  i.e. it\u0027s either a s3 request OR something like `/auth/v1.0`\n\nMaybe it\u0027d be easier for callers to consistently catch the ValueError? so the error handling appears in the exception block instead under a `if not acc` or `if acc is None` or `if not all([acc, cont, obj])` block or some other spelling?\n\n... actually upon further reading the interface may be fine for what it is - it would just really benifit from a docstring.","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"91bf6bebd51e5e74fa5ba2f19ab233f5c391317e","unresolved":false,"context_lines":[{"line_number":116,"context_line":"        if not valid_api_version(version):"},{"line_number":117,"context_line":"            raise ValueError"},{"line_number":118,"context_line":"    except ValueError:"},{"line_number":119,"context_line":"        acc, cont, obj \u003d None, None, None"},{"line_number":120,"context_line":"    return acc, cont, obj"},{"line_number":121,"context_line":""},{"line_number":122,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"6a2cd5fc_179fe55d","line":119,"in_reply_to":"15482afd_6a52f8d8","updated":"2025-02-11 20:34:03.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":122,"context_line":""},{"line_number":123,"context_line":"def get_metric_name_type(req, swift_path\u003dNone):"},{"line_number":124,"context_line":"    if swift_path is None:"},{"line_number":125,"context_line":"        swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"},{"line_number":126,"context_line":"    acc, cont, obj \u003d get_aco_from_path(swift_path)"},{"line_number":127,"context_line":"    return get_metric_name_type_from_aco(req, acc, cont, obj)"},{"line_number":128,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"c81feb1c_9ee7ee24","line":125,"updated":"2025-01-17 21:20:47.000000000","message":"wat?  it looks really weird to explicitly pass `swift_path` which prevents using the req.environ - that kwarg/behavior wasn\u0027t in the original method.\n\nI think a doc-string *again* would be *really* helpful\n\nSometimes the effort to try and spell out all of a functions behaviors/side-effects can make me rethink if that\u0027s *really* the way I want an interface to be understood/used?\n\n```\nIf the implementation is hard to explain, it\u0027s a bad idea.\nIf the implementation is easy to explain, it may be a good idea.\n```","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"91bf6bebd51e5e74fa5ba2f19ab233f5c391317e","unresolved":false,"context_lines":[{"line_number":122,"context_line":""},{"line_number":123,"context_line":"def get_metric_name_type(req, swift_path\u003dNone):"},{"line_number":124,"context_line":"    if swift_path is None:"},{"line_number":125,"context_line":"        swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"},{"line_number":126,"context_line":"    acc, cont, obj \u003d get_aco_from_path(swift_path)"},{"line_number":127,"context_line":"    return get_metric_name_type_from_aco(req, acc, cont, obj)"},{"line_number":128,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"1f21990e_235a77f2","line":125,"in_reply_to":"c81feb1c_9ee7ee24","updated":"2025-02-11 20:34:03.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":133,"context_line":"    if cont:"},{"line_number":134,"context_line":"        return \u0027container\u0027"},{"line_number":135,"context_line":"    if acc:"},{"line_number":136,"context_line":"        return \u0027account\u0027"},{"line_number":137,"context_line":"    return req.environ.get(\u0027swift.source\u0027) or \u0027UNKNOWN\u0027"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"7a877595_2f53d4f7","line":136,"updated":"2025-01-17 21:20:47.000000000","message":"so the trick to understanding `if acc is None` in `__call__` and the interface of `get_aco_from_path` in general - is understanding that it\u0027s calling `split_path` with `min_segs\u003d1` and translating ValueErrors and invalid `/v1` to `(None, None, None)`\n\notherwise it\u0027s how you\u0027d expect `split_path` to work to parse a swift path into the normal\n\n```\n(account, None, None)\n(account, container, None)\n(account, container, obj)\n```\n\n... tuples\n\nactually a doc-string like we have on `split_path` with examples would probably be really helpful!","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"91bf6bebd51e5e74fa5ba2f19ab233f5c391317e","unresolved":false,"context_lines":[{"line_number":133,"context_line":"    if cont:"},{"line_number":134,"context_line":"        return \u0027container\u0027"},{"line_number":135,"context_line":"    if acc:"},{"line_number":136,"context_line":"        return \u0027account\u0027"},{"line_number":137,"context_line":"    return req.environ.get(\u0027swift.source\u0027) or \u0027UNKNOWN\u0027"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"8b3c6524_b2eaef52","line":136,"in_reply_to":"7a877595_2f53d4f7","updated":"2025-02-11 20:34:03.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":163,"context_line":"                         acc\u003dNone, cont\u003dNone, policy_index\u003dNone,"},{"line_number":164,"context_line":"                         server_type\u003dNone):"},{"line_number":165,"context_line":"    if server_type is None:"},{"line_number":166,"context_line":"        server_type \u003d get_metric_name_type(req)"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"    labels \u003d {"},{"line_number":169,"context_line":"        \u0027type\u0027: server_type,"}],"source_content_type":"text/x-python","patch_set":13,"id":"a41cc222_652436cb","line":166,"updated":"2025-01-17 21:20:47.000000000","message":"why is this *optional* - either this function pulls it from the req or it takes it as an explicit input.  How could the caller *possibily* know when it\u0027s correct to pass in None or if it needs to have called `get_metric_name_type_from_aco` or `get_metric_name_type` first?\n\nOk, so in many cases this is implicitly relying on the req environ somehow being able to tell if a request was account/bucket/obj sometimes via backend_path OR explicit up-front s3 path parsing.","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"c497484c0b6f27f6f3ebb0e997780f911912c04c","unresolved":false,"context_lines":[{"line_number":163,"context_line":"                         acc\u003dNone, cont\u003dNone, policy_index\u003dNone,"},{"line_number":164,"context_line":"                         server_type\u003dNone):"},{"line_number":165,"context_line":"    if server_type is None:"},{"line_number":166,"context_line":"        server_type \u003d get_metric_name_type(req)"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"    labels \u003d {"},{"line_number":169,"context_line":"        \u0027type\u0027: server_type,"}],"source_content_type":"text/x-python","patch_set":13,"id":"ebdd0dad_a6f769dd","line":166,"in_reply_to":"390969c0_d03d9fc9","updated":"2025-02-11 20:34:26.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"91bf6bebd51e5e74fa5ba2f19ab233f5c391317e","unresolved":true,"context_lines":[{"line_number":163,"context_line":"                         acc\u003dNone, cont\u003dNone, policy_index\u003dNone,"},{"line_number":164,"context_line":"                         server_type\u003dNone):"},{"line_number":165,"context_line":"    if server_type is None:"},{"line_number":166,"context_line":"        server_type \u003d get_metric_name_type(req)"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"    labels \u003d {"},{"line_number":169,"context_line":"        \u0027type\u0027: server_type,"}],"source_content_type":"text/x-python","patch_set":13,"id":"390969c0_d03d9fc9","line":166,"in_reply_to":"a41cc222_652436cb","updated":"2025-02-11 20:34:03.000000000","message":"Indeed used in s3 path","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":167,"context_line":""},{"line_number":168,"context_line":"    labels \u003d {"},{"line_number":169,"context_line":"        \u0027type\u0027: server_type,"},{"line_number":170,"context_line":"        \u0027method\u0027: stat_method,"},{"line_number":171,"context_line":"    }"},{"line_number":172,"context_line":"    if status_int:"},{"line_number":173,"context_line":"        labels[\u0027status\u0027] \u003d status_int"}],"source_content_type":"text/x-python","patch_set":13,"id":"8d4859cc_e3746df0","line":170,"updated":"2025-01-17 21:20:47.000000000","message":"this is a new argument to this function - previously as a method it used `self.valid_methods`","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"91bf6bebd51e5e74fa5ba2f19ab233f5c391317e","unresolved":false,"context_lines":[{"line_number":167,"context_line":""},{"line_number":168,"context_line":"    labels \u003d {"},{"line_number":169,"context_line":"        \u0027type\u0027: server_type,"},{"line_number":170,"context_line":"        \u0027method\u0027: stat_method,"},{"line_number":171,"context_line":"    }"},{"line_number":172,"context_line":"    if status_int:"},{"line_number":173,"context_line":"        labels[\u0027status\u0027] \u003d status_int"}],"source_content_type":"text/x-python","patch_set":13,"id":"42f85df4_ba0c5d63","line":170,"in_reply_to":"8d4859cc_e3746df0","updated":"2025-02-11 20:34:03.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":172,"context_line":"    if status_int:"},{"line_number":173,"context_line":"        labels[\u0027status\u0027] \u003d status_int"},{"line_number":174,"context_line":"    if acc:"},{"line_number":175,"context_line":"        labels[\u0027account\u0027] \u003d acc"},{"line_number":176,"context_line":"    if cont:"},{"line_number":177,"context_line":"        labels[\u0027container\u0027] \u003d cont"},{"line_number":178,"context_line":"    if labels[\u0027type\u0027] \u003d\u003d \u0027object\u0027 and \\"}],"source_content_type":"text/x-python","patch_set":13,"id":"86e9073f_00a00068","line":175,"updated":"2025-01-17 21:20:47.000000000","message":"of all the places we might want to look into the request and pull out the account from the magical back-propagation req.environ why in THIS function do we choose to just not even include the key in the dict if it was passed in as `None` or implicitly ommited!?","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"2cf84e04dade1b637fc97428392dddc14d0eff30","unresolved":false,"context_lines":[{"line_number":172,"context_line":"    if status_int:"},{"line_number":173,"context_line":"        labels[\u0027status\u0027] \u003d status_int"},{"line_number":174,"context_line":"    if acc:"},{"line_number":175,"context_line":"        labels[\u0027account\u0027] \u003d acc"},{"line_number":176,"context_line":"    if cont:"},{"line_number":177,"context_line":"        labels[\u0027container\u0027] \u003d cont"},{"line_number":178,"context_line":"    if labels[\u0027type\u0027] \u003d\u003d \u0027object\u0027 and \\"}],"source_content_type":"text/x-python","patch_set":13,"id":"3a1c247c_f94a4456","line":175,"in_reply_to":"86e9073f_00a00068","updated":"2025-02-24 16:22:27.000000000","message":"In current implementation , the labels are not emitted if the value is None. Could discuss more about this","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":184,"context_line":""},{"line_number":185,"context_line":"class BufferXferEmitCallback(object):"},{"line_number":186,"context_line":"    def __init__(self, req, stat_method, metric_name, labels, statsd,"},{"line_number":187,"context_line":"                 emit_buffer_xfer_bytes_sec):"},{"line_number":188,"context_line":"        self.req \u003d req"},{"line_number":189,"context_line":"        self.stat_method \u003d stat_method"},{"line_number":190,"context_line":"        self.metric_name \u003d metric_name"}],"source_content_type":"text/x-python","patch_set":13,"id":"f4177e75_66b3ba2c","line":187,"updated":"2025-01-17 21:20:47.000000000","message":"I think it\u0027s *really* great to have this separate class take in all it\u0027s explicit inputs expressing it\u0027s minimal dependencies on the proxy-logging app instance.\n\nBut it\u0027s not *calling* any of these new module level functions, right?  All these new functions are only/always called from w/i the ProxyLogging mw instance?  No?  Can you point me to what I\u0027m missing with my greps?\n\nOR - if the method extraction was *just* a refactor - that\u0027s *great* - love me some functional programing; but I can\u0027t really see the interface amoung 7 little functions - when do I need which one?  Are the \"get_name[policy]\" and \"get_labels\" sort of the *main* entrypoints, are the other ones just helpers in service of the 3-4 other \"external\" functions?  Maybe rename \n\n```\n_stat_method_name(req, valid_methods)\n```","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"2cf84e04dade1b637fc97428392dddc14d0eff30","unresolved":false,"context_lines":[{"line_number":184,"context_line":""},{"line_number":185,"context_line":"class BufferXferEmitCallback(object):"},{"line_number":186,"context_line":"    def __init__(self, req, stat_method, metric_name, labels, statsd,"},{"line_number":187,"context_line":"                 emit_buffer_xfer_bytes_sec):"},{"line_number":188,"context_line":"        self.req \u003d req"},{"line_number":189,"context_line":"        self.stat_method \u003d stat_method"},{"line_number":190,"context_line":"        self.metric_name \u003d metric_name"}],"source_content_type":"text/x-python","patch_set":13,"id":"169e73b8_096ac275","line":187,"in_reply_to":"f4177e75_66b3ba2c","updated":"2025-02-24 16:22:27.000000000","message":"Right this class is not calling the module level functions. Renaming as suggested","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":198,"context_line":"        if self.emit_buffer_xfer_bytes_sec \u003c 0:"},{"line_number":199,"context_line":"            return None"},{"line_number":200,"context_line":""},{"line_number":201,"context_line":"        if self.labels.get(\u0027account\u0027, None) is None:"},{"line_number":202,"context_line":"            path_parts \u003d self.req.environ.get(\u0027swift.path_parts\u0027)"},{"line_number":203,"context_line":"            self.labels[\u0027account\u0027] \u003d path_parts[0]"},{"line_number":204,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"5cb50001_9fde386f","line":201,"updated":"2025-01-17 21:20:47.000000000","message":"I\u0027m not sure this is how I\u0027d want this class interface to work.\n\nFor output bytes we just already have the response/environ answer when we create labels - so the response labels always include the account.  But this conditional doesn\u0027t read like \"if output_bytes path\" - it reads like \"if client didn\u0027t include an account label\" and that\u0027s like... WELL WHY DIDN\u0027T THEY!?  Did they forget!?  Did they not WANT an account label!?  Why does this class work like this!!!???\n\nAnd only through a whole bunch of grok do you learn for *input_bytes* we pass in acct\u003dNone as the label (why do we do that!?  What does acct\u003dNone *mean*!?); and rely on this ~*~ magic ~*~ to not *actually* label the metrics as `acct\u003dNone` when it comes time to emit the metrics because by THEN the right most proxy-logging will have filled in acct... just like... somewhere *else* - not in this classes labels\u0027 attribute, but in it\u0027s req\u0027s environ attribute.\n\nIdeally there\u0027d just be one explicit interface like \"labels_or_lazy_labels\"\n\n```\ndef __init__(..., labels_or_lazy_labels):\n    if iscallable(labels_or_lazy_labels):\n        self._lazy_labels_callable \u003d labels_or_lazy_labels\n        self._labels \u003d None\n    else:\n        self._lazy_labels_callable \u003d None\n        self._labels \u003d labels_or_lazy_labels\n        \ndef __call__(...):\n    if self._labels is None and self._lazy_labels_callable:\n        # well, it\u0027s NOW or never bubba!\n        self._labels \u003d self._lazy_labels_callable()\n    self.statsd.update_stats(..., labels\u003dself._labels)\n```\n\none benifit of this structure is the `BufferXferEmitCallback` doesn\u0027t have to \"know\" about the request object/structure (and certainly not the account back-propogation) at all.  It just knows sometimes people can\u0027t tell me the labels up front - so instead of a dict I allow them to pass in a lambda.\n\n\n```\nlabels\u003dfunctools.partial(statsd_metric_labels, req, ...)\n```","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"2cf84e04dade1b637fc97428392dddc14d0eff30","unresolved":false,"context_lines":[{"line_number":198,"context_line":"        if self.emit_buffer_xfer_bytes_sec \u003c 0:"},{"line_number":199,"context_line":"            return None"},{"line_number":200,"context_line":""},{"line_number":201,"context_line":"        if self.labels.get(\u0027account\u0027, None) is None:"},{"line_number":202,"context_line":"            path_parts \u003d self.req.environ.get(\u0027swift.path_parts\u0027)"},{"line_number":203,"context_line":"            self.labels[\u0027account\u0027] \u003d path_parts[0]"},{"line_number":204,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"3c54fa72_518f89d3","line":201,"in_reply_to":"5cb50001_9fde386f","updated":"2025-02-24 16:22:27.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"14cf8a0f380dfd1b62c64e3ae94d323a6c4d23ef","unresolved":true,"context_lines":[{"line_number":200,"context_line":""},{"line_number":201,"context_line":"        if self.labels.get(\u0027account\u0027, None) is None:"},{"line_number":202,"context_line":"            path_parts \u003d self.req.environ.get(\u0027swift.path_parts\u0027)"},{"line_number":203,"context_line":"            self.labels[\u0027account\u0027] \u003d path_parts[0]"},{"line_number":204,"context_line":""},{"line_number":205,"context_line":"        self.emit_bytes +\u003d buffer_len"},{"line_number":206,"context_line":"        now \u003d time.time()"}],"source_content_type":"text/x-python","patch_set":13,"id":"7f4cfb6b_ed400803","line":203,"range":{"start_line":203,"start_character":37,"end_line":203,"end_character":50},"updated":"2025-01-15 15:01:49.000000000","message":"Be defensive: AFAICT swift.path_parts should have been set in the environ, but we should probably check that is has and is a list, or better, wrap this in a try/except, just in case.","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"576f7aa1851788b769331c8c466ad3f6ec18fb59","unresolved":false,"context_lines":[{"line_number":200,"context_line":""},{"line_number":201,"context_line":"        if self.labels.get(\u0027account\u0027, None) is None:"},{"line_number":202,"context_line":"            path_parts \u003d self.req.environ.get(\u0027swift.path_parts\u0027)"},{"line_number":203,"context_line":"            self.labels[\u0027account\u0027] \u003d path_parts[0]"},{"line_number":204,"context_line":""},{"line_number":205,"context_line":"        self.emit_bytes +\u003d buffer_len"},{"line_number":206,"context_line":"        now \u003d time.time()"}],"source_content_type":"text/x-python","patch_set":13,"id":"e2385c18_476e5587","line":203,"range":{"start_line":203,"start_character":37,"end_line":203,"end_character":50},"in_reply_to":"7f4cfb6b_ed400803","updated":"2025-02-11 20:22:12.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":204,"context_line":""},{"line_number":205,"context_line":"        self.emit_bytes +\u003d buffer_len"},{"line_number":206,"context_line":"        now \u003d time.time()"},{"line_number":207,"context_line":"        if self.labels.get(\u0027account\u0027, None) and \\"},{"line_number":208,"context_line":"                (self.emit_buffer_xfer_bytes_sec \u003d\u003d 0 or"},{"line_number":209,"context_line":"                 self.next_emit_time \u003c\u003d now):"},{"line_number":210,"context_line":"            self.statsd.update_stats("}],"source_content_type":"text/x-python","patch_set":13,"id":"3600aa91_cc86a16d","line":207,"updated":"2025-01-17 21:20:47.000000000","message":"why is it not reasonable to use this class w/o the acct label?","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"2cf84e04dade1b637fc97428392dddc14d0eff30","unresolved":false,"context_lines":[{"line_number":204,"context_line":""},{"line_number":205,"context_line":"        self.emit_bytes +\u003d buffer_len"},{"line_number":206,"context_line":"        now \u003d time.time()"},{"line_number":207,"context_line":"        if self.labels.get(\u0027account\u0027, None) and \\"},{"line_number":208,"context_line":"                (self.emit_buffer_xfer_bytes_sec \u003d\u003d 0 or"},{"line_number":209,"context_line":"                 self.next_emit_time \u003c\u003d now):"},{"line_number":210,"context_line":"            self.statsd.update_stats("}],"source_content_type":"text/x-python","patch_set":13,"id":"add5bf96_1f8f7f42","line":207,"in_reply_to":"3600aa91_cc86a16d","updated":"2025-02-24 16:22:27.000000000","message":"a previous comment suggests that we don\u0027t emit if has not acct label","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":252,"context_line":"            conf.get(\u0027log_statsd_valid_http_methods\u0027,"},{"line_number":253,"context_line":"                     \u0027GET,HEAD,POST,PUT,DELETE,COPY,OPTIONS,UPDATE\u0027))"},{"line_number":254,"context_line":"        self.valid_methods \u003d [m.strip().upper() for m in"},{"line_number":255,"context_line":"                              self.valid_methods.split(\u0027,\u0027) if m.strip()]"},{"line_number":256,"context_line":"        log_conf \u003d dict(conf)"},{"line_number":257,"context_line":"        access_prefix_len \u003d len(\u0027access_\u0027)"},{"line_number":258,"context_line":"        for k, v in conf.items():"}],"source_content_type":"text/x-python","patch_set":13,"id":"b612418d_b3db3b2f","line":255,"updated":"2025-01-17 21:20:47.000000000","message":"why is this `valid_method`/`BAD_METHOD` stuff restricted to this *class* when we have top-level *functions* like `statsd_metric_name` that take an argument like `stat_method`?\n\nIs it *ever* \"correct\" to call `statsd_metric_name` with `method_from_req` or should callers consistently run it through `self.statsd_metric_method` ???","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"2cf84e04dade1b637fc97428392dddc14d0eff30","unresolved":false,"context_lines":[{"line_number":252,"context_line":"            conf.get(\u0027log_statsd_valid_http_methods\u0027,"},{"line_number":253,"context_line":"                     \u0027GET,HEAD,POST,PUT,DELETE,COPY,OPTIONS,UPDATE\u0027))"},{"line_number":254,"context_line":"        self.valid_methods \u003d [m.strip().upper() for m in"},{"line_number":255,"context_line":"                              self.valid_methods.split(\u0027,\u0027) if m.strip()]"},{"line_number":256,"context_line":"        log_conf \u003d dict(conf)"},{"line_number":257,"context_line":"        access_prefix_len \u003d len(\u0027access_\u0027)"},{"line_number":258,"context_line":"        for k, v in conf.items():"}],"source_content_type":"text/x-python","patch_set":13,"id":"66ee8c08_797d3bda","line":255,"in_reply_to":"b612418d_b3db3b2f","updated":"2025-02-24 16:22:27.000000000","message":"to be consistent with existing implementation, we should probably call self.statsd_metric_method for methods used in stats","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":270,"context_line":"        self.check_log_msg_template_validity()"},{"line_number":271,"context_line":"        self.storage_domains \u003d conf.get(\u0027storage_domains \u0027, None)"},{"line_number":272,"context_line":"        self.dns_compliant_bucket_names \u003d conf.get("},{"line_number":273,"context_line":"            \u0027dns_compliant_bucket_names \u0027, False)"},{"line_number":274,"context_line":"        statsd_emit_buffer_xfer_bytes_ms \u003d int("},{"line_number":275,"context_line":"            conf.get(\u0027statsd_emit_buffer_xfer_bytes_ms\u0027, -1))"},{"line_number":276,"context_line":"        if statsd_emit_buffer_xfer_bytes_ms \u003c 0:"}],"source_content_type":"text/x-python","patch_set":13,"id":"8705a1a4_182be227","line":273,"updated":"2025-01-17 21:20:47.000000000","message":"any time I see updates to config options it screams out there should be a diff to the sample configs in etc/","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"2cf84e04dade1b637fc97428392dddc14d0eff30","unresolved":false,"context_lines":[{"line_number":270,"context_line":"        self.check_log_msg_template_validity()"},{"line_number":271,"context_line":"        self.storage_domains \u003d conf.get(\u0027storage_domains \u0027, None)"},{"line_number":272,"context_line":"        self.dns_compliant_bucket_names \u003d conf.get("},{"line_number":273,"context_line":"            \u0027dns_compliant_bucket_names \u0027, False)"},{"line_number":274,"context_line":"        statsd_emit_buffer_xfer_bytes_ms \u003d int("},{"line_number":275,"context_line":"            conf.get(\u0027statsd_emit_buffer_xfer_bytes_ms\u0027, -1))"},{"line_number":276,"context_line":"        if statsd_emit_buffer_xfer_bytes_ms \u003c 0:"}],"source_content_type":"text/x-python","patch_set":13,"id":"f8644f2b_7be73144","line":273,"in_reply_to":"8705a1a4_182be227","updated":"2025-02-24 16:22:27.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":491,"context_line":"    def statsd_metric_method(self, method):"},{"line_number":492,"context_line":"        stat_method \u003d method if method in self.valid_methods \\"},{"line_number":493,"context_line":"            else \u0027BAD_METHOD\u0027"},{"line_number":494,"context_line":"        return stat_method"},{"line_number":495,"context_line":""},{"line_number":496,"context_line":"    def get_buffer_xfer_emit_callback(self, req, metric_name, labels):"},{"line_number":497,"context_line":"        method \u003d method_from_req(req)"}],"source_content_type":"text/x-python","patch_set":13,"id":"7767a499_95ce4595","line":494,"updated":"2025-01-17 21:20:47.000000000","message":"ohhhh kay - maybe a doc-string here too\n\nor have `method_from_req` accept an optional `valid_methods` kwarg?","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"2cf84e04dade1b637fc97428392dddc14d0eff30","unresolved":false,"context_lines":[{"line_number":491,"context_line":"    def statsd_metric_method(self, method):"},{"line_number":492,"context_line":"        stat_method \u003d method if method in self.valid_methods \\"},{"line_number":493,"context_line":"            else \u0027BAD_METHOD\u0027"},{"line_number":494,"context_line":"        return stat_method"},{"line_number":495,"context_line":""},{"line_number":496,"context_line":"    def get_buffer_xfer_emit_callback(self, req, metric_name, labels):"},{"line_number":497,"context_line":"        method \u003d method_from_req(req)"}],"source_content_type":"text/x-python","patch_set":13,"id":"bed4669b_e19ca772","line":494,"in_reply_to":"7767a499_95ce4595","updated":"2025-02-24 16:22:27.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":494,"context_line":"        return stat_method"},{"line_number":495,"context_line":""},{"line_number":496,"context_line":"    def get_buffer_xfer_emit_callback(self, req, metric_name, labels):"},{"line_number":497,"context_line":"        method \u003d method_from_req(req)"},{"line_number":498,"context_line":"        stat_method \u003d self.statsd_metric_method(method)"},{"line_number":499,"context_line":"        return BufferXferEmitCallback("},{"line_number":500,"context_line":"            req, stat_method, metric_name, labels, self.statsd,"}],"source_content_type":"text/x-python","patch_set":13,"id":"0d5bb9b1_31bf6141","line":497,"updated":"2025-01-17 21:20:47.000000000","message":"why is `method_from_req` a function here - everywhere else in this call we use `self.statsd_metric_method`","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"2cf84e04dade1b637fc97428392dddc14d0eff30","unresolved":false,"context_lines":[{"line_number":494,"context_line":"        return stat_method"},{"line_number":495,"context_line":""},{"line_number":496,"context_line":"    def get_buffer_xfer_emit_callback(self, req, metric_name, labels):"},{"line_number":497,"context_line":"        method \u003d method_from_req(req)"},{"line_number":498,"context_line":"        stat_method \u003d self.statsd_metric_method(method)"},{"line_number":499,"context_line":"        return BufferXferEmitCallback("},{"line_number":500,"context_line":"            req, stat_method, metric_name, labels, self.statsd,"}],"source_content_type":"text/x-python","patch_set":13,"id":"72936f50_ac7a3d2d","line":497,"in_reply_to":"0d5bb9b1_31bf6141","updated":"2025-02-24 16:22:27.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":495,"context_line":""},{"line_number":496,"context_line":"    def get_buffer_xfer_emit_callback(self, req, metric_name, labels):"},{"line_number":497,"context_line":"        method \u003d method_from_req(req)"},{"line_number":498,"context_line":"        stat_method \u003d self.statsd_metric_method(method)"},{"line_number":499,"context_line":"        return BufferXferEmitCallback("},{"line_number":500,"context_line":"            req, stat_method, metric_name, labels, self.statsd,"},{"line_number":501,"context_line":"            self.emit_buffer_xfer_bytes_sec)"}],"source_content_type":"text/x-python","patch_set":13,"id":"a9346b71_3ec00779","line":498,"updated":"2025-01-17 21:20:47.000000000","message":"why isn\u0027t *this* one a function now?","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"2cf84e04dade1b637fc97428392dddc14d0eff30","unresolved":false,"context_lines":[{"line_number":495,"context_line":""},{"line_number":496,"context_line":"    def get_buffer_xfer_emit_callback(self, req, metric_name, labels):"},{"line_number":497,"context_line":"        method \u003d method_from_req(req)"},{"line_number":498,"context_line":"        stat_method \u003d self.statsd_metric_method(method)"},{"line_number":499,"context_line":"        return BufferXferEmitCallback("},{"line_number":500,"context_line":"            req, stat_method, metric_name, labels, self.statsd,"},{"line_number":501,"context_line":"            self.emit_buffer_xfer_bytes_sec)"}],"source_content_type":"text/x-python","patch_set":13,"id":"ba8dc21d_ab32e588","line":498,"in_reply_to":"a9346b71_3ec00779","updated":"2025-02-24 16:22:27.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"14cf8a0f380dfd1b62c64e3ae94d323a6c4d23ef","unresolved":true,"context_lines":[{"line_number":502,"context_line":""},{"line_number":503,"context_line":"    def __call__(self, env, start_response):"},{"line_number":504,"context_line":"        req \u003d Request(env)"},{"line_number":505,"context_line":"        swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"},{"line_number":506,"context_line":"        acc, cont, obj \u003d get_aco_from_path(swift_path)"},{"line_number":507,"context_line":"        server_type \u003d None"},{"line_number":508,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"f0885f63_193a82c9","line":505,"range":{"start_line":505,"start_character":37,"end_line":505,"end_character":57},"updated":"2025-01-15 15:01:49.000000000","message":"I\u0027m not sure ``swift.backend_path`` will ever be set when proxy_logging enters ``__call__``. It is set in the client request after s3api has handled it, which is after this line has executed in the leftmost proxy_logging, and after the rightmost proxy_logging has handled all swift-requests.\n\nBut is IS set when we reach log_request which is bothering me because does that mean that the xfer bytes metrics may use a different path for labels vs the end-of-request metrics?\n\nHere\u0027s an example of the inconsistency, stats from an s3api upload-part request where the backend PUT is redirected to the test+segments container, but the input bytes metrics label has the test container:\n\n```\nswift_proxy_request_body_input_bytes:65536|c|#account:AUTH_test,container:test,method:PUT,type:object\nswift_proxy_request_body_input_bytes:393216|c|#account:AUTH_test,container:test,method:PUT,type:object\nswift_proxy_request_body_input_bytes:458752|c|#account:AUTH_test,container:test,method:PUT,type:object\nswift_proxy_request_body_input_bytes:458752|c|#account:AUTH_test,container:test,method:PUT,type:object\nswift_proxy_request_body_input_bytes:655360|c|#account:AUTH_test,container:test,method:PUT,type:object\nswift_proxy_request_body_input_bytes:983040|c|#account:AUTH_test,container:test,method:PUT,type:object\nsubrequest.proxy-server.object.PUT.201.timing:74.3158|ms\nsubrequest.proxy-server.object.PUT.201.xfer:5120000|c\nsubrequest.proxy-server.object.policy.0.PUT.201.timing:74.3158|ms\nsubrequest.proxy-server.object.policy.0.PUT.201.xfer:5120000|c\nproxy-server.object.PUT.200.timing:93.3537|ms\nproxy-server.object.PUT.200.xfer:5120000|c\nproxy-server.object.policy.0.PUT.200.timing:93.3537|ms\nproxy-server.object.policy.0.PUT.200.xfer:5120000|c\nswift_proxy_request_timing:93.3537|ms|#account:AUTH_test,container:test+segments,method:PUT,policy:0,status:200,type:object\nswift_proxy_request_body_bytes:5120000|c|#account:AUTH_test,container:test+segments,method:PUT,policy:0,status:200,type:object\nswift_proxy_response_body_bytes:0|c|#account:AUTH_test,container:test+segments,method:PUT,policy:0,status:200,type:object\n```","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"576f7aa1851788b769331c8c466ad3f6ec18fb59","unresolved":false,"context_lines":[{"line_number":502,"context_line":""},{"line_number":503,"context_line":"    def __call__(self, env, start_response):"},{"line_number":504,"context_line":"        req \u003d Request(env)"},{"line_number":505,"context_line":"        swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"},{"line_number":506,"context_line":"        acc, cont, obj \u003d get_aco_from_path(swift_path)"},{"line_number":507,"context_line":"        server_type \u003d None"},{"line_number":508,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"c373c2e6_d1596a44","line":505,"range":{"start_line":505,"start_character":37,"end_line":505,"end_character":57},"in_reply_to":"f0885f63_193a82c9","updated":"2025-02-11 20:22:12.000000000","message":"Indeed should not use swift.backend_path. Thanks for pointing out the inconsistency. Resolving that per our discussion","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":504,"context_line":"        req \u003d Request(env)"},{"line_number":505,"context_line":"        swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"},{"line_number":506,"context_line":"        acc, cont, obj \u003d get_aco_from_path(swift_path)"},{"line_number":507,"context_line":"        server_type \u003d None"},{"line_number":508,"context_line":""},{"line_number":509,"context_line":"        path_parts \u003d env.get(\u0027swift.path_parts\u0027)"},{"line_number":510,"context_line":"        if path_parts is None:"}],"source_content_type":"text/x-python","patch_set":13,"id":"eaf6bd00_4ce7c60c","line":507,"updated":"2025-01-17 21:20:47.000000000","message":"why is *this* ever the correct answer for a swift path?","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"2cf84e04dade1b637fc97428392dddc14d0eff30","unresolved":false,"context_lines":[{"line_number":504,"context_line":"        req \u003d Request(env)"},{"line_number":505,"context_line":"        swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"},{"line_number":506,"context_line":"        acc, cont, obj \u003d get_aco_from_path(swift_path)"},{"line_number":507,"context_line":"        server_type \u003d None"},{"line_number":508,"context_line":""},{"line_number":509,"context_line":"        path_parts \u003d env.get(\u0027swift.path_parts\u0027)"},{"line_number":510,"context_line":"        if path_parts is None:"}],"source_content_type":"text/x-python","patch_set":13,"id":"ace60253_323a87f5","line":507,"in_reply_to":"eaf6bd00_4ce7c60c","updated":"2025-02-24 16:22:27.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"14cf8a0f380dfd1b62c64e3ae94d323a6c4d23ef","unresolved":true,"context_lines":[{"line_number":507,"context_line":"        server_type \u003d None"},{"line_number":508,"context_line":""},{"line_number":509,"context_line":"        path_parts \u003d env.get(\u0027swift.path_parts\u0027)"},{"line_number":510,"context_line":"        if path_parts is None:"},{"line_number":511,"context_line":"            if acc is None:"},{"line_number":512,"context_line":"                try:"},{"line_number":513,"context_line":"                    cont, obj \u003d parse_host_uri("}],"source_content_type":"text/x-python","patch_set":13,"id":"71659baa_4510c0e1","line":510,"updated":"2025-01-15 15:01:49.000000000","message":"I would find it really helpful to have comment here such as:\n\n```\n# expected in the left-most proxy_logging instance\n```","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"576f7aa1851788b769331c8c466ad3f6ec18fb59","unresolved":false,"context_lines":[{"line_number":507,"context_line":"        server_type \u003d None"},{"line_number":508,"context_line":""},{"line_number":509,"context_line":"        path_parts \u003d env.get(\u0027swift.path_parts\u0027)"},{"line_number":510,"context_line":"        if path_parts is None:"},{"line_number":511,"context_line":"            if acc is None:"},{"line_number":512,"context_line":"                try:"},{"line_number":513,"context_line":"                    cont, obj \u003d parse_host_uri("}],"source_content_type":"text/x-python","patch_set":13,"id":"760aeb21_3cc388a8","line":510,"in_reply_to":"40823557_e1baffde","updated":"2025-02-11 20:22:12.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":507,"context_line":"        server_type \u003d None"},{"line_number":508,"context_line":""},{"line_number":509,"context_line":"        path_parts \u003d env.get(\u0027swift.path_parts\u0027)"},{"line_number":510,"context_line":"        if path_parts is None:"},{"line_number":511,"context_line":"            if acc is None:"},{"line_number":512,"context_line":"                try:"},{"line_number":513,"context_line":"                    cont, obj \u003d parse_host_uri("}],"source_content_type":"text/x-python","patch_set":13,"id":"40823557_e1baffde","line":510,"in_reply_to":"71659baa_4510c0e1","updated":"2025-01-17 21:20:47.000000000","message":"maybe even:\n\n```\nif \u0027swift.path_parts\u0027 not in env:\n    # this is left most proxy logging\n    ...\n    env[\u0027swift.path_parts\u0027] \u003d setup_data_structure\nelse:\n    # this is right most proxy loggoing\n    ...\n    # update data structure\n    evn[\u0027swift.path_parts\u0027][0]\n```","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":508,"context_line":""},{"line_number":509,"context_line":"        path_parts \u003d env.get(\u0027swift.path_parts\u0027)"},{"line_number":510,"context_line":"        if path_parts is None:"},{"line_number":511,"context_line":"            if acc is None:"},{"line_number":512,"context_line":"                try:"},{"line_number":513,"context_line":"                    cont, obj \u003d parse_host_uri("},{"line_number":514,"context_line":"                        self.storage_domains,"}],"source_content_type":"text/x-python","patch_set":13,"id":"672ea280_5f319abf","line":511,"updated":"2025-01-17 21:20:47.000000000","message":"am I correct to understand this is another way to spell `not any([acc, cont, obj])`???","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"2cf84e04dade1b637fc97428392dddc14d0eff30","unresolved":false,"context_lines":[{"line_number":508,"context_line":""},{"line_number":509,"context_line":"        path_parts \u003d env.get(\u0027swift.path_parts\u0027)"},{"line_number":510,"context_line":"        if path_parts is None:"},{"line_number":511,"context_line":"            if acc is None:"},{"line_number":512,"context_line":"                try:"},{"line_number":513,"context_line":"                    cont, obj \u003d parse_host_uri("},{"line_number":514,"context_line":"                        self.storage_domains,"}],"source_content_type":"text/x-python","patch_set":13,"id":"8325ff61_fe0a93ab","line":511,"in_reply_to":"672ea280_5f319abf","updated":"2025-02-24 16:22:27.000000000","message":"Right","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":517,"context_line":"                        req, acc, cont, obj)"},{"line_number":518,"context_line":"                except Exception:"},{"line_number":519,"context_line":"                    pass"},{"line_number":520,"context_line":"            env[\u0027swift.path_parts\u0027] \u003d [acc, cont, obj]"},{"line_number":521,"context_line":"        else:"},{"line_number":522,"context_line":"            env[\u0027swift.path_parts\u0027][0] \u003d acc"},{"line_number":523,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"568c5b89_a957ca6b","line":520,"updated":"2025-01-17 21:20:47.000000000","message":"ok, and so this *might* be `(None, bucket obj)` or even `(None, None, None)` for a \"s3api \u0027list-buckets`\" operation.\n\n...but *typically* for swift requests we can expect it to be a normal","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"2cf84e04dade1b637fc97428392dddc14d0eff30","unresolved":false,"context_lines":[{"line_number":517,"context_line":"                        req, acc, cont, obj)"},{"line_number":518,"context_line":"                except Exception:"},{"line_number":519,"context_line":"                    pass"},{"line_number":520,"context_line":"            env[\u0027swift.path_parts\u0027] \u003d [acc, cont, obj]"},{"line_number":521,"context_line":"        else:"},{"line_number":522,"context_line":"            env[\u0027swift.path_parts\u0027][0] \u003d acc"},{"line_number":523,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"123adc9c_d0e8db3c","line":520,"in_reply_to":"568c5b89_a957ca6b","updated":"2025-02-24 16:22:27.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"14cf8a0f380dfd1b62c64e3ae94d323a6c4d23ef","unresolved":true,"context_lines":[{"line_number":518,"context_line":"                except Exception:"},{"line_number":519,"context_line":"                    pass"},{"line_number":520,"context_line":"            env[\u0027swift.path_parts\u0027] \u003d [acc, cont, obj]"},{"line_number":521,"context_line":"        else:"},{"line_number":522,"context_line":"            env[\u0027swift.path_parts\u0027][0] \u003d acc"},{"line_number":523,"context_line":""},{"line_number":524,"context_line":"        if self.req_already_logged(env):"}],"source_content_type":"text/x-python","patch_set":13,"id":"44d52c79_64b4772c","line":521,"updated":"2025-01-15 15:01:49.000000000","message":"I would find it really helpful to have comment here such as:\n\n```\n# expected in the right-most proxy_logging instance\n```","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"576f7aa1851788b769331c8c466ad3f6ec18fb59","unresolved":false,"context_lines":[{"line_number":518,"context_line":"                except Exception:"},{"line_number":519,"context_line":"                    pass"},{"line_number":520,"context_line":"            env[\u0027swift.path_parts\u0027] \u003d [acc, cont, obj]"},{"line_number":521,"context_line":"        else:"},{"line_number":522,"context_line":"            env[\u0027swift.path_parts\u0027][0] \u003d acc"},{"line_number":523,"context_line":""},{"line_number":524,"context_line":"        if self.req_already_logged(env):"}],"source_content_type":"text/x-python","patch_set":13,"id":"42fdfb21_bbf325ca","line":521,"in_reply_to":"44d52c79_64b4772c","updated":"2025-02-11 20:22:12.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"14cf8a0f380dfd1b62c64e3ae94d323a6c4d23ef","unresolved":true,"context_lines":[{"line_number":519,"context_line":"                    pass"},{"line_number":520,"context_line":"            env[\u0027swift.path_parts\u0027] \u003d [acc, cont, obj]"},{"line_number":521,"context_line":"        else:"},{"line_number":522,"context_line":"            env[\u0027swift.path_parts\u0027][0] \u003d acc"},{"line_number":523,"context_line":""},{"line_number":524,"context_line":"        if self.req_already_logged(env):"},{"line_number":525,"context_line":"            return self.app(env, start_response)"}],"source_content_type":"text/x-python","patch_set":13,"id":"c6e08040_89ccf165","line":522,"updated":"2025-01-15 15:01:49.000000000","message":"We might want to be a little more cautious here and only set ``acc`` if it is not already set. I\u0027m being very hypothetical/paranoid, but thinking if we ever introduced a middleware that redirected request to another (hidden/internal) account, then that middleware should be responsible for setting ``acc``","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"576f7aa1851788b769331c8c466ad3f6ec18fb59","unresolved":false,"context_lines":[{"line_number":519,"context_line":"                    pass"},{"line_number":520,"context_line":"            env[\u0027swift.path_parts\u0027] \u003d [acc, cont, obj]"},{"line_number":521,"context_line":"        else:"},{"line_number":522,"context_line":"            env[\u0027swift.path_parts\u0027][0] \u003d acc"},{"line_number":523,"context_line":""},{"line_number":524,"context_line":"        if self.req_already_logged(env):"},{"line_number":525,"context_line":"            return self.app(env, start_response)"}],"source_content_type":"text/x-python","patch_set":13,"id":"003c8a6a_9e6d6579","line":522,"in_reply_to":"c6e08040_89ccf165","updated":"2025-02-11 20:22:12.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":532,"context_line":"        stat_method \u003d self.statsd_metric_method(method)"},{"line_number":533,"context_line":""},{"line_number":534,"context_line":"        xfer_metric_name \u003d \u0027swift_proxy_request_body_input_bytes\u0027"},{"line_number":535,"context_line":"        xfer_labels \u003d statsd_metric_labels("},{"line_number":536,"context_line":"            req, stat_method, status_int\u003dNone,"},{"line_number":537,"context_line":"            acc\u003dacc, cont\u003dcont, policy_index\u003dNone, server_type\u003dserver_type)"},{"line_number":538,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"526d1e76_cf4be612","line":535,"updated":"2025-01-17 21:20:47.000000000","message":"since we don\u0027t use these xfer_labels later when call `get_buffer_xfer_emit_callback` for the `output_bytes` I think it might be more clear to name these `input_xfer_labels`\n\n... but I also sort of wonder when the labels calculated in `iter_response` are any different from the labels we\u0027ve calculated here?  Like can we get a complete/correct set of labels up-front in the request path or NOT?","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"2cf84e04dade1b637fc97428392dddc14d0eff30","unresolved":false,"context_lines":[{"line_number":532,"context_line":"        stat_method \u003d self.statsd_metric_method(method)"},{"line_number":533,"context_line":""},{"line_number":534,"context_line":"        xfer_metric_name \u003d \u0027swift_proxy_request_body_input_bytes\u0027"},{"line_number":535,"context_line":"        xfer_labels \u003d statsd_metric_labels("},{"line_number":536,"context_line":"            req, stat_method, status_int\u003dNone,"},{"line_number":537,"context_line":"            acc\u003dacc, cont\u003dcont, policy_index\u003dNone, server_type\u003dserver_type)"},{"line_number":538,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"685f447c_bbe9b26c","line":535,"in_reply_to":"526d1e76_cf4be612","updated":"2025-02-24 16:22:27.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":537,"context_line":"            acc\u003dacc, cont\u003dcont, policy_index\u003dNone, server_type\u003dserver_type)"},{"line_number":538,"context_line":""},{"line_number":539,"context_line":"        statsd_emit_callback \u003d self.get_buffer_xfer_emit_callback("},{"line_number":540,"context_line":"            req, xfer_metric_name, xfer_labels)"},{"line_number":541,"context_line":"        input_proxy \u003d InputProxy(env[\u0027wsgi.input\u0027], statsd_emit_callback)"},{"line_number":542,"context_line":"        env[\u0027wsgi.input\u0027] \u003d input_proxy"},{"line_number":543,"context_line":"        start_time \u003d time.time()"}],"source_content_type":"text/x-python","patch_set":13,"id":"acfcd1e9_c423fefa","line":540,"updated":"2025-01-17 21:20:47.000000000","message":"ok, there\u0027s an analogy to this call for *output_bytes* later in a closure in this *same method* - but it just uses a dict of labels called \"labels\" (because the labels are reused by other response related metrics.","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"2cf84e04dade1b637fc97428392dddc14d0eff30","unresolved":false,"context_lines":[{"line_number":537,"context_line":"            acc\u003dacc, cont\u003dcont, policy_index\u003dNone, server_type\u003dserver_type)"},{"line_number":538,"context_line":""},{"line_number":539,"context_line":"        statsd_emit_callback \u003d self.get_buffer_xfer_emit_callback("},{"line_number":540,"context_line":"            req, xfer_metric_name, xfer_labels)"},{"line_number":541,"context_line":"        input_proxy \u003d InputProxy(env[\u0027wsgi.input\u0027], statsd_emit_callback)"},{"line_number":542,"context_line":"        env[\u0027wsgi.input\u0027] \u003d input_proxy"},{"line_number":543,"context_line":"        start_time \u003d time.time()"}],"source_content_type":"text/x-python","patch_set":13,"id":"204cf4e1_a74e2e50","line":540,"in_reply_to":"acfcd1e9_c423fefa","updated":"2025-02-24 16:22:27.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":589,"context_line":"                metric_name \u003d statsd_metric_name("},{"line_number":590,"context_line":"                    req, wire_status_int, stat_method)"},{"line_number":591,"context_line":"                metric_name_policy \u003d statsd_metric_name_policy("},{"line_number":592,"context_line":"                    req, wire_status_int, stat_method, policy_index)"},{"line_number":593,"context_line":""},{"line_number":594,"context_line":"                ttfb \u003d time.time() - start_time"},{"line_number":595,"context_line":"                if metric_name:"}],"source_content_type":"text/x-python","patch_set":13,"id":"b4dadf52_080db184","line":592,"updated":"2025-01-17 21:20:47.000000000","message":"like one thing that jumps out as awkward about this new functional interface is that this change is introducing a new *conditional* call to `get_metric_name_type_from_aco` up above the definition of this closure; but then `statsd_metric_name` doesn\u0027t let you pass in `server_type` - it always/unconditionally extracts it using `get_metric_name_type` to again parse the path.\n\n```\nThere should be one-- and preferably only one --obvious way to do it.\n```\n\nIf the main idea of this refactor is:\n\n\u003e proxy-logging doesn\u0027t need to wait on the response/backend-path to figure out the server_type/metric_name anymore: we\u0027re going to teach it how to parse s3 paths so it can do that up-front on the way in.\n\nThen let\u0027s just *do that* in the most straight forward and obvious way possible and not ANY more cyclomatic complexity that absolutely necessary!","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"2cf84e04dade1b637fc97428392dddc14d0eff30","unresolved":false,"context_lines":[{"line_number":589,"context_line":"                metric_name \u003d statsd_metric_name("},{"line_number":590,"context_line":"                    req, wire_status_int, stat_method)"},{"line_number":591,"context_line":"                metric_name_policy \u003d statsd_metric_name_policy("},{"line_number":592,"context_line":"                    req, wire_status_int, stat_method, policy_index)"},{"line_number":593,"context_line":""},{"line_number":594,"context_line":"                ttfb \u003d time.time() - start_time"},{"line_number":595,"context_line":"                if metric_name:"}],"source_content_type":"text/x-python","patch_set":13,"id":"a3787499_4e54c86d","line":592,"in_reply_to":"b4dadf52_080db184","updated":"2025-02-24 16:22:27.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":603,"context_line":"                    \u0027swift_proxy_request_ttfb\u0027,"},{"line_number":604,"context_line":"                    ttfb * 1000,"},{"line_number":605,"context_line":"                    labels\u003dlabels,"},{"line_number":606,"context_line":"                )"},{"line_number":607,"context_line":""},{"line_number":608,"context_line":"            bytes_sent \u003d 0"},{"line_number":609,"context_line":"            xfer_labels \u003d labels"}],"source_content_type":"text/x-python","patch_set":13,"id":"b12555cb_f0d07c0e","line":606,"updated":"2025-01-17 21:20:47.000000000","message":"i hate closures - but especially 50 line long closures in the middle of 100 line long methods.\n\nAFAICT this is the end of iter_resp; the diff below here is back in the \"on the way in\" path.\n\noh... wait no - this is all still `iter_response`!","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"2cf84e04dade1b637fc97428392dddc14d0eff30","unresolved":false,"context_lines":[{"line_number":603,"context_line":"                    \u0027swift_proxy_request_ttfb\u0027,"},{"line_number":604,"context_line":"                    ttfb * 1000,"},{"line_number":605,"context_line":"                    labels\u003dlabels,"},{"line_number":606,"context_line":"                )"},{"line_number":607,"context_line":""},{"line_number":608,"context_line":"            bytes_sent \u003d 0"},{"line_number":609,"context_line":"            xfer_labels \u003d labels"}],"source_content_type":"text/x-python","patch_set":13,"id":"f098339c_32dfcbe0","line":606,"in_reply_to":"b12555cb_f0d07c0e","updated":"2025-02-24 16:22:27.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":608,"context_line":"            bytes_sent \u003d 0"},{"line_number":609,"context_line":"            xfer_labels \u003d labels"},{"line_number":610,"context_line":"            statsd_emit_callback \u003d self.get_buffer_xfer_emit_callback("},{"line_number":611,"context_line":"                req, \u0027swift_proxy_response_body_output_bytes\u0027, xfer_labels)"},{"line_number":612,"context_line":"            try:"},{"line_number":613,"context_line":"                for chunk in iterator:"},{"line_number":614,"context_line":"                    bytes_sent +\u003d len(chunk)"}],"source_content_type":"text/x-python","patch_set":13,"id":"45a164bb_cab573ba","line":611,"updated":"2025-01-17 21:20:47.000000000","message":"oic, this is *output* bytes - which we don\u0027t have to setup until we\u0027ve got the response.","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"2cf84e04dade1b637fc97428392dddc14d0eff30","unresolved":false,"context_lines":[{"line_number":608,"context_line":"            bytes_sent \u003d 0"},{"line_number":609,"context_line":"            xfer_labels \u003d labels"},{"line_number":610,"context_line":"            statsd_emit_callback \u003d self.get_buffer_xfer_emit_callback("},{"line_number":611,"context_line":"                req, \u0027swift_proxy_response_body_output_bytes\u0027, xfer_labels)"},{"line_number":612,"context_line":"            try:"},{"line_number":613,"context_line":"                for chunk in iterator:"},{"line_number":614,"context_line":"                    bytes_sent +\u003d len(chunk)"}],"source_content_type":"text/x-python","patch_set":13,"id":"e29424a7_c1244e09","line":611,"in_reply_to":"45a164bb_cab573ba","updated":"2025-02-24 16:22:27.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":637,"context_line":"            status_int \u003d status_int_for_logging()"},{"line_number":638,"context_line":"            self.log_request("},{"line_number":639,"context_line":"                req, status_int, input_proxy.bytes_received, 0, start_time,"},{"line_number":640,"context_line":"                time.time())"},{"line_number":641,"context_line":"            raise"},{"line_number":642,"context_line":"        else:"},{"line_number":643,"context_line":"            return iter_response(iterable)"}],"source_content_type":"text/x-python","patch_set":13,"id":"f3a2ba28_476d595d","line":640,"updated":"2025-01-17 21:20:47.000000000","message":"`log_request` *also* has to parse out `labels` including all the server_type/path parsing we\u0027ve already done twice in this method - should labels maybe instead just be an input to `log_request` or do we really want/expect it will come up with it\u0027s own/different/independent answers for labels sometimes?","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"2cf84e04dade1b637fc97428392dddc14d0eff30","unresolved":false,"context_lines":[{"line_number":637,"context_line":"            status_int \u003d status_int_for_logging()"},{"line_number":638,"context_line":"            self.log_request("},{"line_number":639,"context_line":"                req, status_int, input_proxy.bytes_received, 0, start_time,"},{"line_number":640,"context_line":"                time.time())"},{"line_number":641,"context_line":"            raise"},{"line_number":642,"context_line":"        else:"},{"line_number":643,"context_line":"            return iter_response(iterable)"}],"source_content_type":"text/x-python","patch_set":13,"id":"e4e5d2ef_5e2bc182","line":640,"in_reply_to":"f3a2ba28_476d595d","updated":"2025-02-24 16:22:27.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ebfa19cdafc981316881875fa2f92939b6d233d5","unresolved":true,"context_lines":[{"line_number":222,"context_line":"        if self.emit_buffer_xfer_bytes_sec \u003c 0:"},{"line_number":223,"context_line":"            return None"},{"line_number":224,"context_line":""},{"line_number":225,"context_line":"        if self.labels.get(\u0027account\u0027, None) is None:"},{"line_number":226,"context_line":"            path_parts \u003d self.req.environ.get(\u0027swift.path_parts\u0027)"},{"line_number":227,"context_line":"            try:"},{"line_number":228,"context_line":"                self.labels[\u0027account\u0027] \u003d path_parts[\u0027base_labels\u0027][\u0027account\u0027]"},{"line_number":229,"context_line":"            except Exception as e:"},{"line_number":230,"context_line":"                raise ValueError(\u0027Invalid path_parts in request environ: %s\u0027"},{"line_number":231,"context_line":"                                 % e)"},{"line_number":232,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"c4e9609e_91f18df3","line":229,"range":{"start_line":225,"start_character":8,"end_line":229,"end_character":0},"updated":"2025-02-26 16:28:18.000000000","message":"this is only necessary because self.labels is a copy of base_labels. We can just pass base_labels to BufferXferEmitCallback and then we don\u0027t need to update self.labels here, it is updated by rightmost ProxyLoggingMiddleware","commit_id":"0631f7a7db1413bbabc646fb2e56720a03596b5c"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"50c87e2d19199cf73e8821c5764a8fb6a635db4d","unresolved":false,"context_lines":[{"line_number":222,"context_line":"        if self.emit_buffer_xfer_bytes_sec \u003c 0:"},{"line_number":223,"context_line":"            return None"},{"line_number":224,"context_line":""},{"line_number":225,"context_line":"        if self.labels.get(\u0027account\u0027, None) is None:"},{"line_number":226,"context_line":"            path_parts \u003d self.req.environ.get(\u0027swift.path_parts\u0027)"},{"line_number":227,"context_line":"            try:"},{"line_number":228,"context_line":"                self.labels[\u0027account\u0027] \u003d path_parts[\u0027base_labels\u0027][\u0027account\u0027]"},{"line_number":229,"context_line":"            except Exception as e:"},{"line_number":230,"context_line":"                raise ValueError(\u0027Invalid path_parts in request environ: %s\u0027"},{"line_number":231,"context_line":"                                 % e)"},{"line_number":232,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"ec8cd8f0_d274013c","line":229,"range":{"start_line":225,"start_character":8,"end_line":229,"end_character":0},"in_reply_to":"c4e9609e_91f18df3","updated":"2025-02-28 16:18:39.000000000","message":"Acknowledged","commit_id":"0631f7a7db1413bbabc646fb2e56720a03596b5c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ebfa19cdafc981316881875fa2f92939b6d233d5","unresolved":true,"context_lines":[{"line_number":533,"context_line":"            self.statsd, self.emit_buffer_xfer_bytes_sec)"},{"line_number":534,"context_line":""},{"line_number":535,"context_line":"    def update_swift_path_parts(self, req):"},{"line_number":536,"context_line":"        swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"},{"line_number":537,"context_line":"        acc, cont, obj \u003d get_aco_from_path(swift_path)"},{"line_number":538,"context_line":"        path_parts \u003d req.environ.get(\u0027swift.path_parts\u0027)"},{"line_number":539,"context_line":"        if path_parts is None:"}],"source_content_type":"text/x-python","patch_set":16,"id":"19d1ec7e_f6ec58d7","line":536,"range":{"start_line":536,"start_character":37,"end_line":536,"end_character":58},"updated":"2025-02-26 16:28:18.000000000","message":"I thought we\u0027d agreed that ``swift.backend_path`` was not relevant?","commit_id":"0631f7a7db1413bbabc646fb2e56720a03596b5c"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"50c87e2d19199cf73e8821c5764a8fb6a635db4d","unresolved":false,"context_lines":[{"line_number":533,"context_line":"            self.statsd, self.emit_buffer_xfer_bytes_sec)"},{"line_number":534,"context_line":""},{"line_number":535,"context_line":"    def update_swift_path_parts(self, req):"},{"line_number":536,"context_line":"        swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"},{"line_number":537,"context_line":"        acc, cont, obj \u003d get_aco_from_path(swift_path)"},{"line_number":538,"context_line":"        path_parts \u003d req.environ.get(\u0027swift.path_parts\u0027)"},{"line_number":539,"context_line":"        if path_parts is None:"}],"source_content_type":"text/x-python","patch_set":16,"id":"4b6f0876_cfa4c5d1","line":536,"range":{"start_line":536,"start_character":37,"end_line":536,"end_character":58},"in_reply_to":"19d1ec7e_f6ec58d7","updated":"2025-02-28 16:18:39.000000000","message":"Indeed. Seems that some existing unit tests were using it","commit_id":"0631f7a7db1413bbabc646fb2e56720a03596b5c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ebfa19cdafc981316881875fa2f92939b6d233d5","unresolved":true,"context_lines":[{"line_number":551,"context_line":"            base_labels \u003d statsd_metric_base_labels("},{"line_number":552,"context_line":"                req, stat_method, server_type, acc, cont)"},{"line_number":553,"context_line":"            req.environ[\u0027swift.path_parts\u0027] \u003d {"},{"line_number":554,"context_line":"                \u0027object\u0027: obj,"},{"line_number":555,"context_line":"                \u0027base_labels\u0027: base_labels"},{"line_number":556,"context_line":"            }"},{"line_number":557,"context_line":"        elif path_parts[\u0027base_labels\u0027].get(\u0027account\u0027, None) is None:"}],"source_content_type":"text/x-python","patch_set":16,"id":"7531435e_ad299644","line":554,"range":{"start_line":554,"start_character":16,"end_line":554,"end_character":30},"updated":"2025-02-26 16:28:18.000000000","message":"I think I understand why you\u0027ve broken out object and base_labels: we don\u0027t want object to be a label by default, but it might prove useful to have it stashed in the req environ.\n\nI think I\u0027d prefer a different workaround though that allows us to maintain a simple dict of \u0027useful stuff\u0027 in the req environ, with very l;ittle implied structure, and pick from it as required for stats (or in the future, logs too):\n\nPut all the items in a dict \u0027swift.base_labels\u0027 in req.environ, then use a list of keys whenever labels are being applied to stats:\n\n```\nextra_labels \u003d {\u0027status\u0027: resp.status_int}  # only necessary in outbound case\nlabels_source \u003d ChainMap(extra_labels, req.environ.get(\u0027swift.base_labels\u0027, {}))\nif \u0027account\u0027 in labels_source:\n    label_keys \u003d (\u0027account\u0027, \u0027container\u0027, \u0027method\u0027, etc)\n    labels \u003d {k: labels_source[k] if k in labels_source\n              for k in label_keys}\n    # emit stat with labels\nelse:\n    # tolerate no account, maybe it\u0027ll be there in time for next stat\n    pass\n```","commit_id":"0631f7a7db1413bbabc646fb2e56720a03596b5c"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"50c87e2d19199cf73e8821c5764a8fb6a635db4d","unresolved":false,"context_lines":[{"line_number":551,"context_line":"            base_labels \u003d statsd_metric_base_labels("},{"line_number":552,"context_line":"                req, stat_method, server_type, acc, cont)"},{"line_number":553,"context_line":"            req.environ[\u0027swift.path_parts\u0027] \u003d {"},{"line_number":554,"context_line":"                \u0027object\u0027: obj,"},{"line_number":555,"context_line":"                \u0027base_labels\u0027: base_labels"},{"line_number":556,"context_line":"            }"},{"line_number":557,"context_line":"        elif path_parts[\u0027base_labels\u0027].get(\u0027account\u0027, None) is None:"}],"source_content_type":"text/x-python","patch_set":16,"id":"19718ecf_13b15695","line":554,"range":{"start_line":554,"start_character":16,"end_line":554,"end_character":30},"in_reply_to":"7531435e_ad299644","updated":"2025-02-28 16:18:39.000000000","message":"Acknowledged","commit_id":"0631f7a7db1413bbabc646fb2e56720a03596b5c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ebfa19cdafc981316881875fa2f92939b6d233d5","unresolved":true,"context_lines":[{"line_number":552,"context_line":"                req, stat_method, server_type, acc, cont)"},{"line_number":553,"context_line":"            req.environ[\u0027swift.path_parts\u0027] \u003d {"},{"line_number":554,"context_line":"                \u0027object\u0027: obj,"},{"line_number":555,"context_line":"                \u0027base_labels\u0027: base_labels"},{"line_number":556,"context_line":"            }"},{"line_number":557,"context_line":"        elif path_parts[\u0027base_labels\u0027].get(\u0027account\u0027, None) is None:"},{"line_number":558,"context_line":"            # expected in the right-most proxy_logging instance"}],"source_content_type":"text/x-python","patch_set":16,"id":"24f7fbe8_25f045f4","line":555,"range":{"start_line":555,"start_character":16,"end_line":555,"end_character":29},"updated":"2025-02-26 16:28:18.000000000","message":"the naming seems odd here\" i.e. \u0027path_parts\u0027 has a field \u0027base_labels\u0027 and has a lot more than path parts now","commit_id":"0631f7a7db1413bbabc646fb2e56720a03596b5c"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"50c87e2d19199cf73e8821c5764a8fb6a635db4d","unresolved":false,"context_lines":[{"line_number":552,"context_line":"                req, stat_method, server_type, acc, cont)"},{"line_number":553,"context_line":"            req.environ[\u0027swift.path_parts\u0027] \u003d {"},{"line_number":554,"context_line":"                \u0027object\u0027: obj,"},{"line_number":555,"context_line":"                \u0027base_labels\u0027: base_labels"},{"line_number":556,"context_line":"            }"},{"line_number":557,"context_line":"        elif path_parts[\u0027base_labels\u0027].get(\u0027account\u0027, None) is None:"},{"line_number":558,"context_line":"            # expected in the right-most proxy_logging instance"}],"source_content_type":"text/x-python","patch_set":16,"id":"6120221a_9cdb25bd","line":555,"range":{"start_line":555,"start_character":16,"end_line":555,"end_character":29},"in_reply_to":"24f7fbe8_25f045f4","updated":"2025-02-28 16:18:39.000000000","message":"Acknowledged","commit_id":"0631f7a7db1413bbabc646fb2e56720a03596b5c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ebfa19cdafc981316881875fa2f92939b6d233d5","unresolved":true,"context_lines":[{"line_number":573,"context_line":""},{"line_number":574,"context_line":"        xfer_metric_name \u003d \u0027swift_proxy_request_body_input_bytes\u0027"},{"line_number":575,"context_line":"        path_parts \u003d req.environ.get(\u0027swift.path_parts\u0027)"},{"line_number":576,"context_line":"        xfer_labels \u003d dict(path_parts[\u0027base_labels\u0027])"},{"line_number":577,"context_line":""},{"line_number":578,"context_line":"        statsd_emit_callback \u003d self.get_buffer_xfer_emit_callback("},{"line_number":579,"context_line":"            req, xfer_metric_name, xfer_labels)"}],"source_content_type":"text/x-python","patch_set":16,"id":"e67129ce_b52bfa25","line":576,"range":{"start_line":576,"start_character":22,"end_line":576,"end_character":26},"updated":"2025-02-26 16:28:18.000000000","message":"copying to another dict breaks the implicit sharing of the ``base_labels`` as they are updated with account","commit_id":"0631f7a7db1413bbabc646fb2e56720a03596b5c"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"50c87e2d19199cf73e8821c5764a8fb6a635db4d","unresolved":false,"context_lines":[{"line_number":573,"context_line":""},{"line_number":574,"context_line":"        xfer_metric_name \u003d \u0027swift_proxy_request_body_input_bytes\u0027"},{"line_number":575,"context_line":"        path_parts \u003d req.environ.get(\u0027swift.path_parts\u0027)"},{"line_number":576,"context_line":"        xfer_labels \u003d dict(path_parts[\u0027base_labels\u0027])"},{"line_number":577,"context_line":""},{"line_number":578,"context_line":"        statsd_emit_callback \u003d self.get_buffer_xfer_emit_callback("},{"line_number":579,"context_line":"            req, xfer_metric_name, xfer_labels)"}],"source_content_type":"text/x-python","patch_set":16,"id":"9422cd1b_341e5710","line":576,"range":{"start_line":576,"start_character":22,"end_line":576,"end_character":26},"in_reply_to":"e67129ce_b52bfa25","updated":"2025-02-28 16:18:39.000000000","message":"Acknowledged","commit_id":"0631f7a7db1413bbabc646fb2e56720a03596b5c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ebfa19cdafc981316881875fa2f92939b6d233d5","unresolved":true,"context_lines":[{"line_number":616,"context_line":""},{"line_number":617,"context_line":"            policy_index \u003d get_policy_index(req.headers, resp_headers)"},{"line_number":618,"context_line":"            path_parts \u003d req.environ.get(\u0027swift.path_parts\u0027)"},{"line_number":619,"context_line":"            labels \u003d path_parts[\u0027base_labels\u0027]"},{"line_number":620,"context_line":"            labels \u003d statsd_metric_resp_labels("},{"line_number":621,"context_line":"                labels, status_int\u003dwire_status_int, policy_index\u003dpolicy_index)"},{"line_number":622,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"8ae17bb8_feee506f","line":619,"updated":"2025-02-26 16:28:18.000000000","message":"in some cases this might change the container label (if swift.backend_path !\u003d the first path that is parsed by update_swift_path_parts)\n\nI think we should restrict the scope of this patch to only add new metrics and then worry about making all the metrics labels consistent in another patch. Small steps forward, particularly while we\u0027re working out the \"architecture\".","commit_id":"0631f7a7db1413bbabc646fb2e56720a03596b5c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c18d9096100c33d4b60c2528df7faba203435a4f","unresolved":true,"context_lines":[{"line_number":616,"context_line":""},{"line_number":617,"context_line":"            policy_index \u003d get_policy_index(req.headers, resp_headers)"},{"line_number":618,"context_line":"            path_parts \u003d req.environ.get(\u0027swift.path_parts\u0027)"},{"line_number":619,"context_line":"            labels \u003d path_parts[\u0027base_labels\u0027]"},{"line_number":620,"context_line":"            labels \u003d statsd_metric_resp_labels("},{"line_number":621,"context_line":"                labels, status_int\u003dwire_status_int, policy_index\u003dpolicy_index)"},{"line_number":622,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"d1ebd82f_9f7af62c","line":619,"in_reply_to":"3238b206_bd2cf7a6","updated":"2025-03-06 18:38:33.000000000","message":"reopening this comment: I suggest this patch should *only* add the new bytes xfer metrics and not touch the existing metrics.","commit_id":"0631f7a7db1413bbabc646fb2e56720a03596b5c"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"50c87e2d19199cf73e8821c5764a8fb6a635db4d","unresolved":false,"context_lines":[{"line_number":616,"context_line":""},{"line_number":617,"context_line":"            policy_index \u003d get_policy_index(req.headers, resp_headers)"},{"line_number":618,"context_line":"            path_parts \u003d req.environ.get(\u0027swift.path_parts\u0027)"},{"line_number":619,"context_line":"            labels \u003d path_parts[\u0027base_labels\u0027]"},{"line_number":620,"context_line":"            labels \u003d statsd_metric_resp_labels("},{"line_number":621,"context_line":"                labels, status_int\u003dwire_status_int, policy_index\u003dpolicy_index)"},{"line_number":622,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"3238b206_bd2cf7a6","line":619,"in_reply_to":"8ae17bb8_feee506f","updated":"2025-02-28 16:18:39.000000000","message":"Acknowledged","commit_id":"0631f7a7db1413bbabc646fb2e56720a03596b5c"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"7ba6da5e7244c7ac095d73a88b59c340feb284e1","unresolved":false,"context_lines":[{"line_number":616,"context_line":""},{"line_number":617,"context_line":"            policy_index \u003d get_policy_index(req.headers, resp_headers)"},{"line_number":618,"context_line":"            path_parts \u003d req.environ.get(\u0027swift.path_parts\u0027)"},{"line_number":619,"context_line":"            labels \u003d path_parts[\u0027base_labels\u0027]"},{"line_number":620,"context_line":"            labels \u003d statsd_metric_resp_labels("},{"line_number":621,"context_line":"                labels, status_int\u003dwire_status_int, policy_index\u003dpolicy_index)"},{"line_number":622,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"c81ff4b4_1b927961","line":619,"in_reply_to":"d1ebd82f_9f7af62c","updated":"2025-03-10 15:23:19.000000000","message":"Good point, reverting the changes","commit_id":"0631f7a7db1413bbabc646fb2e56720a03596b5c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c18d9096100c33d4b60c2528df7faba203435a4f","unresolved":true,"context_lines":[{"line_number":214,"context_line":"    def __init__(self, req, stat_method, metric_name,"},{"line_number":215,"context_line":"                 labels, statsd,"},{"line_number":216,"context_line":"                 emit_buffer_xfer_bytes_sec):"},{"line_number":217,"context_line":"        self.req \u003d req"},{"line_number":218,"context_line":"        self.stat_method \u003d stat_method"},{"line_number":219,"context_line":"        self.metric_name \u003d metric_name"},{"line_number":220,"context_line":"        self.labels_source \u003d labels"}],"source_content_type":"text/x-python","patch_set":18,"id":"0f02cf1e_a2e26a28","line":217,"updated":"2025-03-06 18:38:33.000000000","message":"this doesn\u0027t appear to be used anymore","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"7ba6da5e7244c7ac095d73a88b59c340feb284e1","unresolved":false,"context_lines":[{"line_number":214,"context_line":"    def __init__(self, req, stat_method, metric_name,"},{"line_number":215,"context_line":"                 labels, statsd,"},{"line_number":216,"context_line":"                 emit_buffer_xfer_bytes_sec):"},{"line_number":217,"context_line":"        self.req \u003d req"},{"line_number":218,"context_line":"        self.stat_method \u003d stat_method"},{"line_number":219,"context_line":"        self.metric_name \u003d metric_name"},{"line_number":220,"context_line":"        self.labels_source \u003d labels"}],"source_content_type":"text/x-python","patch_set":18,"id":"7344b4b0_00f8ffc8","line":217,"in_reply_to":"0f02cf1e_a2e26a28","updated":"2025-03-10 15:23:19.000000000","message":"Acknowledged","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c18d9096100c33d4b60c2528df7faba203435a4f","unresolved":true,"context_lines":[{"line_number":215,"context_line":"                 labels, statsd,"},{"line_number":216,"context_line":"                 emit_buffer_xfer_bytes_sec):"},{"line_number":217,"context_line":"        self.req \u003d req"},{"line_number":218,"context_line":"        self.stat_method \u003d stat_method"},{"line_number":219,"context_line":"        self.metric_name \u003d metric_name"},{"line_number":220,"context_line":"        self.labels_source \u003d labels"},{"line_number":221,"context_line":"        self.statsd \u003d statsd"}],"source_content_type":"text/x-python","patch_set":18,"id":"42f96b4e_ceca1508","line":218,"range":{"start_line":218,"start_character":8,"end_line":218,"end_character":38},"updated":"2025-03-06 18:38:33.000000000","message":"this doesn\u0027t appear to be used anymore","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"7ba6da5e7244c7ac095d73a88b59c340feb284e1","unresolved":false,"context_lines":[{"line_number":215,"context_line":"                 labels, statsd,"},{"line_number":216,"context_line":"                 emit_buffer_xfer_bytes_sec):"},{"line_number":217,"context_line":"        self.req \u003d req"},{"line_number":218,"context_line":"        self.stat_method \u003d stat_method"},{"line_number":219,"context_line":"        self.metric_name \u003d metric_name"},{"line_number":220,"context_line":"        self.labels_source \u003d labels"},{"line_number":221,"context_line":"        self.statsd \u003d statsd"}],"source_content_type":"text/x-python","patch_set":18,"id":"b787247b_75d3f0b5","line":218,"range":{"start_line":218,"start_character":8,"end_line":218,"end_character":38},"in_reply_to":"42f96b4e_ceca1508","updated":"2025-03-10 15:23:19.000000000","message":"Acknowledged","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c18d9096100c33d4b60c2528df7faba203435a4f","unresolved":true,"context_lines":[{"line_number":225,"context_line":""},{"line_number":226,"context_line":"    def __call__(self, buffer_len):"},{"line_number":227,"context_line":"        if self.emit_buffer_xfer_bytes_sec \u003c 0:"},{"line_number":228,"context_line":"            return None"},{"line_number":229,"context_line":""},{"line_number":230,"context_line":"        self.emit_bytes +\u003d buffer_len"},{"line_number":231,"context_line":"        now \u003d time.time()"}],"source_content_type":"text/x-python","patch_set":18,"id":"1c686504_d01ce590","line":228,"updated":"2025-03-06 18:38:33.000000000","message":"I think it could be clearer to have all the early return conditions up front:\n\nno account in labels_source? return\nnot time yet? return\n\nthen you\u0027re just left with \n\n```\nlabels \u003d {k: self.labels_source[k] for k in LABEL_KEYS\n                      if k in self.labels_source}\nself.statsd.update_stats(\n                self.metric_name,\n                self.emit_bytes,\n                labels\u003dlabels,\n            )\nself.emit_bytes \u003d 0\nself.next_emit_time \u003d (now + self.emit_buffer_xfer_bytes_sec)\n```","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"7ba6da5e7244c7ac095d73a88b59c340feb284e1","unresolved":false,"context_lines":[{"line_number":225,"context_line":""},{"line_number":226,"context_line":"    def __call__(self, buffer_len):"},{"line_number":227,"context_line":"        if self.emit_buffer_xfer_bytes_sec \u003c 0:"},{"line_number":228,"context_line":"            return None"},{"line_number":229,"context_line":""},{"line_number":230,"context_line":"        self.emit_bytes +\u003d buffer_len"},{"line_number":231,"context_line":"        now \u003d time.time()"}],"source_content_type":"text/x-python","patch_set":18,"id":"86deff22_790a5645","line":228,"in_reply_to":"1c686504_d01ce590","updated":"2025-03-10 15:23:19.000000000","message":"Acknowledged","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c18d9096100c33d4b60c2528df7faba203435a4f","unresolved":true,"context_lines":[{"line_number":231,"context_line":"        now \u003d time.time()"},{"line_number":232,"context_line":"        labels \u003d {}"},{"line_number":233,"context_line":"        if self.labels_source.get(\u0027account\u0027, None):"},{"line_number":234,"context_line":"            labels \u003d {k: self.labels_source[k] for k in LABEL_KEYS"},{"line_number":235,"context_line":"                      if k in self.labels_source}"},{"line_number":236,"context_line":"        else:"},{"line_number":237,"context_line":"            # tolerate no account, maybe it\u0027ll be there in time for next stat"},{"line_number":238,"context_line":"            pass"}],"source_content_type":"text/x-python","patch_set":18,"id":"91ecd388_e89a32f9","line":235,"range":{"start_line":234,"start_character":12,"end_line":235,"end_character":49},"updated":"2025-03-06 18:38:33.000000000","message":"labels shouldn\u0027t change from one stat to the next, so small optimisation would be to have self.labels, update it once when account is available and then re-use on every ``__call__``","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"7ba6da5e7244c7ac095d73a88b59c340feb284e1","unresolved":false,"context_lines":[{"line_number":231,"context_line":"        now \u003d time.time()"},{"line_number":232,"context_line":"        labels \u003d {}"},{"line_number":233,"context_line":"        if self.labels_source.get(\u0027account\u0027, None):"},{"line_number":234,"context_line":"            labels \u003d {k: self.labels_source[k] for k in LABEL_KEYS"},{"line_number":235,"context_line":"                      if k in self.labels_source}"},{"line_number":236,"context_line":"        else:"},{"line_number":237,"context_line":"            # tolerate no account, maybe it\u0027ll be there in time for next stat"},{"line_number":238,"context_line":"            pass"}],"source_content_type":"text/x-python","patch_set":18,"id":"e5320d3e_389ea0c8","line":235,"range":{"start_line":234,"start_character":12,"end_line":235,"end_character":49},"in_reply_to":"91ecd388_e89a32f9","updated":"2025-03-10 15:23:19.000000000","message":"Acknowledged","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c18d9096100c33d4b60c2528df7faba203435a4f","unresolved":true,"context_lines":[{"line_number":531,"context_line":"    def get_buffer_xfer_emit_callback(self, req, metric_name,"},{"line_number":532,"context_line":"                                      labels):"},{"line_number":533,"context_line":"        method \u003d method_from_req(req)"},{"line_number":534,"context_line":"        stat_method \u003d self.statsd_metric_method(method)"},{"line_number":535,"context_line":"        return BufferXferEmitCallback("},{"line_number":536,"context_line":"            req, stat_method, metric_name, labels,"},{"line_number":537,"context_line":"            self.statsd, self.emit_buffer_xfer_bytes_sec)"}],"source_content_type":"text/x-python","patch_set":18,"id":"5aab7174_95b78b17","line":534,"updated":"2025-03-06 18:38:33.000000000","message":"given that stat_method is no longer needed in ``BufferXferEmitCallback``, this method becomes redundant and we can just construct a ``BufferXferEmitCallback`` in the two places that this method is called.","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"7ba6da5e7244c7ac095d73a88b59c340feb284e1","unresolved":false,"context_lines":[{"line_number":531,"context_line":"    def get_buffer_xfer_emit_callback(self, req, metric_name,"},{"line_number":532,"context_line":"                                      labels):"},{"line_number":533,"context_line":"        method \u003d method_from_req(req)"},{"line_number":534,"context_line":"        stat_method \u003d self.statsd_metric_method(method)"},{"line_number":535,"context_line":"        return BufferXferEmitCallback("},{"line_number":536,"context_line":"            req, stat_method, metric_name, labels,"},{"line_number":537,"context_line":"            self.statsd, self.emit_buffer_xfer_bytes_sec)"}],"source_content_type":"text/x-python","patch_set":18,"id":"ae4b6366_52b654f9","line":534,"in_reply_to":"5aab7174_95b78b17","updated":"2025-03-10 15:23:19.000000000","message":"Acknowledged","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c18d9096100c33d4b60c2528df7faba203435a4f","unresolved":true,"context_lines":[{"line_number":549,"context_line":"            stat_method \u003d self.statsd_metric_method(method)"},{"line_number":550,"context_line":"            server_type \u003d get_metric_name_type_from_aco("},{"line_number":551,"context_line":"                req, acc, cont, obj)"},{"line_number":552,"context_line":"            base_labels \u003d statsd_metric_base_labels("},{"line_number":553,"context_line":"                req, stat_method, server_type, acc, cont)"},{"line_number":554,"context_line":"            if obj:"},{"line_number":555,"context_line":"                base_labels[\u0027object\u0027] \u003d obj"}],"source_content_type":"text/x-python","patch_set":18,"id":"88a67ee1_ecd93c8f","line":552,"range":{"start_line":552,"start_character":26,"end_line":552,"end_character":51},"updated":"2025-03-06 18:38:33.000000000","message":"this seems to be the only place we call this function...I\u0027m not sure it\u0027s necessary to break out the code to another function","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"7ba6da5e7244c7ac095d73a88b59c340feb284e1","unresolved":false,"context_lines":[{"line_number":549,"context_line":"            stat_method \u003d self.statsd_metric_method(method)"},{"line_number":550,"context_line":"            server_type \u003d get_metric_name_type_from_aco("},{"line_number":551,"context_line":"                req, acc, cont, obj)"},{"line_number":552,"context_line":"            base_labels \u003d statsd_metric_base_labels("},{"line_number":553,"context_line":"                req, stat_method, server_type, acc, cont)"},{"line_number":554,"context_line":"            if obj:"},{"line_number":555,"context_line":"                base_labels[\u0027object\u0027] \u003d obj"}],"source_content_type":"text/x-python","patch_set":18,"id":"ea6f7f2d_53de9478","line":552,"range":{"start_line":552,"start_character":26,"end_line":552,"end_character":51},"in_reply_to":"88a67ee1_ecd93c8f","updated":"2025-03-10 15:23:19.000000000","message":"Acknowledged","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c18d9096100c33d4b60c2528df7faba203435a4f","unresolved":true,"context_lines":[{"line_number":553,"context_line":"                req, stat_method, server_type, acc, cont)"},{"line_number":554,"context_line":"            if obj:"},{"line_number":555,"context_line":"                base_labels[\u0027object\u0027] \u003d obj"},{"line_number":556,"context_line":"            req.environ[\u0027swift.path_parts\u0027] \u003d base_labels"},{"line_number":557,"context_line":"        elif path_parts.get(\u0027account\u0027, None) is None:"},{"line_number":558,"context_line":"            # expected in the right-most proxy_logging instance"},{"line_number":559,"context_line":"            path_parts[\u0027account\u0027] \u003d acc"}],"source_content_type":"text/x-python","patch_set":18,"id":"5c21eeb3_31543823","line":556,"updated":"2025-03-06 18:38:33.000000000","message":"I\u0027m still thinking this would be better named ``swift.base_labels``  now that its scope has increased, but maybe that can happen when we shake out which pieces of code need to be ported back to the parent patch","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"7ba6da5e7244c7ac095d73a88b59c340feb284e1","unresolved":false,"context_lines":[{"line_number":553,"context_line":"                req, stat_method, server_type, acc, cont)"},{"line_number":554,"context_line":"            if obj:"},{"line_number":555,"context_line":"                base_labels[\u0027object\u0027] \u003d obj"},{"line_number":556,"context_line":"            req.environ[\u0027swift.path_parts\u0027] \u003d base_labels"},{"line_number":557,"context_line":"        elif path_parts.get(\u0027account\u0027, None) is None:"},{"line_number":558,"context_line":"            # expected in the right-most proxy_logging instance"},{"line_number":559,"context_line":"            path_parts[\u0027account\u0027] \u003d acc"}],"source_content_type":"text/x-python","patch_set":18,"id":"cae4411c_8306a38c","line":556,"in_reply_to":"5c21eeb3_31543823","updated":"2025-03-10 15:23:19.000000000","message":"Acknowledged","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c18d9096100c33d4b60c2528df7faba203435a4f","unresolved":true,"context_lines":[{"line_number":572,"context_line":"        method \u003d method_from_req(req)"},{"line_number":573,"context_line":""},{"line_number":574,"context_line":"        xfer_metric_name \u003d \u0027swift_proxy_request_body_input_bytes\u0027"},{"line_number":575,"context_line":"        xfer_labels \u003d req.environ.get(\u0027swift.path_parts\u0027)"},{"line_number":576,"context_line":""},{"line_number":577,"context_line":"        statsd_emit_callback \u003d self.get_buffer_xfer_emit_callback("},{"line_number":578,"context_line":"            req, xfer_metric_name, xfer_labels)"}],"source_content_type":"text/x-python","patch_set":18,"id":"e60d579e_911379ec","line":575,"range":{"start_line":575,"start_character":8,"end_line":575,"end_character":19},"updated":"2025-03-06 18:38:33.000000000","message":"please use consistent naming of vars through the execution path: ``xfer_labels`` becomes ``labels`` in ``get_buffer_xfer_emit_callback`` which becomes ``labels_source`` in ``BufferXferEmitCallback``. IMHO ``labels_source`` is the most accurate description.","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"7ba6da5e7244c7ac095d73a88b59c340feb284e1","unresolved":false,"context_lines":[{"line_number":572,"context_line":"        method \u003d method_from_req(req)"},{"line_number":573,"context_line":""},{"line_number":574,"context_line":"        xfer_metric_name \u003d \u0027swift_proxy_request_body_input_bytes\u0027"},{"line_number":575,"context_line":"        xfer_labels \u003d req.environ.get(\u0027swift.path_parts\u0027)"},{"line_number":576,"context_line":""},{"line_number":577,"context_line":"        statsd_emit_callback \u003d self.get_buffer_xfer_emit_callback("},{"line_number":578,"context_line":"            req, xfer_metric_name, xfer_labels)"}],"source_content_type":"text/x-python","patch_set":18,"id":"123ca91a_3d94b1a5","line":575,"range":{"start_line":575,"start_character":8,"end_line":575,"end_character":19},"in_reply_to":"e60d579e_911379ec","updated":"2025-03-10 15:23:19.000000000","message":"Acknowledged","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c18d9096100c33d4b60c2528df7faba203435a4f","unresolved":true,"context_lines":[{"line_number":619,"context_line":"                labels_source, status_int\u003dwire_status_int,"},{"line_number":620,"context_line":"                policy_index\u003dpolicy_index)"},{"line_number":621,"context_line":"            labels \u003d {k: labels_source[k] for k in LABEL_KEYS"},{"line_number":622,"context_line":"                      if k in labels_source}"},{"line_number":623,"context_line":""},{"line_number":624,"context_line":"            # Log timing information for time-to-first-byte (GET requests only)"},{"line_number":625,"context_line":"            ttfb \u003d 0.0"}],"source_content_type":"text/x-python","patch_set":18,"id":"501a094e_64d1e18e","line":622,"updated":"2025-03-06 18:38:33.000000000","message":"I think these changes are facilitating the existing metrics using the same labels source...but I\u0027m advocating that we don\u0027t go that far in this patch","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"7ba6da5e7244c7ac095d73a88b59c340feb284e1","unresolved":false,"context_lines":[{"line_number":619,"context_line":"                labels_source, status_int\u003dwire_status_int,"},{"line_number":620,"context_line":"                policy_index\u003dpolicy_index)"},{"line_number":621,"context_line":"            labels \u003d {k: labels_source[k] for k in LABEL_KEYS"},{"line_number":622,"context_line":"                      if k in labels_source}"},{"line_number":623,"context_line":""},{"line_number":624,"context_line":"            # Log timing information for time-to-first-byte (GET requests only)"},{"line_number":625,"context_line":"            ttfb \u003d 0.0"}],"source_content_type":"text/x-python","patch_set":18,"id":"9987bd74_7796ff80","line":622,"in_reply_to":"501a094e_64d1e18e","updated":"2025-03-10 15:23:19.000000000","message":"Acknowledged","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c18d9096100c33d4b60c2528df7faba203435a4f","unresolved":true,"context_lines":[{"line_number":628,"context_line":"                metric_name \u003d _statsd_metric_name("},{"line_number":629,"context_line":"                    req, wire_status_int, stat_method)"},{"line_number":630,"context_line":"                metric_name_policy \u003d _statsd_metric_name_policy("},{"line_number":631,"context_line":"                    req, wire_status_int, stat_method, policy_index)"},{"line_number":632,"context_line":""},{"line_number":633,"context_line":"                ttfb \u003d time.time() - start_time"},{"line_number":634,"context_line":"                if metric_name:"}],"source_content_type":"text/x-python","patch_set":18,"id":"dfd40b6c_8c98ffe8","line":631,"updated":"2025-03-06 18:38:33.000000000","message":"ditto...let\u0027s not do this in this patch","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"7ba6da5e7244c7ac095d73a88b59c340feb284e1","unresolved":false,"context_lines":[{"line_number":628,"context_line":"                metric_name \u003d _statsd_metric_name("},{"line_number":629,"context_line":"                    req, wire_status_int, stat_method)"},{"line_number":630,"context_line":"                metric_name_policy \u003d _statsd_metric_name_policy("},{"line_number":631,"context_line":"                    req, wire_status_int, stat_method, policy_index)"},{"line_number":632,"context_line":""},{"line_number":633,"context_line":"                ttfb \u003d time.time() - start_time"},{"line_number":634,"context_line":"                if metric_name:"}],"source_content_type":"text/x-python","patch_set":18,"id":"b1bacc85_fa826b69","line":631,"in_reply_to":"dfd40b6c_8c98ffe8","updated":"2025-03-10 15:23:19.000000000","message":"Acknowledged","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c18d9096100c33d4b60c2528df7faba203435a4f","unresolved":true,"context_lines":[{"line_number":646,"context_line":""},{"line_number":647,"context_line":"            bytes_sent \u003d 0"},{"line_number":648,"context_line":"            statsd_emit_callback \u003d self.get_buffer_xfer_emit_callback("},{"line_number":649,"context_line":"                req, \u0027swift_proxy_response_body_output_bytes\u0027, labels)"},{"line_number":650,"context_line":"            try:"},{"line_number":651,"context_line":"                for chunk in iterator:"},{"line_number":652,"context_line":"                    bytes_sent +\u003d len(chunk)"}],"source_content_type":"text/x-python","patch_set":18,"id":"003b17b8_1c895b0c","line":649,"range":{"start_line":649,"start_character":63,"end_line":649,"end_character":69},"updated":"2025-03-06 18:38:33.000000000","message":"so this is passing in ``labels`` rather than labels_source, which works because ``labels`` is a subset of ``labels_source``, but it\u0027s confusing!\n\nI understand that ``labels`` has been selected from ``labels_source`` at line 621 so it can be used for other metrics, but I feel we should restrict scope of this patch, so for the time being at least just pass ``labels_source`` to the ``BufferXferEmitCallback`` and have it do the selection of labels.","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"7ba6da5e7244c7ac095d73a88b59c340feb284e1","unresolved":false,"context_lines":[{"line_number":646,"context_line":""},{"line_number":647,"context_line":"            bytes_sent \u003d 0"},{"line_number":648,"context_line":"            statsd_emit_callback \u003d self.get_buffer_xfer_emit_callback("},{"line_number":649,"context_line":"                req, \u0027swift_proxy_response_body_output_bytes\u0027, labels)"},{"line_number":650,"context_line":"            try:"},{"line_number":651,"context_line":"                for chunk in iterator:"},{"line_number":652,"context_line":"                    bytes_sent +\u003d len(chunk)"}],"source_content_type":"text/x-python","patch_set":18,"id":"6df3a96b_d2553c27","line":649,"range":{"start_line":649,"start_character":63,"end_line":649,"end_character":69},"in_reply_to":"003b17b8_1c895b0c","updated":"2025-03-10 15:23:19.000000000","message":"Acknowledged","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c08213424b4cec83182a67366e68896d4f5a67cf","unresolved":true,"context_lines":[{"line_number":231,"context_line":"        now \u003d time.time()"},{"line_number":232,"context_line":"        labels \u003d {}"},{"line_number":233,"context_line":"        if self.labels_source.get(\u0027account\u0027, None):"},{"line_number":234,"context_line":"            labels \u003d {k: self.labels_source[k] for k in LABEL_KEYS"},{"line_number":235,"context_line":"                      if k in self.labels_source}"},{"line_number":236,"context_line":"        else:"},{"line_number":237,"context_line":"            # tolerate no account, maybe it\u0027ll be there in time for next stat"}],"source_content_type":"text/x-python","patch_set":19,"id":"9458ec30_1821d74d","line":234,"range":{"start_line":234,"start_character":12,"end_line":234,"end_character":66},"updated":"2025-03-07 12:39:36.000000000","message":"I felt frustrated that we had to have this subset construction happening here, so I had a go at providing a helper map that could be passed to BufferXferEmitCallback and would automagically provide a view of only the LABEL_KEYS \nhttps://review.opendev.org/c/openstack/swift/+/943676\n\nWhat do you think?","commit_id":"a5565e3eeae8ee9fd424f63e52b32587a0efd322"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"7ba6da5e7244c7ac095d73a88b59c340feb284e1","unresolved":false,"context_lines":[{"line_number":231,"context_line":"        now \u003d time.time()"},{"line_number":232,"context_line":"        labels \u003d {}"},{"line_number":233,"context_line":"        if self.labels_source.get(\u0027account\u0027, None):"},{"line_number":234,"context_line":"            labels \u003d {k: self.labels_source[k] for k in LABEL_KEYS"},{"line_number":235,"context_line":"                      if k in self.labels_source}"},{"line_number":236,"context_line":"        else:"},{"line_number":237,"context_line":"            # tolerate no account, maybe it\u0027ll be there in time for next stat"}],"source_content_type":"text/x-python","patch_set":19,"id":"6b8a1f61_ba10e746","line":234,"range":{"start_line":234,"start_character":12,"end_line":234,"end_character":66},"in_reply_to":"9458ec30_1821d74d","updated":"2025-03-10 15:23:19.000000000","message":"Squashed the patch, thanks Al!","commit_id":"a5565e3eeae8ee9fd424f63e52b32587a0efd322"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":397,"context_line":"        return req.environ.get(\u0027swift.source\u0027) or \u0027UNKNOWN\u0027"},{"line_number":398,"context_line":""},{"line_number":399,"context_line":"    def statsd_metric_method(self, method):"},{"line_number":400,"context_line":"        return method if method in self.valid_methods else \u0027BAD_METHOD\u0027"},{"line_number":401,"context_line":""},{"line_number":402,"context_line":"    def statsd_metric_name(self, req, status_int, metric_method):"},{"line_number":403,"context_line":"        stat_type \u003d self.get_metric_name_type(req)"}],"source_content_type":"text/x-python","patch_set":38,"id":"2d5dcc7f_7b6a2e3e","side":"PARENT","line":400,"updated":"2025-05-19 15:40:26.000000000","message":"this didn\u0027t need to change","commit_id":"46b31ab3172a8c4c1a28545172157f4f46a38023"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"e4e0a6fc9d7d441739e81faaadc47f012f9afc20","unresolved":false,"context_lines":[{"line_number":397,"context_line":"        return req.environ.get(\u0027swift.source\u0027) or \u0027UNKNOWN\u0027"},{"line_number":398,"context_line":""},{"line_number":399,"context_line":"    def statsd_metric_method(self, method):"},{"line_number":400,"context_line":"        return method if method in self.valid_methods else \u0027BAD_METHOD\u0027"},{"line_number":401,"context_line":""},{"line_number":402,"context_line":"    def statsd_metric_name(self, req, status_int, metric_method):"},{"line_number":403,"context_line":"        stat_type \u003d self.get_metric_name_type(req)"}],"source_content_type":"text/x-python","patch_set":38,"id":"e4870753_112addcd","side":"PARENT","line":400,"in_reply_to":"2d5dcc7f_7b6a2e3e","updated":"2025-05-20 20:58:18.000000000","message":"Done","commit_id":"46b31ab3172a8c4c1a28545172157f4f46a38023"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":401,"context_line":""},{"line_number":402,"context_line":"    def statsd_metric_name(self, req, status_int, metric_method):"},{"line_number":403,"context_line":"        stat_type \u003d self.get_metric_name_type(req)"},{"line_number":404,"context_line":"        return \u0027.\u0027.join((stat_type, metric_method, str(status_int)))"},{"line_number":405,"context_line":""},{"line_number":406,"context_line":"    def statsd_metric_name_policy(self, req, status_int, metric_method,"},{"line_number":407,"context_line":"                                  policy_index):"}],"source_content_type":"text/x-python","patch_set":38,"id":"fe25be91_b19a92af","side":"PARENT","line":404,"updated":"2025-05-19 15:40:26.000000000","message":"this didn\u0027t need to change","commit_id":"46b31ab3172a8c4c1a28545172157f4f46a38023"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"e4e0a6fc9d7d441739e81faaadc47f012f9afc20","unresolved":false,"context_lines":[{"line_number":401,"context_line":""},{"line_number":402,"context_line":"    def statsd_metric_name(self, req, status_int, metric_method):"},{"line_number":403,"context_line":"        stat_type \u003d self.get_metric_name_type(req)"},{"line_number":404,"context_line":"        return \u0027.\u0027.join((stat_type, metric_method, str(status_int)))"},{"line_number":405,"context_line":""},{"line_number":406,"context_line":"    def statsd_metric_name_policy(self, req, status_int, metric_method,"},{"line_number":407,"context_line":"                                  policy_index):"}],"source_content_type":"text/x-python","patch_set":38,"id":"6419ef2a_4a83938a","side":"PARENT","line":404,"in_reply_to":"fe25be91_b19a92af","updated":"2025-05-20 20:58:18.000000000","message":"Acknowledged","commit_id":"46b31ab3172a8c4c1a28545172157f4f46a38023"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":118,"context_line":"        extra_labels[\u0027status\u0027] \u003d status_int"},{"line_number":119,"context_line":"    if base_labels[\u0027resource\u0027] \u003d\u003d \u0027object\u0027 and \\"},{"line_number":120,"context_line":"            policy_index is not None and \\"},{"line_number":121,"context_line":"            POLICIES.get_by_index(policy_index) is not None:"},{"line_number":122,"context_line":"        extra_labels[\u0027policy\u0027] \u003d policy_index"},{"line_number":123,"context_line":"    labels_source \u003d ChainMap(extra_labels, base_labels)"},{"line_number":124,"context_line":"    return labels_source"}],"source_content_type":"text/x-python","patch_set":38,"id":"913c097e_2566661f","line":121,"updated":"2025-05-19 15:40:26.000000000","message":"why not apply the policy_index always if it is not None?\n\n- if it isn\u0027t an object request then it may be interesting to see that there is a policy index\n- if it isn\u0027t an existent policy then it will be interesting to see that in metrics\n\nIt seems unnecessary an possibly unhelpful to redact unexpected label values rather than report the unexpected.","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"b341a2ec64623dd1d758b6b7c37d19846e3bcc8c","unresolved":false,"context_lines":[{"line_number":118,"context_line":"        extra_labels[\u0027status\u0027] \u003d status_int"},{"line_number":119,"context_line":"    if base_labels[\u0027resource\u0027] \u003d\u003d \u0027object\u0027 and \\"},{"line_number":120,"context_line":"            policy_index is not None and \\"},{"line_number":121,"context_line":"            POLICIES.get_by_index(policy_index) is not None:"},{"line_number":122,"context_line":"        extra_labels[\u0027policy\u0027] \u003d policy_index"},{"line_number":123,"context_line":"    labels_source \u003d ChainMap(extra_labels, base_labels)"},{"line_number":124,"context_line":"    return labels_source"}],"source_content_type":"text/x-python","patch_set":38,"id":"5a62e2f7_077b4ff0","line":121,"in_reply_to":"913c097e_2566661f","updated":"2025-06-03 11:34:30.000000000","message":"Yes, we can show even if the policy index is none and get stats!\nIf we get a lot of none policy index and later wish to not have, we can easily change!","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":447,"context_line":"            acc, cont, obj \u003d None, None, None"},{"line_number":448,"context_line":"        return acc, cont, obj"},{"line_number":449,"context_line":""},{"line_number":450,"context_line":"    def get_metric_name_type(self, req):"},{"line_number":451,"context_line":"        swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"},{"line_number":452,"context_line":"        acc, cont, obj \u003d self.get_aco_from_path(swift_path)"},{"line_number":453,"context_line":"        return self.get_metric_name_type_from_aco(req, acc, cont, obj)"}],"source_content_type":"text/x-python","patch_set":38,"id":"217883d0_56965d8d","line":450,"updated":"2025-05-19 15:40:26.000000000","message":"This method returns the value that we now call ``resource`` in the labels as an abbreviation of ``resource_type``.\n\nIn my experience it is helpful to use the same term to refer to the same thing *everywhere*. So I suggest renaming this to ``get_resource_type`` and renaming vars that get assigned its return value as ``resource_type`` or ``resource`` vs the current mix of ``stat_type`` and ``resource_type``\n\ni.e. everywhere have:\n\n``resource_type \u003d get_resource_type(...)``\n\nor \n\n``labels[\u0027resource\u0027] \u003d get_resource_type(...)``","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"e4e0a6fc9d7d441739e81faaadc47f012f9afc20","unresolved":false,"context_lines":[{"line_number":447,"context_line":"            acc, cont, obj \u003d None, None, None"},{"line_number":448,"context_line":"        return acc, cont, obj"},{"line_number":449,"context_line":""},{"line_number":450,"context_line":"    def get_metric_name_type(self, req):"},{"line_number":451,"context_line":"        swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"},{"line_number":452,"context_line":"        acc, cont, obj \u003d self.get_aco_from_path(swift_path)"},{"line_number":453,"context_line":"        return self.get_metric_name_type_from_aco(req, acc, cont, obj)"}],"source_content_type":"text/x-python","patch_set":38,"id":"efb3a048_0f4a9491","line":450,"in_reply_to":"217883d0_56965d8d","updated":"2025-05-20 20:58:18.000000000","message":"Acknowledged","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":463,"context_line":""},{"line_number":464,"context_line":"    def statsd_metric_name(self, req, status_int, method):"},{"line_number":465,"context_line":"        stat_type \u003d self.get_metric_name_type(req)"},{"line_number":466,"context_line":"        stat_method \u003d self.statsd_metric_method(method)"},{"line_number":467,"context_line":"        return \u0027.\u0027.join((stat_type, stat_method, str(status_int)))"},{"line_number":468,"context_line":""},{"line_number":469,"context_line":"    def statsd_metric_method(self, method):"}],"source_content_type":"text/x-python","patch_set":38,"id":"25131389_f5af3f99","line":466,"range":{"start_line":466,"start_character":27,"end_line":466,"end_character":55},"updated":"2025-05-19 15:40:26.000000000","message":"this has already been taken care before statsd_metric_name is called","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"e4e0a6fc9d7d441739e81faaadc47f012f9afc20","unresolved":false,"context_lines":[{"line_number":463,"context_line":""},{"line_number":464,"context_line":"    def statsd_metric_name(self, req, status_int, method):"},{"line_number":465,"context_line":"        stat_type \u003d self.get_metric_name_type(req)"},{"line_number":466,"context_line":"        stat_method \u003d self.statsd_metric_method(method)"},{"line_number":467,"context_line":"        return \u0027.\u0027.join((stat_type, stat_method, str(status_int)))"},{"line_number":468,"context_line":""},{"line_number":469,"context_line":"    def statsd_metric_method(self, method):"}],"source_content_type":"text/x-python","patch_set":38,"id":"cbf57910_46e7cd8d","line":466,"range":{"start_line":466,"start_character":27,"end_line":466,"end_character":55},"in_reply_to":"25131389_f5af3f99","updated":"2025-05-20 20:58:18.000000000","message":"Done","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":481,"context_line":"                    req, self.storage_domains, False)"},{"line_number":482,"context_line":""},{"line_number":483,"context_line":"            method \u003d self.method_from_req(req)"},{"line_number":484,"context_line":"            stat_method \u003d self.statsd_metric_method(method)"},{"line_number":485,"context_line":"            resource_type \u003d self.get_metric_name_type_from_aco("},{"line_number":486,"context_line":"                req, acc, cont, obj)"},{"line_number":487,"context_line":"            base_labels \u003d {"}],"source_content_type":"text/x-python","patch_set":38,"id":"235bf9ec_6607084c","line":484,"range":{"start_line":484,"start_character":12,"end_line":484,"end_character":23},"updated":"2025-05-19 15:40:26.000000000","message":"at line 404 the same value is called metric_method - consist naming is good, and results in less concepts/names for maintainers to track","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"e4e0a6fc9d7d441739e81faaadc47f012f9afc20","unresolved":false,"context_lines":[{"line_number":481,"context_line":"                    req, self.storage_domains, False)"},{"line_number":482,"context_line":""},{"line_number":483,"context_line":"            method \u003d self.method_from_req(req)"},{"line_number":484,"context_line":"            stat_method \u003d self.statsd_metric_method(method)"},{"line_number":485,"context_line":"            resource_type \u003d self.get_metric_name_type_from_aco("},{"line_number":486,"context_line":"                req, acc, cont, obj)"},{"line_number":487,"context_line":"            base_labels \u003d {"}],"source_content_type":"text/x-python","patch_set":38,"id":"58446bc6_14a8d382","line":484,"range":{"start_line":484,"start_character":12,"end_line":484,"end_character":23},"in_reply_to":"235bf9ec_6607084c","updated":"2025-05-20 20:58:18.000000000","message":"renamed it to metric_method","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":493,"context_line":"            if cont:"},{"line_number":494,"context_line":"                base_labels[\u0027container\u0027] \u003d cont"},{"line_number":495,"context_line":"            if obj:"},{"line_number":496,"context_line":"                base_labels[\u0027object\u0027] \u003d obj"},{"line_number":497,"context_line":"            req.environ[\u0027swift.base_labels\u0027] \u003d base_labels"},{"line_number":498,"context_line":"        elif base_labels.get(\u0027account\u0027, None) is None:"},{"line_number":499,"context_line":"            # expected in the right-most proxy_logging instance"}],"source_content_type":"text/x-python","patch_set":38,"id":"4c7e5d7d_44907cee","line":496,"updated":"2025-05-19 15:40:26.000000000","message":"We anticipate this item being useful in the future (to replace swift.backend_path), but right now it is not used, and we have the SubsetMap whose sole purpose is to obscure this item.\n\nUnfortunately, anticipation isn\u0027t always a justification for merging unnecessary code. So I think for *this* patch we should Keep It Simple and drop \u0027object\u0027 from the base_labels. Then we can also drop the SubsetMap and the patch gets smaller. It can come back in if and when we need it for other applications of base_labels.\n\nI know I suggested some of this stuff, so I apologise for now winding back on it. It was useful to see where the design might end up, but we have to consider this patch on its own.","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"b341a2ec64623dd1d758b6b7c37d19846e3bcc8c","unresolved":false,"context_lines":[{"line_number":493,"context_line":"            if cont:"},{"line_number":494,"context_line":"                base_labels[\u0027container\u0027] \u003d cont"},{"line_number":495,"context_line":"            if obj:"},{"line_number":496,"context_line":"                base_labels[\u0027object\u0027] \u003d obj"},{"line_number":497,"context_line":"            req.environ[\u0027swift.base_labels\u0027] \u003d base_labels"},{"line_number":498,"context_line":"        elif base_labels.get(\u0027account\u0027, None) is None:"},{"line_number":499,"context_line":"            # expected in the right-most proxy_logging instance"}],"source_content_type":"text/x-python","patch_set":38,"id":"f96ed5df_496d904f","line":496,"in_reply_to":"4c7e5d7d_44907cee","updated":"2025-06-03 11:34:30.000000000","message":"Acknowledged","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":495,"context_line":"            if obj:"},{"line_number":496,"context_line":"                base_labels[\u0027object\u0027] \u003d obj"},{"line_number":497,"context_line":"            req.environ[\u0027swift.base_labels\u0027] \u003d base_labels"},{"line_number":498,"context_line":"        elif base_labels.get(\u0027account\u0027, None) is None:"},{"line_number":499,"context_line":"            # expected in the right-most proxy_logging instance"},{"line_number":500,"context_line":"            base_labels[\u0027account\u0027] \u003d acc"},{"line_number":501,"context_line":""}],"source_content_type":"text/x-python","patch_set":38,"id":"cad1422c_5db245a2","line":498,"range":{"start_line":498,"start_character":38,"end_line":498,"end_character":44},"updated":"2025-05-19 15:40:26.000000000","message":"nit: it isn\u0027t necessary to specify ``None`` as the default for a dict.get()","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":495,"context_line":"            if obj:"},{"line_number":496,"context_line":"                base_labels[\u0027object\u0027] \u003d obj"},{"line_number":497,"context_line":"            req.environ[\u0027swift.base_labels\u0027] \u003d base_labels"},{"line_number":498,"context_line":"        elif base_labels.get(\u0027account\u0027, None) is None:"},{"line_number":499,"context_line":"            # expected in the right-most proxy_logging instance"},{"line_number":500,"context_line":"            base_labels[\u0027account\u0027] \u003d acc"},{"line_number":501,"context_line":""}],"source_content_type":"text/x-python","patch_set":38,"id":"88a91b45_2462ce59","line":498,"range":{"start_line":498,"start_character":8,"end_line":498,"end_character":12},"updated":"2025-05-19 15:40:26.000000000","message":"you could avoid a dangling ``elif`` by writing this:\n\n```\nelse:\n    base_labels.setdefault(\u0027account\u0027, acc)\n```","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"e4e0a6fc9d7d441739e81faaadc47f012f9afc20","unresolved":false,"context_lines":[{"line_number":495,"context_line":"            if obj:"},{"line_number":496,"context_line":"                base_labels[\u0027object\u0027] \u003d obj"},{"line_number":497,"context_line":"            req.environ[\u0027swift.base_labels\u0027] \u003d base_labels"},{"line_number":498,"context_line":"        elif base_labels.get(\u0027account\u0027, None) is None:"},{"line_number":499,"context_line":"            # expected in the right-most proxy_logging instance"},{"line_number":500,"context_line":"            base_labels[\u0027account\u0027] \u003d acc"},{"line_number":501,"context_line":""}],"source_content_type":"text/x-python","patch_set":38,"id":"61e270ae_20150b70","line":498,"range":{"start_line":498,"start_character":8,"end_line":498,"end_character":12},"in_reply_to":"88a91b45_2462ce59","updated":"2025-05-20 20:58:18.000000000","message":"Done","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"e4e0a6fc9d7d441739e81faaadc47f012f9afc20","unresolved":false,"context_lines":[{"line_number":495,"context_line":"            if obj:"},{"line_number":496,"context_line":"                base_labels[\u0027object\u0027] \u003d obj"},{"line_number":497,"context_line":"            req.environ[\u0027swift.base_labels\u0027] \u003d base_labels"},{"line_number":498,"context_line":"        elif base_labels.get(\u0027account\u0027, None) is None:"},{"line_number":499,"context_line":"            # expected in the right-most proxy_logging instance"},{"line_number":500,"context_line":"            base_labels[\u0027account\u0027] \u003d acc"},{"line_number":501,"context_line":""}],"source_content_type":"text/x-python","patch_set":38,"id":"3ecd2b6f_2f7e259f","line":498,"range":{"start_line":498,"start_character":38,"end_line":498,"end_character":44},"in_reply_to":"cad1422c_5db245a2","updated":"2025-05-20 20:58:18.000000000","message":"Acknowledged","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":497,"context_line":"            req.environ[\u0027swift.base_labels\u0027] \u003d base_labels"},{"line_number":498,"context_line":"        elif base_labels.get(\u0027account\u0027, None) is None:"},{"line_number":499,"context_line":"            # expected in the right-most proxy_logging instance"},{"line_number":500,"context_line":"            base_labels[\u0027account\u0027] \u003d acc"},{"line_number":501,"context_line":""},{"line_number":502,"context_line":"    def statsd_metric_name_policy(self, req, status_int, method,"},{"line_number":503,"context_line":"                                  policy_index):"}],"source_content_type":"text/x-python","patch_set":38,"id":"a7a79ea2_f8da2c3a","line":500,"updated":"2025-05-19 15:40:26.000000000","message":"1. here we set \u0027account\u0027 even if it is None, but not in the ``if`` clause\n\n2. shouldn\u0027t we also re-evaluate resource_type now that we have account?\n\nI wrote some tests to illustrate https://paste.openstack.org/show/bdlMKqYskyYMUzZ9rDew/\n\nNote: there do seem to be existing tests that cover end-to-end request handling, but I assume they just don\u0027t hit the case of an s3 request to an account resource, or a /info request.","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"b341a2ec64623dd1d758b6b7c37d19846e3bcc8c","unresolved":false,"context_lines":[{"line_number":497,"context_line":"            req.environ[\u0027swift.base_labels\u0027] \u003d base_labels"},{"line_number":498,"context_line":"        elif base_labels.get(\u0027account\u0027, None) is None:"},{"line_number":499,"context_line":"            # expected in the right-most proxy_logging instance"},{"line_number":500,"context_line":"            base_labels[\u0027account\u0027] \u003d acc"},{"line_number":501,"context_line":""},{"line_number":502,"context_line":"    def statsd_metric_name_policy(self, req, status_int, method,"},{"line_number":503,"context_line":"                                  policy_index):"}],"source_content_type":"text/x-python","patch_set":38,"id":"8fc00ca1_fcaa5001","line":500,"in_reply_to":"a7a79ea2_f8da2c3a","updated":"2025-06-03 11:34:30.000000000","message":"Acknowledged","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":499,"context_line":"            # expected in the right-most proxy_logging instance"},{"line_number":500,"context_line":"            base_labels[\u0027account\u0027] \u003d acc"},{"line_number":501,"context_line":""},{"line_number":502,"context_line":"    def statsd_metric_name_policy(self, req, status_int, method,"},{"line_number":503,"context_line":"                                  policy_index):"},{"line_number":504,"context_line":"        if policy_index is None:"},{"line_number":505,"context_line":"            return None"}],"source_content_type":"text/x-python","patch_set":38,"id":"245cfb72_c0e4df6e","line":502,"updated":"2025-05-19 15:40:26.000000000","message":"I don\u0027t think the changes to this method are necessary - the request method has been sanitised before being passed in","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"e4e0a6fc9d7d441739e81faaadc47f012f9afc20","unresolved":false,"context_lines":[{"line_number":499,"context_line":"            # expected in the right-most proxy_logging instance"},{"line_number":500,"context_line":"            base_labels[\u0027account\u0027] \u003d acc"},{"line_number":501,"context_line":""},{"line_number":502,"context_line":"    def statsd_metric_name_policy(self, req, status_int, method,"},{"line_number":503,"context_line":"                                  policy_index):"},{"line_number":504,"context_line":"        if policy_index is None:"},{"line_number":505,"context_line":"            return None"}],"source_content_type":"text/x-python","patch_set":38,"id":"a483e436_2bceac0a","line":502,"in_reply_to":"245cfb72_c0e4df6e","updated":"2025-05-20 20:58:18.000000000","message":"Done","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"32ae30a71d34143d937378fbf06b84f19ea34ef7","unresolved":true,"context_lines":[{"line_number":404,"context_line":"        metric_method \u003d self.statsd_metric_method(method)"},{"line_number":405,"context_line":"        metric_name \u003d self.statsd_metric_name(req, status_int, metric_method)"},{"line_number":406,"context_line":"        metric_name_policy \u003d self.statsd_metric_name_policy("},{"line_number":407,"context_line":"            req, status_int, method, policy_index)"},{"line_number":408,"context_line":""},{"line_number":409,"context_line":"        # Only log data for valid controllers (or SOS) to keep the metric count"},{"line_number":410,"context_line":"        # down (egregious errors will get logged by the proxy server itself)."}],"source_content_type":"text/x-python","patch_set":40,"id":"3a0d4ea6_ea7a86c1","line":407,"range":{"start_line":407,"start_character":29,"end_line":407,"end_character":35},"updated":"2025-05-21 11:38:08.000000000","message":"why did this change? shouldn\u0027t it still be metric_method?","commit_id":"b70738f11f1c24ba30dfeb0a822a191be1122ef2"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"31e0fb568a380319c15ece5acc47007595b0cbcb","unresolved":false,"context_lines":[{"line_number":404,"context_line":"        metric_method \u003d self.statsd_metric_method(method)"},{"line_number":405,"context_line":"        metric_name \u003d self.statsd_metric_name(req, status_int, metric_method)"},{"line_number":406,"context_line":"        metric_name_policy \u003d self.statsd_metric_name_policy("},{"line_number":407,"context_line":"            req, status_int, method, policy_index)"},{"line_number":408,"context_line":""},{"line_number":409,"context_line":"        # Only log data for valid controllers (or SOS) to keep the metric count"},{"line_number":410,"context_line":"        # down (egregious errors will get logged by the proxy server itself)."}],"source_content_type":"text/x-python","patch_set":40,"id":"76a4352d_27c22867","line":407,"range":{"start_line":407,"start_character":29,"end_line":407,"end_character":35},"in_reply_to":"3a0d4ea6_ea7a86c1","updated":"2025-05-28 12:47:46.000000000","message":"You are right, shouldn\u0027t have changed","commit_id":"b70738f11f1c24ba30dfeb0a822a191be1122ef2"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"32ae30a71d34143d937378fbf06b84f19ea34ef7","unresolved":true,"context_lines":[{"line_number":450,"context_line":"    def get_resource_type(self, req):"},{"line_number":451,"context_line":"        swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"},{"line_number":452,"context_line":"        acc, cont, obj \u003d self.get_aco_from_path(swift_path)"},{"line_number":453,"context_line":"        return self.get_resource_type_from_aco(req, acc, cont, obj)"},{"line_number":454,"context_line":""},{"line_number":455,"context_line":"    def get_resource_type_from_aco(self, req, acc, cont, obj):"},{"line_number":456,"context_line":"        if obj:"}],"source_content_type":"text/x-python","patch_set":40,"id":"07bbeda4_c4212e69","line":453,"updated":"2025-05-21 11:38:08.000000000","message":"nit: this method calls out to two others - one is above, one is below. I usually expect to look upwards for calls, so could we have ``get_resource_type_from_aco`` above ``get_resource_type``","commit_id":"b70738f11f1c24ba30dfeb0a822a191be1122ef2"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"31e0fb568a380319c15ece5acc47007595b0cbcb","unresolved":false,"context_lines":[{"line_number":450,"context_line":"    def get_resource_type(self, req):"},{"line_number":451,"context_line":"        swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"},{"line_number":452,"context_line":"        acc, cont, obj \u003d self.get_aco_from_path(swift_path)"},{"line_number":453,"context_line":"        return self.get_resource_type_from_aco(req, acc, cont, obj)"},{"line_number":454,"context_line":""},{"line_number":455,"context_line":"    def get_resource_type_from_aco(self, req, acc, cont, obj):"},{"line_number":456,"context_line":"        if obj:"}],"source_content_type":"text/x-python","patch_set":40,"id":"13b7a2e1_076322f6","line":453,"in_reply_to":"07bbeda4_c4212e69","updated":"2025-05-28 12:47:46.000000000","message":"Acknowledged","commit_id":"b70738f11f1c24ba30dfeb0a822a191be1122ef2"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"32ae30a71d34143d937378fbf06b84f19ea34ef7","unresolved":true,"context_lines":[{"line_number":464,"context_line":"    def statsd_metric_method(self, method):"},{"line_number":465,"context_line":"        return method if method in self.valid_methods else \u0027BAD_METHOD\u0027"},{"line_number":466,"context_line":""},{"line_number":467,"context_line":"    def statsd_metric_name(self, req, status_int, method):"},{"line_number":468,"context_line":"        resource_type \u003d self.get_resource_type(req)"},{"line_number":469,"context_line":"        return \u0027.\u0027.join((resource_type, method, str(status_int)))"},{"line_number":470,"context_line":""}],"source_content_type":"text/x-python","patch_set":40,"id":"e22ee6cc_99f15309","line":467,"range":{"start_line":467,"start_character":50,"end_line":467,"end_character":56},"updated":"2025-05-21 11:38:08.000000000","message":"why change this arg name - it\u0027s metric_method that is passed in ?","commit_id":"b70738f11f1c24ba30dfeb0a822a191be1122ef2"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"647c63912629da7b26772262a54113d71d6a93ce","unresolved":false,"context_lines":[{"line_number":464,"context_line":"    def statsd_metric_method(self, method):"},{"line_number":465,"context_line":"        return method if method in self.valid_methods else \u0027BAD_METHOD\u0027"},{"line_number":466,"context_line":""},{"line_number":467,"context_line":"    def statsd_metric_name(self, req, status_int, method):"},{"line_number":468,"context_line":"        resource_type \u003d self.get_resource_type(req)"},{"line_number":469,"context_line":"        return \u0027.\u0027.join((resource_type, method, str(status_int)))"},{"line_number":470,"context_line":""}],"source_content_type":"text/x-python","patch_set":40,"id":"d5dbd905_4ffb4902","line":467,"range":{"start_line":467,"start_character":50,"end_line":467,"end_character":56},"in_reply_to":"e22ee6cc_99f15309","updated":"2025-05-28 16:01:48.000000000","message":"Right, I was trying to get it on line with master but forgot about the proxy_logging patch","commit_id":"b70738f11f1c24ba30dfeb0a822a191be1122ef2"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":108,"context_line":"    get_sensitive_params, register_sensitive_header"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"def statsd_metric_resp_labels(base_labels, status_int\u003dNone, policy_index\u003dNone):"},{"line_number":112,"context_line":"    extra_labels \u003d {}"},{"line_number":113,"context_line":"    if status_int:"},{"line_number":114,"context_line":"        extra_labels[\u0027status\u0027] \u003d status_int"}],"source_content_type":"text/x-python","patch_set":43,"id":"2c0d5c37_bcf00787","line":111,"updated":"2025-06-04 18:08:30.000000000","message":"nit: please add a (brief) docstring e.g. ``compose labels used for response metrics``","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"882046edbfa151e01a295bbd60d141e128e3c8ff","unresolved":false,"context_lines":[{"line_number":108,"context_line":"    get_sensitive_params, register_sensitive_header"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"def statsd_metric_resp_labels(base_labels, status_int\u003dNone, policy_index\u003dNone):"},{"line_number":112,"context_line":"    extra_labels \u003d {}"},{"line_number":113,"context_line":"    if status_int:"},{"line_number":114,"context_line":"        extra_labels[\u0027status\u0027] \u003d status_int"}],"source_content_type":"text/x-python","patch_set":43,"id":"0c2cbdf4_8b3b4325","line":111,"in_reply_to":"2c0d5c37_bcf00787","updated":"2025-06-14 04:17:00.000000000","message":"Acknowledged","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":112,"context_line":"    extra_labels \u003d {}"},{"line_number":113,"context_line":"    if status_int:"},{"line_number":114,"context_line":"        extra_labels[\u0027status\u0027] \u003d status_int"},{"line_number":115,"context_line":"        extra_labels[\u0027policy\u0027] \u003d policy_index"},{"line_number":116,"context_line":"    labels_source \u003d ChainMap(extra_labels, base_labels)"},{"line_number":117,"context_line":"    return labels_source"},{"line_number":118,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"8726a0cb_05ccec5b","line":115,"updated":"2025-06-04 18:08:30.000000000","message":"this has ended up being conditional on ``if status_int``\n\nI think that the condition should be ``if policy_index is not None``:","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9c175fca54bd4eec0f0d2e996f5cb2bb4fce3870","unresolved":false,"context_lines":[{"line_number":112,"context_line":"    extra_labels \u003d {}"},{"line_number":113,"context_line":"    if status_int:"},{"line_number":114,"context_line":"        extra_labels[\u0027status\u0027] \u003d status_int"},{"line_number":115,"context_line":"        extra_labels[\u0027policy\u0027] \u003d policy_index"},{"line_number":116,"context_line":"    labels_source \u003d ChainMap(extra_labels, base_labels)"},{"line_number":117,"context_line":"    return labels_source"},{"line_number":118,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"b2c6a259_2982f695","line":115,"in_reply_to":"1160f258_5df0fcc7","updated":"2025-07-21 21:19:09.000000000","message":"Acknowledged","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"882046edbfa151e01a295bbd60d141e128e3c8ff","unresolved":false,"context_lines":[{"line_number":112,"context_line":"    extra_labels \u003d {}"},{"line_number":113,"context_line":"    if status_int:"},{"line_number":114,"context_line":"        extra_labels[\u0027status\u0027] \u003d status_int"},{"line_number":115,"context_line":"        extra_labels[\u0027policy\u0027] \u003d policy_index"},{"line_number":116,"context_line":"    labels_source \u003d ChainMap(extra_labels, base_labels)"},{"line_number":117,"context_line":"    return labels_source"},{"line_number":118,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"8ac4c387_2e58b305","line":115,"in_reply_to":"8726a0cb_05ccec5b","updated":"2025-06-14 04:17:00.000000000","message":"Acknowledged","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1432c12767bfa249bb2d1d29e769cd306b817b23","unresolved":true,"context_lines":[{"line_number":112,"context_line":"    extra_labels \u003d {}"},{"line_number":113,"context_line":"    if status_int:"},{"line_number":114,"context_line":"        extra_labels[\u0027status\u0027] \u003d status_int"},{"line_number":115,"context_line":"        extra_labels[\u0027policy\u0027] \u003d policy_index"},{"line_number":116,"context_line":"    labels_source \u003d ChainMap(extra_labels, base_labels)"},{"line_number":117,"context_line":"    return labels_source"},{"line_number":118,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"1160f258_5df0fcc7","line":115,"in_reply_to":"8ac4c387_2e58b305","updated":"2025-07-17 14:31:02.000000000","message":"my comment referred to only line 115 i.e including the policy label should be conditional on there being a policy index.","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":137,"context_line":"            return"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"        now \u003d time.time()"},{"line_number":140,"context_line":"        if (self.emit_buffer_xfer_bytes_sec !\u003d 0 and"},{"line_number":141,"context_line":"                self.next_emit_time \u003e now):"},{"line_number":142,"context_line":"            return"},{"line_number":143,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"d18bad56_c8cfe2a4","line":140,"range":{"start_line":140,"start_character":12,"end_line":140,"end_character":49},"updated":"2025-06-04 18:08:30.000000000","message":"I\u0027m not sure this part of the condition is necessary:\n\nif self.emit_buffer_xfer_bytes_sec is zero then at line 150 we\u0027ll add zero to now to get next_emit_time, and next time the callback is called then ``now`` has to be ``\u003e next_emit_time``\n\n...and no tests fail if I remove ``self.emit_buffer_xfer_bytes_sec !\u003d 0 and``","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"cd45a581820bc1bee129daf0e9221cbf54e58829","unresolved":false,"context_lines":[{"line_number":137,"context_line":"            return"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"        now \u003d time.time()"},{"line_number":140,"context_line":"        if (self.emit_buffer_xfer_bytes_sec !\u003d 0 and"},{"line_number":141,"context_line":"                self.next_emit_time \u003e now):"},{"line_number":142,"context_line":"            return"},{"line_number":143,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"ec5a03a8_ebb8576e","line":140,"range":{"start_line":140,"start_character":12,"end_line":140,"end_character":49},"in_reply_to":"d18bad56_c8cfe2a4","updated":"2025-06-27 14:49:57.000000000","message":"Acknowledged","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":483,"context_line":"        elif acc:"},{"line_number":484,"context_line":"            resource_type \u003d self.get_resource_type_from_aco("},{"line_number":485,"context_line":"                req, acc, cont, obj)"},{"line_number":486,"context_line":"            # expected in the right-most proxy_logging instance"},{"line_number":487,"context_line":"            base_labels.setdefault(\u0027account\u0027, acc)"},{"line_number":488,"context_line":"            base_labels.setdefault(\u0027resource\u0027, resource_type)"},{"line_number":489,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"ed24846e_dbe39699","line":486,"updated":"2025-06-04 18:08:30.000000000","message":"nit: please move the comment up to line 484 i.e. start of the elif clause","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"882046edbfa151e01a295bbd60d141e128e3c8ff","unresolved":false,"context_lines":[{"line_number":483,"context_line":"        elif acc:"},{"line_number":484,"context_line":"            resource_type \u003d self.get_resource_type_from_aco("},{"line_number":485,"context_line":"                req, acc, cont, obj)"},{"line_number":486,"context_line":"            # expected in the right-most proxy_logging instance"},{"line_number":487,"context_line":"            base_labels.setdefault(\u0027account\u0027, acc)"},{"line_number":488,"context_line":"            base_labels.setdefault(\u0027resource\u0027, resource_type)"},{"line_number":489,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"d6fb2743_61da2850","line":486,"in_reply_to":"ed24846e_dbe39699","updated":"2025-06-14 04:17:00.000000000","message":"Done","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":127,"context_line":"        self.emit_bytes \u003d 0"},{"line_number":128,"context_line":"        self.next_emit_time \u003d 0"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"    def __call__(self, buffer_len):"},{"line_number":131,"context_line":"        if self.emit_buffer_xfer_bytes_sec \u003c 0:"},{"line_number":132,"context_line":"            return"},{"line_number":133,"context_line":""}],"source_content_type":"text/x-python","patch_set":44,"id":"6382f95a_baa92210","line":130,"updated":"2025-06-05 11:46:42.000000000","message":"The callback interface also needs to pass ``eof`` from the InputProxy so that the final stat with any accumulated emit_bytes can be emitted regardless of time when ``eof\u003dTrue`` - otherwise we may not get a stat for the last few bytes.","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9c175fca54bd4eec0f0d2e996f5cb2bb4fce3870","unresolved":false,"context_lines":[{"line_number":127,"context_line":"        self.emit_bytes \u003d 0"},{"line_number":128,"context_line":"        self.next_emit_time \u003d 0"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"    def __call__(self, buffer_len):"},{"line_number":131,"context_line":"        if self.emit_buffer_xfer_bytes_sec \u003c 0:"},{"line_number":132,"context_line":"            return"},{"line_number":133,"context_line":""}],"source_content_type":"text/x-python","patch_set":44,"id":"afe05d26_bc26ab06","line":130,"in_reply_to":"2b9704b4_8bde6f3c","updated":"2025-07-21 21:19:09.000000000","message":"Added eof and \n        if eof is False and self.next_emit_time \u003e now:\n            return","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"cd45a581820bc1bee129daf0e9221cbf54e58829","unresolved":false,"context_lines":[{"line_number":127,"context_line":"        self.emit_bytes \u003d 0"},{"line_number":128,"context_line":"        self.next_emit_time \u003d 0"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"    def __call__(self, buffer_len):"},{"line_number":131,"context_line":"        if self.emit_buffer_xfer_bytes_sec \u003c 0:"},{"line_number":132,"context_line":"            return"},{"line_number":133,"context_line":""}],"source_content_type":"text/x-python","patch_set":44,"id":"6a62eb64_aaaae63f","line":130,"in_reply_to":"6382f95a_baa92210","updated":"2025-06-27 14:49:57.000000000","message":"Added callback for the last remaining stats","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1432c12767bfa249bb2d1d29e769cd306b817b23","unresolved":true,"context_lines":[{"line_number":127,"context_line":"        self.emit_bytes \u003d 0"},{"line_number":128,"context_line":"        self.next_emit_time \u003d 0"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"    def __call__(self, buffer_len):"},{"line_number":131,"context_line":"        if self.emit_buffer_xfer_bytes_sec \u003c 0:"},{"line_number":132,"context_line":"            return"},{"line_number":133,"context_line":""}],"source_content_type":"text/x-python","patch_set":44,"id":"2b9704b4_8bde6f3c","line":130,"in_reply_to":"6a62eb64_aaaae63f","updated":"2025-07-17 14:31:02.000000000","message":"I can\u0027t see where the ``eof`` from InputProxy has been added.\n\nWhat happens when self.emit_bytes in non-zero and the callback is never called again? How do the final emit_bytes get flushed out as a final statsd metric?\n\nI am suggesting that ``__call__`` needs another argument that *forces* the current ``emit_bytes`` to be sent as a metric\n\nsomething like:\n\n```\ndef __call__(self, buffer_len, eof\u003dFalse):\n\n```\n\nand then at line 140\n\n```\nif (self.emit_buffer_xfer_bytes_sec !\u003d 0 and\n                self.next_emit_time \u003e now and not eof):\n```\n\nAnd we need tests to cover this case.","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":626,"context_line":"            except Exception:"},{"line_number":627,"context_line":"                env[\u0027swift.proxy_logging_status\u0027] \u003d 500"},{"line_number":628,"context_line":"                raise"},{"line_number":629,"context_line":"            finally:"},{"line_number":630,"context_line":"                env.setdefault(\u0027swift.proxy_logging_status\u0027, wire_status_int)"},{"line_number":631,"context_line":"                status_int \u003d status_int_for_logging()"},{"line_number":632,"context_line":"                self.log_request("}],"source_content_type":"text/x-python","patch_set":44,"id":"b6a7cd13_18c62643","line":629,"updated":"2025-06-05 11:46:42.000000000","message":"we get here when StopIteration is raised (i.e. no more chunks) at which time the BufferXferEmitCallback needs to unconditionally emit a stat with any accumulated bytes that have not yet been reported","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"5a6a291f5a616b4ba8f14fea825d14cf68656b81","unresolved":false,"context_lines":[{"line_number":626,"context_line":"            except Exception:"},{"line_number":627,"context_line":"                env[\u0027swift.proxy_logging_status\u0027] \u003d 500"},{"line_number":628,"context_line":"                raise"},{"line_number":629,"context_line":"            finally:"},{"line_number":630,"context_line":"                env.setdefault(\u0027swift.proxy_logging_status\u0027, wire_status_int)"},{"line_number":631,"context_line":"                status_int \u003d status_int_for_logging()"},{"line_number":632,"context_line":"                self.log_request("}],"source_content_type":"text/x-python","patch_set":44,"id":"3767d5e7_25e1ec10","line":629,"in_reply_to":"b6a7cd13_18c62643","updated":"2025-07-09 16:30:59.000000000","message":"Done","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1432c12767bfa249bb2d1d29e769cd306b817b23","unresolved":true,"context_lines":[{"line_number":111,"context_line":"def statsd_metric_resp_labels(base_labels, status_int\u003dNone, policy_index\u003dNone):"},{"line_number":112,"context_line":"    # compose labels used for response metrics"},{"line_number":113,"context_line":"    extra_labels \u003d {}"},{"line_number":114,"context_line":"    if policy_index is not None:"},{"line_number":115,"context_line":"        extra_labels[\u0027status\u0027] \u003d status_int"},{"line_number":116,"context_line":"        extra_labels[\u0027policy\u0027] \u003d policy_index"},{"line_number":117,"context_line":"    labels_source \u003d ChainMap(extra_labels, base_labels)"}],"source_content_type":"text/x-python","patch_set":57,"id":"8e490057_27f337ba","line":114,"updated":"2025-07-17 14:31:02.000000000","message":"pls revert this to as it was in patchset 44 - including a status label *should* be conditional on there being a status_int\n\ndo we have a ``test_statsd_metric_resp_labels`` ? we *should* have that and test these conditions explicitly","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9c175fca54bd4eec0f0d2e996f5cb2bb4fce3870","unresolved":false,"context_lines":[{"line_number":111,"context_line":"def statsd_metric_resp_labels(base_labels, status_int\u003dNone, policy_index\u003dNone):"},{"line_number":112,"context_line":"    # compose labels used for response metrics"},{"line_number":113,"context_line":"    extra_labels \u003d {}"},{"line_number":114,"context_line":"    if policy_index is not None:"},{"line_number":115,"context_line":"        extra_labels[\u0027status\u0027] \u003d status_int"},{"line_number":116,"context_line":"        extra_labels[\u0027policy\u0027] \u003d policy_index"},{"line_number":117,"context_line":"    labels_source \u003d ChainMap(extra_labels, base_labels)"}],"source_content_type":"text/x-python","patch_set":57,"id":"5cd7f71b_aa8af3b1","line":114,"in_reply_to":"8e490057_27f337ba","updated":"2025-07-21 21:19:09.000000000","message":"Acknowledged","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1432c12767bfa249bb2d1d29e769cd306b817b23","unresolved":true,"context_lines":[{"line_number":113,"context_line":"    extra_labels \u003d {}"},{"line_number":114,"context_line":"    if policy_index is not None:"},{"line_number":115,"context_line":"        extra_labels[\u0027status\u0027] \u003d status_int"},{"line_number":116,"context_line":"        extra_labels[\u0027policy\u0027] \u003d policy_index"},{"line_number":117,"context_line":"    labels_source \u003d ChainMap(extra_labels, base_labels)"},{"line_number":118,"context_line":"    return labels_source"},{"line_number":119,"context_line":""}],"source_content_type":"text/x-python","patch_set":57,"id":"93c409b1_d3d489a8","line":116,"updated":"2025-07-17 14:31:02.000000000","message":"policy label is subject to a wholly different condition:\n\n```\nif policy_index is not None:\n    extra_labels[\u0027policy\u0027] \u003d policy_index\n```","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9c175fca54bd4eec0f0d2e996f5cb2bb4fce3870","unresolved":false,"context_lines":[{"line_number":113,"context_line":"    extra_labels \u003d {}"},{"line_number":114,"context_line":"    if policy_index is not None:"},{"line_number":115,"context_line":"        extra_labels[\u0027status\u0027] \u003d status_int"},{"line_number":116,"context_line":"        extra_labels[\u0027policy\u0027] \u003d policy_index"},{"line_number":117,"context_line":"    labels_source \u003d ChainMap(extra_labels, base_labels)"},{"line_number":118,"context_line":"    return labels_source"},{"line_number":119,"context_line":""}],"source_content_type":"text/x-python","patch_set":57,"id":"af087fff_cf8240ec","line":116,"in_reply_to":"93c409b1_d3d489a8","updated":"2025-07-21 21:19:09.000000000","message":"Done","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1432c12767bfa249bb2d1d29e769cd306b817b23","unresolved":true,"context_lines":[{"line_number":628,"context_line":"                env[\u0027swift.proxy_logging_status\u0027] \u003d 500"},{"line_number":629,"context_line":"                raise"},{"line_number":630,"context_line":"            finally:"},{"line_number":631,"context_line":"                statsd_emit_callback(0)"},{"line_number":632,"context_line":"                env.setdefault(\u0027swift.proxy_logging_status\u0027, wire_status_int)"},{"line_number":633,"context_line":"                status_int \u003d status_int_for_logging()"},{"line_number":634,"context_line":"                self.log_request("}],"source_content_type":"text/x-python","patch_set":57,"id":"abc3afe7_26f9a252","line":631,"range":{"start_line":631,"start_character":37,"end_line":631,"end_character":38},"updated":"2025-07-17 14:31:02.000000000","message":"what does this always zero call achieve?\n\nwe need to provoke a final metric when there are remaining bytes that have not been reported in a previous metric.\n\nfrom my previous comment: \n```\nwe get here when StopIteration is raised (i.e. no more chunks) at which\ntime the BufferXferEmitCallback needs to unconditionally emit a stat\nwith any accumulated bytes that have not yet been reported\n```","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9c175fca54bd4eec0f0d2e996f5cb2bb4fce3870","unresolved":false,"context_lines":[{"line_number":628,"context_line":"                env[\u0027swift.proxy_logging_status\u0027] \u003d 500"},{"line_number":629,"context_line":"                raise"},{"line_number":630,"context_line":"            finally:"},{"line_number":631,"context_line":"                statsd_emit_callback(0)"},{"line_number":632,"context_line":"                env.setdefault(\u0027swift.proxy_logging_status\u0027, wire_status_int)"},{"line_number":633,"context_line":"                status_int \u003d status_int_for_logging()"},{"line_number":634,"context_line":"                self.log_request("}],"source_content_type":"text/x-python","patch_set":57,"id":"9c2a28b4_b8d49c76","line":631,"range":{"start_line":631,"start_character":37,"end_line":631,"end_character":38},"in_reply_to":"abc3afe7_26f9a252","updated":"2025-07-21 21:19:09.000000000","message":"I\u0027ve added a flag called eof and until its set as true, bytes will be counted.","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed52e6f601100413157c728b3379848ae27d2538","unresolved":true,"context_lines":[{"line_number":132,"context_line":"    def __call__(self, buffer, eof\u003dFalse):"},{"line_number":133,"context_line":"        if self.emit_buffer_xfer_bytes_sec \u003c 0:"},{"line_number":134,"context_line":"            return"},{"line_number":135,"context_line":"        buffer_len \u003d buffer if type(buffer) is int else len(buffer)"},{"line_number":136,"context_line":"        self.emit_bytes +\u003d buffer_len"},{"line_number":137,"context_line":"        if not self.labels.get(\u0027account\u0027, None):"},{"line_number":138,"context_line":"            # tolerate no account, maybe it\u0027ll be there in time for next stat"}],"source_content_type":"text/x-python","patch_set":58,"id":"dcb7333f_406fe713","line":135,"range":{"start_line":135,"start_character":21,"end_line":135,"end_character":50},"updated":"2025-07-24 09:38:58.000000000","message":"who ever calls this with an int value? - that would be a bug IMHO - the `buffer` arg should be an object that implements len().\n\nSometimes it does make sense for a function arg to accept multiple types, but in general it\u0027s best avoided. \"Keep It Simple\".\n\nTo make this clear, a docstring should be added\n\n```\ndef __call__(self, buffer, eof\u003dFalse):\n   \"\"\"\n   Accumulate the length of ``buffer`` and periodically emit a stat\n   with the accumulated length.\n   \n   :param buffer: the buffer that has been read.\n   :param eof: if True, a stat is emitted immediately; otherwise a\n       stat will be emitted when ``next_emit_time`` has been reached.\n   \"\"\"\n```","commit_id":"4641e0ca4aa3481f0bd66d4af9ff4a61e5267946"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"a37da6eb6c70194e35ae4422536f75ee9e681e35","unresolved":false,"context_lines":[{"line_number":132,"context_line":"    def __call__(self, buffer, eof\u003dFalse):"},{"line_number":133,"context_line":"        if self.emit_buffer_xfer_bytes_sec \u003c 0:"},{"line_number":134,"context_line":"            return"},{"line_number":135,"context_line":"        buffer_len \u003d buffer if type(buffer) is int else len(buffer)"},{"line_number":136,"context_line":"        self.emit_bytes +\u003d buffer_len"},{"line_number":137,"context_line":"        if not self.labels.get(\u0027account\u0027, None):"},{"line_number":138,"context_line":"            # tolerate no account, maybe it\u0027ll be there in time for next stat"}],"source_content_type":"text/x-python","patch_set":58,"id":"bed0fd93_6e4ac0ac","line":135,"range":{"start_line":135,"start_character":21,"end_line":135,"end_character":50},"in_reply_to":"dcb7333f_406fe713","updated":"2025-07-24 22:24:06.000000000","message":"Acknowledged","commit_id":"4641e0ca4aa3481f0bd66d4af9ff4a61e5267946"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed52e6f601100413157c728b3379848ae27d2538","unresolved":true,"context_lines":[{"line_number":630,"context_line":"                env[\u0027swift.proxy_logging_status\u0027] \u003d 500"},{"line_number":631,"context_line":"                raise"},{"line_number":632,"context_line":"            finally:"},{"line_number":633,"context_line":"                statsd_emit_callback(0, eof\u003dTrue)"},{"line_number":634,"context_line":"                env.setdefault(\u0027swift.proxy_logging_status\u0027, wire_status_int)"},{"line_number":635,"context_line":"                status_int \u003d status_int_for_logging()"},{"line_number":636,"context_line":"                self.log_request("}],"source_content_type":"text/x-python","patch_set":58,"id":"05c206b6_a282716d","line":633,"updated":"2025-07-24 09:38:58.000000000","message":"ok, so this callback will trigger the final stat with any unreported bytes, but I\u0027m not sure why it would pass ``0`` now that the interface to the callback has changed? I expected this to pass an empty buffer ``\u0027\u0027``\n\nNow I see why the ``__call__`` has to accept an int for ``buffer`` but that\u0027s unnecessary - just pass an empty string here.","commit_id":"4641e0ca4aa3481f0bd66d4af9ff4a61e5267946"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"a37da6eb6c70194e35ae4422536f75ee9e681e35","unresolved":false,"context_lines":[{"line_number":630,"context_line":"                env[\u0027swift.proxy_logging_status\u0027] \u003d 500"},{"line_number":631,"context_line":"                raise"},{"line_number":632,"context_line":"            finally:"},{"line_number":633,"context_line":"                statsd_emit_callback(0, eof\u003dTrue)"},{"line_number":634,"context_line":"                env.setdefault(\u0027swift.proxy_logging_status\u0027, wire_status_int)"},{"line_number":635,"context_line":"                status_int \u003d status_int_for_logging()"},{"line_number":636,"context_line":"                self.log_request("}],"source_content_type":"text/x-python","patch_set":58,"id":"e9a94e0f_4bf33cb9","line":633,"in_reply_to":"05c206b6_a282716d","updated":"2025-07-24 22:24:06.000000000","message":"There\u0027s also int called in TestBufferXferEmitCallback tests, will get those to not use int too","commit_id":"4641e0ca4aa3481f0bd66d4af9ff4a61e5267946"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"198b984c59b8a6fd4ba03b46d765c424b2ef8250","unresolved":true,"context_lines":[{"line_number":148,"context_line":"            return"},{"line_number":149,"context_line":""},{"line_number":150,"context_line":"        now \u003d time.time()"},{"line_number":151,"context_line":"        if eof is False and self.next_emit_time \u003e now:"},{"line_number":152,"context_line":"            return"},{"line_number":153,"context_line":""},{"line_number":154,"context_line":"        if self.emit_bytes !\u003d 0:"}],"source_content_type":"text/x-python","patch_set":61,"id":"dc088321_eddbb1f3","line":151,"range":{"start_line":151,"start_character":8,"end_line":151,"end_character":24},"updated":"2025-07-28 14:00:11.000000000","message":"ok, so this is covered in TestProxyLogging but it would be nice to also have a simple test in TestBufferXferEmitCallback that covers this condition (eof\u003dTrue vs False)","commit_id":"74e88a1633605f28d0d5eb95d1c889616245a54f"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"6cd17935952a72154c46b0576c8d1e4c49521cdc","unresolved":true,"context_lines":[{"line_number":148,"context_line":"            return"},{"line_number":149,"context_line":""},{"line_number":150,"context_line":"        now \u003d time.time()"},{"line_number":151,"context_line":"        if eof is False and self.next_emit_time \u003e now:"},{"line_number":152,"context_line":"            return"},{"line_number":153,"context_line":""},{"line_number":154,"context_line":"        if self.emit_bytes !\u003d 0:"}],"source_content_type":"text/x-python","patch_set":61,"id":"fb10d324_e1a21a53","line":151,"range":{"start_line":151,"start_character":8,"end_line":151,"end_character":24},"in_reply_to":"dc088321_eddbb1f3","updated":"2025-08-01 15:49:03.000000000","message":"Acknowledged","commit_id":"74e88a1633605f28d0d5eb95d1c889616245a54f"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"718fe7ff32d084b0bcfa35aab8949d5d353da5f2","unresolved":false,"context_lines":[{"line_number":148,"context_line":"            return"},{"line_number":149,"context_line":""},{"line_number":150,"context_line":"        now \u003d time.time()"},{"line_number":151,"context_line":"        if eof is False and self.next_emit_time \u003e now:"},{"line_number":152,"context_line":"            return"},{"line_number":153,"context_line":""},{"line_number":154,"context_line":"        if self.emit_bytes !\u003d 0:"}],"source_content_type":"text/x-python","patch_set":61,"id":"7db5e731_ca6bee7b","line":151,"range":{"start_line":151,"start_character":8,"end_line":151,"end_character":24},"in_reply_to":"fb10d324_e1a21a53","updated":"2025-08-01 20:30:51.000000000","message":"Done","commit_id":"74e88a1633605f28d0d5eb95d1c889616245a54f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"144e64fa36b2a06eef9c238f2ce7f42c529efe6f","unresolved":true,"context_lines":[{"line_number":639,"context_line":"                env[\u0027swift.proxy_logging_status\u0027] \u003d 500"},{"line_number":640,"context_line":"                raise"},{"line_number":641,"context_line":"            finally:"},{"line_number":642,"context_line":"                statsd_emit_callback(\u0027\u0027, eof\u003dTrue)"},{"line_number":643,"context_line":"                env.setdefault(\u0027swift.proxy_logging_status\u0027, wire_status_int)"},{"line_number":644,"context_line":"                status_int \u003d status_int_for_logging()"},{"line_number":645,"context_line":"                self.log_request("}],"source_content_type":"text/x-python","patch_set":61,"id":"248aacc1_8dbf9b4c","line":642,"range":{"start_line":642,"start_character":37,"end_line":642,"end_character":39},"updated":"2025-07-25 17:44:50.000000000","message":"nit: `b\u0027\u0027` to be consistent about the types we ought to be passing around.","commit_id":"74e88a1633605f28d0d5eb95d1c889616245a54f"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"6cd17935952a72154c46b0576c8d1e4c49521cdc","unresolved":false,"context_lines":[{"line_number":639,"context_line":"                env[\u0027swift.proxy_logging_status\u0027] \u003d 500"},{"line_number":640,"context_line":"                raise"},{"line_number":641,"context_line":"            finally:"},{"line_number":642,"context_line":"                statsd_emit_callback(\u0027\u0027, eof\u003dTrue)"},{"line_number":643,"context_line":"                env.setdefault(\u0027swift.proxy_logging_status\u0027, wire_status_int)"},{"line_number":644,"context_line":"                status_int \u003d status_int_for_logging()"},{"line_number":645,"context_line":"                self.log_request("}],"source_content_type":"text/x-python","patch_set":61,"id":"8aeb24ff_6b535e58","line":642,"range":{"start_line":642,"start_character":37,"end_line":642,"end_character":39},"in_reply_to":"248aacc1_8dbf9b4c","updated":"2025-08-01 15:49:03.000000000","message":"Acknowledged","commit_id":"74e88a1633605f28d0d5eb95d1c889616245a54f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"fbfb2a73e3030a8ddeecea098b1d17d6043d82a1","unresolved":true,"context_lines":[{"line_number":158,"context_line":"                labels\u003dself.labels,"},{"line_number":159,"context_line":"            )"},{"line_number":160,"context_line":"        self.emit_bytes \u003d 0"},{"line_number":161,"context_line":"        self.next_emit_time \u003d (now + self.emit_buffer_xfer_bytes_sec)"},{"line_number":162,"context_line":""},{"line_number":163,"context_line":""},{"line_number":164,"context_line":"class ProxyLoggingMiddleware(object):"}],"source_content_type":"text/x-python","patch_set":65,"id":"3fd6428a_1251ffe4","line":161,"updated":"2025-08-07 12:33:31.000000000","message":"so are we requiring this callback to return the chunk or not? the CallbackInputProxy docstring says it should, but it isn\u0027t yet","commit_id":"d8a8d7e051e290790b5e8df57fca28166015a6c8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"42336a8cd9e9c574e3e1b551220f2baf412a2b0d","unresolved":false,"context_lines":[{"line_number":158,"context_line":"                labels\u003dself.labels,"},{"line_number":159,"context_line":"            )"},{"line_number":160,"context_line":"        self.emit_bytes \u003d 0"},{"line_number":161,"context_line":"        self.next_emit_time \u003d (now + self.emit_buffer_xfer_bytes_sec)"},{"line_number":162,"context_line":""},{"line_number":163,"context_line":""},{"line_number":164,"context_line":"class ProxyLoggingMiddleware(object):"}],"source_content_type":"text/x-python","patch_set":65,"id":"a16a9e9c_c8377624","line":161,"in_reply_to":"3fd6428a_1251ffe4","updated":"2025-08-07 22:46:58.000000000","message":"Done","commit_id":"d8a8d7e051e290790b5e8df57fca28166015a6c8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"94af435e5e843a4093f95790290a679681a01ea5","unresolved":true,"context_lines":[{"line_number":131,"context_line":"    def __init__(self, wsgi_input, callback):"},{"line_number":132,"context_line":"        super().__init__(wsgi_input)"},{"line_number":133,"context_line":"        self.callback \u003d (lambda chunk, eof\u003dNone: chunk) if callback is None \\"},{"line_number":134,"context_line":"            else callback"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"    def chunk_update(self, chunk, eof, *arg, **kwargs):"},{"line_number":137,"context_line":"        chunk \u003d self.callback(chunk, eof)"}],"source_content_type":"text/x-python","patch_set":66,"id":"bc1ba736_9c1e98d5","line":134,"updated":"2025-08-08 17:38:52.000000000","message":"now that the callback arg is required (good call by Tim!) there\u0027s no need to provide a default.\n\nWe don\u0027t typically \u0027check\u0027 every arg is of the expected type (e.g. not None) - it\u0027s just a bug if someone instantiates this class with callback\u003dNone.","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"4bcbfbcbc06a15be10d54b1253f8bd6a8e3bbcc3","unresolved":false,"context_lines":[{"line_number":131,"context_line":"    def __init__(self, wsgi_input, callback):"},{"line_number":132,"context_line":"        super().__init__(wsgi_input)"},{"line_number":133,"context_line":"        self.callback \u003d (lambda chunk, eof\u003dNone: chunk) if callback is None \\"},{"line_number":134,"context_line":"            else callback"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"    def chunk_update(self, chunk, eof, *arg, **kwargs):"},{"line_number":137,"context_line":"        chunk \u003d self.callback(chunk, eof)"}],"source_content_type":"text/x-python","patch_set":66,"id":"7c81518b_96eb2312","line":134,"in_reply_to":"bc1ba736_9c1e98d5","updated":"2025-08-08 20:17:53.000000000","message":"Acknowledged","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"94af435e5e843a4093f95790290a679681a01ea5","unresolved":true,"context_lines":[{"line_number":135,"context_line":""},{"line_number":136,"context_line":"    def chunk_update(self, chunk, eof, *arg, **kwargs):"},{"line_number":137,"context_line":"        chunk \u003d self.callback(chunk, eof)"},{"line_number":138,"context_line":"        return chunk"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"class BufferXferEmitCallback(object):"}],"source_content_type":"text/x-python","patch_set":66,"id":"76679c3e_0dc6efbb","line":138,"updated":"2025-08-08 17:38:52.000000000","message":"nit: the chunk variable isn\u0027t really necessary, just ``return self.callback(chunk, eof)``","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"4bcbfbcbc06a15be10d54b1253f8bd6a8e3bbcc3","unresolved":false,"context_lines":[{"line_number":135,"context_line":""},{"line_number":136,"context_line":"    def chunk_update(self, chunk, eof, *arg, **kwargs):"},{"line_number":137,"context_line":"        chunk \u003d self.callback(chunk, eof)"},{"line_number":138,"context_line":"        return chunk"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"class BufferXferEmitCallback(object):"}],"source_content_type":"text/x-python","patch_set":66,"id":"87016bd8_77ce14cd","line":138,"in_reply_to":"76679c3e_0dc6efbb","updated":"2025-08-08 20:17:53.000000000","message":"Done","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c21f8ce79fd1904a2a8ea1a8f3a5eeedd48c8ff8","unresolved":true,"context_lines":[{"line_number":157,"context_line":"           \"\"\""},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"        if self.emit_buffer_xfer_bytes_sec \u003c 0:"},{"line_number":160,"context_line":"            return buffer"},{"line_number":161,"context_line":"        buffer_len \u003d len(buffer)"},{"line_number":162,"context_line":"        self.emit_bytes +\u003d buffer_len"},{"line_number":163,"context_line":"        if not self.labels.get(\u0027account\u0027, None):"}],"source_content_type":"text/x-python","patch_set":67,"id":"16bd2785_8cba4092","line":160,"updated":"2025-08-11 13:37:44.000000000","message":"while I was playing with this in my VSAIO I realised that *every* request has a first stat emitted for 65536 bytes because this callback starts life with next_emit_time \u003d 0.\n\nI wonder if we might want to add an early return here to suppress that, i.e.\n```\nif self.next_emit_time \u003d\u003d 0:\n    return buffer\n```","commit_id":"752531a59abaad6978e1e3ed6e0f0c47abd10472"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed17a4c7ab656b8c1515a91dc93db37242d8d334","unresolved":true,"context_lines":[{"line_number":157,"context_line":"           \"\"\""},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"        if self.emit_buffer_xfer_bytes_sec \u003c 0:"},{"line_number":160,"context_line":"            return buffer"},{"line_number":161,"context_line":"        buffer_len \u003d len(buffer)"},{"line_number":162,"context_line":"        self.emit_bytes +\u003d buffer_len"},{"line_number":163,"context_line":"        if not self.labels.get(\u0027account\u0027, None):"}],"source_content_type":"text/x-python","patch_set":67,"id":"25b0aa1f_c501a541","line":160,"in_reply_to":"16bd2785_8cba4092","updated":"2025-08-11 14:17:00.000000000","message":"that would clearly not be right, something more like:\n\n```\nif self.next_emit_time \u003d\u003d 0:\n    self.next_emit_time \u003d (now + self.emit_buffer_xfer_bytes_sec)\n    return buffer\n```","commit_id":"752531a59abaad6978e1e3ed6e0f0c47abd10472"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"504f1547325aa77e6e44f5dea300a57dda4ba0e4","unresolved":false,"context_lines":[{"line_number":157,"context_line":"           \"\"\""},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"        if self.emit_buffer_xfer_bytes_sec \u003c 0:"},{"line_number":160,"context_line":"            return buffer"},{"line_number":161,"context_line":"        buffer_len \u003d len(buffer)"},{"line_number":162,"context_line":"        self.emit_bytes +\u003d buffer_len"},{"line_number":163,"context_line":"        if not self.labels.get(\u0027account\u0027, None):"}],"source_content_type":"text/x-python","patch_set":67,"id":"ba8d601d_445fb8d4","line":160,"in_reply_to":"25b0aa1f_c501a541","updated":"2025-09-03 19:00:05.000000000","message":"Acknowledged","commit_id":"752531a59abaad6978e1e3ed6e0f0c47abd10472"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c21f8ce79fd1904a2a8ea1a8f3a5eeedd48c8ff8","unresolved":true,"context_lines":[{"line_number":176,"context_line":"            )"},{"line_number":177,"context_line":"        self.emit_bytes \u003d 0"},{"line_number":178,"context_line":"        self.next_emit_time \u003d (now + self.emit_buffer_xfer_bytes_sec)"},{"line_number":179,"context_line":"        return buffer"},{"line_number":180,"context_line":""},{"line_number":181,"context_line":""},{"line_number":182,"context_line":"class ProxyLoggingMiddleware(object):"}],"source_content_type":"text/x-python","patch_set":67,"id":"be4e2e47_e2f6d5b8","line":179,"updated":"2025-08-11 13:37:44.000000000","message":"nit: we could avoid having to ``return buffer`` in multiple places (which is just waiting for someone to add another return and forget to return the buffer) by making ``__call__()`` very simple and move all the logic to another ``_maybe_emit_stat`` method that just has empty returns:\n\n```\ndef __call__(self, buffer, eof\u003dFalse):\n    self._maybe_emit_stat(buffer, eof)\n    return buffer\n```","commit_id":"752531a59abaad6978e1e3ed6e0f0c47abd10472"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"504f1547325aa77e6e44f5dea300a57dda4ba0e4","unresolved":false,"context_lines":[{"line_number":176,"context_line":"            )"},{"line_number":177,"context_line":"        self.emit_bytes \u003d 0"},{"line_number":178,"context_line":"        self.next_emit_time \u003d (now + self.emit_buffer_xfer_bytes_sec)"},{"line_number":179,"context_line":"        return buffer"},{"line_number":180,"context_line":""},{"line_number":181,"context_line":""},{"line_number":182,"context_line":"class ProxyLoggingMiddleware(object):"}],"source_content_type":"text/x-python","patch_set":67,"id":"7e14c227_12195e93","line":179,"in_reply_to":"be4e2e47_e2f6d5b8","updated":"2025-09-03 19:00:05.000000000","message":"Acknowledged","commit_id":"752531a59abaad6978e1e3ed6e0f0c47abd10472"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c21f8ce79fd1904a2a8ea1a8f3a5eeedd48c8ff8","unresolved":true,"context_lines":[{"line_number":199,"context_line":"        # convert it now to prevent useless convertion later."},{"line_number":200,"context_line":"        self.anonymization_method \u003d conf.get(\u0027log_anonymization_method\u0027, \u0027md5\u0027)"},{"line_number":201,"context_line":"        self.anonymization_salt \u003d conf.get(\u0027log_anonymization_salt\u0027, \u0027\u0027)"},{"line_number":202,"context_line":"        self.storage_domains \u003d list_from_csv(conf.get(\u0027storage_domain\u0027, \u0027\u0027))"},{"line_number":203,"context_line":"        self.log_hdrs \u003d config_true_value(conf.get("},{"line_number":204,"context_line":"            \u0027access_log_headers\u0027,"},{"line_number":205,"context_line":"            conf.get(\u0027log_headers\u0027, \u0027no\u0027)))"}],"source_content_type":"text/x-python","patch_set":67,"id":"6e655e16_b996c32d","line":202,"updated":"2025-08-11 13:37:44.000000000","message":"I was thinking more about Tim\u0027s earlier comment that this is an unfortunate bleeding of conf options...\n\nGiven that the left most proxy-logging cannot infer the account for an s3 request, and therefore defers populating the ``account`` field in ``base_labels`` to the rightmost proxy-logging, we could also defer populating the container field to rightmost proxy-logging, by which time s3api will have translated the path for bucket-in-host. Then we don\u0027t need to know about storage_domain here. The ``base_labels`` aren\u0027t useful until they have ``account`` so there\u0027s no urgency to infer ``container`` without ``account``.\n\nHowever, the container may be further modified by s3api (or other middleware) for example to route a PUT to a segments bucket, so we\u0027d need to decide *which* container we want to label the stat with. Sigh! IIRC ``swift.backend_path`` actually adopts the segments container, so which direction do we want to go to eventually have all the stats report consistent labels?","commit_id":"752531a59abaad6978e1e3ed6e0f0c47abd10472"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"504f1547325aa77e6e44f5dea300a57dda4ba0e4","unresolved":false,"context_lines":[{"line_number":199,"context_line":"        # convert it now to prevent useless convertion later."},{"line_number":200,"context_line":"        self.anonymization_method \u003d conf.get(\u0027log_anonymization_method\u0027, \u0027md5\u0027)"},{"line_number":201,"context_line":"        self.anonymization_salt \u003d conf.get(\u0027log_anonymization_salt\u0027, \u0027\u0027)"},{"line_number":202,"context_line":"        self.storage_domains \u003d list_from_csv(conf.get(\u0027storage_domain\u0027, \u0027\u0027))"},{"line_number":203,"context_line":"        self.log_hdrs \u003d config_true_value(conf.get("},{"line_number":204,"context_line":"            \u0027access_log_headers\u0027,"},{"line_number":205,"context_line":"            conf.get(\u0027log_headers\u0027, \u0027no\u0027)))"}],"source_content_type":"text/x-python","patch_set":67,"id":"f1050017_9f26b953","line":202,"in_reply_to":"6e655e16_b996c32d","updated":"2025-09-03 19:00:05.000000000","message":"Discussed in the meeting","commit_id":"752531a59abaad6978e1e3ed6e0f0c47abd10472"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"b13aaec32653c7cb6d0b7c00ede2b860498b0144","unresolved":true,"context_lines":[{"line_number":645,"context_line":"            statsd_emit_callback \u003d BufferXferEmitCallback("},{"line_number":646,"context_line":"                \u0027swift_proxy_server_response_body_streaming_bytes\u0027,"},{"line_number":647,"context_line":"                resp_xfer_labels,"},{"line_number":648,"context_line":"                self.statsd, self.emit_buffer_xfer_bytes_sec)"},{"line_number":649,"context_line":"            try:"},{"line_number":650,"context_line":"                for chunk in iterator:"},{"line_number":651,"context_line":"                    bytes_sent +\u003d len(chunk)"}],"source_content_type":"text/x-python","patch_set":67,"id":"d8f1899c_48de628d","line":648,"updated":"2025-08-25 06:44:46.000000000","message":"Umm, didn\u0027t we already wrap the request input with a new callback version of the ProxyInput object with a BufferXferEmitCallback as a callback to emit stats back on line 566 - 574?\n\nAnd now we\u0027re creating the callback again and manually using it again, I thought wrapping the imput already did this, are we now emiting the stats twice now?\n\nI guess it\u0027s time to pull this into my VSAIO and fire it up properly and find out.","commit_id":"752531a59abaad6978e1e3ed6e0f0c47abd10472"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"504f1547325aa77e6e44f5dea300a57dda4ba0e4","unresolved":false,"context_lines":[{"line_number":645,"context_line":"            statsd_emit_callback \u003d BufferXferEmitCallback("},{"line_number":646,"context_line":"                \u0027swift_proxy_server_response_body_streaming_bytes\u0027,"},{"line_number":647,"context_line":"                resp_xfer_labels,"},{"line_number":648,"context_line":"                self.statsd, self.emit_buffer_xfer_bytes_sec)"},{"line_number":649,"context_line":"            try:"},{"line_number":650,"context_line":"                for chunk in iterator:"},{"line_number":651,"context_line":"                    bytes_sent +\u003d len(chunk)"}],"source_content_type":"text/x-python","patch_set":67,"id":"6d6f684c_f09fcd28","line":648,"in_reply_to":"37620a2f_6f500158","updated":"2025-09-03 19:00:05.000000000","message":"Done","commit_id":"752531a59abaad6978e1e3ed6e0f0c47abd10472"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"37a14d43fdbd6d6681d7e180153e2f52cc8b7404","unresolved":true,"context_lines":[{"line_number":645,"context_line":"            statsd_emit_callback \u003d BufferXferEmitCallback("},{"line_number":646,"context_line":"                \u0027swift_proxy_server_response_body_streaming_bytes\u0027,"},{"line_number":647,"context_line":"                resp_xfer_labels,"},{"line_number":648,"context_line":"                self.statsd, self.emit_buffer_xfer_bytes_sec)"},{"line_number":649,"context_line":"            try:"},{"line_number":650,"context_line":"                for chunk in iterator:"},{"line_number":651,"context_line":"                    bytes_sent +\u003d len(chunk)"}],"source_content_type":"text/x-python","patch_set":67,"id":"37620a2f_6f500158","line":648,"in_reply_to":"3c7d17e8_e2b028e9","updated":"2025-08-29 08:08:08.000000000","message":"ahh right, yeah I see that now. First on the req input.. thats as we read it. And this is the response, got it! Thanks Tim\n\nKinda wish is was as seamless as the coming in. like we could wrap in iterable coming in or iterater.. but yeah this makes sense now","commit_id":"752531a59abaad6978e1e3ed6e0f0c47abd10472"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ea59bdc7df092684f0fd45d3d9f3f8bd2eceb3f1","unresolved":true,"context_lines":[{"line_number":645,"context_line":"            statsd_emit_callback \u003d BufferXferEmitCallback("},{"line_number":646,"context_line":"                \u0027swift_proxy_server_response_body_streaming_bytes\u0027,"},{"line_number":647,"context_line":"                resp_xfer_labels,"},{"line_number":648,"context_line":"                self.statsd, self.emit_buffer_xfer_bytes_sec)"},{"line_number":649,"context_line":"            try:"},{"line_number":650,"context_line":"                for chunk in iterator:"},{"line_number":651,"context_line":"                    bytes_sent +\u003d len(chunk)"}],"source_content_type":"text/x-python","patch_set":67,"id":"3c7d17e8_e2b028e9","line":648,"in_reply_to":"d8f1899c_48de628d","updated":"2025-08-25 15:48:19.000000000","message":"So the `CallbackInputProxy` is being used to track request body bytes *coming in*; this one is for response body bytes *going out*.","commit_id":"752531a59abaad6978e1e3ed6e0f0c47abd10472"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f719d84280a8c3c93378a84805a52e9720b34b4e","unresolved":true,"context_lines":[{"line_number":144,"context_line":"        self.statsd \u003d statsd"},{"line_number":145,"context_line":"        self.emit_buffer_xfer_bytes_sec \u003d emit_buffer_xfer_bytes_sec"},{"line_number":146,"context_line":"        self.emit_bytes \u003d 0"},{"line_number":147,"context_line":"        self.next_emit_time \u003d 0"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"    def __call__(self, buffer, eof\u003dFalse):"},{"line_number":150,"context_line":"        self._maybe_emit_stat(buffer, eof)"}],"source_content_type":"text/x-python","patch_set":75,"id":"2ffd4559_362f305e","line":147,"updated":"2025-09-24 22:04:31.000000000","message":"What do we think about doing `self.next_emit_time \u003d (time.time() + self.emit_buffer_xfer_bytes_sec)` here? I think Alistair had a similar idea a few patchsets ago. I guess it gets a little more complicated if you want to keep test churn down, but I think this diff would be fairly reasonable: https://paste.opendev.org/show/bxMEBnHf4ayWvWbov7OU/\n\nOTOH, maybe it\u0027s kind of a good thing to get *some* value out there for the timeseries ASAP, so taking a rate of the counter works as quickly as possible...","commit_id":"e4bac03afdc5b67284407a8a585eea20d624cddb"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"79e53f5d982a5df59c1b5b89ec7abbb7901bfdf1","unresolved":false,"context_lines":[{"line_number":144,"context_line":"        self.statsd \u003d statsd"},{"line_number":145,"context_line":"        self.emit_buffer_xfer_bytes_sec \u003d emit_buffer_xfer_bytes_sec"},{"line_number":146,"context_line":"        self.emit_bytes \u003d 0"},{"line_number":147,"context_line":"        self.next_emit_time \u003d 0"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"    def __call__(self, buffer, eof\u003dFalse):"},{"line_number":150,"context_line":"        self._maybe_emit_stat(buffer, eof)"}],"source_content_type":"text/x-python","patch_set":75,"id":"bd2d46c1_451124d0","line":147,"in_reply_to":"2ffd4559_362f305e","updated":"2025-10-07 15:36:59.000000000","message":"Acknowledged","commit_id":"e4bac03afdc5b67284407a8a585eea20d624cddb"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f719d84280a8c3c93378a84805a52e9720b34b4e","unresolved":true,"context_lines":[{"line_number":166,"context_line":"        self.emit_bytes +\u003d buffer_len"},{"line_number":167,"context_line":"        if not self.labels.get(\u0027account\u0027, None):"},{"line_number":168,"context_line":"            # tolerate no account, maybe it\u0027ll be there in time for next stat"},{"line_number":169,"context_line":"            return"},{"line_number":170,"context_line":""},{"line_number":171,"context_line":"        now \u003d time.time()"},{"line_number":172,"context_line":"        if eof is False and self.next_emit_time \u003e now:"}],"source_content_type":"text/x-python","patch_set":75,"id":"51f9598b_02c258e3","line":169,"updated":"2025-09-24 22:04:31.000000000","message":"Interesting... so if the account label *never* shows up, we don\u0027t emit the stat? Even when `eof` is true...","commit_id":"e4bac03afdc5b67284407a8a585eea20d624cddb"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"79e53f5d982a5df59c1b5b89ec7abbb7901bfdf1","unresolved":true,"context_lines":[{"line_number":166,"context_line":"        self.emit_bytes +\u003d buffer_len"},{"line_number":167,"context_line":"        if not self.labels.get(\u0027account\u0027, None):"},{"line_number":168,"context_line":"            # tolerate no account, maybe it\u0027ll be there in time for next stat"},{"line_number":169,"context_line":"            return"},{"line_number":170,"context_line":""},{"line_number":171,"context_line":"        now \u003d time.time()"},{"line_number":172,"context_line":"        if eof is False and self.next_emit_time \u003e now:"}],"source_content_type":"text/x-python","patch_set":75,"id":"97b5ed9d_52d67a96","line":169,"in_reply_to":"51f9598b_02c258e3","updated":"2025-10-07 15:36:59.000000000","message":"If the account label never shows up, do we still want to emit stats? If there\u0027s no valid account, there might not be a valid container and other useful labels too.","commit_id":"e4bac03afdc5b67284407a8a585eea20d624cddb"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"bb73cfefbee08032ad27edd00b6f5c0e9da82f79","unresolved":false,"context_lines":[{"line_number":166,"context_line":"        self.emit_bytes +\u003d buffer_len"},{"line_number":167,"context_line":"        if not self.labels.get(\u0027account\u0027, None):"},{"line_number":168,"context_line":"            # tolerate no account, maybe it\u0027ll be there in time for next stat"},{"line_number":169,"context_line":"            return"},{"line_number":170,"context_line":""},{"line_number":171,"context_line":"        now \u003d time.time()"},{"line_number":172,"context_line":"        if eof is False and self.next_emit_time \u003e now:"}],"source_content_type":"text/x-python","patch_set":75,"id":"6e2a72a6_943704c2","line":169,"in_reply_to":"97b5ed9d_52d67a96","updated":"2025-10-10 18:27:29.000000000","message":"Done","commit_id":"e4bac03afdc5b67284407a8a585eea20d624cddb"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f719d84280a8c3c93378a84805a52e9720b34b4e","unresolved":true,"context_lines":[{"line_number":180,"context_line":"            )"},{"line_number":181,"context_line":"        self.emit_bytes \u003d 0"},{"line_number":182,"context_line":"        self.next_emit_time \u003d (now + self.emit_buffer_xfer_bytes_sec)"},{"line_number":183,"context_line":"        return"},{"line_number":184,"context_line":""},{"line_number":185,"context_line":""},{"line_number":186,"context_line":"class ProxyLoggingMiddleware(object):"}],"source_content_type":"text/x-python","patch_set":75,"id":"2151de77_dd1abc6a","line":183,"updated":"2025-09-24 22:04:31.000000000","message":"nit: Could drop the explicit return.","commit_id":"e4bac03afdc5b67284407a8a585eea20d624cddb"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"79e53f5d982a5df59c1b5b89ec7abbb7901bfdf1","unresolved":false,"context_lines":[{"line_number":180,"context_line":"            )"},{"line_number":181,"context_line":"        self.emit_bytes \u003d 0"},{"line_number":182,"context_line":"        self.next_emit_time \u003d (now + self.emit_buffer_xfer_bytes_sec)"},{"line_number":183,"context_line":"        return"},{"line_number":184,"context_line":""},{"line_number":185,"context_line":""},{"line_number":186,"context_line":"class ProxyLoggingMiddleware(object):"}],"source_content_type":"text/x-python","patch_set":75,"id":"b0c2c7b3_7ce05d5d","line":183,"in_reply_to":"2151de77_dd1abc6a","updated":"2025-10-07 15:36:59.000000000","message":"Acknowledged","commit_id":"e4bac03afdc5b67284407a8a585eea20d624cddb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"76643d87c6df6f4e4763013d011e0eb171b67d10","unresolved":true,"context_lines":[{"line_number":348,"context_line":"        :returns: User ID for logging if available, None otherwise"},{"line_number":349,"context_line":"        \"\"\""},{"line_number":350,"context_line":"        return req.environ.get("},{"line_number":351,"context_line":"            \u0027swift.access_logging\u0027, {}).get(\u0027user_id\u0027)"},{"line_number":352,"context_line":""},{"line_number":353,"context_line":"    def log_request(self, req, status_int, bytes_received, bytes_sent,"},{"line_number":354,"context_line":"                    start_time, end_time, resp_headers\u003dNone, ttfb\u003d0,"}],"source_content_type":"text/x-python","patch_set":84,"id":"968a6523_afdb9d43","line":351,"updated":"2025-10-13 15:54:33.000000000","message":"nit: unnecessary change","commit_id":"042e31fd0d5e282c830fd7ca2186e4a7aec31533"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"bf6fcd6af598f6f2171b61e9ee5ae1889d99cfc0","unresolved":false,"context_lines":[{"line_number":348,"context_line":"        :returns: User ID for logging if available, None otherwise"},{"line_number":349,"context_line":"        \"\"\""},{"line_number":350,"context_line":"        return req.environ.get("},{"line_number":351,"context_line":"            \u0027swift.access_logging\u0027, {}).get(\u0027user_id\u0027)"},{"line_number":352,"context_line":""},{"line_number":353,"context_line":"    def log_request(self, req, status_int, bytes_received, bytes_sent,"},{"line_number":354,"context_line":"                    start_time, end_time, resp_headers\u003dNone, ttfb\u003d0,"}],"source_content_type":"text/x-python","patch_set":84,"id":"b5492d40_11ea6ede","line":351,"in_reply_to":"968a6523_afdb9d43","updated":"2025-10-13 16:29:50.000000000","message":"Acknowledged","commit_id":"042e31fd0d5e282c830fd7ca2186e4a7aec31533"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"76643d87c6df6f4e4763013d011e0eb171b67d10","unresolved":true,"context_lines":[{"line_number":632,"context_line":"            start_response(*start_response_args[0])"},{"line_number":633,"context_line":""},{"line_number":634,"context_line":"            policy_index \u003d get_policy_index(req.headers, resp_headers)"},{"line_number":635,"context_line":"            swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"},{"line_number":636,"context_line":"            acc, cont, _ \u003d self.get_aco_from_path(swift_path)"},{"line_number":637,"context_line":"            labels \u003d self.statsd_metric_labels("},{"line_number":638,"context_line":"                req, wire_status_int, method,"},{"line_number":639,"context_line":"                acc\u003dacc, cont\u003dcont, policy_index\u003dpolicy_index)"},{"line_number":640,"context_line":""},{"line_number":641,"context_line":"            # Log timing information for time-to-first-byte (GET requests only)"},{"line_number":642,"context_line":"            ttfb \u003d 0.0"}],"source_content_type":"text/x-python","patch_set":84,"id":"55ab52bd_2166726e","line":639,"range":{"start_line":635,"start_character":12,"end_line":639,"end_character":62},"updated":"2025-10-13 15:54:33.000000000","message":"lines 635 to 639 didn\u0027t need to move - we just needed the policy_index to use outside the ``if clause``\n\nI think it would best to move them back to as they were because (a) the diff will be smaller and (b) it\u0027s confusing to see a labels dict created here but then another different one created at line 663 (eventually they should be the same when we normalise the legacy labels but not in this patch)","commit_id":"042e31fd0d5e282c830fd7ca2186e4a7aec31533"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"bf6fcd6af598f6f2171b61e9ee5ae1889d99cfc0","unresolved":false,"context_lines":[{"line_number":632,"context_line":"            start_response(*start_response_args[0])"},{"line_number":633,"context_line":""},{"line_number":634,"context_line":"            policy_index \u003d get_policy_index(req.headers, resp_headers)"},{"line_number":635,"context_line":"            swift_path \u003d req.environ.get(\u0027swift.backend_path\u0027, req.path)"},{"line_number":636,"context_line":"            acc, cont, _ \u003d self.get_aco_from_path(swift_path)"},{"line_number":637,"context_line":"            labels \u003d self.statsd_metric_labels("},{"line_number":638,"context_line":"                req, wire_status_int, method,"},{"line_number":639,"context_line":"                acc\u003dacc, cont\u003dcont, policy_index\u003dpolicy_index)"},{"line_number":640,"context_line":""},{"line_number":641,"context_line":"            # Log timing information for time-to-first-byte (GET requests only)"},{"line_number":642,"context_line":"            ttfb \u003d 0.0"}],"source_content_type":"text/x-python","patch_set":84,"id":"6f5ff4ee_d3619da1","line":639,"range":{"start_line":635,"start_character":12,"end_line":639,"end_character":62},"in_reply_to":"55ab52bd_2166726e","updated":"2025-10-13 16:29:50.000000000","message":"Acknowledged","commit_id":"042e31fd0d5e282c830fd7ca2186e4a7aec31533"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"fd08a6b9075fc5125bb65152f0ac612e74508e53","unresolved":true,"context_lines":[{"line_number":182,"context_line":"                labels\u003dself.labels,"},{"line_number":183,"context_line":"            )"},{"line_number":184,"context_line":"        self.emit_bytes \u003d 0"},{"line_number":185,"context_line":"        self.next_emit_time \u003d (now + self.emit_buffer_xfer_bytes_sec)"},{"line_number":186,"context_line":""},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"class ProxyLoggingMiddleware(object):"}],"source_content_type":"text/x-python","patch_set":88,"id":"bf905981_98e3fca5","line":185,"updated":"2025-11-03 04:33:51.000000000","message":"Because this is resetting the emit_bytes to 0, should this be a counter or a guage? It feels like it should be guage rather then a counter. I guess its fine if we can take into account the old value. to find the differnece. But counters don\u0027t really reset do they.\n\nI guess it depends if were tracking the current throughput speed of an account or tracking an upload or download over time.\n\nIf we were to support and use a guage, then maybe we\u0027d also want to send emit 0\u0027s so we could track stalled downloads to stuck clients or what not.","commit_id":"dcd5a265f6f36551e0bc0feac0e08bfdd09301a3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"6806342e03965f5ec7301292ef7c3f255797b395","unresolved":true,"context_lines":[{"line_number":182,"context_line":"                labels\u003dself.labels,"},{"line_number":183,"context_line":"            )"},{"line_number":184,"context_line":"        self.emit_bytes \u003d 0"},{"line_number":185,"context_line":"        self.next_emit_time \u003d (now + self.emit_buffer_xfer_bytes_sec)"},{"line_number":186,"context_line":""},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"class ProxyLoggingMiddleware(object):"}],"source_content_type":"text/x-python","patch_set":88,"id":"ecacaf2a_6ddd95aa","line":185,"in_reply_to":"bf905981_98e3fca5","updated":"2025-11-03 16:23:39.000000000","message":"Thanks for the comment, Matt! you are right about gauge. indeed this is resetting the emit_bytes to 0, although that is the increment value, not the the counter value, so the counter would still only increase. Tracking stalled downloads to stuck clients sounds like an interesting idea, we could discuss about that","commit_id":"dcd5a265f6f36551e0bc0feac0e08bfdd09301a3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"8ae5e38e20ef7737af2a6b2864c877fa68c5a26e","unresolved":true,"context_lines":[{"line_number":182,"context_line":"                labels\u003dself.labels,"},{"line_number":183,"context_line":"            )"},{"line_number":184,"context_line":"        self.emit_bytes \u003d 0"},{"line_number":185,"context_line":"        self.next_emit_time \u003d (now + self.emit_buffer_xfer_bytes_sec)"},{"line_number":186,"context_line":""},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"class ProxyLoggingMiddleware(object):"}],"source_content_type":"text/x-python","patch_set":88,"id":"06eb26ed_71328237","line":185,"in_reply_to":"ecacaf2a_6ddd95aa","updated":"2025-11-03 16:59:31.000000000","message":"``emit_bytes`` is the count of bytes since the last time the same metric was emitted. The metric semantic is the same as the existing bytes counter that is updated at the end of the request in log_request, except this counter is updated piecemeal during the transfer rather than all at once at the end.","commit_id":"dcd5a265f6f36551e0bc0feac0e08bfdd09301a3"}],"swift/common/middleware/s3api/s3request.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"735abc7928e73bf5b3f3464946fe04633df6fb42","unresolved":true,"context_lines":[{"line_number":1458,"context_line":"        sw_req \u003d self.to_swift_req(method, container, obj, headers\u003dheaders,"},{"line_number":1459,"context_line":"                                   body\u003dbody, query\u003dquery)"},{"line_number":1460,"context_line":""},{"line_number":1461,"context_line":"        sw_req.environ[\u0027backpropagate_proxy_env\u0027] \u003d self.environ"},{"line_number":1462,"context_line":""},{"line_number":1463,"context_line":"        try:"},{"line_number":1464,"context_line":"            sw_resp \u003d sw_req.get_response(app)"}],"source_content_type":"text/x-python","patch_set":2,"id":"ddaad713_6f424f76","line":1461,"updated":"2024-10-07 17:15:03.000000000","message":"whoa; do we need/want the *whole* environ to have a backref?\n\nmaybe better to just stuff the information we need in the req environ when we need it.","commit_id":"93971c11c36809e4f15deb33704f4929c44ec3ab"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"6578bf38dcfbbb449948bb15e330a17d5db773cf","unresolved":false,"context_lines":[{"line_number":1458,"context_line":"        sw_req \u003d self.to_swift_req(method, container, obj, headers\u003dheaders,"},{"line_number":1459,"context_line":"                                   body\u003dbody, query\u003dquery)"},{"line_number":1460,"context_line":""},{"line_number":1461,"context_line":"        sw_req.environ[\u0027backpropagate_proxy_env\u0027] \u003d self.environ"},{"line_number":1462,"context_line":""},{"line_number":1463,"context_line":"        try:"},{"line_number":1464,"context_line":"            sw_resp \u003d sw_req.get_response(app)"}],"source_content_type":"text/x-python","patch_set":2,"id":"7ff0d8f7_f9aa4c47","line":1461,"in_reply_to":"64914a51_043ccc67","updated":"2024-10-11 15:33:16.000000000","message":"Acknowledged","commit_id":"93971c11c36809e4f15deb33704f4929c44ec3ab"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"cf087b0546a525a7c0b6b9144552345ff5068d98","unresolved":true,"context_lines":[{"line_number":1458,"context_line":"        sw_req \u003d self.to_swift_req(method, container, obj, headers\u003dheaders,"},{"line_number":1459,"context_line":"                                   body\u003dbody, query\u003dquery)"},{"line_number":1460,"context_line":""},{"line_number":1461,"context_line":"        sw_req.environ[\u0027backpropagate_proxy_env\u0027] \u003d self.environ"},{"line_number":1462,"context_line":""},{"line_number":1463,"context_line":"        try:"},{"line_number":1464,"context_line":"            sw_resp \u003d sw_req.get_response(app)"}],"source_content_type":"text/x-python","patch_set":2,"id":"64914a51_043ccc67","line":1461,"in_reply_to":"ddaad713_6f424f76","updated":"2024-10-11 15:22:05.000000000","message":"Ack. Updated to include necessary info","commit_id":"93971c11c36809e4f15deb33704f4929c44ec3ab"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"88385b4cb0bf4ad1b773fc44366c408fde5ed0b7","unresolved":true,"context_lines":[{"line_number":1456,"context_line":"            obj \u003d self.object_name"},{"line_number":1457,"context_line":""},{"line_number":1458,"context_line":"        sw_req \u003d self.to_swift_req(method, container, obj, headers\u003dheaders,"},{"line_number":1459,"context_line":"                                   body\u003dbody, query\u003dquery)"},{"line_number":1460,"context_line":""},{"line_number":1461,"context_line":"        proxy_env \u003d {}"},{"line_number":1462,"context_line":"        self.environ[\u0027backpropagate_proxy_env\u0027] \u003d proxy_env"}],"source_content_type":"text/x-python","patch_set":4,"id":"e1edbe7f_4f9cfd65","line":1459,"updated":"2024-10-29 17:29:39.000000000","message":"N.B. this request PATH_INFO is not correct yet - the access_key_id is getting stuffed in the the account part of the path.\n\ntempauth is doing this:\n\n```\n            user \u003d self.users[account_user]\n            account \u003d account_user.split(\u0027:\u0027, 1)[0]\n            account_id \u003d user[\u0027url\u0027].rsplit(\u0027/\u0027, 1)[-1]\n            if not s3_auth_details[\u0027check_signature\u0027](user[\u0027key\u0027]):\n                return None\n            env[\u0027PATH_INFO\u0027] \u003d env[\u0027PATH_INFO\u0027].replace(\n                str_to_wsgi(account_user), wsgi_unquote(account_id), 1)\n            groups \u003d self._get_user_groups(account, account_user, account_id)\n```\n\nS8KA does something similar; it calls `check_signature` and then it modifies the request PATH_INFO\n\nSo it looks like s3api consistently doesn\u0027t get to know what the actual swift-request PATH is going to be until it gets the response.","commit_id":"cdb1cdf7df5bdc8bfcf782b7efa622976eb0df1b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"770fc5ba81f79fd485837068bcefe7f8e5d99a74","unresolved":false,"context_lines":[{"line_number":1456,"context_line":"            obj \u003d self.object_name"},{"line_number":1457,"context_line":""},{"line_number":1458,"context_line":"        sw_req \u003d self.to_swift_req(method, container, obj, headers\u003dheaders,"},{"line_number":1459,"context_line":"                                   body\u003dbody, query\u003dquery)"},{"line_number":1460,"context_line":""},{"line_number":1461,"context_line":"        proxy_env \u003d {}"},{"line_number":1462,"context_line":"        self.environ[\u0027backpropagate_proxy_env\u0027] \u003d proxy_env"}],"source_content_type":"text/x-python","patch_set":4,"id":"49aad780_ea4d3097","line":1459,"in_reply_to":"e1edbe7f_4f9cfd65","updated":"2024-11-01 15:35:26.000000000","message":"Acknowledged","commit_id":"cdb1cdf7df5bdc8bfcf782b7efa622976eb0df1b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"88385b4cb0bf4ad1b773fc44366c408fde5ed0b7","unresolved":true,"context_lines":[{"line_number":1461,"context_line":"        proxy_env \u003d {}"},{"line_number":1462,"context_line":"        self.environ[\u0027backpropagate_proxy_env\u0027] \u003d proxy_env"},{"line_number":1463,"context_line":"        sw_req.environ[\u0027backpropagate_proxy_env\u0027] \u003d proxy_env"},{"line_number":1464,"context_line":""},{"line_number":1465,"context_line":"        try:"},{"line_number":1466,"context_line":"            sw_resp \u003d sw_req.get_response(app)"},{"line_number":1467,"context_line":"        except S3InputSHA256Mismatch as err:"}],"source_content_type":"text/x-python","patch_set":4,"id":"92ab85fc_21e10f02","line":1464,"updated":"2024-10-29 17:29:39.000000000","message":"this looks weird, we\u0027re creating an empty dict and stuffing it in both our request environ and the swift request environ - which are already dicts.  Why not just put in the values we want when we have them?\n\nNew environ keys that we use for mw-message-passing typically get namespaced with `swift.xxx` by convention","commit_id":"cdb1cdf7df5bdc8bfcf782b7efa622976eb0df1b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"770fc5ba81f79fd485837068bcefe7f8e5d99a74","unresolved":false,"context_lines":[{"line_number":1461,"context_line":"        proxy_env \u003d {}"},{"line_number":1462,"context_line":"        self.environ[\u0027backpropagate_proxy_env\u0027] \u003d proxy_env"},{"line_number":1463,"context_line":"        sw_req.environ[\u0027backpropagate_proxy_env\u0027] \u003d proxy_env"},{"line_number":1464,"context_line":""},{"line_number":1465,"context_line":"        try:"},{"line_number":1466,"context_line":"            sw_resp \u003d sw_req.get_response(app)"},{"line_number":1467,"context_line":"        except S3InputSHA256Mismatch as err:"}],"source_content_type":"text/x-python","patch_set":4,"id":"92830428_809a4e2d","line":1464,"in_reply_to":"92ab85fc_21e10f02","updated":"2024-11-01 15:35:26.000000000","message":"Acknowledged","commit_id":"cdb1cdf7df5bdc8bfcf782b7efa622976eb0df1b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e6df311bac282d96055b00037a8324cedb49d04a","unresolved":true,"context_lines":[{"line_number":557,"context_line":""},{"line_number":558,"context_line":"    def __init__(self, env, app\u003dNone, conf\u003dNone):"},{"line_number":559,"context_line":"        # NOTE: app is not used by this class, need for compatibility of S3acl"},{"line_number":560,"context_line":"        swob.Request.__init__(self, env)"},{"line_number":561,"context_line":"        self.conf \u003d conf or Config()"},{"line_number":562,"context_line":"        self.location \u003d self.conf.location"},{"line_number":563,"context_line":"        self._timestamp \u003d None"}],"source_content_type":"text/x-python","patch_set":6,"id":"c63b8547_99c79452","line":560,"updated":"2024-11-19 18:58:22.000000000","message":"this is where the tagging of the root/user req environ should happen\n\nwe think for now that to_swift_req should propagate this tagging.","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":557,"context_line":""},{"line_number":558,"context_line":"    def __init__(self, env, app\u003dNone, conf\u003dNone):"},{"line_number":559,"context_line":"        # NOTE: app is not used by this class, need for compatibility of S3acl"},{"line_number":560,"context_line":"        swob.Request.__init__(self, env)"},{"line_number":561,"context_line":"        self.conf \u003d conf or Config()"},{"line_number":562,"context_line":"        self.location \u003d self.conf.location"},{"line_number":563,"context_line":"        self._timestamp \u003d None"}],"source_content_type":"text/x-python","patch_set":6,"id":"6aa95d1a_0291e879","line":560,"in_reply_to":"c63b8547_99c79452","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e6df311bac282d96055b00037a8324cedb49d04a","unresolved":true,"context_lines":[{"line_number":1186,"context_line":"        else:"},{"line_number":1187,"context_line":"            account \u003d self.account"},{"line_number":1188,"context_line":""},{"line_number":1189,"context_line":"        env \u003d self.environ.copy()"},{"line_number":1190,"context_line":"        env[\u0027swift.infocache\u0027] \u003d self.environ.setdefault(\u0027swift.infocache\u0027, {})"},{"line_number":1191,"context_line":""},{"line_number":1192,"context_line":"        def sanitize(value):"}],"source_content_type":"text/x-python","patch_set":6,"id":"3d4d6723_b58966e6","line":1189,"updated":"2024-11-19 18:58:22.000000000","message":"if we set an explicit flag in `self.environ[\u0027swift.is_s3_req\u0027] \u003d True` in `__init__` it would show up in sub-request environs as well.\n\nor maybe `swift.was_originally_s3api_user_request`","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":1186,"context_line":"        else:"},{"line_number":1187,"context_line":"            account \u003d self.account"},{"line_number":1188,"context_line":""},{"line_number":1189,"context_line":"        env \u003d self.environ.copy()"},{"line_number":1190,"context_line":"        env[\u0027swift.infocache\u0027] \u003d self.environ.setdefault(\u0027swift.infocache\u0027, {})"},{"line_number":1191,"context_line":""},{"line_number":1192,"context_line":"        def sanitize(value):"}],"source_content_type":"text/x-python","patch_set":6,"id":"6edd96b7_5ca29613","line":1189,"in_reply_to":"3d4d6723_b58966e6","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e6df311bac282d96055b00037a8324cedb49d04a","unresolved":true,"context_lines":[{"line_number":1256,"context_line":"                        del env[key]"},{"line_number":1257,"context_line":""},{"line_number":1258,"context_line":"        if self.conf.force_swift_request_proxy_log:"},{"line_number":1259,"context_line":"            env[\u0027swift.proxy_access_log_made\u0027] \u003d False"},{"line_number":1260,"context_line":"        env[\u0027swift.source\u0027] \u003d \u0027S3\u0027"},{"line_number":1261,"context_line":""},{"line_number":1262,"context_line":"        if method is not None:"}],"source_content_type":"text/x-python","patch_set":6,"id":"c67ffe2d_bad40337","line":1259,"updated":"2024-11-19 18:58:22.000000000","message":"this is an example of a key, set in the \"swift request\" environ (N.B. s3api doesn\u0027t use make_env/make_subrequest) that is NOT propogated by make_env (i.e. if some other middleware like SLO took one of s3api\u0027s swift requests and created a subrequest, this key would not be propogated to it\u0027s sub-requests)","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":1256,"context_line":"                        del env[key]"},{"line_number":1257,"context_line":""},{"line_number":1258,"context_line":"        if self.conf.force_swift_request_proxy_log:"},{"line_number":1259,"context_line":"            env[\u0027swift.proxy_access_log_made\u0027] \u003d False"},{"line_number":1260,"context_line":"        env[\u0027swift.source\u0027] \u003d \u0027S3\u0027"},{"line_number":1261,"context_line":""},{"line_number":1262,"context_line":"        if method is not None:"}],"source_content_type":"text/x-python","patch_set":6,"id":"8f4e9f04_645a808a","line":1259,"in_reply_to":"c67ffe2d_bad40337","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e6df311bac282d96055b00037a8324cedb49d04a","unresolved":true,"context_lines":[{"line_number":1257,"context_line":""},{"line_number":1258,"context_line":"        if self.conf.force_swift_request_proxy_log:"},{"line_number":1259,"context_line":"            env[\u0027swift.proxy_access_log_made\u0027] \u003d False"},{"line_number":1260,"context_line":"        env[\u0027swift.source\u0027] \u003d \u0027S3\u0027"},{"line_number":1261,"context_line":""},{"line_number":1262,"context_line":"        if method is not None:"},{"line_number":1263,"context_line":"            env[\u0027REQUEST_METHOD\u0027] \u003d method"}],"source_content_type":"text/x-python","patch_set":6,"id":"2e3cc339_e07e4601","line":1260,"updated":"2024-11-19 18:58:22.000000000","message":"we can also update self.environ[\u0027swift.is_s3_req\u0027] \u003d True\n\nbut it would probably be better to it *before* we call `to_swift_req` - instead the left hand side environ should be updated to \"this is a s3 request and always will be\" - probably in `__init__`\n\nFWIW `swift.source` *is* propagated by make_env","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":1257,"context_line":""},{"line_number":1258,"context_line":"        if self.conf.force_swift_request_proxy_log:"},{"line_number":1259,"context_line":"            env[\u0027swift.proxy_access_log_made\u0027] \u003d False"},{"line_number":1260,"context_line":"        env[\u0027swift.source\u0027] \u003d \u0027S3\u0027"},{"line_number":1261,"context_line":""},{"line_number":1262,"context_line":"        if method is not None:"},{"line_number":1263,"context_line":"            env[\u0027REQUEST_METHOD\u0027] \u003d method"}],"source_content_type":"text/x-python","patch_set":6,"id":"c0a5c3c3_1edc8217","line":1260,"in_reply_to":"2e3cc339_e07e4601","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"34996bc75ca6f593d928381298d4af325195443c","unresolved":true,"context_lines":[{"line_number":1258,"context_line":"        if self.conf.force_swift_request_proxy_log:"},{"line_number":1259,"context_line":"            env[\u0027swift.proxy_access_log_made\u0027] \u003d False"},{"line_number":1260,"context_line":"        env[\u0027swift.source\u0027] \u003d \u0027S3\u0027"},{"line_number":1261,"context_line":""},{"line_number":1262,"context_line":"        if method is not None:"},{"line_number":1263,"context_line":"            env[\u0027REQUEST_METHOD\u0027] \u003d method"},{"line_number":1264,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"667a9bc1_81d6ca2e","line":1261,"updated":"2024-11-14 14:41:23.000000000","message":"unnecessary change","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":1258,"context_line":"        if self.conf.force_swift_request_proxy_log:"},{"line_number":1259,"context_line":"            env[\u0027swift.proxy_access_log_made\u0027] \u003d False"},{"line_number":1260,"context_line":"        env[\u0027swift.source\u0027] \u003d \u0027S3\u0027"},{"line_number":1261,"context_line":""},{"line_number":1262,"context_line":"        if method is not None:"},{"line_number":1263,"context_line":"            env[\u0027REQUEST_METHOD\u0027] \u003d method"},{"line_number":1264,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"498b25d9_b77aad25","line":1261,"in_reply_to":"667a9bc1_81d6ca2e","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"14cf8a0f380dfd1b62c64e3ae94d323a6c4d23ef","unresolved":true,"context_lines":[{"line_number":121,"context_line":""},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"def _parse_host(storage_domains, environ):"},{"line_number":124,"context_line":"    return parse_host(storage_domains, environ)"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"def _parse_uri(bucket_in_host, dns_compliant_bucket_names, swob_req):"}],"source_content_type":"text/x-python","patch_set":13,"id":"66f853da_1bbf5b91","line":124,"updated":"2025-01-15 15:01:49.000000000","message":"this function doesn\u0027t seem necessary i.e. just call `parse_host`","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"576f7aa1851788b769331c8c466ad3f6ec18fb59","unresolved":false,"context_lines":[{"line_number":121,"context_line":""},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"def _parse_host(storage_domains, environ):"},{"line_number":124,"context_line":"    return parse_host(storage_domains, environ)"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"def _parse_uri(bucket_in_host, dns_compliant_bucket_names, swob_req):"}],"source_content_type":"text/x-python","patch_set":13,"id":"ce1b9668_46196729","line":124,"in_reply_to":"3d4643c3_64afc61e","updated":"2025-02-11 20:22:12.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":121,"context_line":""},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"def _parse_host(storage_domains, environ):"},{"line_number":124,"context_line":"    return parse_host(storage_domains, environ)"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"def _parse_uri(bucket_in_host, dns_compliant_bucket_names, swob_req):"}],"source_content_type":"text/x-python","patch_set":13,"id":"3d4643c3_64afc61e","line":124,"in_reply_to":"66f853da_1bbf5b91","updated":"2025-01-17 21:20:47.000000000","message":"Yan, if you\u0027re doing self-review and you understand \"code is the enemy\" [1] you shouldn\u0027t need Al or I to provide this feedback; which would help reduce the time it takes to get new features landed by having less review back-and-forth.\n\nAfter you push up a change; while you\u0027re waiting on someone else to look at it - go look at it yourself (click on every file and read every red and green line) and ask yourself the same question a reviewer would: why does this change HAVE to be here?\n\nIt\u0027s not about \"code golf\" - it\u0027s about making changes small, independent and obviously helpful - so that it\u0027s easier for reviewers read/understand everything in the diff and quickly say \"+A we need this!\"\n\n1. https://blog.codinghorror.com/the-best-code-is-no-code-at-all/","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"14cf8a0f380dfd1b62c64e3ae94d323a6c4d23ef","unresolved":true,"context_lines":[{"line_number":124,"context_line":"    return parse_host(storage_domains, environ)"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"def _parse_uri(bucket_in_host, dns_compliant_bucket_names, swob_req):"},{"line_number":128,"context_line":"    try:"},{"line_number":129,"context_line":"        return parse_uri(bucket_in_host, dns_compliant_bucket_names, swob_req)"},{"line_number":130,"context_line":"    except InvalidURIParseError as err:"}],"source_content_type":"text/x-python","patch_set":13,"id":"45b3e350_aa776bb7","line":127,"range":{"start_line":127,"start_character":59,"end_line":127,"end_character":67},"updated":"2025-01-15 15:01:49.000000000","message":"same as comment in utils - I have a preference for request to be the first arg","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":124,"context_line":"    return parse_host(storage_domains, environ)"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"def _parse_uri(bucket_in_host, dns_compliant_bucket_names, swob_req):"},{"line_number":128,"context_line":"    try:"},{"line_number":129,"context_line":"        return parse_uri(bucket_in_host, dns_compliant_bucket_names, swob_req)"},{"line_number":130,"context_line":"    except InvalidURIParseError as err:"}],"source_content_type":"text/x-python","patch_set":13,"id":"96960cd0_1530a9b4","line":127,"range":{"start_line":127,"start_character":59,"end_line":127,"end_character":67},"in_reply_to":"45b3e350_aa776bb7","updated":"2025-01-17 21:20:47.000000000","message":"\"first arg is `req`\" is a common convention in the swift code base that you would only learn through practice and review feedback - it\u0027s very much NOT the kind of thing you\u0027d be able to predict with self-review.  And it\u0027s also obviously a nit that would never hold up an otherwise complete, correct, and obviously beneficial change from getting merged:\n\nhttps://github.com/NVIDIA/swift/blob/master/REVIEW_GUIDELINES.rst#maintainable-code-is-obvious","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"576f7aa1851788b769331c8c466ad3f6ec18fb59","unresolved":false,"context_lines":[{"line_number":124,"context_line":"    return parse_host(storage_domains, environ)"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"def _parse_uri(bucket_in_host, dns_compliant_bucket_names, swob_req):"},{"line_number":128,"context_line":"    try:"},{"line_number":129,"context_line":"        return parse_uri(bucket_in_host, dns_compliant_bucket_names, swob_req)"},{"line_number":130,"context_line":"    except InvalidURIParseError as err:"}],"source_content_type":"text/x-python","patch_set":13,"id":"86cc5ddd_6e00c781","line":127,"range":{"start_line":127,"start_character":59,"end_line":127,"end_character":67},"in_reply_to":"96960cd0_1530a9b4","updated":"2025-02-11 20:22:12.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":130,"context_line":"    except InvalidURIParseError as err:"},{"line_number":131,"context_line":"        raise InvalidURI(err.uri)"},{"line_number":132,"context_line":"    except InvalidBucketNameParseError as err:"},{"line_number":133,"context_line":"        raise InvalidBucketName(err.bucket_name)"},{"line_number":134,"context_line":""},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"class S3InputSHA256Mismatch(BaseException):"}],"source_content_type":"text/x-python","patch_set":13,"id":"2e4e44e2_ec6c6dcc","line":133,"updated":"2025-01-17 21:20:47.000000000","message":"so this function ONLY exists to translate the ValueErrors to ResponseErrors - that sucks.\n\nwe have `s3api.exception` it looks like *maybe* we could move ErrorResponse in there; but I don\u0027t know how reasonable it would be for the s3api.utils.parse_uri helper function to raise ErrorResponse instances directly.\n\nI *do* know that eventually someone is going to write:\n\n```\ntry:\n    bucket, obj \u003d s3api.utils.parse_uri(req, False, True)\nexcept InvalidBucketName:\n    sys.exit(f\u0027bad bucket_name {e.bucket_name}\u0027)\n```\n\n... and be confused why they\u0027re looking at a traceback for `InvalidBucketNameParseError` for longer than they want to admit.","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"2cf84e04dade1b637fc97428392dddc14d0eff30","unresolved":false,"context_lines":[{"line_number":130,"context_line":"    except InvalidURIParseError as err:"},{"line_number":131,"context_line":"        raise InvalidURI(err.uri)"},{"line_number":132,"context_line":"    except InvalidBucketNameParseError as err:"},{"line_number":133,"context_line":"        raise InvalidBucketName(err.bucket_name)"},{"line_number":134,"context_line":""},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"class S3InputSHA256Mismatch(BaseException):"}],"source_content_type":"text/x-python","patch_set":13,"id":"5259e1a4_4428fe67","line":133,"in_reply_to":"2e4e44e2_ec6c6dcc","updated":"2025-02-24 16:22:27.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"}],"swift/common/middleware/s3api/utils.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"14cf8a0f380dfd1b62c64e3ae94d323a6c4d23ef","unresolved":true,"context_lines":[{"line_number":110,"context_line":"        return True"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"def parse_host(storage_domains, environ):"},{"line_number":114,"context_line":"    if not storage_domains:"},{"line_number":115,"context_line":"        return None"},{"line_number":116,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"aa3ffd8f_919f7150","line":113,"updated":"2025-01-15 15:01:49.000000000","message":"we should add a doc string now this is a utils function e.g.\n\n```\n\"\"\"\nA bucket-in-host request has the bucket name as the first part of a ``.``-separated host. If the host ends with any of the given storage_domains then the bucket name is returned. Otherwise ``None`` is returned.\n\n:param storage_domains: a list of storage domains for which bucket-in-host is supported.\n:param swob_req: a request\n\"\"\"\n```\n\nI\u0027d also suggest changing the function name to be more descriptive e.g. ``parse_bucket_in_host``\n\nFinally, for consistent interfaces, we could pass the request into this function as we do for ``parse_uri`` and then dereference environ within the function.","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"576f7aa1851788b769331c8c466ad3f6ec18fb59","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        return True"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"def parse_host(storage_domains, environ):"},{"line_number":114,"context_line":"    if not storage_domains:"},{"line_number":115,"context_line":"        return None"},{"line_number":116,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"b3e02bf3_97b3d3fe","line":113,"in_reply_to":"aa3ffd8f_919f7150","updated":"2025-02-11 20:22:12.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"14cf8a0f380dfd1b62c64e3ae94d323a6c4d23ef","unresolved":true,"context_lines":[{"line_number":120,"context_line":"        given_domain \u003d environ[\u0027SERVER_NAME\u0027]"},{"line_number":121,"context_line":"    else:"},{"line_number":122,"context_line":"        return None"},{"line_number":123,"context_line":"    port \u003d \u0027\u0027"},{"line_number":124,"context_line":"    if \u0027:\u0027 in given_domain:"},{"line_number":125,"context_line":"        given_domain, port \u003d given_domain.rsplit(\u0027:\u0027, 1)"},{"line_number":126,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"19839cfc_f1775c84","line":123,"updated":"2025-01-15 15:01:49.000000000","message":"part is not used (existing code but can be cleaned up)","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"576f7aa1851788b769331c8c466ad3f6ec18fb59","unresolved":false,"context_lines":[{"line_number":120,"context_line":"        given_domain \u003d environ[\u0027SERVER_NAME\u0027]"},{"line_number":121,"context_line":"    else:"},{"line_number":122,"context_line":"        return None"},{"line_number":123,"context_line":"    port \u003d \u0027\u0027"},{"line_number":124,"context_line":"    if \u0027:\u0027 in given_domain:"},{"line_number":125,"context_line":"        given_domain, port \u003d given_domain.rsplit(\u0027:\u0027, 1)"},{"line_number":126,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"0eec6901_00f1ee93","line":123,"in_reply_to":"19839cfc_f1775c84","updated":"2025-02-11 20:22:12.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"14cf8a0f380dfd1b62c64e3ae94d323a6c4d23ef","unresolved":true,"context_lines":[{"line_number":122,"context_line":"        return None"},{"line_number":123,"context_line":"    port \u003d \u0027\u0027"},{"line_number":124,"context_line":"    if \u0027:\u0027 in given_domain:"},{"line_number":125,"context_line":"        given_domain, port \u003d given_domain.rsplit(\u0027:\u0027, 1)"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"    for storage_domain in storage_domains:"},{"line_number":128,"context_line":"        if not storage_domain.startswith(\u0027.\u0027):"}],"source_content_type":"text/x-python","patch_set":13,"id":"3d62647a_8ac0a5f0","line":125,"range":{"start_line":125,"start_character":8,"end_line":125,"end_character":56},"updated":"2025-01-15 15:01:49.000000000","message":"or \n\n```\ngiven_domain \u003d given_domain.rsplit(\u0027:\u0027, 1)[0]\n```","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"576f7aa1851788b769331c8c466ad3f6ec18fb59","unresolved":false,"context_lines":[{"line_number":122,"context_line":"        return None"},{"line_number":123,"context_line":"    port \u003d \u0027\u0027"},{"line_number":124,"context_line":"    if \u0027:\u0027 in given_domain:"},{"line_number":125,"context_line":"        given_domain, port \u003d given_domain.rsplit(\u0027:\u0027, 1)"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"    for storage_domain in storage_domains:"},{"line_number":128,"context_line":"        if not storage_domain.startswith(\u0027.\u0027):"}],"source_content_type":"text/x-python","patch_set":13,"id":"47fc5b12_9b8ff352","line":125,"range":{"start_line":125,"start_character":8,"end_line":125,"end_character":56},"in_reply_to":"3d62647a_8ac0a5f0","updated":"2025-02-11 20:22:12.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"14cf8a0f380dfd1b62c64e3ae94d323a6c4d23ef","unresolved":true,"context_lines":[{"line_number":134,"context_line":"    return None"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"def parse_uri(bucket_in_host, dns_compliant_bucket_names, swob_req):"},{"line_number":138,"context_line":"    # NB: returns WSGI strings"},{"line_number":139,"context_line":"    if not check_utf8(wsgi_to_str(swob_req.environ[\u0027PATH_INFO\u0027])):"},{"line_number":140,"context_line":"        raise InvalidURIParseError(swob_req.path)"}],"source_content_type":"text/x-python","patch_set":13,"id":"c75d83a8_526a6044","line":137,"range":{"start_line":137,"start_character":58,"end_line":137,"end_character":66},"updated":"2025-01-15 15:01:49.000000000","message":"In request_helpers.py we have tended to pass the request as the first arg to a helper function. Based on that and what I feel is a general pattern, I think I\u0027d expect the swob_req to be the first arg. I\u0027m not sure if I could justify that formally - perhaps something to do with the request being the thing the function is acting on and the other args being parameters for the action??? But certainly if we considered moving these functions to request_helpers.py then I would be wanting the request to the first arg.\n\nDitto for parse_host\n\nAlso please add a docstring","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"576f7aa1851788b769331c8c466ad3f6ec18fb59","unresolved":false,"context_lines":[{"line_number":134,"context_line":"    return None"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"def parse_uri(bucket_in_host, dns_compliant_bucket_names, swob_req):"},{"line_number":138,"context_line":"    # NB: returns WSGI strings"},{"line_number":139,"context_line":"    if not check_utf8(wsgi_to_str(swob_req.environ[\u0027PATH_INFO\u0027])):"},{"line_number":140,"context_line":"        raise InvalidURIParseError(swob_req.path)"}],"source_content_type":"text/x-python","patch_set":13,"id":"f7f97cd3_341f6df4","line":137,"range":{"start_line":137,"start_character":58,"end_line":137,"end_character":66},"in_reply_to":"c75d83a8_526a6044","updated":"2025-02-11 20:22:12.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":137,"context_line":"def parse_uri(bucket_in_host, dns_compliant_bucket_names, swob_req):"},{"line_number":138,"context_line":"    # NB: returns WSGI strings"},{"line_number":139,"context_line":"    if not check_utf8(wsgi_to_str(swob_req.environ[\u0027PATH_INFO\u0027])):"},{"line_number":140,"context_line":"        raise InvalidURIParseError(swob_req.path)"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"    if bucket_in_host:"},{"line_number":143,"context_line":"        obj \u003d swob_req.environ[\u0027PATH_INFO\u0027][1:] or None"}],"source_content_type":"text/x-python","patch_set":13,"id":"b30c88de_d8ce5247","line":140,"updated":"2025-01-17 21:20:47.000000000","message":"I\u0027m guessing it\u0027s not POSSIBLE to import the existing errors from s3api.s3response here because this module is imported there and we\u0027d get a circular dependency problem.","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"2cf84e04dade1b637fc97428392dddc14d0eff30","unresolved":false,"context_lines":[{"line_number":137,"context_line":"def parse_uri(bucket_in_host, dns_compliant_bucket_names, swob_req):"},{"line_number":138,"context_line":"    # NB: returns WSGI strings"},{"line_number":139,"context_line":"    if not check_utf8(wsgi_to_str(swob_req.environ[\u0027PATH_INFO\u0027])):"},{"line_number":140,"context_line":"        raise InvalidURIParseError(swob_req.path)"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"    if bucket_in_host:"},{"line_number":143,"context_line":"        obj \u003d swob_req.environ[\u0027PATH_INFO\u0027][1:] or None"}],"source_content_type":"text/x-python","patch_set":13,"id":"23f11e02_0492c8a5","line":140,"in_reply_to":"b30c88de_d8ce5247","updated":"2025-02-24 16:22:27.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"14cf8a0f380dfd1b62c64e3ae94d323a6c4d23ef","unresolved":true,"context_lines":[{"line_number":152,"context_line":"    return bucket, obj"},{"line_number":153,"context_line":""},{"line_number":154,"context_line":""},{"line_number":155,"context_line":"def parse_host_uri(storage_domains, dns_compliant_bucket_names, swob_req):"},{"line_number":156,"context_line":"    bucket_in_host \u003d parse_host(storage_domains, swob_req.environ)"},{"line_number":157,"context_line":"    return parse_uri(bucket_in_host, dns_compliant_bucket_names, swob_req)"},{"line_number":158,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"0d653c45_8a154b9f","line":155,"range":{"start_line":155,"start_character":4,"end_line":155,"end_character":18},"updated":"2025-01-15 15:01:49.000000000","message":"we could rename parse_uri as parse_path and then name this function parse_uri\n\nAlso, please add a docstring","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6dc23d89aa71584c07c81b7b2de5d803576085ca","unresolved":true,"context_lines":[{"line_number":152,"context_line":"    return bucket, obj"},{"line_number":153,"context_line":""},{"line_number":154,"context_line":""},{"line_number":155,"context_line":"def parse_host_uri(storage_domains, dns_compliant_bucket_names, swob_req):"},{"line_number":156,"context_line":"    bucket_in_host \u003d parse_host(storage_domains, swob_req.environ)"},{"line_number":157,"context_line":"    return parse_uri(bucket_in_host, dns_compliant_bucket_names, swob_req)"},{"line_number":158,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"0e8b6695_77d22663","line":155,"range":{"start_line":155,"start_character":4,"end_line":155,"end_character":18},"in_reply_to":"0d653c45_8a154b9f","updated":"2025-01-17 21:20:47.000000000","message":"+1 docstrings, new utils functions should come with new test_utils tests","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"576f7aa1851788b769331c8c466ad3f6ec18fb59","unresolved":false,"context_lines":[{"line_number":152,"context_line":"    return bucket, obj"},{"line_number":153,"context_line":""},{"line_number":154,"context_line":""},{"line_number":155,"context_line":"def parse_host_uri(storage_domains, dns_compliant_bucket_names, swob_req):"},{"line_number":156,"context_line":"    bucket_in_host \u003d parse_host(storage_domains, swob_req.environ)"},{"line_number":157,"context_line":"    return parse_uri(bucket_in_host, dns_compliant_bucket_names, swob_req)"},{"line_number":158,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"33ad923c_0fde11c1","line":155,"range":{"start_line":155,"start_character":4,"end_line":155,"end_character":18},"in_reply_to":"0e8b6695_77d22663","updated":"2025-02-11 20:22:12.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"14cf8a0f380dfd1b62c64e3ae94d323a6c4d23ef","unresolved":true,"context_lines":[{"line_number":157,"context_line":"    return parse_uri(bucket_in_host, dns_compliant_bucket_names, swob_req)"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":""},{"line_number":160,"context_line":"class InvalidBucketNameParseError(Exception):"},{"line_number":161,"context_line":"    _msg \u003d \u0027The specified bucket is not valid\u0027"},{"line_number":162,"context_line":""},{"line_number":163,"context_line":"    def __init__(self, bucket):"}],"source_content_type":"text/x-python","patch_set":13,"id":"8a58c611_6b354c5d","line":160,"range":{"start_line":160,"start_character":23,"end_line":160,"end_character":28},"updated":"2025-01-15 15:01:49.000000000","message":"nit: IDK if we need the word ``Parse`` in the name","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"576f7aa1851788b769331c8c466ad3f6ec18fb59","unresolved":false,"context_lines":[{"line_number":157,"context_line":"    return parse_uri(bucket_in_host, dns_compliant_bucket_names, swob_req)"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":""},{"line_number":160,"context_line":"class InvalidBucketNameParseError(Exception):"},{"line_number":161,"context_line":"    _msg \u003d \u0027The specified bucket is not valid\u0027"},{"line_number":162,"context_line":""},{"line_number":163,"context_line":"    def __init__(self, bucket):"}],"source_content_type":"text/x-python","patch_set":13,"id":"314fa969_22f276fc","line":160,"range":{"start_line":160,"start_character":23,"end_line":160,"end_character":28},"in_reply_to":"8a58c611_6b354c5d","updated":"2025-02-11 20:22:12.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"14cf8a0f380dfd1b62c64e3ae94d323a6c4d23ef","unresolved":true,"context_lines":[{"line_number":170,"context_line":"class InvalidURIParseError(Exception):"},{"line_number":171,"context_line":"    _msg \u003d \u0027Couldn\\\u0027t parse the specified URI\u0027"},{"line_number":172,"context_line":""},{"line_number":173,"context_line":"    def __init__(self, uri):"},{"line_number":174,"context_line":"        self.uri \u003d uri"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"    def __str__(self):"}],"source_content_type":"text/x-python","patch_set":13,"id":"62ab236e_133508fa","line":173,"range":{"start_line":173,"start_character":23,"end_line":173,"end_character":26},"updated":"2025-01-15 15:01:49.000000000","message":"this is actually the path","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"576f7aa1851788b769331c8c466ad3f6ec18fb59","unresolved":false,"context_lines":[{"line_number":170,"context_line":"class InvalidURIParseError(Exception):"},{"line_number":171,"context_line":"    _msg \u003d \u0027Couldn\\\u0027t parse the specified URI\u0027"},{"line_number":172,"context_line":""},{"line_number":173,"context_line":"    def __init__(self, uri):"},{"line_number":174,"context_line":"        self.uri \u003d uri"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"    def __str__(self):"}],"source_content_type":"text/x-python","patch_set":13,"id":"4bbc09df_da20f57c","line":173,"range":{"start_line":173,"start_character":23,"end_line":173,"end_character":26},"in_reply_to":"62ab236e_133508fa","updated":"2025-02-11 20:22:12.000000000","message":"Acknowledged","commit_id":"e5dd8769e64eb93e3bef81043321b0ea655df85b"}],"swift/common/utils/__init__.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"88385b4cb0bf4ad1b773fc44366c408fde5ed0b7","unresolved":true,"context_lines":[{"line_number":2404,"context_line":"    To be swapped in for wsgi.input for accounting purposes."},{"line_number":2405,"context_line":"    \"\"\""},{"line_number":2406,"context_line":""},{"line_number":2407,"context_line":"    def __init__(self, wsgi_input, statsd_emit_callback\u003dNone):"},{"line_number":2408,"context_line":"        \"\"\""},{"line_number":2409,"context_line":"        :param wsgi_input: file-like object to wrap the functionality of"},{"line_number":2410,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"49bf6f41_d2f438d7","line":2407,"updated":"2024-10-29 17:29:39.000000000","message":"if this defaults to `lambda chunk: None` we can just always call it.","commit_id":"cdb1cdf7df5bdc8bfcf782b7efa622976eb0df1b"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"770fc5ba81f79fd485837068bcefe7f8e5d99a74","unresolved":false,"context_lines":[{"line_number":2404,"context_line":"    To be swapped in for wsgi.input for accounting purposes."},{"line_number":2405,"context_line":"    \"\"\""},{"line_number":2406,"context_line":""},{"line_number":2407,"context_line":"    def __init__(self, wsgi_input, statsd_emit_callback\u003dNone):"},{"line_number":2408,"context_line":"        \"\"\""},{"line_number":2409,"context_line":"        :param wsgi_input: file-like object to wrap the functionality of"},{"line_number":2410,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"78a1f775_eccc147f","line":2407,"in_reply_to":"49bf6f41_d2f438d7","updated":"2024-11-01 15:35:26.000000000","message":"Acknowledged","commit_id":"cdb1cdf7df5bdc8bfcf782b7efa622976eb0df1b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"34996bc75ca6f593d928381298d4af325195443c","unresolved":true,"context_lines":[{"line_number":2404,"context_line":"    To be swapped in for wsgi.input for accounting purposes."},{"line_number":2405,"context_line":"    \"\"\""},{"line_number":2406,"context_line":""},{"line_number":2407,"context_line":"    def __init__(self, wsgi_input, statsd_emit_callback\u003dlambda chunk: None):"},{"line_number":2408,"context_line":"        \"\"\""},{"line_number":2409,"context_line":"        :param wsgi_input: file-like object to wrap the functionality of"},{"line_number":2410,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":6,"id":"3c3ffa00_8bc431d4","line":2407,"range":{"start_line":2407,"start_character":56,"end_line":2407,"end_character":75},"updated":"2024-11-14 14:41:23.000000000","message":"setting this default here means that a caller can\u0027t pass ``None``\n\nso I couldn\u0027t write:\n\n```\ndef get_buffer_xfer_emit_callback(...):\n    if self.emit_buffer_xfer_bytes_sec \u003c 0:\n        return None\n     ...\n     \nInputProxy(wgsi_input, callback\u003dget_buffer_xfer_emit_callback(...))\n```\n\nwhereas that would be possible if the default is None and then we have\n\n```\nself.callback \u003d lambda chunk: None if callback is None else callback\n```\n\n(see comment in proxy_logging too)","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"34996bc75ca6f593d928381298d4af325195443c","unresolved":true,"context_lines":[{"line_number":2404,"context_line":"    To be swapped in for wsgi.input for accounting purposes."},{"line_number":2405,"context_line":"    \"\"\""},{"line_number":2406,"context_line":""},{"line_number":2407,"context_line":"    def __init__(self, wsgi_input, statsd_emit_callback\u003dlambda chunk: None):"},{"line_number":2408,"context_line":"        \"\"\""},{"line_number":2409,"context_line":"        :param wsgi_input: file-like object to wrap the functionality of"},{"line_number":2410,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":6,"id":"5dc6b4bf_f8d76e5f","line":2407,"range":{"start_line":2407,"start_character":35,"end_line":2407,"end_character":55},"updated":"2024-11-14 14:41:23.000000000","message":"the ``statsd_emit_`` part of this name is a detail of the proxy_logging usage. In general it\u0027s just a callback that can do anything it likes, so the name should be less specific.","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":2404,"context_line":"    To be swapped in for wsgi.input for accounting purposes."},{"line_number":2405,"context_line":"    \"\"\""},{"line_number":2406,"context_line":""},{"line_number":2407,"context_line":"    def __init__(self, wsgi_input, statsd_emit_callback\u003dlambda chunk: None):"},{"line_number":2408,"context_line":"        \"\"\""},{"line_number":2409,"context_line":"        :param wsgi_input: file-like object to wrap the functionality of"},{"line_number":2410,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":6,"id":"d3afafab_9d332744","line":2407,"range":{"start_line":2407,"start_character":56,"end_line":2407,"end_character":75},"in_reply_to":"3c3ffa00_8bc431d4","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":2404,"context_line":"    To be swapped in for wsgi.input for accounting purposes."},{"line_number":2405,"context_line":"    \"\"\""},{"line_number":2406,"context_line":""},{"line_number":2407,"context_line":"    def __init__(self, wsgi_input, statsd_emit_callback\u003dlambda chunk: None):"},{"line_number":2408,"context_line":"        \"\"\""},{"line_number":2409,"context_line":"        :param wsgi_input: file-like object to wrap the functionality of"},{"line_number":2410,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":6,"id":"73532e64_9b805f61","line":2407,"range":{"start_line":2407,"start_character":35,"end_line":2407,"end_character":55},"in_reply_to":"5dc6b4bf_f8d76e5f","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3c9db4b292eacdc99e65c8934ed5e7d5148bdd8b","unresolved":true,"context_lines":[{"line_number":2411,"context_line":"        self.wsgi_input \u003d wsgi_input"},{"line_number":2412,"context_line":"        self.bytes_received \u003d 0"},{"line_number":2413,"context_line":"        self.client_disconnect \u003d False"},{"line_number":2414,"context_line":"        self.callback \u003d (lambda chunk: None) if callback is None else callback"},{"line_number":2415,"context_line":""},{"line_number":2416,"context_line":"    def read(self, *args, **kwargs):"},{"line_number":2417,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":9,"id":"781c881a_49a014b5","line":2414,"updated":"2024-11-29 16:33:28.000000000","message":"+1 I prefer this over defining the lanmda as the default arg because in general it allows a caller to use ``InputProxy(wsgi_input, None)``","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"ec749a90b62e4614dfbbd965ec77307a011e0994","unresolved":false,"context_lines":[{"line_number":2411,"context_line":"        self.wsgi_input \u003d wsgi_input"},{"line_number":2412,"context_line":"        self.bytes_received \u003d 0"},{"line_number":2413,"context_line":"        self.client_disconnect \u003d False"},{"line_number":2414,"context_line":"        self.callback \u003d (lambda chunk: None) if callback is None else callback"},{"line_number":2415,"context_line":""},{"line_number":2416,"context_line":"    def read(self, *args, **kwargs):"},{"line_number":2417,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":9,"id":"bed2c5f8_055da085","line":2414,"in_reply_to":"781c881a_49a014b5","updated":"2024-12-10 16:29:15.000000000","message":"Acknowledged","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"b341a2ec64623dd1d758b6b7c37d19846e3bcc8c","unresolved":false,"context_lines":[{"line_number":5240,"context_line":"        raise"},{"line_number":5241,"context_line":""},{"line_number":5242,"context_line":""},{"line_number":5243,"context_line":"class SubsetMap(Mapping):"},{"line_number":5244,"context_line":"    \"\"\""},{"line_number":5245,"context_line":"    A map that can be used to restrict the views of a wrapped map to a given"},{"line_number":5246,"context_line":"    subset of keys."}],"source_content_type":"text/x-python","patch_set":42,"id":"706ff6f3_82a1f6f3","line":5243,"range":{"start_line":5243,"start_character":6,"end_line":5243,"end_character":15},"updated":"2025-06-03 11:34:30.000000000","message":"@alistairncoles@gmail.com do we still need this if not used for proxy_logging? We have tests for this too","commit_id":"860d8978fa781cffafb3c9eae18849083aaf8548"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":2574,"context_line":"            raise"},{"line_number":2575,"context_line":"        self.bytes_received +\u003d len(chunk)"},{"line_number":2576,"context_line":"        eof \u003d size is None or size \u003c 0 or len(chunk) \u003c size"},{"line_number":2577,"context_line":"        self.callback(len(chunk))"},{"line_number":2578,"context_line":"        return self.chunk_update(chunk, eof)"},{"line_number":2579,"context_line":""},{"line_number":2580,"context_line":"    def readline(self, size\u003dNone, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":44,"id":"bda43fc4_8e009df8","line":2577,"updated":"2025-06-05 11:46:42.000000000","message":"this needs to also pass ``eof`` so that a stat can be emitted when the stream is exhausted","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"cd45a581820bc1bee129daf0e9221cbf54e58829","unresolved":false,"context_lines":[{"line_number":2574,"context_line":"            raise"},{"line_number":2575,"context_line":"        self.bytes_received +\u003d len(chunk)"},{"line_number":2576,"context_line":"        eof \u003d size is None or size \u003c 0 or len(chunk) \u003c size"},{"line_number":2577,"context_line":"        self.callback(len(chunk))"},{"line_number":2578,"context_line":"        return self.chunk_update(chunk, eof)"},{"line_number":2579,"context_line":""},{"line_number":2580,"context_line":"    def readline(self, size\u003dNone, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":44,"id":"299f9765_1f654f71","line":2577,"in_reply_to":"bda43fc4_8e009df8","updated":"2025-06-27 14:49:57.000000000","message":"Acknowledged","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1432c12767bfa249bb2d1d29e769cd306b817b23","unresolved":true,"context_lines":[{"line_number":2573,"context_line":"            raise"},{"line_number":2574,"context_line":"        self.bytes_received +\u003d len(chunk)"},{"line_number":2575,"context_line":"        eof \u003d size is None or size \u003c 0 or len(chunk) \u003c size"},{"line_number":2576,"context_line":"        self.callback(len(chunk))"},{"line_number":2577,"context_line":"        return self.chunk_update(chunk, eof)"},{"line_number":2578,"context_line":""},{"line_number":2579,"context_line":"    def readline(self, size\u003dNone, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":57,"id":"fe25a39f_14c454b5","line":2576,"updated":"2025-07-17 14:31:02.000000000","message":"I think you\u0027re going to need this callback to also take ``eof`` as an optional arg so that we know when there are no more bytes coming and the final stats should be emitted.\n\nGiven that, then for consistency I think I\u0027d like the callback interface to be the same as the chunk_update interface i.e.\n\n```\ncallback(chunk, eof)\n```\n\nand have the callback handler find ``len(chunk)``.\n\nSince InputProxy is intended to be re-usable, this would mean that it has to ways to be enhanced:\n* subclass and override ``chunk_update(chunk, eof)``\n* install ``callback(chunk, eof)``","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"0db17671d6943738520718e212eb15e008a094ea","unresolved":false,"context_lines":[{"line_number":2573,"context_line":"            raise"},{"line_number":2574,"context_line":"        self.bytes_received +\u003d len(chunk)"},{"line_number":2575,"context_line":"        eof \u003d size is None or size \u003c 0 or len(chunk) \u003c size"},{"line_number":2576,"context_line":"        self.callback(len(chunk))"},{"line_number":2577,"context_line":"        return self.chunk_update(chunk, eof)"},{"line_number":2578,"context_line":""},{"line_number":2579,"context_line":"    def readline(self, size\u003dNone, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":57,"id":"e0b8bfba_78bd5ac2","line":2576,"in_reply_to":"94231fb6_34add078","updated":"2025-07-22 21:45:11.000000000","message":"to-do","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"8c2a19bbda3bdcd0e5880e10e26a46764be3ae0a","unresolved":true,"context_lines":[{"line_number":2573,"context_line":"            raise"},{"line_number":2574,"context_line":"        self.bytes_received +\u003d len(chunk)"},{"line_number":2575,"context_line":"        eof \u003d size is None or size \u003c 0 or len(chunk) \u003c size"},{"line_number":2576,"context_line":"        self.callback(len(chunk))"},{"line_number":2577,"context_line":"        return self.chunk_update(chunk, eof)"},{"line_number":2578,"context_line":""},{"line_number":2579,"context_line":"    def readline(self, size\u003dNone, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":57,"id":"ff4b7af0_ee697895","line":2576,"in_reply_to":"e0b8bfba_78bd5ac2","updated":"2025-07-22 22:35:04.000000000","message":"to-do","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9c175fca54bd4eec0f0d2e996f5cb2bb4fce3870","unresolved":false,"context_lines":[{"line_number":2573,"context_line":"            raise"},{"line_number":2574,"context_line":"        self.bytes_received +\u003d len(chunk)"},{"line_number":2575,"context_line":"        eof \u003d size is None or size \u003c 0 or len(chunk) \u003c size"},{"line_number":2576,"context_line":"        self.callback(len(chunk))"},{"line_number":2577,"context_line":"        return self.chunk_update(chunk, eof)"},{"line_number":2578,"context_line":""},{"line_number":2579,"context_line":"    def readline(self, size\u003dNone, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":57,"id":"94231fb6_34add078","line":2576,"in_reply_to":"fe25a39f_14c454b5","updated":"2025-07-21 21:19:09.000000000","message":"Acknowledged","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"a37da6eb6c70194e35ae4422536f75ee9e681e35","unresolved":false,"context_lines":[{"line_number":2573,"context_line":"            raise"},{"line_number":2574,"context_line":"        self.bytes_received +\u003d len(chunk)"},{"line_number":2575,"context_line":"        eof \u003d size is None or size \u003c 0 or len(chunk) \u003c size"},{"line_number":2576,"context_line":"        self.callback(len(chunk))"},{"line_number":2577,"context_line":"        return self.chunk_update(chunk, eof)"},{"line_number":2578,"context_line":""},{"line_number":2579,"context_line":"    def readline(self, size\u003dNone, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":57,"id":"6e8d887b_84a33ae4","line":2576,"in_reply_to":"ff4b7af0_ee697895","updated":"2025-07-24 22:24:06.000000000","message":"Done","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed52e6f601100413157c728b3379848ae27d2538","unresolved":true,"context_lines":[{"line_number":2522,"context_line":"    File-like object that counts bytes read."},{"line_number":2523,"context_line":"    To be swapped in for wsgi.input for accounting purposes."},{"line_number":2524,"context_line":""},{"line_number":2525,"context_line":"    :param wsgi_input: file-like object to be wrapped"},{"line_number":2526,"context_line":"    \"\"\""},{"line_number":2527,"context_line":""},{"line_number":2528,"context_line":"    def __init__(self, wsgi_input, callback\u003dNone):"}],"source_content_type":"text/x-python","patch_set":58,"id":"df4d5bf9_43e782ce","line":2525,"updated":"2025-07-24 09:38:58.000000000","message":"need to add a docstring param for ``callback`` which should describe the signature expected for the callback function.","commit_id":"4641e0ca4aa3481f0bd66d4af9ff4a61e5267946"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"a37da6eb6c70194e35ae4422536f75ee9e681e35","unresolved":false,"context_lines":[{"line_number":2522,"context_line":"    File-like object that counts bytes read."},{"line_number":2523,"context_line":"    To be swapped in for wsgi.input for accounting purposes."},{"line_number":2524,"context_line":""},{"line_number":2525,"context_line":"    :param wsgi_input: file-like object to be wrapped"},{"line_number":2526,"context_line":"    \"\"\""},{"line_number":2527,"context_line":""},{"line_number":2528,"context_line":"    def __init__(self, wsgi_input, callback\u003dNone):"}],"source_content_type":"text/x-python","patch_set":58,"id":"56450806_fdd307ac","line":2525,"in_reply_to":"df4d5bf9_43e782ce","updated":"2025-07-24 22:24:06.000000000","message":"Done","commit_id":"4641e0ca4aa3481f0bd66d4af9ff4a61e5267946"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed52e6f601100413157c728b3379848ae27d2538","unresolved":true,"context_lines":[{"line_number":2573,"context_line":"            raise"},{"line_number":2574,"context_line":"        self.bytes_received +\u003d len(chunk)"},{"line_number":2575,"context_line":"        eof \u003d size is None or size \u003c 0 or len(chunk) \u003c size"},{"line_number":2576,"context_line":"        self.callback(chunk)"},{"line_number":2577,"context_line":"        return self.chunk_update(chunk, eof)"},{"line_number":2578,"context_line":""},{"line_number":2579,"context_line":"    def readline(self, size\u003dNone, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":58,"id":"07391dc0_b1b417d8","line":2576,"updated":"2025-07-24 09:38:58.000000000","message":"this still isn\u0027t passing the ``eof``?? which also tells me there is missing or faulty test coverage since all the tests have passed.","commit_id":"4641e0ca4aa3481f0bd66d4af9ff4a61e5267946"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"a37da6eb6c70194e35ae4422536f75ee9e681e35","unresolved":false,"context_lines":[{"line_number":2573,"context_line":"            raise"},{"line_number":2574,"context_line":"        self.bytes_received +\u003d len(chunk)"},{"line_number":2575,"context_line":"        eof \u003d size is None or size \u003c 0 or len(chunk) \u003c size"},{"line_number":2576,"context_line":"        self.callback(chunk)"},{"line_number":2577,"context_line":"        return self.chunk_update(chunk, eof)"},{"line_number":2578,"context_line":""},{"line_number":2579,"context_line":"    def readline(self, size\u003dNone, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":58,"id":"43ea06b0_1bebb6ae","line":2576,"in_reply_to":"07391dc0_b1b417d8","updated":"2025-07-24 22:24:06.000000000","message":"Done\nMade test changes to reflect remaining bytes for input streaming in TestProxyLogging::test_xfer_stats_emit_frequency_put","commit_id":"4641e0ca4aa3481f0bd66d4af9ff4a61e5267946"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed52e6f601100413157c728b3379848ae27d2538","unresolved":true,"context_lines":[{"line_number":2592,"context_line":"        self.bytes_received +\u003d len(line)"},{"line_number":2593,"context_line":"        eof \u003d ((size is None or size \u003c 0 or len(line) \u003c size)"},{"line_number":2594,"context_line":"               and (line[-1:] !\u003d b\u0027\\n\u0027))"},{"line_number":2595,"context_line":"        self.callback(line)"},{"line_number":2596,"context_line":"        return self.chunk_update(line, eof)"},{"line_number":2597,"context_line":""},{"line_number":2598,"context_line":"    def close(self):"}],"source_content_type":"text/x-python","patch_set":58,"id":"862ed648_4ed7203b","line":2595,"updated":"2025-07-24 09:38:58.000000000","message":"ditto, ``eof`` not passed","commit_id":"4641e0ca4aa3481f0bd66d4af9ff4a61e5267946"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"a37da6eb6c70194e35ae4422536f75ee9e681e35","unresolved":false,"context_lines":[{"line_number":2592,"context_line":"        self.bytes_received +\u003d len(line)"},{"line_number":2593,"context_line":"        eof \u003d ((size is None or size \u003c 0 or len(line) \u003c size)"},{"line_number":2594,"context_line":"               and (line[-1:] !\u003d b\u0027\\n\u0027))"},{"line_number":2595,"context_line":"        self.callback(line)"},{"line_number":2596,"context_line":"        return self.chunk_update(line, eof)"},{"line_number":2597,"context_line":""},{"line_number":2598,"context_line":"    def close(self):"}],"source_content_type":"text/x-python","patch_set":58,"id":"a60da2f4_a9e5a225","line":2595,"in_reply_to":"862ed648_4ed7203b","updated":"2025-07-24 22:24:06.000000000","message":"Done","commit_id":"4641e0ca4aa3481f0bd66d4af9ff4a61e5267946"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"144e64fa36b2a06eef9c238f2ce7f42c529efe6f","unresolved":true,"context_lines":[{"line_number":2523,"context_line":"    To be swapped in for wsgi.input for accounting purposes."},{"line_number":2524,"context_line":""},{"line_number":2525,"context_line":"    :param wsgi_input: file-like object to be wrapped"},{"line_number":2526,"context_line":"    :param callback: a no-argument function that should"},{"line_number":2527,"context_line":"        return a BufferXferEmitCallback like object or None"},{"line_number":2528,"context_line":"    \"\"\""},{"line_number":2529,"context_line":""}],"source_content_type":"text/x-python","patch_set":61,"id":"7b314104_b6d1eb6a","line":2526,"updated":"2025-07-25 17:44:50.000000000","message":"Why grow this interface? The \"normal\" way we use `InputProxy` is to subclass and override `chunk_update` -- so something like\n```\nclass TransferStatTrackingInput(InputProxy):\n    def __init__(self, wsgi_input, metric_name, labels, statsd,\n                 emit_buffer_xfer_bytes_sec):\n        super().__init__(wsgi_input)\n        self.metric_name \u003d ...\n        ...\n\n    def chunk_update(chunk, eof, *arg, **kwargs):\n        # all your logic from BufferXferEmitCallback.__call__\n        # except careful to always `return chunk`\n```\nand then we use *that* in proxy-logging. Note that it\u0027ll mean we no longer instantiate a plain old `InputProxy` anymore.\n\nOr, now that I see `BufferXferEmitCallback` is being used to track responses, too:\n```\nclass TransferStatTrackingInput(InputProxy):\n    def __init__(self, wsgi_input, callback):\n        super().__init__(wsgi_input)\n        self.callback \u003d callback\n\n    def chunk_update(chunk, eof, *arg, **kwargs):\n        self.callback(chunk, eof)\n        return chunk\n```","commit_id":"74e88a1633605f28d0d5eb95d1c889616245a54f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"28ee66864f14fc57e21e89c76273b2fe42fad4be","unresolved":true,"context_lines":[{"line_number":2523,"context_line":"    To be swapped in for wsgi.input for accounting purposes."},{"line_number":2524,"context_line":""},{"line_number":2525,"context_line":"    :param wsgi_input: file-like object to be wrapped"},{"line_number":2526,"context_line":"    :param callback: a no-argument function that should"},{"line_number":2527,"context_line":"        return a BufferXferEmitCallback like object or None"},{"line_number":2528,"context_line":"    \"\"\""},{"line_number":2529,"context_line":""}],"source_content_type":"text/x-python","patch_set":61,"id":"53fcc3f8_f8eb2955","line":2526,"in_reply_to":"2683cd38_a5a54ae4","updated":"2025-08-01 16:02:27.000000000","message":"on reflection, probably best to Keep It Simple:\n\n* subclass InputProxy to implement the callback\n* keep the existing callback class","commit_id":"74e88a1633605f28d0d5eb95d1c889616245a54f"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"203d2e18ce30234f4d9fc616b4fa97ca519a0fdc","unresolved":false,"context_lines":[{"line_number":2523,"context_line":"    To be swapped in for wsgi.input for accounting purposes."},{"line_number":2524,"context_line":""},{"line_number":2525,"context_line":"    :param wsgi_input: file-like object to be wrapped"},{"line_number":2526,"context_line":"    :param callback: a no-argument function that should"},{"line_number":2527,"context_line":"        return a BufferXferEmitCallback like object or None"},{"line_number":2528,"context_line":"    \"\"\""},{"line_number":2529,"context_line":""}],"source_content_type":"text/x-python","patch_set":61,"id":"5dbcec05_8aeca0e9","line":2526,"in_reply_to":"53fcc3f8_f8eb2955","updated":"2025-08-04 20:35:53.000000000","message":"Acknowledged","commit_id":"74e88a1633605f28d0d5eb95d1c889616245a54f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"198b984c59b8a6fd4ba03b46d765c424b2ef8250","unresolved":true,"context_lines":[{"line_number":2523,"context_line":"    To be swapped in for wsgi.input for accounting purposes."},{"line_number":2524,"context_line":""},{"line_number":2525,"context_line":"    :param wsgi_input: file-like object to be wrapped"},{"line_number":2526,"context_line":"    :param callback: a no-argument function that should"},{"line_number":2527,"context_line":"        return a BufferXferEmitCallback like object or None"},{"line_number":2528,"context_line":"    \"\"\""},{"line_number":2529,"context_line":""}],"source_content_type":"text/x-python","patch_set":61,"id":"2683cd38_a5a54ae4","line":2526,"in_reply_to":"7b314104_b6d1eb6a","updated":"2025-07-28 14:00:11.000000000","message":"I could get behind this. If the simple subclass is to live in utils I might call it something more generic like CallbackInputProxy.\n\nHowever, I can also see Tim\u0027s first idea working i.e. create subclass of InputProxy that implements the stats calling in its chunk_update methods, and in the read path instantiate it without a wsgi_input and call chunk_update directly.\n\n```\nclass TransferStatTrackingInput(InputProxy):\n    def __init__(self, metric_name, labels, statsd,\n                 emit_buffer_xfer_bytes_sec, wsgi_input\u003dNone):\n        super().__init__(wsgi_input or io.BytesIO(b\u0027\u0027))\n        self.metric_name \u003d ...\n        ...\n\n    def chunk_update(chunk, eof, *arg, **kwargs):\n        # all your logic from BufferXferEmitCallback.__call__\n        # except careful to always `return chunk`\n```        \n        \nUse either:\n\n```\nenv[\u0027wsgi_input\u0027] \u003d TransferStatTrackingInput(...., wsgi_input\u003denv[\u0027wsgi_input\u0027])\nenv[\u0027wsgi_input\u0027].read()\n```\n\nor\n```\nstatsd_emitter \u003d TransferStatTrackingInput(....)\n\n\nfor chunk in iterator:\n                    bytes_sent +\u003d len(chunk)\n                    statsd_emitter.chunk_update(chunk)\n                    yield chunk\n```","commit_id":"74e88a1633605f28d0d5eb95d1c889616245a54f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"39f2ccece4cf04b118f66a5b48358098d758c9b7","unresolved":true,"context_lines":[{"line_number":2533,"context_line":"        #: ``False`` otherwise"},{"line_number":2534,"context_line":"        self.client_disconnect \u003d False"},{"line_number":2535,"context_line":""},{"line_number":2536,"context_line":"    def chunk_update(self, chunk, *args, **kwargs):"},{"line_number":2537,"context_line":"        \"\"\""},{"line_number":2538,"context_line":"        Called each time a chunk of bytes is read from the wrapped input."},{"line_number":2539,"context_line":""}],"source_content_type":"text/x-python","patch_set":64,"id":"c0873255_a3a93ea6","line":2536,"range":{"start_line":2536,"start_character":8,"end_line":2536,"end_character":51},"updated":"2025-08-06 15:02:22.000000000","message":"somewhere in the patchsets we\u0027ve lost the ``eof`` positional arg w.r.t. whats on master (the Base patchset on gerrit)","commit_id":"89f2c7a2e176b641d2b0d2c5cd17c1c0e47747bb"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"5a2be1b55ca7dfdee0efbda8033b4833e0b2c6bc","unresolved":false,"context_lines":[{"line_number":2533,"context_line":"        #: ``False`` otherwise"},{"line_number":2534,"context_line":"        self.client_disconnect \u003d False"},{"line_number":2535,"context_line":""},{"line_number":2536,"context_line":"    def chunk_update(self, chunk, *args, **kwargs):"},{"line_number":2537,"context_line":"        \"\"\""},{"line_number":2538,"context_line":"        Called each time a chunk of bytes is read from the wrapped input."},{"line_number":2539,"context_line":""}],"source_content_type":"text/x-python","patch_set":64,"id":"d5b8016f_2cfee8cd","line":2536,"range":{"start_line":2536,"start_character":8,"end_line":2536,"end_character":51},"in_reply_to":"c0873255_a3a93ea6","updated":"2025-08-06 20:31:35.000000000","message":"Acknowledged","commit_id":"89f2c7a2e176b641d2b0d2c5cd17c1c0e47747bb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"39f2ccece4cf04b118f66a5b48358098d758c9b7","unresolved":true,"context_lines":[{"line_number":2596,"context_line":"        close_if_possible(self.wsgi_input)"},{"line_number":2597,"context_line":""},{"line_number":2598,"context_line":""},{"line_number":2599,"context_line":"class TransferStatTrackingInput(InputProxy):"},{"line_number":2600,"context_line":"    \"\"\""},{"line_number":2601,"context_line":"    :param wsgi_input: file-like object to be wrapped"},{"line_number":2602,"context_line":"    :param callback: a no-argument function that should"}],"source_content_type":"text/x-python","patch_set":64,"id":"df53c965_ef785d99","line":2599,"range":{"start_line":2599,"start_character":6,"end_line":2599,"end_character":31},"updated":"2025-08-06 15:02:22.000000000","message":"this class is more widely applicable (and its in the utils module) so I suggest calling it something less specific e.g. ``CallbackInputProxy``","commit_id":"89f2c7a2e176b641d2b0d2c5cd17c1c0e47747bb"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"5a2be1b55ca7dfdee0efbda8033b4833e0b2c6bc","unresolved":false,"context_lines":[{"line_number":2596,"context_line":"        close_if_possible(self.wsgi_input)"},{"line_number":2597,"context_line":""},{"line_number":2598,"context_line":""},{"line_number":2599,"context_line":"class TransferStatTrackingInput(InputProxy):"},{"line_number":2600,"context_line":"    \"\"\""},{"line_number":2601,"context_line":"    :param wsgi_input: file-like object to be wrapped"},{"line_number":2602,"context_line":"    :param callback: a no-argument function that should"}],"source_content_type":"text/x-python","patch_set":64,"id":"8f92d79f_069a2856","line":2599,"range":{"start_line":2599,"start_character":6,"end_line":2599,"end_character":31},"in_reply_to":"df53c965_ef785d99","updated":"2025-08-06 20:31:35.000000000","message":"Acknowledged","commit_id":"89f2c7a2e176b641d2b0d2c5cd17c1c0e47747bb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"39f2ccece4cf04b118f66a5b48358098d758c9b7","unresolved":true,"context_lines":[{"line_number":2600,"context_line":"    \"\"\""},{"line_number":2601,"context_line":"    :param wsgi_input: file-like object to be wrapped"},{"line_number":2602,"context_line":"    :param callback: a no-argument function that should"},{"line_number":2603,"context_line":"        return a BufferXferEmitCallback like object or None"},{"line_number":2604,"context_line":"    \"\"\""},{"line_number":2605,"context_line":"    def __init__(self, wsgi_input, callback\u003dNone):"},{"line_number":2606,"context_line":"        super().__init__(wsgi_input)"}],"source_content_type":"text/x-python","patch_set":64,"id":"79460f82_d17502c2","line":2603,"updated":"2025-08-06 15:02:22.000000000","message":"this is wrong (and was before) : the callback function must accept two args ``(chunk, eof)``. IMO it\u0027s not necessary or relevant to mention ``BufferXferEmitCallback``  here - that just happens to be something that implements the required callback interface.\n\nThere\u0027s probably a debate to be had about whether the callback should be expected to return the chunk (or a modified chunk) in the same way that the ``chunk_update`` method does. It\u0027s not required by this initial use case, but:\n - IMHO it\u0027s intuitive to continue the pattern of \"passed a chunk, return a chunk\"\n - it will be hard to change to requiring the chunk to be returned later, once anyone has started to use this class\n \n so I\u0027d vote for requiring it now.","commit_id":"89f2c7a2e176b641d2b0d2c5cd17c1c0e47747bb"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"5a2be1b55ca7dfdee0efbda8033b4833e0b2c6bc","unresolved":false,"context_lines":[{"line_number":2600,"context_line":"    \"\"\""},{"line_number":2601,"context_line":"    :param wsgi_input: file-like object to be wrapped"},{"line_number":2602,"context_line":"    :param callback: a no-argument function that should"},{"line_number":2603,"context_line":"        return a BufferXferEmitCallback like object or None"},{"line_number":2604,"context_line":"    \"\"\""},{"line_number":2605,"context_line":"    def __init__(self, wsgi_input, callback\u003dNone):"},{"line_number":2606,"context_line":"        super().__init__(wsgi_input)"}],"source_content_type":"text/x-python","patch_set":64,"id":"6959ec65_0e9fd6ce","line":2603,"in_reply_to":"79460f82_d17502c2","updated":"2025-08-06 20:31:35.000000000","message":"Acknowledged","commit_id":"89f2c7a2e176b641d2b0d2c5cd17c1c0e47747bb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"39f2ccece4cf04b118f66a5b48358098d758c9b7","unresolved":true,"context_lines":[{"line_number":2609,"context_line":""},{"line_number":2610,"context_line":"    def chunk_update(self, chunk, eof, *arg, **kwargs):"},{"line_number":2611,"context_line":"        self.callback(chunk, eof)"},{"line_number":2612,"context_line":"        return chunk"},{"line_number":2613,"context_line":""},{"line_number":2614,"context_line":""},{"line_number":2615,"context_line":"class LRUCache(object):"}],"source_content_type":"text/x-python","patch_set":64,"id":"6e9f2468_50d3abfe","line":2612,"updated":"2025-08-06 15:02:22.000000000","message":"we ought to have a test case in test_utils for this new class - it will be quite simple - \"I created an instance with this callback function, I read it and I assert my callback was called\".","commit_id":"89f2c7a2e176b641d2b0d2c5cd17c1c0e47747bb"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"5a2be1b55ca7dfdee0efbda8033b4833e0b2c6bc","unresolved":false,"context_lines":[{"line_number":2609,"context_line":""},{"line_number":2610,"context_line":"    def chunk_update(self, chunk, eof, *arg, **kwargs):"},{"line_number":2611,"context_line":"        self.callback(chunk, eof)"},{"line_number":2612,"context_line":"        return chunk"},{"line_number":2613,"context_line":""},{"line_number":2614,"context_line":""},{"line_number":2615,"context_line":"class LRUCache(object):"}],"source_content_type":"text/x-python","patch_set":64,"id":"1d218c8a_4712cf4b","line":2612,"in_reply_to":"6e9f2468_50d3abfe","updated":"2025-08-06 20:31:35.000000000","message":"Done","commit_id":"89f2c7a2e176b641d2b0d2c5cd17c1c0e47747bb"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d6a4ea68434d00c67f23c3c16c93fbe87ebac2d4","unresolved":true,"context_lines":[{"line_number":2596,"context_line":"        close_if_possible(self.wsgi_input)"},{"line_number":2597,"context_line":""},{"line_number":2598,"context_line":""},{"line_number":2599,"context_line":"class CallbackInputProxy(InputProxy):"},{"line_number":2600,"context_line":"    \"\"\""},{"line_number":2601,"context_line":"    :param wsgi_input: file-like object to be wrapped"},{"line_number":2602,"context_line":"    :param callback: a function that accept args (chunk, eof),"}],"source_content_type":"text/x-python","patch_set":65,"id":"3d950f95_2298850e","line":2599,"updated":"2025-08-07 16:39:59.000000000","message":"Since we\u0027ve only got the one caller, I\u0027m tempted to keep this in proxy-logging (until we find another user).","commit_id":"d8a8d7e051e290790b5e8df57fca28166015a6c8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"42336a8cd9e9c574e3e1b551220f2baf412a2b0d","unresolved":false,"context_lines":[{"line_number":2596,"context_line":"        close_if_possible(self.wsgi_input)"},{"line_number":2597,"context_line":""},{"line_number":2598,"context_line":""},{"line_number":2599,"context_line":"class CallbackInputProxy(InputProxy):"},{"line_number":2600,"context_line":"    \"\"\""},{"line_number":2601,"context_line":"    :param wsgi_input: file-like object to be wrapped"},{"line_number":2602,"context_line":"    :param callback: a function that accept args (chunk, eof),"}],"source_content_type":"text/x-python","patch_set":65,"id":"feb98083_aa133c93","line":2599,"in_reply_to":"3d950f95_2298850e","updated":"2025-08-07 22:46:58.000000000","message":"Acknowledged","commit_id":"d8a8d7e051e290790b5e8df57fca28166015a6c8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"fbfb2a73e3030a8ddeecea098b1d17d6043d82a1","unresolved":true,"context_lines":[{"line_number":2600,"context_line":"    \"\"\""},{"line_number":2601,"context_line":"    :param wsgi_input: file-like object to be wrapped"},{"line_number":2602,"context_line":"    :param callback: a function that accept args (chunk, eof),"},{"line_number":2603,"context_line":"        and return chunk or or a modified chunk."},{"line_number":2604,"context_line":"        eof is ``True`` if there are no more bytes to"},{"line_number":2605,"context_line":"        read from the wrapped input, ``False`` otherwise."},{"line_number":2606,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":65,"id":"559c5bab_1944df1b","line":2603,"range":{"start_line":2603,"start_character":12,"end_line":2603,"end_character":18},"updated":"2025-08-07 12:33:31.000000000","message":"nit: s/return/returns/","commit_id":"d8a8d7e051e290790b5e8df57fca28166015a6c8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"42336a8cd9e9c574e3e1b551220f2baf412a2b0d","unresolved":false,"context_lines":[{"line_number":2600,"context_line":"    \"\"\""},{"line_number":2601,"context_line":"    :param wsgi_input: file-like object to be wrapped"},{"line_number":2602,"context_line":"    :param callback: a function that accept args (chunk, eof),"},{"line_number":2603,"context_line":"        and return chunk or or a modified chunk."},{"line_number":2604,"context_line":"        eof is ``True`` if there are no more bytes to"},{"line_number":2605,"context_line":"        read from the wrapped input, ``False`` otherwise."},{"line_number":2606,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":65,"id":"de86a11f_96af2569","line":2603,"range":{"start_line":2603,"start_character":12,"end_line":2603,"end_character":18},"in_reply_to":"559c5bab_1944df1b","updated":"2025-08-07 22:46:58.000000000","message":"Acknowledged","commit_id":"d8a8d7e051e290790b5e8df57fca28166015a6c8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d6a4ea68434d00c67f23c3c16c93fbe87ebac2d4","unresolved":true,"context_lines":[{"line_number":2604,"context_line":"        eof is ``True`` if there are no more bytes to"},{"line_number":2605,"context_line":"        read from the wrapped input, ``False`` otherwise."},{"line_number":2606,"context_line":"    \"\"\""},{"line_number":2607,"context_line":"    def __init__(self, wsgi_input, callback\u003dNone):"},{"line_number":2608,"context_line":"        super().__init__(wsgi_input)"},{"line_number":2609,"context_line":"        self.callback \u003d (lambda chunk, eof\u003dNone: None) if callback is None \\"},{"line_number":2610,"context_line":"            else callback"}],"source_content_type":"text/x-python","patch_set":65,"id":"6b03d52c_a901bd70","line":2607,"range":{"start_line":2607,"start_character":35,"end_line":2607,"end_character":48},"updated":"2025-08-07 16:39:59.000000000","message":"We can just make this required, yeah? If the caller didn\u0027t want to provide a callback, they should just use `InputProxy`.","commit_id":"d8a8d7e051e290790b5e8df57fca28166015a6c8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"42336a8cd9e9c574e3e1b551220f2baf412a2b0d","unresolved":false,"context_lines":[{"line_number":2604,"context_line":"        eof is ``True`` if there are no more bytes to"},{"line_number":2605,"context_line":"        read from the wrapped input, ``False`` otherwise."},{"line_number":2606,"context_line":"    \"\"\""},{"line_number":2607,"context_line":"    def __init__(self, wsgi_input, callback\u003dNone):"},{"line_number":2608,"context_line":"        super().__init__(wsgi_input)"},{"line_number":2609,"context_line":"        self.callback \u003d (lambda chunk, eof\u003dNone: None) if callback is None \\"},{"line_number":2610,"context_line":"            else callback"}],"source_content_type":"text/x-python","patch_set":65,"id":"e30da672_4d0b3240","line":2607,"range":{"start_line":2607,"start_character":35,"end_line":2607,"end_character":48},"in_reply_to":"6b03d52c_a901bd70","updated":"2025-08-07 22:46:58.000000000","message":"Acknowledged","commit_id":"d8a8d7e051e290790b5e8df57fca28166015a6c8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"fbfb2a73e3030a8ddeecea098b1d17d6043d82a1","unresolved":true,"context_lines":[{"line_number":2610,"context_line":"            else callback"},{"line_number":2611,"context_line":""},{"line_number":2612,"context_line":"    def chunk_update(self, chunk, eof, *arg, **kwargs):"},{"line_number":2613,"context_line":"        self.callback(chunk, eof)"},{"line_number":2614,"context_line":"        return chunk"},{"line_number":2615,"context_line":""},{"line_number":2616,"context_line":""}],"source_content_type":"text/x-python","patch_set":65,"id":"17a7a4eb_70a0a1fe","line":2613,"updated":"2025-08-07 12:33:31.000000000","message":"if the callback is required to return a chunk then we need to return it here too","commit_id":"d8a8d7e051e290790b5e8df57fca28166015a6c8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"42336a8cd9e9c574e3e1b551220f2baf412a2b0d","unresolved":false,"context_lines":[{"line_number":2610,"context_line":"            else callback"},{"line_number":2611,"context_line":""},{"line_number":2612,"context_line":"    def chunk_update(self, chunk, eof, *arg, **kwargs):"},{"line_number":2613,"context_line":"        self.callback(chunk, eof)"},{"line_number":2614,"context_line":"        return chunk"},{"line_number":2615,"context_line":""},{"line_number":2616,"context_line":""}],"source_content_type":"text/x-python","patch_set":65,"id":"60246521_caceac24","line":2613,"in_reply_to":"17a7a4eb_70a0a1fe","updated":"2025-08-07 22:46:58.000000000","message":"Done","commit_id":"d8a8d7e051e290790b5e8df57fca28166015a6c8"}],"swift/common/wsgi.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"144e64fa36b2a06eef9c238f2ce7f42c529efe6f","unresolved":true,"context_lines":[{"line_number":1352,"context_line":"                 \u0027swift.trans_id\u0027, \u0027swift.authorize_override\u0027,"},{"line_number":1353,"context_line":"                 \u0027swift.authorize\u0027, \u0027HTTP_X_USER_ID\u0027, \u0027HTTP_X_PROJECT_ID\u0027,"},{"line_number":1354,"context_line":"                 \u0027HTTP_REFERER\u0027, \u0027swift.infocache\u0027,"},{"line_number":1355,"context_line":"                 \u0027swift.base_labels\u0027, \u0027swift.shard_listing_history\u0027):"},{"line_number":1356,"context_line":"        if name in env:"},{"line_number":1357,"context_line":"            newenv[name] \u003d env[name]"},{"line_number":1358,"context_line":"    if method:"}],"source_content_type":"text/x-python","patch_set":61,"id":"fd40f034_77eeb41f","line":1355,"updated":"2025-07-25 17:44:50.000000000","message":"This seems like a really interesting/powerful change, and a good way to improve our ability to get the labels from the two placements of proxy-logging.","commit_id":"74e88a1633605f28d0d5eb95d1c889616245a54f"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"6cd17935952a72154c46b0576c8d1e4c49521cdc","unresolved":false,"context_lines":[{"line_number":1352,"context_line":"                 \u0027swift.trans_id\u0027, \u0027swift.authorize_override\u0027,"},{"line_number":1353,"context_line":"                 \u0027swift.authorize\u0027, \u0027HTTP_X_USER_ID\u0027, \u0027HTTP_X_PROJECT_ID\u0027,"},{"line_number":1354,"context_line":"                 \u0027HTTP_REFERER\u0027, \u0027swift.infocache\u0027,"},{"line_number":1355,"context_line":"                 \u0027swift.base_labels\u0027, \u0027swift.shard_listing_history\u0027):"},{"line_number":1356,"context_line":"        if name in env:"},{"line_number":1357,"context_line":"            newenv[name] \u003d env[name]"},{"line_number":1358,"context_line":"    if method:"}],"source_content_type":"text/x-python","patch_set":61,"id":"14918d4e_ca3d3097","line":1355,"in_reply_to":"fd40f034_77eeb41f","updated":"2025-08-01 15:49:03.000000000","message":"yey","commit_id":"74e88a1633605f28d0d5eb95d1c889616245a54f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"94af435e5e843a4093f95790290a679681a01ea5","unresolved":true,"context_lines":[{"line_number":1352,"context_line":"                 \u0027swift.trans_id\u0027, \u0027swift.authorize_override\u0027,"},{"line_number":1353,"context_line":"                 \u0027swift.authorize\u0027, \u0027HTTP_X_USER_ID\u0027, \u0027HTTP_X_PROJECT_ID\u0027,"},{"line_number":1354,"context_line":"                 \u0027HTTP_REFERER\u0027, \u0027swift.infocache\u0027,"},{"line_number":1355,"context_line":"                 \u0027swift.base_labels\u0027, \u0027swift.shard_listing_history\u0027):"},{"line_number":1356,"context_line":"        if name in env:"},{"line_number":1357,"context_line":"            newenv[name] \u003d env[name]"},{"line_number":1358,"context_line":"    if method:"}],"source_content_type":"text/x-python","patch_set":66,"id":"62ac9564_6c415252","line":1355,"updated":"2025-08-08 17:38:52.000000000","message":"needs test coverage\n\nsee 956947: sq: bytes xfer stats test fixups | https://review.opendev.org/c/openstack/swift/+/956947","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"4bcbfbcbc06a15be10d54b1253f8bd6a8e3bbcc3","unresolved":false,"context_lines":[{"line_number":1352,"context_line":"                 \u0027swift.trans_id\u0027, \u0027swift.authorize_override\u0027,"},{"line_number":1353,"context_line":"                 \u0027swift.authorize\u0027, \u0027HTTP_X_USER_ID\u0027, \u0027HTTP_X_PROJECT_ID\u0027,"},{"line_number":1354,"context_line":"                 \u0027HTTP_REFERER\u0027, \u0027swift.infocache\u0027,"},{"line_number":1355,"context_line":"                 \u0027swift.base_labels\u0027, \u0027swift.shard_listing_history\u0027):"},{"line_number":1356,"context_line":"        if name in env:"},{"line_number":1357,"context_line":"            newenv[name] \u003d env[name]"},{"line_number":1358,"context_line":"    if method:"}],"source_content_type":"text/x-python","patch_set":66,"id":"358e97f8_d5c5fe4c","line":1355,"in_reply_to":"62ac9564_6c415252","updated":"2025-08-08 20:17:53.000000000","message":"Done","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"}],"test/unit/common/middleware/helpers.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d21278b9a94cd7c6739dd5897408c28bc9120615","unresolved":true,"context_lines":[{"line_number":266,"context_line":"            self._calls.append(call)"},{"line_number":267,"context_line":""},{"line_number":268,"context_line":"        req_body \u003d None  # generally, we don\u0027t care and let eventlet discard()"},{"line_number":269,"context_line":"        if (cont and not obj and method \u003d\u003d \u0027UPDATE\u0027) or ("},{"line_number":270,"context_line":"                obj and method \u003d\u003d \u0027PUT\u0027):"},{"line_number":271,"context_line":"            if not self.test_chunk_read:"},{"line_number":272,"context_line":"                req_body \u003d b\u0027\u0027.join(iter(env[\u0027wsgi.input\u0027].read, b\u0027\u0027))"}],"source_content_type":"text/x-python","patch_set":6,"id":"c603a8a0_688af9ce","line":269,"updated":"2024-11-15 19:40:40.000000000","message":"I wonder why container UPDATE requests need to read the req_body","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":266,"context_line":"            self._calls.append(call)"},{"line_number":267,"context_line":""},{"line_number":268,"context_line":"        req_body \u003d None  # generally, we don\u0027t care and let eventlet discard()"},{"line_number":269,"context_line":"        if (cont and not obj and method \u003d\u003d \u0027UPDATE\u0027) or ("},{"line_number":270,"context_line":"                obj and method \u003d\u003d \u0027PUT\u0027):"},{"line_number":271,"context_line":"            if not self.test_chunk_read:"},{"line_number":272,"context_line":"                req_body \u003d b\u0027\u0027.join(iter(env[\u0027wsgi.input\u0027].read, b\u0027\u0027))"}],"source_content_type":"text/x-python","patch_set":6,"id":"6eaa39cc_c31507e5","line":269,"in_reply_to":"c603a8a0_688af9ce","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d21278b9a94cd7c6739dd5897408c28bc9120615","unresolved":true,"context_lines":[{"line_number":271,"context_line":"            if not self.test_chunk_read:"},{"line_number":272,"context_line":"                req_body \u003d b\u0027\u0027.join(iter(env[\u0027wsgi.input\u0027].read, b\u0027\u0027))"},{"line_number":273,"context_line":"            else:"},{"line_number":274,"context_line":"                buf \u003d env[\u0027wsgi.input\u0027].read(5)"},{"line_number":275,"context_line":"                while buf:"},{"line_number":276,"context_line":"                    req_body \u003d b\u0027\u0027.join([req_body, buf]) if req_body else buf"},{"line_number":277,"context_line":"                    buf \u003d env[\u0027wsgi.input\u0027].read(5)"}],"source_content_type":"text/x-python","patch_set":6,"id":"11177481_68b13825","line":274,"updated":"2024-11-15 19:40:40.000000000","message":"what\u0027s with the `5` here as a magic number?","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":271,"context_line":"            if not self.test_chunk_read:"},{"line_number":272,"context_line":"                req_body \u003d b\u0027\u0027.join(iter(env[\u0027wsgi.input\u0027].read, b\u0027\u0027))"},{"line_number":273,"context_line":"            else:"},{"line_number":274,"context_line":"                buf \u003d env[\u0027wsgi.input\u0027].read(5)"},{"line_number":275,"context_line":"                while buf:"},{"line_number":276,"context_line":"                    req_body \u003d b\u0027\u0027.join([req_body, buf]) if req_body else buf"},{"line_number":277,"context_line":"                    buf \u003d env[\u0027wsgi.input\u0027].read(5)"}],"source_content_type":"text/x-python","patch_set":6,"id":"f233ed7e_5584e15d","line":274,"in_reply_to":"11177481_68b13825","updated":"2024-11-22 20:30:38.000000000","message":"indeed was copied from FakeApp","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d21278b9a94cd7c6739dd5897408c28bc9120615","unresolved":true,"context_lines":[{"line_number":273,"context_line":"            else:"},{"line_number":274,"context_line":"                buf \u003d env[\u0027wsgi.input\u0027].read(5)"},{"line_number":275,"context_line":"                while buf:"},{"line_number":276,"context_line":"                    req_body \u003d b\u0027\u0027.join([req_body, buf]) if req_body else buf"},{"line_number":277,"context_line":"                    buf \u003d env[\u0027wsgi.input\u0027].read(5)"},{"line_number":278,"context_line":""},{"line_number":279,"context_line":"        # simulate object PUT"}],"source_content_type":"text/x-python","patch_set":6,"id":"d6394b10_68951f15","line":276,"updated":"2024-11-15 19:40:40.000000000","message":"this is a weird way to spell\n\n```\n    req_body +\u003d buff\n```","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":273,"context_line":"            else:"},{"line_number":274,"context_line":"                buf \u003d env[\u0027wsgi.input\u0027].read(5)"},{"line_number":275,"context_line":"                while buf:"},{"line_number":276,"context_line":"                    req_body \u003d b\u0027\u0027.join([req_body, buf]) if req_body else buf"},{"line_number":277,"context_line":"                    buf \u003d env[\u0027wsgi.input\u0027].read(5)"},{"line_number":278,"context_line":""},{"line_number":279,"context_line":"        # simulate object PUT"}],"source_content_type":"text/x-python","patch_set":6,"id":"74f5effa_9eb02c52","line":276,"in_reply_to":"d6394b10_68951f15","updated":"2024-11-22 20:30:38.000000000","message":"the initial value is None thus this would cause TypeError: unsupported operand type(s) for +\u003d: \u0027NoneType\u0027 and \u0027bytes\u0027. Updated to use + accordingly","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d21278b9a94cd7c6739dd5897408c28bc9120615","unresolved":true,"context_lines":[{"line_number":274,"context_line":"                buf \u003d env[\u0027wsgi.input\u0027].read(5)"},{"line_number":275,"context_line":"                while buf:"},{"line_number":276,"context_line":"                    req_body \u003d b\u0027\u0027.join([req_body, buf]) if req_body else buf"},{"line_number":277,"context_line":"                    buf \u003d env[\u0027wsgi.input\u0027].read(5)"},{"line_number":278,"context_line":""},{"line_number":279,"context_line":"        # simulate object PUT"},{"line_number":280,"context_line":"        if method \u003d\u003d \u0027PUT\u0027 and obj:"}],"source_content_type":"text/x-python","patch_set":6,"id":"df45805c_bb9166b4","line":277,"updated":"2024-11-15 19:40:40.000000000","message":"maybe instead of `test_chunk_read` as a boolean we can just make the read size a kwarg that\u0027s None (0?  -1?) by default but callers can also make it smaller (and the size of the read is explicit in the test)","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":274,"context_line":"                buf \u003d env[\u0027wsgi.input\u0027].read(5)"},{"line_number":275,"context_line":"                while buf:"},{"line_number":276,"context_line":"                    req_body \u003d b\u0027\u0027.join([req_body, buf]) if req_body else buf"},{"line_number":277,"context_line":"                    buf \u003d env[\u0027wsgi.input\u0027].read(5)"},{"line_number":278,"context_line":""},{"line_number":279,"context_line":"        # simulate object PUT"},{"line_number":280,"context_line":"        if method \u003d\u003d \u0027PUT\u0027 and obj:"}],"source_content_type":"text/x-python","patch_set":6,"id":"b4befc77_c6388e54","line":277,"in_reply_to":"df45805c_bb9166b4","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d21278b9a94cd7c6739dd5897408c28bc9120615","unresolved":true,"context_lines":[{"line_number":309,"context_line":"                         k.lower \u003d\u003d \u0027content-type\u0027)))"},{"line_number":310,"context_line":"            self.uploaded[env[\u0027PATH_INFO\u0027]] \u003d new_metadata, data"},{"line_number":311,"context_line":""},{"line_number":312,"context_line":"        self.req_bodies.append(req_body)"},{"line_number":313,"context_line":""},{"line_number":314,"context_line":"        # Some middlewares (e.g. proxy_logging) inspect the request headers"},{"line_number":315,"context_line":"        # after it has been handled, so simulate some request headers updates"}],"source_content_type":"text/x-python","patch_set":6,"id":"81bd20f6_5691f6e2","line":312,"updated":"2024-11-15 19:40:40.000000000","message":"I guess container UPDATE requests just need the req_body for tracking - they probably don\u0027t care about the read size or etag.","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":309,"context_line":"                         k.lower \u003d\u003d \u0027content-type\u0027)))"},{"line_number":310,"context_line":"            self.uploaded[env[\u0027PATH_INFO\u0027]] \u003d new_metadata, data"},{"line_number":311,"context_line":""},{"line_number":312,"context_line":"        self.req_bodies.append(req_body)"},{"line_number":313,"context_line":""},{"line_number":314,"context_line":"        # Some middlewares (e.g. proxy_logging) inspect the request headers"},{"line_number":315,"context_line":"        # after it has been handled, so simulate some request headers updates"}],"source_content_type":"text/x-python","patch_set":6,"id":"b88cc2b3_8933b5c5","line":312,"in_reply_to":"81bd20f6_5691f6e2","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c18d9096100c33d4b60c2528df7faba203435a4f","unresolved":true,"context_lines":[{"line_number":325,"context_line":"        req_body \u003d None  # generally, we don\u0027t care and let eventlet discard()"},{"line_number":326,"context_line":"        if (cont and not obj and method \u003d\u003d \u0027UPDATE\u0027) or ("},{"line_number":327,"context_line":"                obj and method \u003d\u003d \u0027PUT\u0027):"},{"line_number":328,"context_line":"            if self.test_read_size \u003c 0:"},{"line_number":329,"context_line":"                req_body \u003d b\u0027\u0027.join(iter(env[\u0027wsgi.input\u0027].read, b\u0027\u0027))"},{"line_number":330,"context_line":"            else:"},{"line_number":331,"context_line":"                buf \u003d env[\u0027wsgi.input\u0027].read(self.test_read_size)"}],"source_content_type":"text/x-python","patch_set":18,"id":"c427d5c7_22740837","line":328,"range":{"start_line":328,"start_character":15,"end_line":328,"end_character":38},"updated":"2025-03-06 18:38:33.000000000","message":"the usual behavior of read() methods is that size\u003d0 means unlimited","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"7ba6da5e7244c7ac095d73a88b59c340feb284e1","unresolved":false,"context_lines":[{"line_number":325,"context_line":"        req_body \u003d None  # generally, we don\u0027t care and let eventlet discard()"},{"line_number":326,"context_line":"        if (cont and not obj and method \u003d\u003d \u0027UPDATE\u0027) or ("},{"line_number":327,"context_line":"                obj and method \u003d\u003d \u0027PUT\u0027):"},{"line_number":328,"context_line":"            if self.test_read_size \u003c 0:"},{"line_number":329,"context_line":"                req_body \u003d b\u0027\u0027.join(iter(env[\u0027wsgi.input\u0027].read, b\u0027\u0027))"},{"line_number":330,"context_line":"            else:"},{"line_number":331,"context_line":"                buf \u003d env[\u0027wsgi.input\u0027].read(self.test_read_size)"}],"source_content_type":"text/x-python","patch_set":18,"id":"47573346_7c741cf1","line":328,"range":{"start_line":328,"start_character":15,"end_line":328,"end_character":38},"in_reply_to":"c427d5c7_22740837","updated":"2025-03-10 15:23:19.000000000","message":"Acknowledged","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c18d9096100c33d4b60c2528df7faba203435a4f","unresolved":true,"context_lines":[{"line_number":329,"context_line":"                req_body \u003d b\u0027\u0027.join(iter(env[\u0027wsgi.input\u0027].read, b\u0027\u0027))"},{"line_number":330,"context_line":"            else:"},{"line_number":331,"context_line":"                buf \u003d env[\u0027wsgi.input\u0027].read(self.test_read_size)"},{"line_number":332,"context_line":"                while buf:"},{"line_number":333,"context_line":"                    req_body \u003d req_body + buf if req_body else buf"},{"line_number":334,"context_line":"                    buf \u003d env[\u0027wsgi.input\u0027].read(self.test_read_size)"},{"line_number":335,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"060c7a7f_40eff528","line":332,"range":{"start_line":332,"start_character":16,"end_line":332,"end_character":25},"updated":"2025-03-06 18:38:33.000000000","message":"if buf is empty we never assign req_body \u003d buf, which is a change in behaviour\n\nmaybe set ``req_body \u003d b\u0027\u0027`` at line 331 and then in the line below here you could write ``req_body +\u003d buf``","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"7ba6da5e7244c7ac095d73a88b59c340feb284e1","unresolved":false,"context_lines":[{"line_number":329,"context_line":"                req_body \u003d b\u0027\u0027.join(iter(env[\u0027wsgi.input\u0027].read, b\u0027\u0027))"},{"line_number":330,"context_line":"            else:"},{"line_number":331,"context_line":"                buf \u003d env[\u0027wsgi.input\u0027].read(self.test_read_size)"},{"line_number":332,"context_line":"                while buf:"},{"line_number":333,"context_line":"                    req_body \u003d req_body + buf if req_body else buf"},{"line_number":334,"context_line":"                    buf \u003d env[\u0027wsgi.input\u0027].read(self.test_read_size)"},{"line_number":335,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"ee1d3fe3_90f69359","line":332,"range":{"start_line":332,"start_character":16,"end_line":332,"end_character":25},"in_reply_to":"060c7a7f_40eff528","updated":"2025-03-10 15:23:19.000000000","message":"Acknowledged","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c18d9096100c33d4b60c2528df7faba203435a4f","unresolved":true,"context_lines":[{"line_number":385,"context_line":"            resolve_ignore_range_header(req, headers)"},{"line_number":386,"context_line":""},{"line_number":387,"context_line":"        # range requests ought to work, hence conditional_response\u003dTrue"},{"line_number":388,"context_line":"        if not isinstance(body, binary_type) and not isinstance(body, str):"},{"line_number":389,"context_line":"            resp \u003d resp_class("},{"line_number":390,"context_line":"                req\u003dreq, headers\u003dheaders, app_iter\u003dbody,"},{"line_number":391,"context_line":"                conditional_response\u003dreq.method in (\u0027GET\u0027, \u0027HEAD\u0027),"}],"source_content_type":"text/x-python","patch_set":18,"id":"e92748c9_0e381c29","line":388,"updated":"2025-03-06 18:38:33.000000000","message":"isinstance can take a tuple of types, so only one call needed\n\nhttps://docs.python.org/3/library/functions.html#isinstance\n\nI\u0027m curious what required this change?","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"7ba6da5e7244c7ac095d73a88b59c340feb284e1","unresolved":false,"context_lines":[{"line_number":385,"context_line":"            resolve_ignore_range_header(req, headers)"},{"line_number":386,"context_line":""},{"line_number":387,"context_line":"        # range requests ought to work, hence conditional_response\u003dTrue"},{"line_number":388,"context_line":"        if not isinstance(body, binary_type) and not isinstance(body, str):"},{"line_number":389,"context_line":"            resp \u003d resp_class("},{"line_number":390,"context_line":"                req\u003dreq, headers\u003dheaders, app_iter\u003dbody,"},{"line_number":391,"context_line":"                conditional_response\u003dreq.method in (\u0027GET\u0027, \u0027HEAD\u0027),"}],"source_content_type":"text/x-python","patch_set":18,"id":"b703dd67_bfa85f47","line":388,"in_reply_to":"e92748c9_0e381c29","updated":"2025-03-10 15:23:19.000000000","message":"some unit tests in test_proxy_logging are using iterable class for FakeSwift","commit_id":"2a9da8ea1d57c0de57d5b6d82df9764f09e990e3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":15,"context_line":"# This stuff can\u0027t live in test/unit/__init__.py due to its swob dependency."},{"line_number":16,"context_line":"from collections import defaultdict"},{"line_number":17,"context_line":"from urllib import parse"},{"line_number":18,"context_line":"from six import binary_type"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"from swift.common import swob"},{"line_number":21,"context_line":"from swift.common.header_key_dict import HeaderKeyDict"}],"source_content_type":"text/x-python","patch_set":44,"id":"e54f099b_2063f45d","line":18,"updated":"2025-06-05 11:46:42.000000000","message":"this is not needed now we\u0027re on py3 only","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1432c12767bfa249bb2d1d29e769cd306b817b23","unresolved":true,"context_lines":[{"line_number":15,"context_line":"# This stuff can\u0027t live in test/unit/__init__.py due to its swob dependency."},{"line_number":16,"context_line":"from collections import defaultdict"},{"line_number":17,"context_line":"from urllib import parse"},{"line_number":18,"context_line":"from six import binary_type"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"from swift.common import swob"},{"line_number":21,"context_line":"from swift.common.header_key_dict import HeaderKeyDict"}],"source_content_type":"text/x-python","patch_set":44,"id":"282780eb_37f62ef2","line":18,"in_reply_to":"191bebe2_794ad6cd","updated":"2025-07-17 14:31:02.000000000","message":"not done","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9c175fca54bd4eec0f0d2e996f5cb2bb4fce3870","unresolved":false,"context_lines":[{"line_number":15,"context_line":"# This stuff can\u0027t live in test/unit/__init__.py due to its swob dependency."},{"line_number":16,"context_line":"from collections import defaultdict"},{"line_number":17,"context_line":"from urllib import parse"},{"line_number":18,"context_line":"from six import binary_type"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"from swift.common import swob"},{"line_number":21,"context_line":"from swift.common.header_key_dict import HeaderKeyDict"}],"source_content_type":"text/x-python","patch_set":44,"id":"30219e06_214cf69b","line":18,"in_reply_to":"282780eb_37f62ef2","updated":"2025-07-21 21:19:09.000000000","message":"Acknowledged","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"a39c0feabac6f56fb66a4ceb2f85c8ec54bd4753","unresolved":false,"context_lines":[{"line_number":15,"context_line":"# This stuff can\u0027t live in test/unit/__init__.py due to its swob dependency."},{"line_number":16,"context_line":"from collections import defaultdict"},{"line_number":17,"context_line":"from urllib import parse"},{"line_number":18,"context_line":"from six import binary_type"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"from swift.common import swob"},{"line_number":21,"context_line":"from swift.common.header_key_dict import HeaderKeyDict"}],"source_content_type":"text/x-python","patch_set":44,"id":"8dbf6d9d_8e3c6756","line":18,"in_reply_to":"30219e06_214cf69b","updated":"2025-07-22 21:26:46.000000000","message":"to-do","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"24c5d44d6b8c78a50f40cc5981234abb91f0d136","unresolved":false,"context_lines":[{"line_number":15,"context_line":"# This stuff can\u0027t live in test/unit/__init__.py due to its swob dependency."},{"line_number":16,"context_line":"from collections import defaultdict"},{"line_number":17,"context_line":"from urllib import parse"},{"line_number":18,"context_line":"from six import binary_type"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"from swift.common import swob"},{"line_number":21,"context_line":"from swift.common.header_key_dict import HeaderKeyDict"}],"source_content_type":"text/x-python","patch_set":44,"id":"191bebe2_794ad6cd","line":18,"in_reply_to":"e54f099b_2063f45d","updated":"2025-06-12 20:05:52.000000000","message":"Done","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1432c12767bfa249bb2d1d29e769cd306b817b23","unresolved":true,"context_lines":[{"line_number":250,"context_line":""},{"line_number":251,"context_line":"    def __init__(self, capture_unexpected_calls\u003dTrue, test_read_size\u003d-1):"},{"line_number":252,"context_line":"        self.capture_unexpected_calls \u003d capture_unexpected_calls"},{"line_number":253,"context_line":"        self.test_read_size \u003d test_read_size"},{"line_number":254,"context_line":"        self._calls \u003d []"},{"line_number":255,"context_line":"        self._unclosed_req_keys \u003d defaultdict(int)"},{"line_number":256,"context_line":"        self._unread_req_paths \u003d defaultdict(int)"}],"source_content_type":"text/x-python","patch_set":57,"id":"210d49bc_4aa74d9d","line":253,"range":{"start_line":253,"start_character":13,"end_line":253,"end_character":27},"updated":"2025-07-17 14:31:02.000000000","message":"nit: this is just a naming preference, but IMHO ``read_size`` or ``read_chunk_size`` would be sufficient - it\u0027s implicit that this is only used in a test context","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9c175fca54bd4eec0f0d2e996f5cb2bb4fce3870","unresolved":false,"context_lines":[{"line_number":250,"context_line":""},{"line_number":251,"context_line":"    def __init__(self, capture_unexpected_calls\u003dTrue, test_read_size\u003d-1):"},{"line_number":252,"context_line":"        self.capture_unexpected_calls \u003d capture_unexpected_calls"},{"line_number":253,"context_line":"        self.test_read_size \u003d test_read_size"},{"line_number":254,"context_line":"        self._calls \u003d []"},{"line_number":255,"context_line":"        self._unclosed_req_keys \u003d defaultdict(int)"},{"line_number":256,"context_line":"        self._unread_req_paths \u003d defaultdict(int)"}],"source_content_type":"text/x-python","patch_set":57,"id":"d2176d93_b0fab244","line":253,"range":{"start_line":253,"start_character":13,"end_line":253,"end_character":27},"in_reply_to":"210d49bc_4aa74d9d","updated":"2025-07-21 21:19:09.000000000","message":"Acknowledged","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"}],"test/unit/common/middleware/s3api/test_obj.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d21278b9a94cd7c6739dd5897408c28bc9120615","unresolved":true,"context_lines":[{"line_number":1341,"context_line":"        self.app \u003d self._wrap_app(subrequest_app)"},{"line_number":1342,"context_line":"        self.app._pipeline_final_app \u003d self.swift"},{"line_number":1343,"context_line":"        self.s3api \u003d filter_factory({"},{"line_number":1344,"context_line":"            \u0027force_swift_request_proxy_log\u0027: True,"},{"line_number":1345,"context_line":"        })(self.app)"},{"line_number":1346,"context_line":"        self.logger \u003d self.s3api.logger \u003d self.swift.logger"},{"line_number":1347,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"2d484527_a37cd6a3","line":1344,"updated":"2024-11-15 19:40:40.000000000","message":"I\u0027m guessing `S3ApiTestCase` doesn\u0027t set this config option and it\u0027s needed to get the subrequest_app to do the right thing.\n\n1) I think it\u0027s a smell that this option is required; I\u0027d like to understand that better and if we could avoid it with a change in s3api\n\n2) I think it may be useful to refactor `S3ApiTestCase` to expose some sort of `self.conf \u003d updated_conf; self.s3api \u003d self._make_s3api_app()` sort of interface - lots of other test cases support the idea that individual test_methods may want to update the base config of the main class/filter/daemon being tested.","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":1341,"context_line":"        self.app \u003d self._wrap_app(subrequest_app)"},{"line_number":1342,"context_line":"        self.app._pipeline_final_app \u003d self.swift"},{"line_number":1343,"context_line":"        self.s3api \u003d filter_factory({"},{"line_number":1344,"context_line":"            \u0027force_swift_request_proxy_log\u0027: True,"},{"line_number":1345,"context_line":"        })(self.app)"},{"line_number":1346,"context_line":"        self.logger \u003d self.s3api.logger \u003d self.swift.logger"},{"line_number":1347,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"beb4e282_0bd73363","line":1344,"in_reply_to":"2d484527_a37cd6a3","updated":"2024-11-22 20:30:38.000000000","message":"updated to not using this config option","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c836907958e81fc6029007ffa68113095eb48b82","unresolved":true,"context_lines":[{"line_number":1357,"context_line":"        self.assertEqual(\u0027/v1/AUTH_test/bucket/object\u0027,"},{"line_number":1358,"context_line":"                         req.environ[\u0027swift.backend_path\u0027])"},{"line_number":1359,"context_line":"        swift_request_paths \u003d req.environ.get("},{"line_number":1360,"context_line":"            \u0027swift.swift_request_paths\u0027, None)"},{"line_number":1361,"context_line":"        self.assertTrue(swift_request_paths is not None)"},{"line_number":1362,"context_line":"        self.assertEqual(\u0027/v1/AUTH_test/bucket/object\u0027,"},{"line_number":1363,"context_line":"                         swift_request_paths[0])"}],"source_content_type":"text/x-python","patch_set":11,"id":"747ef9f0_4d756a36","line":1360,"range":{"start_line":1360,"start_character":41,"end_line":1360,"end_character":46},"updated":"2024-12-11 15:35:43.000000000","message":"dict get returns None by default - it isn\u0027t necessary to pass in None here","commit_id":"1af3d28b70a02ca2ed62f9252b527b1efb018b60"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"95af8f10f32e2f8430669825672d1b9701c15cf6","unresolved":false,"context_lines":[{"line_number":1357,"context_line":"        self.assertEqual(\u0027/v1/AUTH_test/bucket/object\u0027,"},{"line_number":1358,"context_line":"                         req.environ[\u0027swift.backend_path\u0027])"},{"line_number":1359,"context_line":"        swift_request_paths \u003d req.environ.get("},{"line_number":1360,"context_line":"            \u0027swift.swift_request_paths\u0027, None)"},{"line_number":1361,"context_line":"        self.assertTrue(swift_request_paths is not None)"},{"line_number":1362,"context_line":"        self.assertEqual(\u0027/v1/AUTH_test/bucket/object\u0027,"},{"line_number":1363,"context_line":"                         swift_request_paths[0])"}],"source_content_type":"text/x-python","patch_set":11,"id":"e6b829ae_e9c4d26f","line":1360,"range":{"start_line":1360,"start_character":41,"end_line":1360,"end_character":46},"in_reply_to":"747ef9f0_4d756a36","updated":"2025-01-03 16:33:48.000000000","message":"Acknowledged","commit_id":"1af3d28b70a02ca2ed62f9252b527b1efb018b60"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c836907958e81fc6029007ffa68113095eb48b82","unresolved":true,"context_lines":[{"line_number":1358,"context_line":"                         req.environ[\u0027swift.backend_path\u0027])"},{"line_number":1359,"context_line":"        swift_request_paths \u003d req.environ.get("},{"line_number":1360,"context_line":"            \u0027swift.swift_request_paths\u0027, None)"},{"line_number":1361,"context_line":"        self.assertTrue(swift_request_paths is not None)"},{"line_number":1362,"context_line":"        self.assertEqual(\u0027/v1/AUTH_test/bucket/object\u0027,"},{"line_number":1363,"context_line":"                         swift_request_paths[0])"},{"line_number":1364,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"481bccbc_2e717ed8","line":1361,"range":{"start_line":1361,"start_character":13,"end_line":1361,"end_character":23},"updated":"2024-12-11 15:35:43.000000000","message":"you can use ``self.assertIsNotNone``","commit_id":"1af3d28b70a02ca2ed62f9252b527b1efb018b60"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"95af8f10f32e2f8430669825672d1b9701c15cf6","unresolved":false,"context_lines":[{"line_number":1358,"context_line":"                         req.environ[\u0027swift.backend_path\u0027])"},{"line_number":1359,"context_line":"        swift_request_paths \u003d req.environ.get("},{"line_number":1360,"context_line":"            \u0027swift.swift_request_paths\u0027, None)"},{"line_number":1361,"context_line":"        self.assertTrue(swift_request_paths is not None)"},{"line_number":1362,"context_line":"        self.assertEqual(\u0027/v1/AUTH_test/bucket/object\u0027,"},{"line_number":1363,"context_line":"                         swift_request_paths[0])"},{"line_number":1364,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"abe058ed_661b70d0","line":1361,"range":{"start_line":1361,"start_character":13,"end_line":1361,"end_character":23},"in_reply_to":"481bccbc_2e717ed8","updated":"2025-01-03 16:33:48.000000000","message":"Acknowledged","commit_id":"1af3d28b70a02ca2ed62f9252b527b1efb018b60"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":1315,"context_line":"        self._register_bucket_policy_index_head(\u0027bucket\u0027, 0)"},{"line_number":1316,"context_line":"        self._do_test_object_policy_index_logging(0)"},{"line_number":1317,"context_line":""},{"line_number":1318,"context_line":"    def test_object_PUT_subrequest_proxy_env(self):"},{"line_number":1319,"context_line":"        self.swift.register(\u0027GET\u0027,"},{"line_number":1320,"context_line":"                            \u0027/v1/AUTH_test/bucket/src_obj\u0027,"},{"line_number":1321,"context_line":"                            swob.HTTPOk, self.response_headers,"}],"source_content_type":"text/x-python","patch_set":38,"id":"c8a20560_8987fbee","line":1318,"updated":"2025-05-19 15:40:26.000000000","message":"can this test be in test_proxy_logging.py? It seems out of place here, given that the request is actually made to a ProxyLogging middleware instance.","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"31e0fb568a380319c15ece5acc47007595b0cbcb","unresolved":false,"context_lines":[{"line_number":1315,"context_line":"        self._register_bucket_policy_index_head(\u0027bucket\u0027, 0)"},{"line_number":1316,"context_line":"        self._do_test_object_policy_index_logging(0)"},{"line_number":1317,"context_line":""},{"line_number":1318,"context_line":"    def test_object_PUT_subrequest_proxy_env(self):"},{"line_number":1319,"context_line":"        self.swift.register(\u0027GET\u0027,"},{"line_number":1320,"context_line":"                            \u0027/v1/AUTH_test/bucket/src_obj\u0027,"},{"line_number":1321,"context_line":"                            swob.HTTPOk, self.response_headers,"}],"source_content_type":"text/x-python","patch_set":38,"id":"80235299_d8c7f6da","line":1318,"in_reply_to":"c8a20560_8987fbee","updated":"2025-05-28 12:47:46.000000000","message":"Done","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":1341,"context_line":"        })(self.app)"},{"line_number":1342,"context_line":"        self.logger \u003d self.s3api.logger \u003d self.swift.logger"},{"line_number":1343,"context_line":""},{"line_number":1344,"context_line":"        self.s3api \u003d ProxyLoggingMiddleware(self.s3api, {"},{"line_number":1345,"context_line":"            \u0027access_log_route\u0027: \u0027proxy-access\u0027,"},{"line_number":1346,"context_line":"        }, logger\u003dself.logger)"},{"line_number":1347,"context_line":"        status, headers, body \u003d self.call_s3api(req)"}],"source_content_type":"text/x-python","patch_set":38,"id":"18b1a0ae_31eaacb5","line":1344,"range":{"start_line":1344,"start_character":8,"end_line":1344,"end_character":43},"updated":"2025-05-19 15:40:26.000000000","message":"that\u0027a a bit confusing...and then we ``call_s3api`` except it isn\u0027t s3api middleware that is called!","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"31e0fb568a380319c15ece5acc47007595b0cbcb","unresolved":false,"context_lines":[{"line_number":1341,"context_line":"        })(self.app)"},{"line_number":1342,"context_line":"        self.logger \u003d self.s3api.logger \u003d self.swift.logger"},{"line_number":1343,"context_line":""},{"line_number":1344,"context_line":"        self.s3api \u003d ProxyLoggingMiddleware(self.s3api, {"},{"line_number":1345,"context_line":"            \u0027access_log_route\u0027: \u0027proxy-access\u0027,"},{"line_number":1346,"context_line":"        }, logger\u003dself.logger)"},{"line_number":1347,"context_line":"        status, headers, body \u003d self.call_s3api(req)"}],"source_content_type":"text/x-python","patch_set":38,"id":"504305d9_4fae4c36","line":1344,"range":{"start_line":1344,"start_character":8,"end_line":1344,"end_character":43},"in_reply_to":"18b1a0ae_31eaacb5","updated":"2025-05-28 12:47:46.000000000","message":"Done","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"fad47fde9e8413872e9248916c63d06d52e3f4d1","unresolved":true,"context_lines":[{"line_number":29,"context_line":"from swift.common.swob import Request"},{"line_number":30,"context_line":"from swift.common.middleware.proxy_logging import ProxyLoggingMiddleware"},{"line_number":31,"context_line":"from test.unit import mock_timestamp_now, patch_policies"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"from test.unit.common.middleware.s3api import S3ApiTestCase, S3ApiTestCaseAcl"},{"line_number":34,"context_line":"from swift.common.middleware.s3api.s3request import SigV4Request"},{"line_number":35,"context_line":"from swift.common.middleware.s3api.subresource import ACL, User, encode_acl, \\"}],"source_content_type":"text/x-python","patch_set":42,"id":"ea9526e7_bb8d0347","side":"PARENT","line":32,"updated":"2025-05-29 14:04:02.000000000","message":"nit: unnecessary change","commit_id":"f5546e62ad2ca87422c4898d0f556e43a38f129a"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"b341a2ec64623dd1d758b6b7c37d19846e3bcc8c","unresolved":false,"context_lines":[{"line_number":29,"context_line":"from swift.common.swob import Request"},{"line_number":30,"context_line":"from swift.common.middleware.proxy_logging import ProxyLoggingMiddleware"},{"line_number":31,"context_line":"from test.unit import mock_timestamp_now, patch_policies"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"from test.unit.common.middleware.s3api import S3ApiTestCase, S3ApiTestCaseAcl"},{"line_number":34,"context_line":"from swift.common.middleware.s3api.s3request import SigV4Request"},{"line_number":35,"context_line":"from swift.common.middleware.s3api.subresource import ACL, User, encode_acl, \\"}],"source_content_type":"text/x-python","patch_set":42,"id":"c92bfc93_91d4437d","side":"PARENT","line":32,"in_reply_to":"ea9526e7_bb8d0347","updated":"2025-06-03 11:34:30.000000000","message":"Acknowledged","commit_id":"f5546e62ad2ca87422c4898d0f556e43a38f129a"}],"test/unit/common/middleware/test_proxy_logging.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"735abc7928e73bf5b3f3464946fe04633df6fb42","unresolved":true,"context_lines":[{"line_number":1892,"context_line":"                    \u0027method\u0027: \u0027GET\u0027,"},{"line_number":1893,"context_line":"                    \u0027type\u0027: \u0027container\u0027,"},{"line_number":1894,"context_line":"                    \u0027status\u0027: 200}}),"},{"line_number":1895,"context_line":"        ], app)"},{"line_number":1896,"context_line":""},{"line_number":1897,"context_line":"    def test_log_query_string(self):"},{"line_number":1898,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware(FakeApp(), {})"}],"source_content_type":"text/x-python","patch_set":2,"id":"25fc74e4_af284c82","line":1895,"updated":"2024-10-07 17:15:03.000000000","message":"it seems like all of these tests fully exhaust the generator - I think it would be nice to see a test that asserts stats are emitted with \"each\" call to `next()`","commit_id":"93971c11c36809e4f15deb33704f4929c44ec3ab"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"15c81a70efeef62d21e0aea498d29aada62c6fec","unresolved":false,"context_lines":[{"line_number":1892,"context_line":"                    \u0027method\u0027: \u0027GET\u0027,"},{"line_number":1893,"context_line":"                    \u0027type\u0027: \u0027container\u0027,"},{"line_number":1894,"context_line":"                    \u0027status\u0027: 200}}),"},{"line_number":1895,"context_line":"        ], app)"},{"line_number":1896,"context_line":""},{"line_number":1897,"context_line":"    def test_log_query_string(self):"},{"line_number":1898,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware(FakeApp(), {})"}],"source_content_type":"text/x-python","patch_set":2,"id":"0c184622_2b99465b","line":1895,"in_reply_to":"25fc74e4_af284c82","updated":"2024-10-25 15:18:36.000000000","message":"Acknowledged","commit_id":"93971c11c36809e4f15deb33704f4929c44ec3ab"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d21278b9a94cd7c6739dd5897408c28bc9120615","unresolved":true,"context_lines":[{"line_number":73,"context_line":"            headers.append((\u0027X-Backend-Storage-Policy-Index\u0027,"},{"line_number":74,"context_line":"                           str(self.policy_idx)))"},{"line_number":75,"context_line":"        start_response(self.response_str, headers)"},{"line_number":76,"context_line":"        while env[\u0027wsgi.input\u0027].read(5):"},{"line_number":77,"context_line":"            pass"},{"line_number":78,"context_line":"        # N.B. mw can set this anytime before the resp is finished"},{"line_number":79,"context_line":"        env.update(self.environ_updates)"}],"source_content_type":"text/x-python","patch_set":6,"id":"76400bc3_9b06d076","side":"PARENT","line":76,"updated":"2024-11-15 19:40:40.000000000","message":"maybe this was the inception of the magic `5`\n\n.. but we\u0027re just discarding the body, I wonder if the value made any difference.","commit_id":"09df3927ca90d4aa215f3c6fb0cbfbdf63ab12fd"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":73,"context_line":"            headers.append((\u0027X-Backend-Storage-Policy-Index\u0027,"},{"line_number":74,"context_line":"                           str(self.policy_idx)))"},{"line_number":75,"context_line":"        start_response(self.response_str, headers)"},{"line_number":76,"context_line":"        while env[\u0027wsgi.input\u0027].read(5):"},{"line_number":77,"context_line":"            pass"},{"line_number":78,"context_line":"        # N.B. mw can set this anytime before the resp is finished"},{"line_number":79,"context_line":"        env.update(self.environ_updates)"}],"source_content_type":"text/x-python","patch_set":6,"id":"237c1ca9_00cfd797","side":"PARENT","line":76,"in_reply_to":"76400bc3_9b06d076","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"09df3927ca90d4aa215f3c6fb0cbfbdf63ab12fd"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d21278b9a94cd7c6739dd5897408c28bc9120615","unresolved":true,"context_lines":[{"line_number":1497,"context_line":"                     b\u0027some additional stuff\\n\u0027"},{"line_number":1498,"context_line":"        buffer_len \u003d len(buffer_str)"},{"line_number":1499,"context_line":"        read_calls \u003d [0]"},{"line_number":1500,"context_line":"        read_bytes \u003d [0]"},{"line_number":1501,"context_line":""},{"line_number":1502,"context_line":"        expect_stats_per_iter \u003d []"},{"line_number":1503,"context_line":"        iter_stats \u003d []"}],"source_content_type":"text/x-python","patch_set":6,"id":"8a4596c4_c37145bd","line":1500,"updated":"2024-11-15 19:40:40.000000000","message":"are these lists both just \"non locals\"???","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":1497,"context_line":"                     b\u0027some additional stuff\\n\u0027"},{"line_number":1498,"context_line":"        buffer_len \u003d len(buffer_str)"},{"line_number":1499,"context_line":"        read_calls \u003d [0]"},{"line_number":1500,"context_line":"        read_bytes \u003d [0]"},{"line_number":1501,"context_line":""},{"line_number":1502,"context_line":"        expect_stats_per_iter \u003d []"},{"line_number":1503,"context_line":"        iter_stats \u003d []"}],"source_content_type":"text/x-python","patch_set":6,"id":"a846bf36_93c9da41","line":1500,"in_reply_to":"8a4596c4_c37145bd","updated":"2024-11-22 20:30:38.000000000","message":"indeed","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d21278b9a94cd7c6739dd5897408c28bc9120615","unresolved":true,"context_lines":[{"line_number":1503,"context_line":"        iter_stats \u003d []"},{"line_number":1504,"context_line":"        nbytes \u003d 0"},{"line_number":1505,"context_line":"        while nbytes + 5 \u003c\u003d buffer_len:"},{"line_number":1506,"context_line":"            iter_stats \u003d iter_stats + ["},{"line_number":1507,"context_line":"                (\u0027swift_proxy_request_body_input_bytes\u0027, 5, {"},{"line_number":1508,"context_line":"                    \u0027labels\u0027: {"},{"line_number":1509,"context_line":"                        \u0027account\u0027: \u0027a\u0027,"}],"source_content_type":"text/x-python","patch_set":6,"id":"578a019d_5ff0c974","line":1506,"updated":"2024-11-15 19:40:40.000000000","message":"ok, so this is explicitly not an append because we need to create a new list...","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":1503,"context_line":"        iter_stats \u003d []"},{"line_number":1504,"context_line":"        nbytes \u003d 0"},{"line_number":1505,"context_line":"        while nbytes + 5 \u003c\u003d buffer_len:"},{"line_number":1506,"context_line":"            iter_stats \u003d iter_stats + ["},{"line_number":1507,"context_line":"                (\u0027swift_proxy_request_body_input_bytes\u0027, 5, {"},{"line_number":1508,"context_line":"                    \u0027labels\u0027: {"},{"line_number":1509,"context_line":"                        \u0027account\u0027: \u0027a\u0027,"}],"source_content_type":"text/x-python","patch_set":6,"id":"087cd9de_811675ac","line":1506,"in_reply_to":"578a019d_5ff0c974","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d21278b9a94cd7c6739dd5897408c28bc9120615","unresolved":true,"context_lines":[{"line_number":1563,"context_line":"        def assert_read_stats(iter_n, nbytes):"},{"line_number":1564,"context_line":"            self.assertUpdateStats(expect_stats_per_iter[iter_n], app)"},{"line_number":1565,"context_line":"            read_calls[0] \u003d iter_n + 1"},{"line_number":1566,"context_line":"            read_bytes[0] +\u003d nbytes"},{"line_number":1567,"context_line":""},{"line_number":1568,"context_line":"        conf \u003d {"},{"line_number":1569,"context_line":"            \u0027log_headers\u0027: \u0027yes\u0027,"}],"source_content_type":"text/x-python","patch_set":6,"id":"da084eb1_65cdaef9","line":1566,"updated":"2024-11-15 19:40:40.000000000","message":"are these non local mutations changing what this assertion does on future calls?","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":1563,"context_line":"        def assert_read_stats(iter_n, nbytes):"},{"line_number":1564,"context_line":"            self.assertUpdateStats(expect_stats_per_iter[iter_n], app)"},{"line_number":1565,"context_line":"            read_calls[0] \u003d iter_n + 1"},{"line_number":1566,"context_line":"            read_bytes[0] +\u003d nbytes"},{"line_number":1567,"context_line":""},{"line_number":1568,"context_line":"        conf \u003d {"},{"line_number":1569,"context_line":"            \u0027log_headers\u0027: \u0027yes\u0027,"}],"source_content_type":"text/x-python","patch_set":6,"id":"61a05956_3f357a37","line":1566,"in_reply_to":"da084eb1_65cdaef9","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d21278b9a94cd7c6739dd5897408c28bc9120615","unresolved":true,"context_lines":[{"line_number":1572,"context_line":"        }"},{"line_number":1573,"context_line":"        self.statsd \u003d debug_labeled_statsd_client(conf)"},{"line_number":1574,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":1575,"context_line":"            FakeApp(read_callback\u003dassert_read_stats), conf, logger\u003dself.logger)"},{"line_number":1576,"context_line":"        app.statsd \u003d self.statsd"},{"line_number":1577,"context_line":"        req \u003d Request.blank("},{"line_number":1578,"context_line":"            \u0027/v1/a/c\u0027,"}],"source_content_type":"text/x-python","patch_set":6,"id":"3f46db54_8b39130c","line":1575,"updated":"2024-11-15 19:40:40.000000000","message":"oh i don\u0027t love that we\u0027re injecting our assertions into a callback in the app","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":1572,"context_line":"        }"},{"line_number":1573,"context_line":"        self.statsd \u003d debug_labeled_statsd_client(conf)"},{"line_number":1574,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":1575,"context_line":"            FakeApp(read_callback\u003dassert_read_stats), conf, logger\u003dself.logger)"},{"line_number":1576,"context_line":"        app.statsd \u003d self.statsd"},{"line_number":1577,"context_line":"        req \u003d Request.blank("},{"line_number":1578,"context_line":"            \u0027/v1/a/c\u0027,"}],"source_content_type":"text/x-python","patch_set":6,"id":"fe55b91a_17560fac","line":1575,"in_reply_to":"3f46db54_8b39130c","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d21278b9a94cd7c6739dd5897408c28bc9120615","unresolved":true,"context_lines":[{"line_number":1581,"context_line":"                     })"},{"line_number":1582,"context_line":"        resp \u003d app(req.environ, start_response)"},{"line_number":1583,"context_line":"        # exhaust generator"},{"line_number":1584,"context_line":"        [x for x in resp]"},{"line_number":1585,"context_line":"        log_parts \u003d self._log_parts(app)"},{"line_number":1586,"context_line":"        self.assertEqual(log_parts[11], str(len(\u0027FAKE APP\u0027)))"},{"line_number":1587,"context_line":"        self.assertEqual(log_parts[10], str(buffer_len))"}],"source_content_type":"text/x-python","patch_set":6,"id":"08acb0d5_756f5bab","line":1584,"updated":"2024-11-15 19:40:40.000000000","message":"could we just do our assertions in line here as we consume the resp with the expected chunk_size?","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":1581,"context_line":"                     })"},{"line_number":1582,"context_line":"        resp \u003d app(req.environ, start_response)"},{"line_number":1583,"context_line":"        # exhaust generator"},{"line_number":1584,"context_line":"        [x for x in resp]"},{"line_number":1585,"context_line":"        log_parts \u003d self._log_parts(app)"},{"line_number":1586,"context_line":"        self.assertEqual(log_parts[11], str(len(\u0027FAKE APP\u0027)))"},{"line_number":1587,"context_line":"        self.assertEqual(log_parts[10], str(buffer_len))"}],"source_content_type":"text/x-python","patch_set":6,"id":"8ac1ba8c_bf16e775","line":1584,"in_reply_to":"08acb0d5_756f5bab","updated":"2024-11-22 20:30:38.000000000","message":"Acknowledged","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d21278b9a94cd7c6739dd5897408c28bc9120615","unresolved":true,"context_lines":[{"line_number":1587,"context_line":"        self.assertEqual(log_parts[10], str(buffer_len))"},{"line_number":1588,"context_line":"        self.assertEqual(read_bytes[0], buffer_len)"},{"line_number":1589,"context_line":"        self.assertEqual(read_calls[0] + 1, len(expect_stats_per_iter))"},{"line_number":1590,"context_line":"        self.assertUpdateStats(expect_stats_per_iter[read_calls[0]], app)"},{"line_number":1591,"context_line":""},{"line_number":1592,"context_line":"    def test_xfer_stats_get(self):"},{"line_number":1593,"context_line":"        class BodyGen(object):"}],"source_content_type":"text/x-python","patch_set":6,"id":"6aa54874_2d118d13","line":1590,"updated":"2024-11-15 19:40:40.000000000","message":"what does this method do that we only care about a single (the last?) value in `expect_stats_per_iter`","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"8062d7d788300517ff28f1945ed9fe676e1def9e","unresolved":false,"context_lines":[{"line_number":1587,"context_line":"        self.assertEqual(log_parts[10], str(buffer_len))"},{"line_number":1588,"context_line":"        self.assertEqual(read_bytes[0], buffer_len)"},{"line_number":1589,"context_line":"        self.assertEqual(read_calls[0] + 1, len(expect_stats_per_iter))"},{"line_number":1590,"context_line":"        self.assertUpdateStats(expect_stats_per_iter[read_calls[0]], app)"},{"line_number":1591,"context_line":""},{"line_number":1592,"context_line":"    def test_xfer_stats_get(self):"},{"line_number":1593,"context_line":"        class BodyGen(object):"}],"source_content_type":"text/x-python","patch_set":6,"id":"db5080f7_c750bf00","line":1590,"in_reply_to":"6aa54874_2d118d13","updated":"2024-11-22 20:30:38.000000000","message":"that should be all metrics emitted","commit_id":"0b792d8917bc1503d3e5d3fe89b07a605fad415d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3c9db4b292eacdc99e65c8934ed5e7d5148bdd8b","unresolved":true,"context_lines":[{"line_number":1591,"context_line":"                        \u0027type\u0027: \u0027container\u0027}})"},{"line_number":1592,"context_line":"            ]"},{"line_number":1593,"context_line":"            expect_stats_per_iter.append(iter_stats)"},{"line_number":1594,"context_line":"            nbytes \u003d buffer_len"},{"line_number":1595,"context_line":"        iter_stats \u003d iter_stats + ["},{"line_number":1596,"context_line":"            (\u0027swift_proxy_request_body_input_bytes\u0027, 0, {"},{"line_number":1597,"context_line":"                \u0027labels\u0027: {"}],"source_content_type":"text/x-python","patch_set":9,"id":"4e5e8c2f_7df44d6b","line":1594,"range":{"start_line":1594,"start_character":12,"end_line":1594,"end_character":31},"updated":"2024-11-29 16:33:28.000000000","message":"this assignment to nbytes is unused","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"ec749a90b62e4614dfbbd965ec77307a011e0994","unresolved":false,"context_lines":[{"line_number":1591,"context_line":"                        \u0027type\u0027: \u0027container\u0027}})"},{"line_number":1592,"context_line":"            ]"},{"line_number":1593,"context_line":"            expect_stats_per_iter.append(iter_stats)"},{"line_number":1594,"context_line":"            nbytes \u003d buffer_len"},{"line_number":1595,"context_line":"        iter_stats \u003d iter_stats + ["},{"line_number":1596,"context_line":"            (\u0027swift_proxy_request_body_input_bytes\u0027, 0, {"},{"line_number":1597,"context_line":"                \u0027labels\u0027: {"}],"source_content_type":"text/x-python","patch_set":9,"id":"b1f98133_1769347d","line":1594,"range":{"start_line":1594,"start_character":12,"end_line":1594,"end_character":31},"in_reply_to":"4e5e8c2f_7df44d6b","updated":"2024-12-10 16:29:15.000000000","message":"Acknowledged","commit_id":"d85b9d0e6a50c0dfb36e67c68e7e9a9e098cead3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c836907958e81fc6029007ffa68113095eb48b82","unresolved":true,"context_lines":[{"line_number":1906,"context_line":"                    \u0027status\u0027: 200}}),"},{"line_number":1907,"context_line":"        ], app)"},{"line_number":1908,"context_line":""},{"line_number":1909,"context_line":"    def test_xfer_stats_put_s3api(self):"},{"line_number":1910,"context_line":"        def call_s3api(req, app):"},{"line_number":1911,"context_line":"            req.headers.setdefault(\"User-Agent\", \"Mozzarella Foxfire\")"},{"line_number":1912,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"397bda9b_931aa868","line":1909,"updated":"2024-12-11 15:35:43.000000000","message":"I made some changes to this test to illustrate the problem with path re-writing in other middlewares like SLO:\nhttps://paste.openstack.org/show/bN7hV0FTZFOCBTzwHdcE/","commit_id":"1af3d28b70a02ca2ed62f9252b527b1efb018b60"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"95af8f10f32e2f8430669825672d1b9701c15cf6","unresolved":false,"context_lines":[{"line_number":1906,"context_line":"                    \u0027status\u0027: 200}}),"},{"line_number":1907,"context_line":"        ], app)"},{"line_number":1908,"context_line":""},{"line_number":1909,"context_line":"    def test_xfer_stats_put_s3api(self):"},{"line_number":1910,"context_line":"        def call_s3api(req, app):"},{"line_number":1911,"context_line":"            req.headers.setdefault(\"User-Agent\", \"Mozzarella Foxfire\")"},{"line_number":1912,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"4cf1978c_e0af3bfc","line":1909,"in_reply_to":"397bda9b_931aa868","updated":"2025-01-03 16:33:48.000000000","message":"Acknowledged","commit_id":"1af3d28b70a02ca2ed62f9252b527b1efb018b60"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":1719,"context_line":"        body \u003d b\u0027\u0027.join(body_iter)"},{"line_number":1720,"context_line":"        return status, headers, body"},{"line_number":1721,"context_line":""},{"line_number":1722,"context_line":"    def test_buffer_xfer_emit_callback(self):"},{"line_number":1723,"context_line":"        conf \u003d {"},{"line_number":1724,"context_line":"            \u0027log_headers\u0027: \u0027yes\u0027,"},{"line_number":1725,"context_line":"            \u0027statsd_label_mode\u0027: \u0027dogstatsd\u0027,"}],"source_content_type":"text/x-python","patch_set":38,"id":"e1205eba_a7e19bfb","line":1722,"updated":"2025-05-19 15:40:26.000000000","message":"this could go in its own TestCase class TestBufferXferEmitCallback","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"31e0fb568a380319c15ece5acc47007595b0cbcb","unresolved":false,"context_lines":[{"line_number":1719,"context_line":"        body \u003d b\u0027\u0027.join(body_iter)"},{"line_number":1720,"context_line":"        return status, headers, body"},{"line_number":1721,"context_line":""},{"line_number":1722,"context_line":"    def test_buffer_xfer_emit_callback(self):"},{"line_number":1723,"context_line":"        conf \u003d {"},{"line_number":1724,"context_line":"            \u0027log_headers\u0027: \u0027yes\u0027,"},{"line_number":1725,"context_line":"            \u0027statsd_label_mode\u0027: \u0027dogstatsd\u0027,"}],"source_content_type":"text/x-python","patch_set":38,"id":"a6ce9415_1629eb25","line":1722,"in_reply_to":"e1205eba_a7e19bfb","updated":"2025-05-28 12:47:46.000000000","message":"Done","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":1747,"context_line":"                \u0027resource\u0027: \u0027container\u0027}),"},{"line_number":1748,"context_line":"        ])"},{"line_number":1749,"context_line":"        callback(5)"},{"line_number":1750,"context_line":"        self.assertLabeledUpdateStats(["},{"line_number":1751,"context_line":"            (\u0027swift_proxy_example_metric\u0027, 5, {"},{"line_number":1752,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":1753,"context_line":"                \u0027container\u0027: \u0027c\u0027,"}],"source_content_type":"text/x-python","patch_set":38,"id":"3840233f_591bfb9f","line":1750,"updated":"2025-05-19 15:40:26.000000000","message":"IIRC we can clear the fake statsd client so these assertions could be more compact and just assert then latest stat was emitted\n\nAlso, maybe vary the bytes length, just to be sure.","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"31e0fb568a380319c15ece5acc47007595b0cbcb","unresolved":false,"context_lines":[{"line_number":1747,"context_line":"                \u0027resource\u0027: \u0027container\u0027}),"},{"line_number":1748,"context_line":"        ])"},{"line_number":1749,"context_line":"        callback(5)"},{"line_number":1750,"context_line":"        self.assertLabeledUpdateStats(["},{"line_number":1751,"context_line":"            (\u0027swift_proxy_example_metric\u0027, 5, {"},{"line_number":1752,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":1753,"context_line":"                \u0027container\u0027: \u0027c\u0027,"}],"source_content_type":"text/x-python","patch_set":38,"id":"b9bb6da7_3243f4e4","line":1750,"in_reply_to":"3840233f_591bfb9f","updated":"2025-05-28 12:47:46.000000000","message":"Acknowledged","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":1784,"context_line":"                     b\u0027some additional stuff\\n\u0027"},{"line_number":1785,"context_line":"        buffer_len \u003d len(buffer_str)"},{"line_number":1786,"context_line":"        read_calls \u003d [0]"},{"line_number":1787,"context_line":"        read_bytes \u003d [0]"},{"line_number":1788,"context_line":""},{"line_number":1789,"context_line":"        expect_stats_per_iter \u003d []"},{"line_number":1790,"context_line":"        iter_stats \u003d []"}],"source_content_type":"text/x-python","patch_set":38,"id":"2c29e047_a7214f4c","line":1787,"updated":"2025-05-19 15:40:26.000000000","message":"now we are py3 ony we can use the nonlocal keyword to avoid having to modify mutables inside inner functions","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"b341a2ec64623dd1d758b6b7c37d19846e3bcc8c","unresolved":false,"context_lines":[{"line_number":1784,"context_line":"                     b\u0027some additional stuff\\n\u0027"},{"line_number":1785,"context_line":"        buffer_len \u003d len(buffer_str)"},{"line_number":1786,"context_line":"        read_calls \u003d [0]"},{"line_number":1787,"context_line":"        read_bytes \u003d [0]"},{"line_number":1788,"context_line":""},{"line_number":1789,"context_line":"        expect_stats_per_iter \u003d []"},{"line_number":1790,"context_line":"        iter_stats \u003d []"}],"source_content_type":"text/x-python","patch_set":38,"id":"d51424ad_6d1bed47","line":1787,"in_reply_to":"2c29e047_a7214f4c","updated":"2025-06-03 11:34:30.000000000","message":"Acknowledged","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":1786,"context_line":"        read_calls \u003d [0]"},{"line_number":1787,"context_line":"        read_bytes \u003d [0]"},{"line_number":1788,"context_line":""},{"line_number":1789,"context_line":"        expect_stats_per_iter \u003d []"},{"line_number":1790,"context_line":"        iter_stats \u003d []"},{"line_number":1791,"context_line":"        nbytes \u003d 0"},{"line_number":1792,"context_line":"        while nbytes + 5 \u003c\u003d buffer_len:"}],"source_content_type":"text/x-python","patch_set":38,"id":"f3d3d985_bb86a966","line":1789,"updated":"2025-05-19 15:40:26.000000000","message":"I think this test would be much simpler if the fake statsd client was cleared during each call to assert_read_stats, after the most recent statsd call have been captured. Then there would be a single list of captured stats that should exactly equal the expected sequence of stats, rather than this list of accumulating statsd call history.","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"6cd17935952a72154c46b0576c8d1e4c49521cdc","unresolved":false,"context_lines":[{"line_number":1786,"context_line":"        read_calls \u003d [0]"},{"line_number":1787,"context_line":"        read_bytes \u003d [0]"},{"line_number":1788,"context_line":""},{"line_number":1789,"context_line":"        expect_stats_per_iter \u003d []"},{"line_number":1790,"context_line":"        iter_stats \u003d []"},{"line_number":1791,"context_line":"        nbytes \u003d 0"},{"line_number":1792,"context_line":"        while nbytes + 5 \u003c\u003d buffer_len:"}],"source_content_type":"text/x-python","patch_set":38,"id":"7fb1e88c_c8dc0dd7","line":1789,"in_reply_to":"a03e4b5d_089c926c","updated":"2025-08-01 15:49:03.000000000","message":"Acknowledged","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"198b984c59b8a6fd4ba03b46d765c424b2ef8250","unresolved":true,"context_lines":[{"line_number":1786,"context_line":"        read_calls \u003d [0]"},{"line_number":1787,"context_line":"        read_bytes \u003d [0]"},{"line_number":1788,"context_line":""},{"line_number":1789,"context_line":"        expect_stats_per_iter \u003d []"},{"line_number":1790,"context_line":"        iter_stats \u003d []"},{"line_number":1791,"context_line":"        nbytes \u003d 0"},{"line_number":1792,"context_line":"        while nbytes + 5 \u003c\u003d buffer_len:"}],"source_content_type":"text/x-python","patch_set":38,"id":"a03e4b5d_089c926c","line":1789,"in_reply_to":"f3d3d985_bb86a966","updated":"2025-07-28 14:00:11.000000000","message":"I still think this test is overly complex","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":1840,"context_line":"        expect_stats_per_iter.append(iter_stats)"},{"line_number":1841,"context_line":"        callback_stats_per_iter \u003d []"},{"line_number":1842,"context_line":""},{"line_number":1843,"context_line":"        def assert_read_stats(iter_n, nbytes):"},{"line_number":1844,"context_line":"            logger_calls \u003d app.access_logger.statsd_client.calls["},{"line_number":1845,"context_line":"                \u0027update_stats\u0027]"},{"line_number":1846,"context_line":"            statsd_calls \u003d self.statsd.calls[\u0027update_stats\u0027]"}],"source_content_type":"text/x-python","patch_set":38,"id":"6614c680_85b00d92","line":1843,"updated":"2025-05-19 15:40:26.000000000","message":"this doesn\u0027t assert anything - it seems to be capturing stats for later assertion, which feels like the right thing to do, I just query the name of the function","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"c57ad89fac0b2e65583f5f342cc167aff89d8139","unresolved":false,"context_lines":[{"line_number":1840,"context_line":"        expect_stats_per_iter.append(iter_stats)"},{"line_number":1841,"context_line":"        callback_stats_per_iter \u003d []"},{"line_number":1842,"context_line":""},{"line_number":1843,"context_line":"        def assert_read_stats(iter_n, nbytes):"},{"line_number":1844,"context_line":"            logger_calls \u003d app.access_logger.statsd_client.calls["},{"line_number":1845,"context_line":"                \u0027update_stats\u0027]"},{"line_number":1846,"context_line":"            statsd_calls \u003d self.statsd.calls[\u0027update_stats\u0027]"}],"source_content_type":"text/x-python","patch_set":38,"id":"8c7b46c7_9216e849","line":1843,"in_reply_to":"6614c680_85b00d92","updated":"2025-06-04 15:04:37.000000000","message":"Okay - capture_read_stats then!","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":1842,"context_line":""},{"line_number":1843,"context_line":"        def assert_read_stats(iter_n, nbytes):"},{"line_number":1844,"context_line":"            logger_calls \u003d app.access_logger.statsd_client.calls["},{"line_number":1845,"context_line":"                \u0027update_stats\u0027]"},{"line_number":1846,"context_line":"            statsd_calls \u003d self.statsd.calls[\u0027update_stats\u0027]"},{"line_number":1847,"context_line":"            update_stats_calls \u003d sorted(logger_calls + statsd_calls)"},{"line_number":1848,"context_line":"            got_metrics_values_and_kwargs \u003d []"}],"source_content_type":"text/x-python","patch_set":38,"id":"ca82233f_21f97da9","line":1845,"updated":"2025-05-19 15:40:26.000000000","message":"what would these logger calls be - that\u0027s legacy metrics right? we don\u0027t expect those for bytes xfer?","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"31e0fb568a380319c15ece5acc47007595b0cbcb","unresolved":false,"context_lines":[{"line_number":1842,"context_line":""},{"line_number":1843,"context_line":"        def assert_read_stats(iter_n, nbytes):"},{"line_number":1844,"context_line":"            logger_calls \u003d app.access_logger.statsd_client.calls["},{"line_number":1845,"context_line":"                \u0027update_stats\u0027]"},{"line_number":1846,"context_line":"            statsd_calls \u003d self.statsd.calls[\u0027update_stats\u0027]"},{"line_number":1847,"context_line":"            update_stats_calls \u003d sorted(logger_calls + statsd_calls)"},{"line_number":1848,"context_line":"            got_metrics_values_and_kwargs \u003d []"}],"source_content_type":"text/x-python","patch_set":38,"id":"2a7f65ba_d152fa56","line":1845,"in_reply_to":"ca82233f_21f97da9","updated":"2025-05-28 12:47:46.000000000","message":"Right!","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":1873,"context_line":"        [x for x in resp]"},{"line_number":1874,"context_line":"        log_parts \u003d self._log_parts(app)"},{"line_number":1875,"context_line":"        self.assertEqual(log_parts[11], str(len(\u0027FAKE APP\u0027)))"},{"line_number":1876,"context_line":"        self.assertEqual(log_parts[10], str(buffer_len))"},{"line_number":1877,"context_line":"        self.assertEqual(read_bytes[0], buffer_len)"},{"line_number":1878,"context_line":"        self.assertEqual(read_calls[0], len(callback_stats_per_iter))"},{"line_number":1879,"context_line":"        self.assertEqual(read_calls[0] + 1, len(expect_stats_per_iter))"}],"source_content_type":"text/x-python","patch_set":38,"id":"c4ca6f0e_38202d78","line":1876,"updated":"2025-05-19 15:40:26.000000000","message":"does this test need to make assertions about log messages? it\u0027s already quite long","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"31e0fb568a380319c15ece5acc47007595b0cbcb","unresolved":false,"context_lines":[{"line_number":1873,"context_line":"        [x for x in resp]"},{"line_number":1874,"context_line":"        log_parts \u003d self._log_parts(app)"},{"line_number":1875,"context_line":"        self.assertEqual(log_parts[11], str(len(\u0027FAKE APP\u0027)))"},{"line_number":1876,"context_line":"        self.assertEqual(log_parts[10], str(buffer_len))"},{"line_number":1877,"context_line":"        self.assertEqual(read_bytes[0], buffer_len)"},{"line_number":1878,"context_line":"        self.assertEqual(read_calls[0], len(callback_stats_per_iter))"},{"line_number":1879,"context_line":"        self.assertEqual(read_calls[0] + 1, len(expect_stats_per_iter))"}],"source_content_type":"text/x-python","patch_set":38,"id":"86e0cfe8_8b4a562b","line":1876,"in_reply_to":"c4ca6f0e_38202d78","updated":"2025-05-28 12:47:46.000000000","message":"Yes, could work!","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":1877,"context_line":"        self.assertEqual(read_bytes[0], buffer_len)"},{"line_number":1878,"context_line":"        self.assertEqual(read_calls[0], len(callback_stats_per_iter))"},{"line_number":1879,"context_line":"        self.assertEqual(read_calls[0] + 1, len(expect_stats_per_iter))"},{"line_number":1880,"context_line":"        self.assertLabeledUpdateStats(expect_stats_per_iter[read_calls[0]])"},{"line_number":1881,"context_line":"        self.assertUpdateStats(["},{"line_number":1882,"context_line":"            (\u0027container.POST.200.xfer\u0027,"},{"line_number":1883,"context_line":"             buffer_len + len(\u0027FAKE APP\u0027)),"}],"source_content_type":"text/x-python","patch_set":38,"id":"61e5257b_b5bcc221","line":1880,"range":{"start_line":1880,"start_character":38,"end_line":1880,"end_character":59},"updated":"2025-05-19 15:40:26.000000000","message":"so IIUC we only use one of the accumulated expect_stats_per_iter items? why create all the others?","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"8d850855ef6a8d8c3488d4b31a3fc82df66487f3","unresolved":false,"context_lines":[{"line_number":1877,"context_line":"        self.assertEqual(read_bytes[0], buffer_len)"},{"line_number":1878,"context_line":"        self.assertEqual(read_calls[0], len(callback_stats_per_iter))"},{"line_number":1879,"context_line":"        self.assertEqual(read_calls[0] + 1, len(expect_stats_per_iter))"},{"line_number":1880,"context_line":"        self.assertLabeledUpdateStats(expect_stats_per_iter[read_calls[0]])"},{"line_number":1881,"context_line":"        self.assertUpdateStats(["},{"line_number":1882,"context_line":"            (\u0027container.POST.200.xfer\u0027,"},{"line_number":1883,"context_line":"             buffer_len + len(\u0027FAKE APP\u0027)),"}],"source_content_type":"text/x-python","patch_set":38,"id":"419605f3_322517ca","line":1880,"range":{"start_line":1880,"start_character":38,"end_line":1880,"end_character":59},"in_reply_to":"61e5257b_b5bcc221","updated":"2025-07-01 17:33:41.000000000","message":"Done","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":2005,"context_line":"                \u0027status\u0027: 200,"},{"line_number":2006,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":2007,"context_line":"                \u0027container\u0027: \u0027c\u0027}),"},{"line_number":2008,"context_line":"            (\u0027swift_proxy_server_request_body_input_bytes\u0027, 5, {"},{"line_number":2009,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":2010,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":2011,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"}],"source_content_type":"text/x-python","patch_set":38,"id":"50f0bca0_a65258af","line":2008,"updated":"2025-05-19 15:40:26.000000000","message":"``swift_proxy_server_request_body_bytes`` ``swift_proxy_server_request_body_input_bytes`` \n\nThese are confusingly similar - didn\u0027t we have some other ideas for naming? \u0027streaming\u0027??","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"c57ad89fac0b2e65583f5f342cc167aff89d8139","unresolved":false,"context_lines":[{"line_number":2005,"context_line":"                \u0027status\u0027: 200,"},{"line_number":2006,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":2007,"context_line":"                \u0027container\u0027: \u0027c\u0027}),"},{"line_number":2008,"context_line":"            (\u0027swift_proxy_server_request_body_input_bytes\u0027, 5, {"},{"line_number":2009,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":2010,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":2011,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"}],"source_content_type":"text/x-python","patch_set":38,"id":"2f611c40_b71e5d84","line":2008,"in_reply_to":"50f0bca0_a65258af","updated":"2025-06-04 15:04:37.000000000","message":"Done - https://jirasw.nvidia.com/browse/NSVISCS-9714","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":2019,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":2020,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":2021,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"},{"line_number":2022,"context_line":"                \u0027resource\u0027: \u0027container\u0027}),"},{"line_number":2023,"context_line":"            (\u0027swift_proxy_response_body_output_bytes\u0027, len(\u0027FAKE APP\u0027), {"},{"line_number":2024,"context_line":"                \u0027resource\u0027: \u0027container\u0027,"},{"line_number":2025,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"}],"source_content_type":"text/x-python","patch_set":38,"id":"87c02414_9c06f3a9","line":2022,"updated":"2025-05-19 15:40:26.000000000","message":"I couldn\u0027t work out why the three input stats are not uniform - what is varying the read sizes per 5ms?","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1432c12767bfa249bb2d1d29e769cd306b817b23","unresolved":false,"context_lines":[{"line_number":2019,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":2020,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":2021,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"},{"line_number":2022,"context_line":"                \u0027resource\u0027: \u0027container\u0027}),"},{"line_number":2023,"context_line":"            (\u0027swift_proxy_response_body_output_bytes\u0027, len(\u0027FAKE APP\u0027), {"},{"line_number":2024,"context_line":"                \u0027resource\u0027: \u0027container\u0027,"},{"line_number":2025,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"}],"source_content_type":"text/x-python","patch_set":38,"id":"82840b0e_7ec74060","line":2022,"in_reply_to":"2b3f06f3_10450a4c","updated":"2025-07-17 14:31:02.000000000","message":"how does calling statsd_emit_callback(0)  cause any more stats to be emitted?\n\ndid you try this:\n\n\"\nTry removing the last 5 bytes from buffer_str so that there is one less read, and now the final stat is not emitted at all 😞 The callback needs to also convey when the final read has happened so the callback can flush its final stat.\n\"","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":2019,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":2020,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":2021,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"},{"line_number":2022,"context_line":"                \u0027resource\u0027: \u0027container\u0027}),"},{"line_number":2023,"context_line":"            (\u0027swift_proxy_response_body_output_bytes\u0027, len(\u0027FAKE APP\u0027), {"},{"line_number":2024,"context_line":"                \u0027resource\u0027: \u0027container\u0027,"},{"line_number":2025,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"}],"source_content_type":"text/x-python","patch_set":38,"id":"976b98aa_ac185c6c","line":2022,"in_reply_to":"87c02414_9c06f3a9","updated":"2025-06-05 11:46:42.000000000","message":"...and then there\u0027s only 20 bytes left until the buffer is exhausted in 4ms and the final read of zero bytes takes us to 5ms so another stat is emitted. But this seems to be just good fortune that the final stat is emitted (because reading 20 bytes plus a final 0 bytes read just happens to get to another 5ms interval).\n\nThis is a bug: Try removing the last 5 bytes from buffer_str so that there is one less read, and now the final stat is not emitted at all 😞 The callback needs to also convey when the final read has happened so the callback can flush its final stat.","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9237818e7872731319b58e2ec2b6f7976543e67d","unresolved":false,"context_lines":[{"line_number":2019,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":2020,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":2021,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"},{"line_number":2022,"context_line":"                \u0027resource\u0027: \u0027container\u0027}),"},{"line_number":2023,"context_line":"            (\u0027swift_proxy_response_body_output_bytes\u0027, len(\u0027FAKE APP\u0027), {"},{"line_number":2024,"context_line":"                \u0027resource\u0027: \u0027container\u0027,"},{"line_number":2025,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"}],"source_content_type":"text/x-python","patch_set":38,"id":"2b3f06f3_10450a4c","line":2022,"in_reply_to":"976b98aa_ac185c6c","updated":"2025-06-25 20:41:54.000000000","message":"Added statsd_emit_callback(0) in the finally block so that all last bytes are emitted","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":2020,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":2021,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"},{"line_number":2022,"context_line":"                \u0027resource\u0027: \u0027container\u0027}),"},{"line_number":2023,"context_line":"            (\u0027swift_proxy_response_body_output_bytes\u0027, len(\u0027FAKE APP\u0027), {"},{"line_number":2024,"context_line":"                \u0027resource\u0027: \u0027container\u0027,"},{"line_number":2025,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"},{"line_number":2026,"context_line":"                \u0027status\u0027: 200,"}],"source_content_type":"text/x-python","patch_set":38,"id":"6890b661_812af4cf","line":2023,"range":{"start_line":2023,"start_character":20,"end_line":2023,"end_character":34},"updated":"2025-05-19 15:40:26.000000000","message":"is there a ``_server`` part missing from this name w.r.t. the others?","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"31e0fb568a380319c15ece5acc47007595b0cbcb","unresolved":false,"context_lines":[{"line_number":2020,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":2021,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"},{"line_number":2022,"context_line":"                \u0027resource\u0027: \u0027container\u0027}),"},{"line_number":2023,"context_line":"            (\u0027swift_proxy_response_body_output_bytes\u0027, len(\u0027FAKE APP\u0027), {"},{"line_number":2024,"context_line":"                \u0027resource\u0027: \u0027container\u0027,"},{"line_number":2025,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"},{"line_number":2026,"context_line":"                \u0027status\u0027: 200,"}],"source_content_type":"text/x-python","patch_set":38,"id":"51c43f27_da78e511","line":2023,"range":{"start_line":2023,"start_character":20,"end_line":2023,"end_character":34},"in_reply_to":"6890b661_812af4cf","updated":"2025-05-28 12:47:46.000000000","message":"Yes, made changes in proxy_logging as well!","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":2026,"context_line":"                \u0027status\u0027: 200,"},{"line_number":2027,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":2028,"context_line":"                \u0027container\u0027: \u0027c\u0027}),"},{"line_number":2029,"context_line":"            (\u0027swift_proxy_server_response_body_bytes\u0027, 8, {"},{"line_number":2030,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":2031,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":2032,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"}],"source_content_type":"text/x-python","patch_set":38,"id":"1e0ca909_5ad2c1ae","line":2029,"range":{"start_line":2029,"start_character":14,"end_line":2029,"end_character":52},"updated":"2025-05-19 15:40:26.000000000","message":"``swift_proxy_response_body_output_bytes``\n``swift_proxy_server_response_body_bytes``\n\nagain, potentially confusing","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"31e0fb568a380319c15ece5acc47007595b0cbcb","unresolved":false,"context_lines":[{"line_number":2026,"context_line":"                \u0027status\u0027: 200,"},{"line_number":2027,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":2028,"context_line":"                \u0027container\u0027: \u0027c\u0027}),"},{"line_number":2029,"context_line":"            (\u0027swift_proxy_server_response_body_bytes\u0027, 8, {"},{"line_number":2030,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":2031,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":2032,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"}],"source_content_type":"text/x-python","patch_set":38,"id":"b607a04d_d076f22e","line":2029,"range":{"start_line":2029,"start_character":14,"end_line":2029,"end_character":52},"in_reply_to":"1e0ca909_5ad2c1ae","updated":"2025-05-28 12:47:46.000000000","message":"Done","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":2077,"context_line":"        self.assertEqual(log_parts[5], \u0027HTTP/1.0\u0027)"},{"line_number":2078,"context_line":"        self.assertEqual(log_parts[6], \u0027200\u0027)"},{"line_number":2079,"context_line":"        self.assertEqual(resp_body, expected_resp)"},{"line_number":2080,"context_line":"        self.assertEqual(log_parts[11], \u002750\u0027)"},{"line_number":2081,"context_line":"        self.assertUpdateStats(["},{"line_number":2082,"context_line":"            (\u0027container.GET.200.xfer\u0027, buffer_len),"},{"line_number":2083,"context_line":"        ], app"}],"source_content_type":"text/x-python","patch_set":38,"id":"7df5d815_3d22c047","line":2080,"updated":"2025-05-19 15:40:26.000000000","message":"do we need to make assertions about the log message?","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"31e0fb568a380319c15ece5acc47007595b0cbcb","unresolved":false,"context_lines":[{"line_number":2077,"context_line":"        self.assertEqual(log_parts[5], \u0027HTTP/1.0\u0027)"},{"line_number":2078,"context_line":"        self.assertEqual(log_parts[6], \u0027200\u0027)"},{"line_number":2079,"context_line":"        self.assertEqual(resp_body, expected_resp)"},{"line_number":2080,"context_line":"        self.assertEqual(log_parts[11], \u002750\u0027)"},{"line_number":2081,"context_line":"        self.assertUpdateStats(["},{"line_number":2082,"context_line":"            (\u0027container.GET.200.xfer\u0027, buffer_len),"},{"line_number":2083,"context_line":"        ], app"}],"source_content_type":"text/x-python","patch_set":38,"id":"459882d0_e1363605","line":2080,"in_reply_to":"7df5d815_3d22c047","updated":"2025-05-28 12:47:46.000000000","message":"yeah, probably not required","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":2108,"context_line":"                \u0027status\u0027: 200}),"},{"line_number":2109,"context_line":"        ])"},{"line_number":2110,"context_line":""},{"line_number":2111,"context_line":"    def test_xfer_stats_put_s3api(self):"},{"line_number":2112,"context_line":"        class PathRewritingApp(object):"},{"line_number":2113,"context_line":"            def __init__(self, app):"},{"line_number":2114,"context_line":"                self.app \u003d app"}],"source_content_type":"text/x-python","patch_set":38,"id":"b454b0ad_3b21ead8","line":2111,"updated":"2025-05-19 15:40:26.000000000","message":"this is what I expected rather than the test in s3api/test_obj.p","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"31e0fb568a380319c15ece5acc47007595b0cbcb","unresolved":false,"context_lines":[{"line_number":2108,"context_line":"                \u0027status\u0027: 200}),"},{"line_number":2109,"context_line":"        ])"},{"line_number":2110,"context_line":""},{"line_number":2111,"context_line":"    def test_xfer_stats_put_s3api(self):"},{"line_number":2112,"context_line":"        class PathRewritingApp(object):"},{"line_number":2113,"context_line":"            def __init__(self, app):"},{"line_number":2114,"context_line":"                self.app \u003d app"}],"source_content_type":"text/x-python","patch_set":38,"id":"f7693971_1fb05714","line":2111,"in_reply_to":"b454b0ad_3b21ead8","updated":"2025-05-28 12:47:46.000000000","message":"Great! I\u0027ll remove that test then","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":2192,"context_line":"            \u0027account\u0027: \u0027AUTH_test\u0027,"},{"line_number":2193,"context_line":"            \u0027container\u0027: \u0027bucket\u0027,"},{"line_number":2194,"context_line":"            \u0027object\u0027: \u0027object\u0027,"},{"line_number":2195,"context_line":"        })"},{"line_number":2196,"context_line":""},{"line_number":2197,"context_line":"        self.assertEqual(swift.calls, ["},{"line_number":2198,"context_line":"            (\u0027PUT\u0027, \u0027/v1/AUTH_test/bucket+segments/object\u0027),"}],"source_content_type":"text/x-python","patch_set":38,"id":"bdca1e92_f44269f7","line":2195,"updated":"2025-05-19 15:40:26.000000000","message":"the test is quite long - do we need to assert base_labels again here?","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"31e0fb568a380319c15ece5acc47007595b0cbcb","unresolved":false,"context_lines":[{"line_number":2192,"context_line":"            \u0027account\u0027: \u0027AUTH_test\u0027,"},{"line_number":2193,"context_line":"            \u0027container\u0027: \u0027bucket\u0027,"},{"line_number":2194,"context_line":"            \u0027object\u0027: \u0027object\u0027,"},{"line_number":2195,"context_line":"        })"},{"line_number":2196,"context_line":""},{"line_number":2197,"context_line":"        self.assertEqual(swift.calls, ["},{"line_number":2198,"context_line":"            (\u0027PUT\u0027, \u0027/v1/AUTH_test/bucket+segments/object\u0027),"}],"source_content_type":"text/x-python","patch_set":38,"id":"a32e3161_3204035b","line":2195,"in_reply_to":"bdca1e92_f44269f7","updated":"2025-05-28 12:47:46.000000000","message":"We have asserted base_labels before at multiple tests, so we can skip making the test smaller!","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"572a5dcc9c9a7c25f5e3a88db1a1ab685fa7893a","unresolved":true,"context_lines":[{"line_number":2266,"context_line":"                \u0027account\u0027: \u0027AUTH_test\u0027,"},{"line_number":2267,"context_line":"                \u0027container\u0027: \u0027bucket\u0027,"},{"line_number":2268,"context_line":"                \u0027method\u0027: \u0027PUT\u0027,"},{"line_number":2269,"context_line":"                \u0027resource\u0027: \u0027object\u0027}),"},{"line_number":2270,"context_line":"            (\u0027swift_proxy_server_response_body_bytes\u0027, 0, {"},{"line_number":2271,"context_line":"                \u0027resource\u0027: \u0027object\u0027,"},{"line_number":2272,"context_line":"                \u0027method\u0027: \u0027PUT\u0027,"}],"source_content_type":"text/x-python","patch_set":38,"id":"a4678403_cb33c8af","line":2269,"updated":"2025-05-19 15:40:26.000000000","message":"this gets a lot more compact with [] * N syntax:\n```\n[(\u0027swift_proxy_server_request_body_input_bytes\u0027, 5, {\n                \u0027account\u0027: \u0027AUTH_test\u0027,\n                \u0027container\u0027: \u0027bucket\u0027,\n                \u0027method\u0027: \u0027PUT\u0027,\n                \u0027resource\u0027: \u0027object\u0027})] * 10 +\n                ```","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"31e0fb568a380319c15ece5acc47007595b0cbcb","unresolved":false,"context_lines":[{"line_number":2266,"context_line":"                \u0027account\u0027: \u0027AUTH_test\u0027,"},{"line_number":2267,"context_line":"                \u0027container\u0027: \u0027bucket\u0027,"},{"line_number":2268,"context_line":"                \u0027method\u0027: \u0027PUT\u0027,"},{"line_number":2269,"context_line":"                \u0027resource\u0027: \u0027object\u0027}),"},{"line_number":2270,"context_line":"            (\u0027swift_proxy_server_response_body_bytes\u0027, 0, {"},{"line_number":2271,"context_line":"                \u0027resource\u0027: \u0027object\u0027,"},{"line_number":2272,"context_line":"                \u0027method\u0027: \u0027PUT\u0027,"}],"source_content_type":"text/x-python","patch_set":38,"id":"34ca3fc7_996b53ee","line":2269,"in_reply_to":"a4678403_cb33c8af","updated":"2025-05-28 12:47:46.000000000","message":"Acknowledged","commit_id":"89a6330b92cfc3e8c99e564ca3b96778fc9016ea"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"fad47fde9e8413872e9248916c63d06d52e3f4d1","unresolved":true,"context_lines":[{"line_number":307,"context_line":""},{"line_number":308,"context_line":"    def assertLabeledUpdateStats(self, exp_metrics_values_labels):"},{"line_number":309,"context_line":"        statsd_calls \u003d sorted(self.statsd.calls[\u0027update_stats\u0027])"},{"line_number":310,"context_line":"        for i in range(len(statsd_calls)):"},{"line_number":311,"context_line":"            statsd_calls[i][1][\u0027labels\u0027] \u003d dict(statsd_calls[i][1][\u0027labels\u0027])"},{"line_number":312,"context_line":"        exp_calls \u003d []"},{"line_number":313,"context_line":"        for metric, value, labels in exp_metrics_values_labels:"}],"source_content_type":"text/x-python","patch_set":42,"id":"df7b3674_d432a8ec","line":310,"updated":"2025-05-29 14:04:02.000000000","message":"simpler using...\n```\nfor statsd_call in statsd_calls:\n```","commit_id":"860d8978fa781cffafb3c9eae18849083aaf8548"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"b341a2ec64623dd1d758b6b7c37d19846e3bcc8c","unresolved":false,"context_lines":[{"line_number":307,"context_line":""},{"line_number":308,"context_line":"    def assertLabeledUpdateStats(self, exp_metrics_values_labels):"},{"line_number":309,"context_line":"        statsd_calls \u003d sorted(self.statsd.calls[\u0027update_stats\u0027])"},{"line_number":310,"context_line":"        for i in range(len(statsd_calls)):"},{"line_number":311,"context_line":"            statsd_calls[i][1][\u0027labels\u0027] \u003d dict(statsd_calls[i][1][\u0027labels\u0027])"},{"line_number":312,"context_line":"        exp_calls \u003d []"},{"line_number":313,"context_line":"        for metric, value, labels in exp_metrics_values_labels:"}],"source_content_type":"text/x-python","patch_set":42,"id":"db465178_cc9d59da","line":310,"in_reply_to":"df7b3674_d432a8ec","updated":"2025-06-03 11:34:30.000000000","message":"Acknowledged","commit_id":"860d8978fa781cffafb3c9eae18849083aaf8548"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"fad47fde9e8413872e9248916c63d06d52e3f4d1","unresolved":true,"context_lines":[{"line_number":308,"context_line":"    def assertLabeledUpdateStats(self, exp_metrics_values_labels):"},{"line_number":309,"context_line":"        statsd_calls \u003d sorted(self.statsd.calls[\u0027update_stats\u0027])"},{"line_number":310,"context_line":"        for i in range(len(statsd_calls)):"},{"line_number":311,"context_line":"            statsd_calls[i][1][\u0027labels\u0027] \u003d dict(statsd_calls[i][1][\u0027labels\u0027])"},{"line_number":312,"context_line":"        exp_calls \u003d []"},{"line_number":313,"context_line":"        for metric, value, labels in exp_metrics_values_labels:"},{"line_number":314,"context_line":"            exp_calls.append(((metric, value), {\u0027labels\u0027: labels}))"}],"source_content_type":"text/x-python","patch_set":42,"id":"e6001cba_ad07f68b","line":311,"updated":"2025-05-29 14:04:02.000000000","message":"this may become unnecessary of we drop the SubsetMap from this pacch","commit_id":"860d8978fa781cffafb3c9eae18849083aaf8548"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"a45685bda3d2ab61fda1f43318276b1ad26ac3d5","unresolved":false,"context_lines":[{"line_number":308,"context_line":"    def assertLabeledUpdateStats(self, exp_metrics_values_labels):"},{"line_number":309,"context_line":"        statsd_calls \u003d sorted(self.statsd.calls[\u0027update_stats\u0027])"},{"line_number":310,"context_line":"        for i in range(len(statsd_calls)):"},{"line_number":311,"context_line":"            statsd_calls[i][1][\u0027labels\u0027] \u003d dict(statsd_calls[i][1][\u0027labels\u0027])"},{"line_number":312,"context_line":"        exp_calls \u003d []"},{"line_number":313,"context_line":"        for metric, value, labels in exp_metrics_values_labels:"},{"line_number":314,"context_line":"            exp_calls.append(((metric, value), {\u0027labels\u0027: labels}))"}],"source_content_type":"text/x-python","patch_set":42,"id":"ddbe8e12_d75cf392","line":311,"in_reply_to":"722422f3_54781882","updated":"2025-06-25 22:20:53.000000000","message":"Done","commit_id":"860d8978fa781cffafb3c9eae18849083aaf8548"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"24c5d44d6b8c78a50f40cc5981234abb91f0d136","unresolved":true,"context_lines":[{"line_number":308,"context_line":"    def assertLabeledUpdateStats(self, exp_metrics_values_labels):"},{"line_number":309,"context_line":"        statsd_calls \u003d sorted(self.statsd.calls[\u0027update_stats\u0027])"},{"line_number":310,"context_line":"        for i in range(len(statsd_calls)):"},{"line_number":311,"context_line":"            statsd_calls[i][1][\u0027labels\u0027] \u003d dict(statsd_calls[i][1][\u0027labels\u0027])"},{"line_number":312,"context_line":"        exp_calls \u003d []"},{"line_number":313,"context_line":"        for metric, value, labels in exp_metrics_values_labels:"},{"line_number":314,"context_line":"            exp_calls.append(((metric, value), {\u0027labels\u0027: labels}))"}],"source_content_type":"text/x-python","patch_set":42,"id":"722422f3_54781882","line":311,"in_reply_to":"7c0ea32e_e53045f5","updated":"2025-06-12 20:05:52.000000000","message":"Dropping subsetmap errors out, maybe we need this? Debugging some more!\n\n\n-\u003e self.assertEqual(exp_calls, statsd_calls)\n(Pdb) exp_calls\n[((\u0027swift_proxy_server_response_body_streaming_bytes\u0027, 11), {\u0027labels\u0027: {\u0027resource\u0027: \u0027object\u0027, \u0027method\u0027: \u0027GET\u0027, \u0027status\u0027: 200, \u0027policy\u0027: \u00270\u0027, \u0027account\u0027: \u0027AUTH_test\u0027, \u0027container\u0027: \u0027bucket\u0027}}), ((\u0027swift_proxy_server_request_body_bytes\u0027, 0), {\u0027labels\u0027: {\u0027resource\u0027: \u0027object\u0027, \u0027method\u0027: \u0027GET\u0027, \u0027status\u0027: 200, \u0027account\u0027: \u0027AUTH_test\u0027, \u0027container\u0027: \u0027bucket\u0027, \u0027policy\u0027: \u00270\u0027}}), ((\u0027swift_proxy_server_response_body_streaming_bytes\u0027, 17), {\u0027labels\u0027: {\u0027resource\u0027: \u0027object\u0027, \u0027method\u0027: \u0027GET\u0027, \u0027status\u0027: 200, \u0027policy\u0027: \u00270\u0027, \u0027account\u0027: \u0027AUTH_test\u0027, \u0027container\u0027: \u0027bucket\u0027}}), ((\u0027swift_proxy_server_response_body_streaming_bytes\u0027, 22), {\u0027labels\u0027: {\u0027resource\u0027: \u0027object\u0027, \u0027method\u0027: \u0027GET\u0027, \u0027status\u0027: 200, \u0027policy\u0027: \u00270\u0027, \u0027account\u0027: \u0027AUTH_test\u0027, \u0027container\u0027: \u0027bucket\u0027}}), ((\u0027swift_proxy_server_response_body_bytes\u0027, 50), {\u0027labels\u0027: {\u0027resource\u0027: \u0027object\u0027, \u0027method\u0027: \u0027GET\u0027, \u0027status\u0027: 200, \u0027account\u0027: \u0027AUTH_test\u0027, \u0027container\u0027: \u0027bucket\u0027, \u0027policy\u0027: \u00270\u0027}})]\n(Pdb) statsd_calls\n[((\u0027swift_pro","commit_id":"860d8978fa781cffafb3c9eae18849083aaf8548"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"b341a2ec64623dd1d758b6b7c37d19846e3bcc8c","unresolved":false,"context_lines":[{"line_number":308,"context_line":"    def assertLabeledUpdateStats(self, exp_metrics_values_labels):"},{"line_number":309,"context_line":"        statsd_calls \u003d sorted(self.statsd.calls[\u0027update_stats\u0027])"},{"line_number":310,"context_line":"        for i in range(len(statsd_calls)):"},{"line_number":311,"context_line":"            statsd_calls[i][1][\u0027labels\u0027] \u003d dict(statsd_calls[i][1][\u0027labels\u0027])"},{"line_number":312,"context_line":"        exp_calls \u003d []"},{"line_number":313,"context_line":"        for metric, value, labels in exp_metrics_values_labels:"},{"line_number":314,"context_line":"            exp_calls.append(((metric, value), {\u0027labels\u0027: labels}))"}],"source_content_type":"text/x-python","patch_set":42,"id":"7c0ea32e_e53045f5","line":311,"in_reply_to":"e6001cba_ad07f68b","updated":"2025-06-03 11:34:30.000000000","message":"Done","commit_id":"860d8978fa781cffafb3c9eae18849083aaf8548"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":80,"context_line":"        while True:"},{"line_number":81,"context_line":"            buf \u003d env[\u0027wsgi.input\u0027].read(5)"},{"line_number":82,"context_line":"            if self.read_callback is not None:"},{"line_number":83,"context_line":"                self.read_callback(iter_n, len(buf))"},{"line_number":84,"context_line":"            iter_n +\u003d 1"},{"line_number":85,"context_line":"            if not buf:"},{"line_number":86,"context_line":"                break"}],"source_content_type":"text/x-python","patch_set":43,"id":"ff929d61_025703a3","line":83,"range":{"start_line":83,"start_character":35,"end_line":83,"end_character":42},"updated":"2025-06-04 18:08:30.000000000","message":"passing this iter counter seems odd - can\u0027t the callback just count how many times it has been called?","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"5a6a291f5a616b4ba8f14fea825d14cf68656b81","unresolved":false,"context_lines":[{"line_number":80,"context_line":"        while True:"},{"line_number":81,"context_line":"            buf \u003d env[\u0027wsgi.input\u0027].read(5)"},{"line_number":82,"context_line":"            if self.read_callback is not None:"},{"line_number":83,"context_line":"                self.read_callback(iter_n, len(buf))"},{"line_number":84,"context_line":"            iter_n +\u003d 1"},{"line_number":85,"context_line":"            if not buf:"},{"line_number":86,"context_line":"                break"}],"source_content_type":"text/x-python","patch_set":43,"id":"d0747941_72546176","line":83,"range":{"start_line":83,"start_character":35,"end_line":83,"end_character":42},"in_reply_to":"ff929d61_025703a3","updated":"2025-07-09 16:30:59.000000000","message":"Yes, not needed, removed!","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":154,"context_line":"            \u0027swift_proxy_example_metric\u0027, labels, app.statsd,"},{"line_number":155,"context_line":"            app.emit_buffer_xfer_bytes_sec)"},{"line_number":156,"context_line":"        callback(5)"},{"line_number":157,"context_line":"        TestProxyLogging.assertLabeledUpdateStats(self, ["},{"line_number":158,"context_line":"            (\u0027swift_proxy_example_metric\u0027, 5, {"},{"line_number":159,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":160,"context_line":"                \u0027container\u0027: \u0027c\u0027,"}],"source_content_type":"text/x-python","patch_set":43,"id":"72e2047f_814b80ef","line":157,"range":{"start_line":157,"start_character":8,"end_line":157,"end_character":49},"updated":"2025-06-04 18:08:30.000000000","message":"The way to reuse this helper is to make a base class that both TestBufferXferEmitCallback and TestProxyLogging inherit from\n\ne.g.\n```\nclass BaseTestProxyLogging(unittest.TestCase):\n    def assertLabeledUpdateStats(...\n    \nclass TestBufferXferEmitCallback(BaseTestProxyLogging):\n\n...\n\n\nclass TestProxyLogging(BaseTestProxyLogging):\n```\n\nwhat you have here may work but is (a) unorthodox and (b) risky because the \u0027self\u0027 you are passing to ``TestProxyLogging.assertLabeledUpdateStats`` is not an instance of ``TestProxyLogging``.\n\nBUT, maybe this test doesn\u0027t really need that helper. The unit that is being tested (BufferXferEmitCallback) just calls a statsd client - it doesn\u0027t care that it is an attribute of a ProxyLoggingMiddleware. So for the purposes of testing BufferXferEmitCallback it could be just passed FakeLabeledStatsdClient for its statsd which will capture calls that BufferXferEmitCallback makes.","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"cd45a581820bc1bee129daf0e9221cbf54e58829","unresolved":false,"context_lines":[{"line_number":154,"context_line":"            \u0027swift_proxy_example_metric\u0027, labels, app.statsd,"},{"line_number":155,"context_line":"            app.emit_buffer_xfer_bytes_sec)"},{"line_number":156,"context_line":"        callback(5)"},{"line_number":157,"context_line":"        TestProxyLogging.assertLabeledUpdateStats(self, ["},{"line_number":158,"context_line":"            (\u0027swift_proxy_example_metric\u0027, 5, {"},{"line_number":159,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":160,"context_line":"                \u0027container\u0027: \u0027c\u0027,"}],"source_content_type":"text/x-python","patch_set":43,"id":"8bd069a1_1564f07c","line":157,"range":{"start_line":157,"start_character":8,"end_line":157,"end_character":49},"in_reply_to":"72e2047f_814b80ef","updated":"2025-06-27 14:49:57.000000000","message":"Acknowledged","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":191,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":192,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"},{"line_number":193,"context_line":"                \u0027resource\u0027: \u0027container\u0027}),"},{"line_number":194,"context_line":"        ])"},{"line_number":195,"context_line":""},{"line_number":196,"context_line":""},{"line_number":197,"context_line":"@patch_policies([StoragePolicy(0, \u0027zero\u0027, False)])"}],"source_content_type":"text/x-python","patch_set":43,"id":"110bda38_f2c0a3fb","line":194,"updated":"2025-06-04 18:08:30.000000000","message":"There are other aspects of the class behaviour to be tested: negative and non-zero statsd_emit_buffer_xfer_bytes_ms, what happens when account is not in labels","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"5a6a291f5a616b4ba8f14fea825d14cf68656b81","unresolved":false,"context_lines":[{"line_number":191,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":192,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"},{"line_number":193,"context_line":"                \u0027resource\u0027: \u0027container\u0027}),"},{"line_number":194,"context_line":"        ])"},{"line_number":195,"context_line":""},{"line_number":196,"context_line":""},{"line_number":197,"context_line":"@patch_policies([StoragePolicy(0, \u0027zero\u0027, False)])"}],"source_content_type":"text/x-python","patch_set":43,"id":"ded72658_436f7d4a","line":194,"in_reply_to":"110bda38_f2c0a3fb","updated":"2025-07-09 16:30:59.000000000","message":"Done","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":468,"context_line":"            statsd.increment(\u0027baz\u0027, labels\u003d{\u0027label_foo\u0027: \u0027foo\u0027})"},{"line_number":469,"context_line":"        self.assertEqual("},{"line_number":470,"context_line":"            [(b\u0027baz:1|c|#label_foo:foo,user_reqctx:subrequest\u0027,"},{"line_number":471,"context_line":"              (\u0027example.com\u0027, 1234))],"},{"line_number":472,"context_line":"            statsd.sendto_calls)"},{"line_number":473,"context_line":""},{"line_number":474,"context_line":"    def test_logger_statsd_prefix(self):"}],"source_content_type":"text/x-python","patch_set":43,"id":"968aa2d0_ccb14fa7","line":471,"updated":"2025-06-04 18:08:30.000000000","message":"unnecessary change (since pep8 seems happy with the format as it is, there is no need to change the git history of the line)","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"24c5d44d6b8c78a50f40cc5981234abb91f0d136","unresolved":false,"context_lines":[{"line_number":468,"context_line":"            statsd.increment(\u0027baz\u0027, labels\u003d{\u0027label_foo\u0027: \u0027foo\u0027})"},{"line_number":469,"context_line":"        self.assertEqual("},{"line_number":470,"context_line":"            [(b\u0027baz:1|c|#label_foo:foo,user_reqctx:subrequest\u0027,"},{"line_number":471,"context_line":"              (\u0027example.com\u0027, 1234))],"},{"line_number":472,"context_line":"            statsd.sendto_calls)"},{"line_number":473,"context_line":""},{"line_number":474,"context_line":"    def test_logger_statsd_prefix(self):"}],"source_content_type":"text/x-python","patch_set":43,"id":"af86e615_2c5241b4","line":471,"in_reply_to":"968aa2d0_ccb14fa7","updated":"2025-06-12 20:05:52.000000000","message":"Acknowledged","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1432c12767bfa249bb2d1d29e769cd306b817b23","unresolved":false,"context_lines":[{"line_number":468,"context_line":"            statsd.increment(\u0027baz\u0027, labels\u003d{\u0027label_foo\u0027: \u0027foo\u0027})"},{"line_number":469,"context_line":"        self.assertEqual("},{"line_number":470,"context_line":"            [(b\u0027baz:1|c|#label_foo:foo,user_reqctx:subrequest\u0027,"},{"line_number":471,"context_line":"              (\u0027example.com\u0027, 1234))],"},{"line_number":472,"context_line":"            statsd.sendto_calls)"},{"line_number":473,"context_line":""},{"line_number":474,"context_line":"    def test_logger_statsd_prefix(self):"}],"source_content_type":"text/x-python","patch_set":43,"id":"1c8ad062_65f837ec","line":471,"in_reply_to":"af86e615_2c5241b4","updated":"2025-07-17 14:31:02.000000000","message":"please revert the change - in general it\u0027s best to not change code unnecessarily for formatting reasons because it changes the git history and bloats the patch\n\nsame wherever there is an unnecessary change","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":559,"context_line":"            b\u0027\u0027.join(resp)"},{"line_number":560,"context_line":"        return app"},{"line_number":561,"context_line":""},{"line_number":562,"context_line":"    def test_log_request_stat_type_bad(self):"},{"line_number":563,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":564,"context_line":"            FakeApp(), {}, logger\u003dself.logger)"},{"line_number":565,"context_line":"        for bad_path in ["}],"source_content_type":"text/x-python","patch_set":43,"id":"0705e025_5f1d755e","line":562,"updated":"2025-06-04 18:08:30.000000000","message":"this test seems to be similar (a subset perhaps?) of ``test_log_request_stat_type_bad_GET`` ... and is makes no assertions about labeled metrics.\n\ndoes it belong in this patch?","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"24c5d44d6b8c78a50f40cc5981234abb91f0d136","unresolved":true,"context_lines":[{"line_number":559,"context_line":"            b\u0027\u0027.join(resp)"},{"line_number":560,"context_line":"        return app"},{"line_number":561,"context_line":""},{"line_number":562,"context_line":"    def test_log_request_stat_type_bad(self):"},{"line_number":563,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":564,"context_line":"            FakeApp(), {}, logger\u003dself.logger)"},{"line_number":565,"context_line":"        for bad_path in ["}],"source_content_type":"text/x-python","patch_set":43,"id":"30f05e17_32ce39bf","line":562,"in_reply_to":"0705e025_5f1d755e","updated":"2025-06-12 20:05:52.000000000","message":"Confirmed with Yan, we both didn\u0027t add this test. Not sure why it\u0027s a new test in this patch.","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1432c12767bfa249bb2d1d29e769cd306b817b23","unresolved":true,"context_lines":[{"line_number":559,"context_line":"            b\u0027\u0027.join(resp)"},{"line_number":560,"context_line":"        return app"},{"line_number":561,"context_line":""},{"line_number":562,"context_line":"    def test_log_request_stat_type_bad(self):"},{"line_number":563,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":564,"context_line":"            FakeApp(), {}, logger\u003dself.logger)"},{"line_number":565,"context_line":"        for bad_path in ["}],"source_content_type":"text/x-python","patch_set":43,"id":"c714cd44_be84e81f","line":562,"in_reply_to":"30f05e17_32ce39bf","updated":"2025-07-17 14:31:02.000000000","message":"if no-one wants the test then someone needs to claim ownership of the patch\u0027s destiny and remove it ;-)","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9c175fca54bd4eec0f0d2e996f5cb2bb4fce3870","unresolved":false,"context_lines":[{"line_number":559,"context_line":"            b\u0027\u0027.join(resp)"},{"line_number":560,"context_line":"        return app"},{"line_number":561,"context_line":""},{"line_number":562,"context_line":"    def test_log_request_stat_type_bad(self):"},{"line_number":563,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":564,"context_line":"            FakeApp(), {}, logger\u003dself.logger)"},{"line_number":565,"context_line":"        for bad_path in ["}],"source_content_type":"text/x-python","patch_set":43,"id":"957c418c_e1dddfbe","line":562,"in_reply_to":"c714cd44_be84e81f","updated":"2025-07-21 21:19:09.000000000","message":"I will remove this test, doesn\u0027t seem necessary","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":700,"context_line":"                                           app)"},{"line_number":701,"context_line":"                else:"},{"line_number":702,"context_line":"                    self.assertUpdateStats([(\u0027%s.GET.321.xfer\u0027 % exp_type,"},{"line_number":703,"context_line":"                                             4 + 7)],"},{"line_number":704,"context_line":"                                           app)"},{"line_number":705,"context_line":"                exp_labels.update({"},{"line_number":706,"context_line":"                    \u0027method\u0027: \u0027GET\u0027,"}],"source_content_type":"text/x-python","patch_set":43,"id":"a8c20565_1cd6256e","line":703,"updated":"2025-06-04 18:08:30.000000000","message":"ditto unnecessary change (since pep8 seems happy with the format as it is, there is no need to change the git history of the line)","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"a45685bda3d2ab61fda1f43318276b1ad26ac3d5","unresolved":false,"context_lines":[{"line_number":700,"context_line":"                                           app)"},{"line_number":701,"context_line":"                else:"},{"line_number":702,"context_line":"                    self.assertUpdateStats([(\u0027%s.GET.321.xfer\u0027 % exp_type,"},{"line_number":703,"context_line":"                                             4 + 7)],"},{"line_number":704,"context_line":"                                           app)"},{"line_number":705,"context_line":"                exp_labels.update({"},{"line_number":706,"context_line":"                    \u0027method\u0027: \u0027GET\u0027,"}],"source_content_type":"text/x-python","patch_set":43,"id":"4ab7b99e_612c300b","line":703,"in_reply_to":"a8c20565_1cd6256e","updated":"2025-06-25 22:20:53.000000000","message":"Done","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":748,"context_line":"                    \u0027status\u0027: 321,"},{"line_number":749,"context_line":"                })"},{"line_number":750,"context_line":"                self.assertUpdateStats([(\u0027%s.GET.321.xfer\u0027 % exp_type,"},{"line_number":751,"context_line":"                                         4 + 7)],"},{"line_number":752,"context_line":"                                       app)"},{"line_number":753,"context_line":"                self.assertLabeledTimingStats(["},{"line_number":754,"context_line":"                    (\u0027swift_proxy_server_request_ttfb\u0027, 0.5 * 1000,"}],"source_content_type":"text/x-python","patch_set":43,"id":"0b2e5b94_5057d800","line":751,"updated":"2025-06-04 18:08:30.000000000","message":"ditto unnecessary change (since pep8 seems happy with the format as it is, there is no need to change the git history of the line)","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"a45685bda3d2ab61fda1f43318276b1ad26ac3d5","unresolved":false,"context_lines":[{"line_number":748,"context_line":"                    \u0027status\u0027: 321,"},{"line_number":749,"context_line":"                })"},{"line_number":750,"context_line":"                self.assertUpdateStats([(\u0027%s.GET.321.xfer\u0027 % exp_type,"},{"line_number":751,"context_line":"                                         4 + 7)],"},{"line_number":752,"context_line":"                                       app)"},{"line_number":753,"context_line":"                self.assertLabeledTimingStats(["},{"line_number":754,"context_line":"                    (\u0027swift_proxy_server_request_ttfb\u0027, 0.5 * 1000,"}],"source_content_type":"text/x-python","patch_set":43,"id":"cd316179_a12b95ad","line":751,"in_reply_to":"0b2e5b94_5057d800","updated":"2025-06-25 22:20:53.000000000","message":"Done","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":912,"context_line":"                        \u0027method\u0027: exp_method,"},{"line_number":913,"context_line":"                        \u0027account\u0027: \u0027a\u0027,"},{"line_number":914,"context_line":"                    }"},{"line_number":915,"context_line":"                })"},{"line_number":916,"context_line":"            now \u003d 10000.0"},{"line_number":917,"context_line":"            app.log_request(req, 299, 11, 3, now, now + 1.17)"},{"line_number":918,"context_line":"            self.assertTiming(\u0027account.%s.299.timing\u0027 % exp_method, app,"}],"source_content_type":"text/x-python","patch_set":43,"id":"afa8d9ee_0b3f3898","line":915,"updated":"2025-06-04 18:08:30.000000000","message":"this change doesn\u0027t seem necessary - no assertions change in this test and it still passes when I remove the swift.base_labels from the environ\n\nThe test is calling log_request which doesn\u0027t emit xfer bytes metrics.","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"5a6a291f5a616b4ba8f14fea825d14cf68656b81","unresolved":false,"context_lines":[{"line_number":912,"context_line":"                        \u0027method\u0027: exp_method,"},{"line_number":913,"context_line":"                        \u0027account\u0027: \u0027a\u0027,"},{"line_number":914,"context_line":"                    }"},{"line_number":915,"context_line":"                })"},{"line_number":916,"context_line":"            now \u003d 10000.0"},{"line_number":917,"context_line":"            app.log_request(req, 299, 11, 3, now, now + 1.17)"},{"line_number":918,"context_line":"            self.assertTiming(\u0027account.%s.299.timing\u0027 % exp_method, app,"}],"source_content_type":"text/x-python","patch_set":43,"id":"eed418da_923489f5","line":915,"in_reply_to":"afa8d9ee_0b3f3898","updated":"2025-07-09 16:30:59.000000000","message":"Acknowledged","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":963,"context_line":"                            \u0027account\u0027: \u0027a\u0027,"},{"line_number":964,"context_line":"                            \u0027container\u0027: \u0027c\u0027"},{"line_number":965,"context_line":"                        }"},{"line_number":966,"context_line":"                    })"},{"line_number":967,"context_line":"                now \u003d 10000.0"},{"line_number":968,"context_line":"                app.log_request(req, 911, 4, 43, now, now + 1.01)"},{"line_number":969,"context_line":"                self.assertTiming(\u0027container.%s.911.timing\u0027 % exp_method, app,"}],"source_content_type":"text/x-python","patch_set":43,"id":"266211b6_e8135c3b","line":966,"updated":"2025-06-04 18:08:30.000000000","message":"ditto this change doesn\u0027t seem necessary - no assertions change in this test and it still passes when I remove the swift.base_labels from the environ","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"a45685bda3d2ab61fda1f43318276b1ad26ac3d5","unresolved":false,"context_lines":[{"line_number":963,"context_line":"                            \u0027account\u0027: \u0027a\u0027,"},{"line_number":964,"context_line":"                            \u0027container\u0027: \u0027c\u0027"},{"line_number":965,"context_line":"                        }"},{"line_number":966,"context_line":"                    })"},{"line_number":967,"context_line":"                now \u003d 10000.0"},{"line_number":968,"context_line":"                app.log_request(req, 911, 4, 43, now, now + 1.01)"},{"line_number":969,"context_line":"                self.assertTiming(\u0027container.%s.911.timing\u0027 % exp_method, app,"}],"source_content_type":"text/x-python","patch_set":43,"id":"5089e27d_e19cf823","line":966,"in_reply_to":"266211b6_e8135c3b","updated":"2025-06-25 22:20:53.000000000","message":"Acknowledged","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":1167,"context_line":"                \u0027account\u0027: \u0027AUTH_test\u0027,"},{"line_number":1168,"context_line":"                \u0027container\u0027: \u0027bucket\u0027,"},{"line_number":1169,"context_line":"                \u0027object\u0027: \u0027path/to/key\u0027,"},{"line_number":1170,"context_line":"            },"},{"line_number":1171,"context_line":"            \u0027swift.backend_path\u0027: \u0027/v1/AUTH_test/bucket/path/to/key\u0027})"},{"line_number":1172,"context_line":"        with mock.patch(\"time.time\", side_effect\u003d["},{"line_number":1173,"context_line":"                18.0, 18.5, 20.71828182846]):"}],"source_content_type":"text/x-python","patch_set":43,"id":"f70b4725_f89a24d2","line":1170,"updated":"2025-06-04 18:08:30.000000000","message":"ditto this change doesn\u0027t seem necessary - no assertions change in this test and it still passes when I remove the swift.base_labels from the environ\n\nThis test does call the app but does not configure ``statsd_emit_buffer_xfer_bytes_ms`` so we don\u0027t expect any new metrics assertions here","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"a45685bda3d2ab61fda1f43318276b1ad26ac3d5","unresolved":false,"context_lines":[{"line_number":1167,"context_line":"                \u0027account\u0027: \u0027AUTH_test\u0027,"},{"line_number":1168,"context_line":"                \u0027container\u0027: \u0027bucket\u0027,"},{"line_number":1169,"context_line":"                \u0027object\u0027: \u0027path/to/key\u0027,"},{"line_number":1170,"context_line":"            },"},{"line_number":1171,"context_line":"            \u0027swift.backend_path\u0027: \u0027/v1/AUTH_test/bucket/path/to/key\u0027})"},{"line_number":1172,"context_line":"        with mock.patch(\"time.time\", side_effect\u003d["},{"line_number":1173,"context_line":"                18.0, 18.5, 20.71828182846]):"}],"source_content_type":"text/x-python","patch_set":43,"id":"e3611098_4de884b9","line":1170,"in_reply_to":"f70b4725_f89a24d2","updated":"2025-06-25 22:20:53.000000000","message":"Acknowledged","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":1302,"context_line":"            (\u0027object.PUT.200.xfer\u0027,"},{"line_number":1303,"context_line":"             len(\u0027some stuff\u0027) + len(\u0027FAKE APP\u0027)),"},{"line_number":1304,"context_line":"            (\u0027object.policy.0.PUT.200.xfer\u0027,"},{"line_number":1305,"context_line":"             len(\u0027some stuff\u0027) + len(\u0027FAKE APP\u0027)),"},{"line_number":1306,"context_line":"        ], app)"},{"line_number":1307,"context_line":"        self.assertLabeledUpdateStats(["},{"line_number":1308,"context_line":"            (\u0027swift_proxy_server_request_body_bytes\u0027, 10, {"}],"source_content_type":"text/x-python","patch_set":43,"id":"cb5fd156_5c223611","line":1305,"updated":"2025-06-04 18:08:30.000000000","message":"more unrelated changes - maybe check your IDE is not auto-formatting when saving the file\n\n...ditto below","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"a45685bda3d2ab61fda1f43318276b1ad26ac3d5","unresolved":false,"context_lines":[{"line_number":1302,"context_line":"            (\u0027object.PUT.200.xfer\u0027,"},{"line_number":1303,"context_line":"             len(\u0027some stuff\u0027) + len(\u0027FAKE APP\u0027)),"},{"line_number":1304,"context_line":"            (\u0027object.policy.0.PUT.200.xfer\u0027,"},{"line_number":1305,"context_line":"             len(\u0027some stuff\u0027) + len(\u0027FAKE APP\u0027)),"},{"line_number":1306,"context_line":"        ], app)"},{"line_number":1307,"context_line":"        self.assertLabeledUpdateStats(["},{"line_number":1308,"context_line":"            (\u0027swift_proxy_server_request_body_bytes\u0027, 10, {"}],"source_content_type":"text/x-python","patch_set":43,"id":"b7250af9_dc5cc0b1","line":1305,"in_reply_to":"cb5fd156_5c223611","updated":"2025-06-25 22:20:53.000000000","message":"Ack, I\u0027ll keep a check.","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":1452,"context_line":""},{"line_number":1453,"context_line":"        environ \u003d {"},{"line_number":1454,"context_line":"            \u0027REQUEST_METHOD\u0027: \u0027PUT\u0027,"},{"line_number":1455,"context_line":"            \u0027HTTP_HOST\u0027: \u0027ahost.domain\u0027,"},{"line_number":1456,"context_line":"        }"},{"line_number":1457,"context_line":"        if extra_environ:"},{"line_number":1458,"context_line":"            environ.update(extra_environ)"}],"source_content_type":"text/x-python","patch_set":43,"id":"3788ac64_48dd7838","line":1455,"range":{"start_line":1455,"start_character":26,"end_line":1455,"end_character":31},"updated":"2025-06-04 18:08:30.000000000","message":"the only  time this appears in an assertion is when it is actually a bucket in host request, so an assertion that ``container \u003d\u003d ahost`` is a little counter-intuitive. Perhaps rename to something less suggestive like ``example.domain`` or ``foo.domain``","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"a45685bda3d2ab61fda1f43318276b1ad26ac3d5","unresolved":false,"context_lines":[{"line_number":1452,"context_line":""},{"line_number":1453,"context_line":"        environ \u003d {"},{"line_number":1454,"context_line":"            \u0027REQUEST_METHOD\u0027: \u0027PUT\u0027,"},{"line_number":1455,"context_line":"            \u0027HTTP_HOST\u0027: \u0027ahost.domain\u0027,"},{"line_number":1456,"context_line":"        }"},{"line_number":1457,"context_line":"        if extra_environ:"},{"line_number":1458,"context_line":"            environ.update(extra_environ)"}],"source_content_type":"text/x-python","patch_set":43,"id":"07ea277a_391225ee","line":1455,"range":{"start_line":1455,"start_character":26,"end_line":1455,"end_character":31},"in_reply_to":"3788ac64_48dd7838","updated":"2025-06-25 22:20:53.000000000","message":"Acknowledged","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":1491,"context_line":"            self._do_test_swift_base_labels(mw_conf, \u0027/v1/a/c/o\u0027, req_hdrs))"},{"line_number":1492,"context_line":""},{"line_number":1493,"context_line":"    def test_update_swift_base_labels_swift_request_partial_existing(self):"},{"line_number":1494,"context_line":"        # verify that existing c, o parts are not replaced"},{"line_number":1495,"context_line":"        mw_conf \u003d {}"},{"line_number":1496,"context_line":"        req_hdrs \u003d {}"},{"line_number":1497,"context_line":"        extra_environ \u003d {"}],"source_content_type":"text/x-python","patch_set":43,"id":"76a14471_d2d7f3c5","line":1494,"range":{"start_line":1494,"start_character":32,"end_line":1494,"end_character":36},"updated":"2025-06-04 18:08:30.000000000","message":"there is no ``o`` part anymore\n\nalso, might be better saying\n```\nverify that existing container field is not updated```","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"a45685bda3d2ab61fda1f43318276b1ad26ac3d5","unresolved":false,"context_lines":[{"line_number":1491,"context_line":"            self._do_test_swift_base_labels(mw_conf, \u0027/v1/a/c/o\u0027, req_hdrs))"},{"line_number":1492,"context_line":""},{"line_number":1493,"context_line":"    def test_update_swift_base_labels_swift_request_partial_existing(self):"},{"line_number":1494,"context_line":"        # verify that existing c, o parts are not replaced"},{"line_number":1495,"context_line":"        mw_conf \u003d {}"},{"line_number":1496,"context_line":"        req_hdrs \u003d {}"},{"line_number":1497,"context_line":"        extra_environ \u003d {"}],"source_content_type":"text/x-python","patch_set":43,"id":"c6eaeef9_610ee50c","line":1494,"range":{"start_line":1494,"start_character":32,"end_line":1494,"end_character":36},"in_reply_to":"76a14471_d2d7f3c5","updated":"2025-06-25 22:20:53.000000000","message":"Done","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":1533,"context_line":"                mw_conf, \u0027/v1/a/c/ooo\u0027, req_hdrs, extra_environ\u003dextra_environ))"},{"line_number":1534,"context_line":""},{"line_number":1535,"context_line":"    def test_update_swift_base_labels_swift_request_empty_existing(self):"},{"line_number":1536,"context_line":"        # verify that existing c, o parts are not replaced even when None"},{"line_number":1537,"context_line":"        mw_conf \u003d {}"},{"line_number":1538,"context_line":"        req_hdrs \u003d {}"},{"line_number":1539,"context_line":"        extra_environ \u003d {"}],"source_content_type":"text/x-python","patch_set":43,"id":"7ea84d10_cca89426","line":1536,"range":{"start_line":1536,"start_character":32,"end_line":1536,"end_character":35},"updated":"2025-06-04 18:08:30.000000000","message":"comment is inaccurate:\n\n1. there is no ``o`` part\n2. The c part is never set to None\n\nI think it should be saying\n``verify that missing container field is not set once base_labels exists``","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"a45685bda3d2ab61fda1f43318276b1ad26ac3d5","unresolved":false,"context_lines":[{"line_number":1533,"context_line":"                mw_conf, \u0027/v1/a/c/ooo\u0027, req_hdrs, extra_environ\u003dextra_environ))"},{"line_number":1534,"context_line":""},{"line_number":1535,"context_line":"    def test_update_swift_base_labels_swift_request_empty_existing(self):"},{"line_number":1536,"context_line":"        # verify that existing c, o parts are not replaced even when None"},{"line_number":1537,"context_line":"        mw_conf \u003d {}"},{"line_number":1538,"context_line":"        req_hdrs \u003d {}"},{"line_number":1539,"context_line":"        extra_environ \u003d {"}],"source_content_type":"text/x-python","patch_set":43,"id":"4c4bdff9_d4c4b05f","line":1536,"range":{"start_line":1536,"start_character":32,"end_line":1536,"end_character":35},"in_reply_to":"7ea84d10_cca89426","updated":"2025-06-25 22:20:53.000000000","message":"Acknowledged","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":1571,"context_line":"                mw_conf, \u0027/v1/a/c/o\u0027, req_hdrs, extra_environ\u003dextra_environ))"},{"line_number":1572,"context_line":""},{"line_number":1573,"context_line":"    def test_update_swift_base_labels_swift_request_complete_existing(self):"},{"line_number":1574,"context_line":"        # verify that existing a, c, o parts are not replaced"},{"line_number":1575,"context_line":"        mw_conf \u003d {}"},{"line_number":1576,"context_line":"        req_hdrs \u003d {}"},{"line_number":1577,"context_line":"        extra_environ \u003d {"}],"source_content_type":"text/x-python","patch_set":43,"id":"2365cd3c_3cd27c3f","line":1574,"range":{"start_line":1574,"start_character":36,"end_line":1574,"end_character":38},"updated":"2025-06-04 18:08:30.000000000","message":"ditto, delete reference to o","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"a45685bda3d2ab61fda1f43318276b1ad26ac3d5","unresolved":false,"context_lines":[{"line_number":1571,"context_line":"                mw_conf, \u0027/v1/a/c/o\u0027, req_hdrs, extra_environ\u003dextra_environ))"},{"line_number":1572,"context_line":""},{"line_number":1573,"context_line":"    def test_update_swift_base_labels_swift_request_complete_existing(self):"},{"line_number":1574,"context_line":"        # verify that existing a, c, o parts are not replaced"},{"line_number":1575,"context_line":"        mw_conf \u003d {}"},{"line_number":1576,"context_line":"        req_hdrs \u003d {}"},{"line_number":1577,"context_line":"        extra_environ \u003d {"}],"source_content_type":"text/x-python","patch_set":43,"id":"0565be0a_2c33a4d6","line":1574,"range":{"start_line":1574,"start_character":36,"end_line":1574,"end_character":38},"in_reply_to":"2365cd3c_3cd27c3f","updated":"2025-06-25 22:20:53.000000000","message":"Done","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":1603,"context_line":"            self._do_test_swift_base_labels("},{"line_number":1604,"context_line":"                mw_conf, \u0027/v1/aa/cc\u0027, req_hdrs, extra_environ\u003dextra_environ))"},{"line_number":1605,"context_line":""},{"line_number":1606,"context_line":"        self.assertEqual("},{"line_number":1607,"context_line":"            {"},{"line_number":1608,"context_line":"                \u0027resource\u0027: \u0027object\u0027,"},{"line_number":1609,"context_line":"                \u0027method\u0027: \u0027PUT\u0027,"},{"line_number":1610,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":1611,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":1612,"context_line":"            },"},{"line_number":1613,"context_line":"            self._do_test_swift_base_labels("},{"line_number":1614,"context_line":"                mw_conf, \u0027/v1/aa/c/oo\u0027, req_hdrs, extra_environ\u003dextra_environ))"},{"line_number":1615,"context_line":""},{"line_number":1616,"context_line":"    def test_update_swift_base_labels_s3_request_partial_existing(self):"},{"line_number":1617,"context_line":"        # verify that existing c, o parts are not replaced by s3 parts"}],"source_content_type":"text/x-python","patch_set":43,"id":"cd17de58_6a48472d","line":1614,"range":{"start_line":1606,"start_character":0,"end_line":1614,"end_character":79},"updated":"2025-06-04 18:08:30.000000000","message":"here and above i think we could drop the cases when only the object part of the request varies, since there is no longer an object field in the base_labels","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"8d850855ef6a8d8c3488d4b31a3fc82df66487f3","unresolved":false,"context_lines":[{"line_number":1603,"context_line":"            self._do_test_swift_base_labels("},{"line_number":1604,"context_line":"                mw_conf, \u0027/v1/aa/cc\u0027, req_hdrs, extra_environ\u003dextra_environ))"},{"line_number":1605,"context_line":""},{"line_number":1606,"context_line":"        self.assertEqual("},{"line_number":1607,"context_line":"            {"},{"line_number":1608,"context_line":"                \u0027resource\u0027: \u0027object\u0027,"},{"line_number":1609,"context_line":"                \u0027method\u0027: \u0027PUT\u0027,"},{"line_number":1610,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":1611,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":1612,"context_line":"            },"},{"line_number":1613,"context_line":"            self._do_test_swift_base_labels("},{"line_number":1614,"context_line":"                mw_conf, \u0027/v1/aa/c/oo\u0027, req_hdrs, extra_environ\u003dextra_environ))"},{"line_number":1615,"context_line":""},{"line_number":1616,"context_line":"    def test_update_swift_base_labels_s3_request_partial_existing(self):"},{"line_number":1617,"context_line":"        # verify that existing c, o parts are not replaced by s3 parts"}],"source_content_type":"text/x-python","patch_set":43,"id":"3296b55c_5ddcfab9","line":1614,"range":{"start_line":1606,"start_character":0,"end_line":1614,"end_character":79},"in_reply_to":"cd17de58_6a48472d","updated":"2025-07-01 17:33:41.000000000","message":"Acknowledged","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":1762,"context_line":"        req.method \u003d \u0027PUT\u0027"},{"line_number":1763,"context_line":"        left_mw \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":1764,"context_line":"            fake_app, mw_conf, logger\u003dself.logger)"},{"line_number":1765,"context_line":"        req.get_response(left_mw)"},{"line_number":1766,"context_line":"        self.assertEqual(1, len(base_labels))"},{"line_number":1767,"context_line":"        req.environ[\u0027PATH_INFO\u0027] \u003d new_path or orig_path"},{"line_number":1768,"context_line":"        right_mw \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":1769,"context_line":"            fake_app, mw_conf, logger\u003dself.logger)"},{"line_number":1770,"context_line":"        req.get_response(right_mw)"},{"line_number":1771,"context_line":"        self.assertEqual(2, len(base_labels))"}],"source_content_type":"text/x-python","patch_set":43,"id":"40edff1d_7d959c36","line":1768,"range":{"start_line":1765,"start_character":0,"end_line":1768,"end_character":2},"updated":"2025-06-04 18:08:30.000000000","message":"this probably works but it would be nicer to have a more conventional pipeline of \n\n```\nleft -\u003e intermediate -\u003e right -\u003e app\n```\n\nrather than calling ``req.get_response`` twice\n\ne.g.\n\n```\n    def _do_test_base_labels_end_to_end(self, orig_path, new_path\u003dNone,\n                                        req_hdrs\u003dNone):\n        # if new_path is given then pretend an s3api/auth middleware\n        # combination replaces the request path with new_path\n        mw_conf \u003d {}\n        base_labels \u003d []\n\n        def fake_mw(env, start_response):\n            base_labels.append(dict(env.get(\u0027swift.base_labels\u0027)))\n            env[\u0027PATH_INFO\u0027] \u003d new_path or orig_path\n            return right_mw(env, start_response)\n\n        def fake_app(env, start_response):\n            base_labels.append(dict(env.get(\u0027swift.base_labels\u0027)))\n            return HTTPOk()(env, start_response)\n\n        left_mw \u003d proxy_logging.ProxyLoggingMiddleware(\n            fake_mw, mw_conf, logger\u003dself.logger)\n        right_mw \u003d proxy_logging.ProxyLoggingMiddleware(\n            fake_app, mw_conf, logger\u003dself.logger)\n\n        req \u003d Request.blank(orig_path, headers\u003dreq_hdrs)\n        req.method \u003d \u0027PUT\u0027\n        req.get_response(left_mw)\n        self.assertEqual(2, len(base_labels))\n\n        return base_labels\n```","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"4b8b2a8d5dc5960c69f5cfbdcd2e05b666c34558","unresolved":false,"context_lines":[{"line_number":1762,"context_line":"        req.method \u003d \u0027PUT\u0027"},{"line_number":1763,"context_line":"        left_mw \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":1764,"context_line":"            fake_app, mw_conf, logger\u003dself.logger)"},{"line_number":1765,"context_line":"        req.get_response(left_mw)"},{"line_number":1766,"context_line":"        self.assertEqual(1, len(base_labels))"},{"line_number":1767,"context_line":"        req.environ[\u0027PATH_INFO\u0027] \u003d new_path or orig_path"},{"line_number":1768,"context_line":"        right_mw \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":1769,"context_line":"            fake_app, mw_conf, logger\u003dself.logger)"},{"line_number":1770,"context_line":"        req.get_response(right_mw)"},{"line_number":1771,"context_line":"        self.assertEqual(2, len(base_labels))"}],"source_content_type":"text/x-python","patch_set":43,"id":"f7efc934_f55764f4","line":1768,"range":{"start_line":1765,"start_character":0,"end_line":1768,"end_character":2},"in_reply_to":"40edff1d_7d959c36","updated":"2025-06-27 15:25:37.000000000","message":"Acknowledged","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":1817,"context_line":"            \u0027/\u0027, \u0027/v1/a\u0027, req_hdrs)"},{"line_number":1818,"context_line":"        self.assertEqual("},{"line_number":1819,"context_line":"            [{\u0027method\u0027: \u0027PUT\u0027, \u0027resource\u0027: \u0027UNKNOWN\u0027},"},{"line_number":1820,"context_line":"             # XXX - resource should be \u0027account\u0027..."},{"line_number":1821,"context_line":"             {\u0027account\u0027: \u0027a\u0027, \u0027method\u0027: \u0027PUT\u0027, \u0027resource\u0027: \u0027UNKNOWN\u0027}],"},{"line_number":1822,"context_line":"            base_labels)"},{"line_number":1823,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"6a0e1bb9_1bbc4c3b","line":1820,"updated":"2025-06-04 18:08:30.000000000","message":"this needs to be fixed\n\nwe\u0027re still getting unknown because the leftmost mw sets in to UNKNOWN and the rightmost mw is using setdefault so does not override it.\n\nI think we need the leftmost mw to not set the resource when it knows it is an s3 req and therefore cannot tell what resource type it is yet. \n\n\u0027UNKNOWN\u0027 actually ends up meaning \u0027known to not be account, container or object\u0027 and I\u0027d prefer it to be \u0027OTHER\u0027 but that\u0027s probably off-topic for this patch.","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9a6e0468f74d52d6b52d5f04ec36c81010501ac6","unresolved":false,"context_lines":[{"line_number":1817,"context_line":"            \u0027/\u0027, \u0027/v1/a\u0027, req_hdrs)"},{"line_number":1818,"context_line":"        self.assertEqual("},{"line_number":1819,"context_line":"            [{\u0027method\u0027: \u0027PUT\u0027, \u0027resource\u0027: \u0027UNKNOWN\u0027},"},{"line_number":1820,"context_line":"             # XXX - resource should be \u0027account\u0027..."},{"line_number":1821,"context_line":"             {\u0027account\u0027: \u0027a\u0027, \u0027method\u0027: \u0027PUT\u0027, \u0027resource\u0027: \u0027UNKNOWN\u0027}],"},{"line_number":1822,"context_line":"            base_labels)"},{"line_number":1823,"context_line":""}],"source_content_type":"text/x-python","patch_set":43,"id":"b0ae889b_f415fe73","line":1820,"in_reply_to":"6a0e1bb9_1bbc4c3b","updated":"2025-07-16 20:48:56.000000000","message":"Done","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":1851,"context_line":"            base_labels)"},{"line_number":1852,"context_line":""},{"line_number":1853,"context_line":"    def _do_test_call_app(self, req, app):"},{"line_number":1854,"context_line":"        req.headers.setdefault(\"User-Agent\", \"Mozzarella Foxfire\")"},{"line_number":1855,"context_line":"        status, headers, body_iter \u003d req.call_application(app)"},{"line_number":1856,"context_line":"        body \u003d b\u0027\u0027.join(body_iter)"},{"line_number":1857,"context_line":"        return status, headers, body"}],"source_content_type":"text/x-python","patch_set":43,"id":"9a091f11_9cbf241c","line":1854,"updated":"2025-06-04 18:08:30.000000000","message":"nit: user-agent doesn\u0027t seem relevant to these tests","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"a45685bda3d2ab61fda1f43318276b1ad26ac3d5","unresolved":false,"context_lines":[{"line_number":1851,"context_line":"            base_labels)"},{"line_number":1852,"context_line":""},{"line_number":1853,"context_line":"    def _do_test_call_app(self, req, app):"},{"line_number":1854,"context_line":"        req.headers.setdefault(\"User-Agent\", \"Mozzarella Foxfire\")"},{"line_number":1855,"context_line":"        status, headers, body_iter \u003d req.call_application(app)"},{"line_number":1856,"context_line":"        body \u003d b\u0027\u0027.join(body_iter)"},{"line_number":1857,"context_line":"        return status, headers, body"}],"source_content_type":"text/x-python","patch_set":43,"id":"4220924e_6fd6c8b4","line":1854,"in_reply_to":"9a091f11_9cbf241c","updated":"2025-06-25 22:20:53.000000000","message":"Acknowledged","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":1910,"context_line":"                 \u0027policy\u0027: \u00270\u0027,"},{"line_number":1911,"context_line":"                 \u0027account\u0027: \u0027a\u0027,"},{"line_number":1912,"context_line":"                 \u0027container\u0027: \u0027c\u0027}),"},{"line_number":1913,"context_line":"            (\u0027swift_proxy_server_response_body_bytes\u0027, 8, {"},{"line_number":1914,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":1915,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":1916,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"}],"source_content_type":"text/x-python","patch_set":43,"id":"4d9b4044_26f6f879","line":1913,"range":{"start_line":1913,"start_character":55,"end_line":1913,"end_character":56},"updated":"2025-06-04 18:08:30.000000000","message":"nit: this is also len(\u0027FAKE APP\u0027) cf line 1906 - maybe define resp_len \u003d 8","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"c6325f932e7ffec038c4ebe1de235cbda134d44f","unresolved":false,"context_lines":[{"line_number":1910,"context_line":"                 \u0027policy\u0027: \u00270\u0027,"},{"line_number":1911,"context_line":"                 \u0027account\u0027: \u0027a\u0027,"},{"line_number":1912,"context_line":"                 \u0027container\u0027: \u0027c\u0027}),"},{"line_number":1913,"context_line":"            (\u0027swift_proxy_server_response_body_bytes\u0027, 8, {"},{"line_number":1914,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":1915,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":1916,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"}],"source_content_type":"text/x-python","patch_set":43,"id":"58c1cc75_26b5f70f","line":1913,"range":{"start_line":1913,"start_character":55,"end_line":1913,"end_character":56},"in_reply_to":"4d9b4044_26f6f879","updated":"2025-06-26 16:13:49.000000000","message":"Acknowledged","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":1931,"context_line":"            callback_stats_per_iter.append(got_metrics_values_and_kwargs)"},{"line_number":1932,"context_line":"            nonlocal read_calls"},{"line_number":1933,"context_line":"            nonlocal read_bytes"},{"line_number":1934,"context_line":"            read_calls \u003d iter_n + 1"},{"line_number":1935,"context_line":"            read_bytes +\u003d nbytes"},{"line_number":1936,"context_line":""},{"line_number":1937,"context_line":"        conf \u003d {"}],"source_content_type":"text/x-python","patch_set":43,"id":"cdd42df0_359b9913","line":1934,"updated":"2025-06-04 18:08:30.000000000","message":"do we need iter_n - can\u0027t this just be\n```\nread_calls +\u003d 1\n```","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9237818e7872731319b58e2ec2b6f7976543e67d","unresolved":false,"context_lines":[{"line_number":1931,"context_line":"            callback_stats_per_iter.append(got_metrics_values_and_kwargs)"},{"line_number":1932,"context_line":"            nonlocal read_calls"},{"line_number":1933,"context_line":"            nonlocal read_bytes"},{"line_number":1934,"context_line":"            read_calls \u003d iter_n + 1"},{"line_number":1935,"context_line":"            read_bytes +\u003d nbytes"},{"line_number":1936,"context_line":""},{"line_number":1937,"context_line":"        conf \u003d {"}],"source_content_type":"text/x-python","patch_set":43,"id":"b7751cd6_708f19f9","line":1934,"in_reply_to":"cdd42df0_359b9913","updated":"2025-06-25 20:41:54.000000000","message":"Done","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":1935,"context_line":"            read_bytes +\u003d nbytes"},{"line_number":1936,"context_line":""},{"line_number":1937,"context_line":"        conf \u003d {"},{"line_number":1938,"context_line":"            \u0027log_headers\u0027: \u0027yes\u0027,"},{"line_number":1939,"context_line":"            \u0027statsd_label_mode\u0027: \u0027dogstatsd\u0027,"},{"line_number":1940,"context_line":"            \u0027statsd_emit_buffer_xfer_bytes_ms\u0027: 0,"},{"line_number":1941,"context_line":"        }"}],"source_content_type":"text/x-python","patch_set":43,"id":"785d67d3_42b1bba5","line":1938,"updated":"2025-06-04 18:08:30.000000000","message":"nit: not sure log_headers is relevant to this test","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9237818e7872731319b58e2ec2b6f7976543e67d","unresolved":false,"context_lines":[{"line_number":1935,"context_line":"            read_bytes +\u003d nbytes"},{"line_number":1936,"context_line":""},{"line_number":1937,"context_line":"        conf \u003d {"},{"line_number":1938,"context_line":"            \u0027log_headers\u0027: \u0027yes\u0027,"},{"line_number":1939,"context_line":"            \u0027statsd_label_mode\u0027: \u0027dogstatsd\u0027,"},{"line_number":1940,"context_line":"            \u0027statsd_emit_buffer_xfer_bytes_ms\u0027: 0,"},{"line_number":1941,"context_line":"        }"}],"source_content_type":"text/x-python","patch_set":43,"id":"3a95c355_00845a39","line":1938,"in_reply_to":"785d67d3_42b1bba5","updated":"2025-06-25 20:41:54.000000000","message":"Might have been taken from other tests and left. That isn\u0027t relevant or needed.","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":1939,"context_line":"            \u0027statsd_label_mode\u0027: \u0027dogstatsd\u0027,"},{"line_number":1940,"context_line":"            \u0027statsd_emit_buffer_xfer_bytes_ms\u0027: 0,"},{"line_number":1941,"context_line":"        }"},{"line_number":1942,"context_line":"        self.statsd \u003d debug_labeled_statsd_client(conf)"},{"line_number":1943,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":1944,"context_line":"            FakeApp(read_callback\u003dassert_read_stats), conf, logger\u003dself.logger)"},{"line_number":1945,"context_line":"        app.statsd \u003d self.statsd"}],"source_content_type":"text/x-python","patch_set":43,"id":"613c8221_d86b3c3a","line":1942,"updated":"2025-06-04 18:08:30.000000000","message":"setUp() already defined this","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9237818e7872731319b58e2ec2b6f7976543e67d","unresolved":false,"context_lines":[{"line_number":1939,"context_line":"            \u0027statsd_label_mode\u0027: \u0027dogstatsd\u0027,"},{"line_number":1940,"context_line":"            \u0027statsd_emit_buffer_xfer_bytes_ms\u0027: 0,"},{"line_number":1941,"context_line":"        }"},{"line_number":1942,"context_line":"        self.statsd \u003d debug_labeled_statsd_client(conf)"},{"line_number":1943,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":1944,"context_line":"            FakeApp(read_callback\u003dassert_read_stats), conf, logger\u003dself.logger)"},{"line_number":1945,"context_line":"        app.statsd \u003d self.statsd"}],"source_content_type":"text/x-python","patch_set":43,"id":"ce7c4590_640190d2","line":1942,"in_reply_to":"613c8221_d86b3c3a","updated":"2025-06-25 20:41:54.000000000","message":"Done","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":1950,"context_line":"                     })"},{"line_number":1951,"context_line":"        resp \u003d app(req.environ, start_response)"},{"line_number":1952,"context_line":"        # exhaust generator"},{"line_number":1953,"context_line":"        [x for x in resp]"},{"line_number":1954,"context_line":"        self.assertEqual(read_bytes, buffer_len)"},{"line_number":1955,"context_line":"        self.assertEqual(read_calls, len(callback_stats_per_iter))"},{"line_number":1956,"context_line":"        self.assertEqual(read_calls + 1, len(expect_stats_per_iter))"}],"source_content_type":"text/x-python","patch_set":43,"id":"9f90428f_e5d50ab6","line":1953,"updated":"2025-06-04 18:08:30.000000000","message":"or\n```\n        self.assertEqual(b\u0027FAKE APP\u0027, b\u0027\u0027.join(resp))\n\n```","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"c6325f932e7ffec038c4ebe1de235cbda134d44f","unresolved":false,"context_lines":[{"line_number":1950,"context_line":"                     })"},{"line_number":1951,"context_line":"        resp \u003d app(req.environ, start_response)"},{"line_number":1952,"context_line":"        # exhaust generator"},{"line_number":1953,"context_line":"        [x for x in resp]"},{"line_number":1954,"context_line":"        self.assertEqual(read_bytes, buffer_len)"},{"line_number":1955,"context_line":"        self.assertEqual(read_calls, len(callback_stats_per_iter))"},{"line_number":1956,"context_line":"        self.assertEqual(read_calls + 1, len(expect_stats_per_iter))"}],"source_content_type":"text/x-python","patch_set":43,"id":"a459f861_e79220ff","line":1953,"in_reply_to":"9f90428f_e5d50ab6","updated":"2025-06-26 16:13:49.000000000","message":"Acknowledged","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":1954,"context_line":"        self.assertEqual(read_bytes, buffer_len)"},{"line_number":1955,"context_line":"        self.assertEqual(read_calls, len(callback_stats_per_iter))"},{"line_number":1956,"context_line":"        self.assertEqual(read_calls + 1, len(expect_stats_per_iter))"},{"line_number":1957,"context_line":"        self.assertLabeledUpdateStats(expect_stats_per_iter[read_calls])"},{"line_number":1958,"context_line":"        self.assertUpdateStats(["},{"line_number":1959,"context_line":"            (\u0027container.POST.200.xfer\u0027,"},{"line_number":1960,"context_line":"             buffer_len + len(\u0027FAKE APP\u0027)),"}],"source_content_type":"text/x-python","patch_set":43,"id":"f6e42714_b1a16c0c","line":1957,"updated":"2025-06-04 18:08:30.000000000","message":"so this test ends up only making an assertion about the accumulated stats from the final \u0027iter\u0027...I don\u0027t understand why the rest of the list of expect_stats_per_iter was constructed with all the intermediate values?","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"5a6a291f5a616b4ba8f14fea825d14cf68656b81","unresolved":false,"context_lines":[{"line_number":1954,"context_line":"        self.assertEqual(read_bytes, buffer_len)"},{"line_number":1955,"context_line":"        self.assertEqual(read_calls, len(callback_stats_per_iter))"},{"line_number":1956,"context_line":"        self.assertEqual(read_calls + 1, len(expect_stats_per_iter))"},{"line_number":1957,"context_line":"        self.assertLabeledUpdateStats(expect_stats_per_iter[read_calls])"},{"line_number":1958,"context_line":"        self.assertUpdateStats(["},{"line_number":1959,"context_line":"            (\u0027container.POST.200.xfer\u0027,"},{"line_number":1960,"context_line":"             buffer_len + len(\u0027FAKE APP\u0027)),"}],"source_content_type":"text/x-python","patch_set":43,"id":"d7f49da6_4afea8a5","line":1957,"in_reply_to":"f6e42714_b1a16c0c","updated":"2025-07-09 16:30:59.000000000","message":"Acknowledged","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":1968,"context_line":"            def __iter__(self):"},{"line_number":1969,"context_line":"                yield self.buffers[0]"},{"line_number":1970,"context_line":"                yield self.buffers[1]"},{"line_number":1971,"context_line":"                yield self.buffers[2]"},{"line_number":1972,"context_line":""},{"line_number":1973,"context_line":"        buffers \u003d [b\u0027some stuff\\n\u0027,"},{"line_number":1974,"context_line":"                   b\u0027some other stuff\\n\u0027,"}],"source_content_type":"text/x-python","patch_set":43,"id":"0df7ddde_7753678c","line":1971,"updated":"2025-06-04 18:08:30.000000000","message":"this seems very brittle in that it assume the class is always init\u0027d with buffers having at least 3 items. That\u0027s likely true in the context of this test, but it could be written more succinctly:\n\n```\ndef __init__(self, buffers):\n    self.buffers \u003d buffers.copy()\n\ndef __iter__(self):\n    yield self.buffers.pop(0)\n```","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":1968,"context_line":"            def __iter__(self):"},{"line_number":1969,"context_line":"                yield self.buffers[0]"},{"line_number":1970,"context_line":"                yield self.buffers[1]"},{"line_number":1971,"context_line":"                yield self.buffers[2]"},{"line_number":1972,"context_line":""},{"line_number":1973,"context_line":"        buffers \u003d [b\u0027some stuff\\n\u0027,"},{"line_number":1974,"context_line":"                   b\u0027some other stuff\\n\u0027,"}],"source_content_type":"text/x-python","patch_set":43,"id":"4025c76c_b935d4af","line":1971,"in_reply_to":"0df7ddde_7753678c","updated":"2025-06-05 11:46:42.000000000","message":"actually this class isn\u0027t needed at all, you can just pass the list of ``buffers`` to FakeApp\n\nso at line 1984\n\n```\nFakeApp(body\u003dbuffers)\n```\n\nplease also fix where this pattern is used in later tests","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"882046edbfa151e01a295bbd60d141e128e3c8ff","unresolved":false,"context_lines":[{"line_number":1968,"context_line":"            def __iter__(self):"},{"line_number":1969,"context_line":"                yield self.buffers[0]"},{"line_number":1970,"context_line":"                yield self.buffers[1]"},{"line_number":1971,"context_line":"                yield self.buffers[2]"},{"line_number":1972,"context_line":""},{"line_number":1973,"context_line":"        buffers \u003d [b\u0027some stuff\\n\u0027,"},{"line_number":1974,"context_line":"                   b\u0027some other stuff\\n\u0027,"}],"source_content_type":"text/x-python","patch_set":43,"id":"43f961f3_dd772381","line":1971,"in_reply_to":"4025c76c_b935d4af","updated":"2025-06-14 04:17:00.000000000","message":"Done","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":1973,"context_line":"        buffers \u003d [b\u0027some stuff\\n\u0027,"},{"line_number":1974,"context_line":"                   b\u0027some other stuff\\n\u0027,"},{"line_number":1975,"context_line":"                   b\u0027some additional stuff\\n\u0027]"},{"line_number":1976,"context_line":"        buffer_len \u003d len(buffers[0]) + len(buffers[1]) + len(buffers[2])"},{"line_number":1977,"context_line":"        conf \u003d {"},{"line_number":1978,"context_line":"            \u0027log_headers\u0027: \u0027yes\u0027,"},{"line_number":1979,"context_line":"            \u0027statsd_label_mode\u0027: \u0027dogstatsd\u0027,"}],"source_content_type":"text/x-python","patch_set":43,"id":"ff5225ea_142593ce","line":1976,"updated":"2025-06-04 18:08:30.000000000","message":"```\n        buffer_len \u003d sum(len(b) for b in buffers)\n\n```","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9237818e7872731319b58e2ec2b6f7976543e67d","unresolved":false,"context_lines":[{"line_number":1973,"context_line":"        buffers \u003d [b\u0027some stuff\\n\u0027,"},{"line_number":1974,"context_line":"                   b\u0027some other stuff\\n\u0027,"},{"line_number":1975,"context_line":"                   b\u0027some additional stuff\\n\u0027]"},{"line_number":1976,"context_line":"        buffer_len \u003d len(buffers[0]) + len(buffers[1]) + len(buffers[2])"},{"line_number":1977,"context_line":"        conf \u003d {"},{"line_number":1978,"context_line":"            \u0027log_headers\u0027: \u0027yes\u0027,"},{"line_number":1979,"context_line":"            \u0027statsd_label_mode\u0027: \u0027dogstatsd\u0027,"}],"source_content_type":"text/x-python","patch_set":43,"id":"cf09b284_f041e9bc","line":1976,"in_reply_to":"ff5225ea_142593ce","updated":"2025-06-25 20:41:54.000000000","message":"Done","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":1979,"context_line":"            \u0027statsd_label_mode\u0027: \u0027dogstatsd\u0027,"},{"line_number":1980,"context_line":"            \u0027statsd_emit_buffer_xfer_bytes_ms\u0027: 0,"},{"line_number":1981,"context_line":"        }"},{"line_number":1982,"context_line":"        self.statsd \u003d debug_labeled_statsd_client(conf)"},{"line_number":1983,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":1984,"context_line":"            FakeApp("},{"line_number":1985,"context_line":"                body\u003dBodyGen(buffers),"}],"source_content_type":"text/x-python","patch_set":43,"id":"221d5161_e09c7657","line":1982,"updated":"2025-06-04 18:08:30.000000000","message":"done in setUp()","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"24c5d44d6b8c78a50f40cc5981234abb91f0d136","unresolved":false,"context_lines":[{"line_number":1979,"context_line":"            \u0027statsd_label_mode\u0027: \u0027dogstatsd\u0027,"},{"line_number":1980,"context_line":"            \u0027statsd_emit_buffer_xfer_bytes_ms\u0027: 0,"},{"line_number":1981,"context_line":"        }"},{"line_number":1982,"context_line":"        self.statsd \u003d debug_labeled_statsd_client(conf)"},{"line_number":1983,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":1984,"context_line":"            FakeApp("},{"line_number":1985,"context_line":"                body\u003dBodyGen(buffers),"}],"source_content_type":"text/x-python","patch_set":43,"id":"0650b316_e44e2b2d","line":1982,"in_reply_to":"221d5161_e09c7657","updated":"2025-06-12 20:05:52.000000000","message":"Acknowledged","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":1990,"context_line":"        resp \u003d app(req.environ, start_response)"},{"line_number":1991,"context_line":"        resp_body \u003d b\u0027\u0027.join(resp)"},{"line_number":1992,"context_line":"        expected_resp \u003d b\u0027\u0027.join(buffers)"},{"line_number":1993,"context_line":"        log_parts \u003d self._log_parts(app)"},{"line_number":1994,"context_line":"        self.assertEqual(log_parts[3], \u0027GET\u0027)"},{"line_number":1995,"context_line":"        self.assertEqual(log_parts[4], \u0027/v1/a/c\u0027)"},{"line_number":1996,"context_line":"        self.assertEqual(log_parts[5], \u0027HTTP/1.0\u0027)"}],"source_content_type":"text/x-python","patch_set":43,"id":"cb3e2550_c1583f51","line":1993,"updated":"2025-06-04 18:08:30.000000000","message":"nit: perhaps not necessary to assert the logging string in this test","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"4b8b2a8d5dc5960c69f5cfbdcd2e05b666c34558","unresolved":false,"context_lines":[{"line_number":1990,"context_line":"        resp \u003d app(req.environ, start_response)"},{"line_number":1991,"context_line":"        resp_body \u003d b\u0027\u0027.join(resp)"},{"line_number":1992,"context_line":"        expected_resp \u003d b\u0027\u0027.join(buffers)"},{"line_number":1993,"context_line":"        log_parts \u003d self._log_parts(app)"},{"line_number":1994,"context_line":"        self.assertEqual(log_parts[3], \u0027GET\u0027)"},{"line_number":1995,"context_line":"        self.assertEqual(log_parts[4], \u0027/v1/a/c\u0027)"},{"line_number":1996,"context_line":"        self.assertEqual(log_parts[5], \u0027HTTP/1.0\u0027)"}],"source_content_type":"text/x-python","patch_set":43,"id":"81b2d6ab_53bbc3e6","line":1993,"in_reply_to":"82ccd279_e5c7675c","updated":"2025-06-27 15:25:37.000000000","message":"Done","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":1990,"context_line":"        resp \u003d app(req.environ, start_response)"},{"line_number":1991,"context_line":"        resp_body \u003d b\u0027\u0027.join(resp)"},{"line_number":1992,"context_line":"        expected_resp \u003d b\u0027\u0027.join(buffers)"},{"line_number":1993,"context_line":"        log_parts \u003d self._log_parts(app)"},{"line_number":1994,"context_line":"        self.assertEqual(log_parts[3], \u0027GET\u0027)"},{"line_number":1995,"context_line":"        self.assertEqual(log_parts[4], \u0027/v1/a/c\u0027)"},{"line_number":1996,"context_line":"        self.assertEqual(log_parts[5], \u0027HTTP/1.0\u0027)"}],"source_content_type":"text/x-python","patch_set":43,"id":"82ccd279_e5c7675c","line":1993,"in_reply_to":"cb3e2550_c1583f51","updated":"2025-06-05 11:46:42.000000000","message":"update : now I got to line 2076 I can see there\u0027s value in asserting the byte counts in the log as a cross-check with the stats.","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":1996,"context_line":"        self.assertEqual(log_parts[5], \u0027HTTP/1.0\u0027)"},{"line_number":1997,"context_line":"        self.assertEqual(log_parts[6], \u0027200\u0027)"},{"line_number":1998,"context_line":"        self.assertEqual(resp_body, expected_resp)"},{"line_number":1999,"context_line":"        self.assertEqual(log_parts[11], \u002750\u0027)"},{"line_number":2000,"context_line":"        self.assertUpdateStats(["},{"line_number":2001,"context_line":"            (\u0027container.GET.200.xfer\u0027,"},{"line_number":2002,"context_line":"             buffer_len),"}],"source_content_type":"text/x-python","patch_set":43,"id":"6c7d9147_d707ce27","line":1999,"updated":"2025-06-04 18:08:30.000000000","message":"is this maybe ``str(buffer_len)``??","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"c6325f932e7ffec038c4ebe1de235cbda134d44f","unresolved":false,"context_lines":[{"line_number":1996,"context_line":"        self.assertEqual(log_parts[5], \u0027HTTP/1.0\u0027)"},{"line_number":1997,"context_line":"        self.assertEqual(log_parts[6], \u0027200\u0027)"},{"line_number":1998,"context_line":"        self.assertEqual(resp_body, expected_resp)"},{"line_number":1999,"context_line":"        self.assertEqual(log_parts[11], \u002750\u0027)"},{"line_number":2000,"context_line":"        self.assertUpdateStats(["},{"line_number":2001,"context_line":"            (\u0027container.GET.200.xfer\u0027,"},{"line_number":2002,"context_line":"             buffer_len),"}],"source_content_type":"text/x-python","patch_set":43,"id":"be1a2764_11cb7f98","line":1999,"in_reply_to":"6c7d9147_d707ce27","updated":"2025-06-26 16:13:49.000000000","message":"Yes!","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a43829fedd2046b7c12451b92dc4a1f3d342a29","unresolved":true,"context_lines":[{"line_number":2013,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":2014,"context_line":"                \u0027method\u0027: \u0027GET\u0027,"},{"line_number":2015,"context_line":"                \u0027resource\u0027: \u0027container\u0027}),"},{"line_number":2016,"context_line":"            (\u0027swift_proxy_server_response_body_bytes\u0027, buffer_len, {"},{"line_number":2017,"context_line":"                \u0027resource\u0027: \u0027container\u0027,"},{"line_number":2018,"context_line":"                \u0027method\u0027: \u0027GET\u0027,"},{"line_number":2019,"context_line":"                \u0027status\u0027: 200,"}],"source_content_type":"text/x-python","patch_set":43,"id":"697939ad_5cb7281c","line":2016,"updated":"2025-06-04 18:08:30.000000000","message":"weird that this total byte count is emitted first\n\noh! the assertion helper sorts the stats call ?!","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9237818e7872731319b58e2ec2b6f7976543e67d","unresolved":false,"context_lines":[{"line_number":2013,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":2014,"context_line":"                \u0027method\u0027: \u0027GET\u0027,"},{"line_number":2015,"context_line":"                \u0027resource\u0027: \u0027container\u0027}),"},{"line_number":2016,"context_line":"            (\u0027swift_proxy_server_response_body_bytes\u0027, buffer_len, {"},{"line_number":2017,"context_line":"                \u0027resource\u0027: \u0027container\u0027,"},{"line_number":2018,"context_line":"                \u0027method\u0027: \u0027GET\u0027,"},{"line_number":2019,"context_line":"                \u0027status\u0027: 200,"}],"source_content_type":"text/x-python","patch_set":43,"id":"b2701da8_36e1f68f","line":2016,"in_reply_to":"697939ad_5cb7281c","updated":"2025-06-25 20:41:54.000000000","message":"It was sorting, I\u0027ve now changed it and it\u0027s not sorting anymore so the order would change!","commit_id":"eb858c8aff531e84c487b01f06bc7d6e0e3c6c3c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":306,"context_line":"                value, statsd_calls[i][0][1], places\u003d4, msg\u003di)"},{"line_number":307,"context_line":""},{"line_number":308,"context_line":"    def assertLabeledUpdateStats(self, exp_metrics_values_labels):"},{"line_number":309,"context_line":"        statsd_calls \u003d sorted(self.statsd.calls[\u0027update_stats\u0027])"},{"line_number":310,"context_line":"        exp_calls \u003d []"},{"line_number":311,"context_line":"        for metric, value, labels in exp_metrics_values_labels:"},{"line_number":312,"context_line":"            exp_calls.append(((metric, value), {\u0027labels\u0027: labels}))"}],"source_content_type":"text/x-python","patch_set":44,"id":"40dcb6ca_d3510576","line":309,"updated":"2025-06-05 11:46:42.000000000","message":"I don\u0027t really like this change - it seems that the order in which stats is emitted is predictable, and its useful/intuitive to see them asserted in that order\n\nI changed a couple of tests to convince myself\n\n```\ndiff --git a/test/unit/common/middleware/test_proxy_logging.py b/test/unit/common/middleware/test_proxy_logging.py\nindex 59d40dac4..44adf0bd0 100644\n--- a/test/unit/common/middleware/test_proxy_logging.py\n+++ b/test/unit/common/middleware/test_proxy_logging.py\n@@ -322,11 +322,11 @@ class TestProxyLogging(unittest.TestCase):\n                 value, statsd_calls[i][0][1], places\u003d4, msg\u003di)\n \n     def assertLabeledUpdateStats(self, exp_metrics_values_labels):\n-        statsd_calls \u003d sorted(self.statsd.calls[\u0027update_stats\u0027])\n+        statsd_calls \u003d self.statsd.calls[\u0027update_stats\u0027]\n         exp_calls \u003d []\n         for metric, value, labels in exp_metrics_values_labels:\n             exp_calls.append(((metric, value), {\u0027labels\u0027: labels}))\n-        exp_calls \u003d sorted(exp_calls)\n+        exp_calls \u003d exp_calls\n         self.assertEqual(exp_calls, statsd_calls)\n \n     def test_init_logger_and_legacy_statsd_options_log_prefix(self):\n@@ -2020,23 +2020,11 @@ class TestProxyLogging(unittest.TestCase):\n              buffer_len),\n         ], app)\n         self.assertLabeledUpdateStats([\n-            (\u0027swift_proxy_server_request_body_bytes\u0027, 0, {\n-                \u0027resource\u0027: \u0027container\u0027,\n-                \u0027method\u0027: \u0027GET\u0027,\n-                \u0027status\u0027: 200,\n-                \u0027account\u0027: \u0027a\u0027,\n-                \u0027container\u0027: \u0027c\u0027}),\n             (\u0027swift_proxy_server_request_body_streaming_bytes\u0027, 0, {\n                 \u0027account\u0027: \u0027a\u0027,\n                 \u0027container\u0027: \u0027c\u0027,\n                 \u0027method\u0027: \u0027GET\u0027,\n                 \u0027resource\u0027: \u0027container\u0027}),\n-            (\u0027swift_proxy_server_response_body_bytes\u0027, buffer_len, {\n-                \u0027resource\u0027: \u0027container\u0027,\n-                \u0027method\u0027: \u0027GET\u0027,\n-                \u0027status\u0027: 200,\n-                \u0027account\u0027: \u0027a\u0027,\n-                \u0027container\u0027: \u0027c\u0027}),\n             (\u0027swift_proxy_server_response_body_streaming_bytes\u0027, 11, {\n                 \u0027account\u0027: \u0027a\u0027,\n                 \u0027container\u0027: \u0027c\u0027,\n@@ -2057,7 +2045,19 @@ class TestProxyLogging(unittest.TestCase):\n                 \u0027method\u0027: \u0027GET\u0027,\n                 \u0027policy\u0027: \u00270\u0027,\n                 \u0027resource\u0027: \u0027container\u0027,\n-                \u0027status\u0027: 200})\n+                \u0027status\u0027: 200}),\n+            (\u0027swift_proxy_server_request_body_bytes\u0027, 0, {\n+                \u0027resource\u0027: \u0027container\u0027,\n+                \u0027method\u0027: \u0027GET\u0027,\n+                \u0027status\u0027: 200,\n+                \u0027account\u0027: \u0027a\u0027,\n+                \u0027container\u0027: \u0027c\u0027}),\n+            (\u0027swift_proxy_server_response_body_bytes\u0027, buffer_len, {\n+                \u0027resource\u0027: \u0027container\u0027,\n+                \u0027method\u0027: \u0027GET\u0027,\n+                \u0027status\u0027: 200,\n+                \u0027account\u0027: \u0027a\u0027,\n+                \u0027container\u0027: \u0027c\u0027}),\n         ])\n \n     def test_xfer_stats_emit_frequency_post(self):\n@@ -2177,23 +2177,11 @@ class TestProxyLogging(unittest.TestCase):\n         ], app\n         )\n         self.assertLabeledUpdateStats([\n-            (\u0027swift_proxy_server_request_body_bytes\u0027, 0, {\n-                \u0027resource\u0027: \u0027container\u0027,\n-                \u0027method\u0027: \u0027GET\u0027,\n-                \u0027status\u0027: 200,\n-                \u0027account\u0027: \u0027a\u0027,\n-                \u0027container\u0027: \u0027c\u0027}),\n             (\u0027swift_proxy_server_request_body_streaming_bytes\u0027, 0, {\n                 \u0027account\u0027: \u0027a\u0027,\n                 \u0027container\u0027: \u0027c\u0027,\n                 \u0027method\u0027: \u0027GET\u0027,\n                 \u0027resource\u0027: \u0027container\u0027}),\n-            (\u0027swift_proxy_server_response_body_bytes\u0027, buffer_len, {\n-                \u0027resource\u0027: \u0027container\u0027,\n-                \u0027method\u0027: \u0027GET\u0027,\n-                \u0027status\u0027: 200,\n-                \u0027account\u0027: \u0027a\u0027,\n-                \u0027container\u0027: \u0027c\u0027}),\n             (\u0027swift_proxy_server_response_body_streaming_bytes\u0027, 11, {\n                 \u0027account\u0027: \u0027a\u0027,\n                 \u0027container\u0027: \u0027c\u0027,\n@@ -2201,6 +2189,18 @@ class TestProxyLogging(unittest.TestCase):\n                 \u0027policy\u0027: \u00270\u0027,\n                 \u0027resource\u0027: \u0027container\u0027,\n                 \u0027status\u0027: 200}),\n+            (\u0027swift_proxy_server_request_body_bytes\u0027, 0, {\n+                \u0027resource\u0027: \u0027container\u0027,\n+                \u0027method\u0027: \u0027GET\u0027,\n+                \u0027status\u0027: 200,\n+                \u0027account\u0027: \u0027a\u0027,\n+                \u0027container\u0027: \u0027c\u0027}),\n+            (\u0027swift_proxy_server_response_body_bytes\u0027, buffer_len, {\n+                \u0027resource\u0027: \u0027container\u0027,\n+                \u0027method\u0027: \u0027GET\u0027,\n+                \u0027status\u0027: 200,\n+                \u0027account\u0027: \u0027a\u0027,\n+                \u0027container\u0027: \u0027c\u0027}),\n         ])\n \n     def test_xfer_stats_put_s3api(self):\n\n```","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"882046edbfa151e01a295bbd60d141e128e3c8ff","unresolved":false,"context_lines":[{"line_number":306,"context_line":"                value, statsd_calls[i][0][1], places\u003d4, msg\u003di)"},{"line_number":307,"context_line":""},{"line_number":308,"context_line":"    def assertLabeledUpdateStats(self, exp_metrics_values_labels):"},{"line_number":309,"context_line":"        statsd_calls \u003d sorted(self.statsd.calls[\u0027update_stats\u0027])"},{"line_number":310,"context_line":"        exp_calls \u003d []"},{"line_number":311,"context_line":"        for metric, value, labels in exp_metrics_values_labels:"},{"line_number":312,"context_line":"            exp_calls.append(((metric, value), {\u0027labels\u0027: labels}))"}],"source_content_type":"text/x-python","patch_set":44,"id":"ae925709_41a5081f","line":309,"in_reply_to":"40dcb6ca_d3510576","updated":"2025-06-14 04:17:00.000000000","message":"Done","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":2043,"context_line":"        ])"},{"line_number":2044,"context_line":""},{"line_number":2045,"context_line":"    def test_xfer_stats_emit_frequency_post(self):"},{"line_number":2046,"context_line":"        curr_time \u003d [100.000]"},{"line_number":2047,"context_line":""},{"line_number":2048,"context_line":"        def patch_time():"},{"line_number":2049,"context_line":"            curr_time[0] +\u003d 0.001"},{"line_number":2050,"context_line":"            return curr_time[0]"},{"line_number":2051,"context_line":""},{"line_number":2052,"context_line":"        conf \u003d {"},{"line_number":2053,"context_line":"            \u0027log_headers\u0027: \u0027yes\u0027,"}],"source_content_type":"text/x-python","patch_set":44,"id":"3573b36e_035d9528","line":2050,"range":{"start_line":2046,"start_character":8,"end_line":2050,"end_character":31},"updated":"2025-06-05 11:46:42.000000000","message":"this is implementing a simple counter which can be done using ``itertools.count``\n\ne.g.\n\n```\npatch_time \u003d (0.001 * i for i in itertools.count())\n```\n\nor at line 2070 \n```\nwith mock.patch(\u0027time.time\u0027, side_effect\u003d(0.001 * i for i in itertools.count()))\n```\n\nI recommend becoming familiar with the itertools package - it has some nice helpers.\n\nAlso, note that ``side_effect`` causes the mock to return the next value in the ``side_effect`` iter each time it is called","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9237818e7872731319b58e2ec2b6f7976543e67d","unresolved":false,"context_lines":[{"line_number":2043,"context_line":"        ])"},{"line_number":2044,"context_line":""},{"line_number":2045,"context_line":"    def test_xfer_stats_emit_frequency_post(self):"},{"line_number":2046,"context_line":"        curr_time \u003d [100.000]"},{"line_number":2047,"context_line":""},{"line_number":2048,"context_line":"        def patch_time():"},{"line_number":2049,"context_line":"            curr_time[0] +\u003d 0.001"},{"line_number":2050,"context_line":"            return curr_time[0]"},{"line_number":2051,"context_line":""},{"line_number":2052,"context_line":"        conf \u003d {"},{"line_number":2053,"context_line":"            \u0027log_headers\u0027: \u0027yes\u0027,"}],"source_content_type":"text/x-python","patch_set":44,"id":"c679e0d7_de5dec9f","line":2050,"range":{"start_line":2046,"start_character":8,"end_line":2050,"end_character":31},"in_reply_to":"3573b36e_035d9528","updated":"2025-06-25 20:41:54.000000000","message":"Interesting package! Looks good!!","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":2050,"context_line":"            return curr_time[0]"},{"line_number":2051,"context_line":""},{"line_number":2052,"context_line":"        conf \u003d {"},{"line_number":2053,"context_line":"            \u0027log_headers\u0027: \u0027yes\u0027,"},{"line_number":2054,"context_line":"            \u0027statsd_label_mode\u0027: \u0027dogstatsd\u0027,"},{"line_number":2055,"context_line":"            \u0027statsd_emit_buffer_xfer_bytes_ms\u0027: 5,"},{"line_number":2056,"context_line":"        }"}],"source_content_type":"text/x-python","patch_set":44,"id":"58fa4487_7f678e35","line":2053,"range":{"start_line":2053,"start_character":12,"end_line":2053,"end_character":33},"updated":"2025-06-05 11:46:42.000000000","message":"nit: I keep seeing this conf option in the new test - I maybe be being too fussy, but could we remove it because it\u0027s a distraction. It makes me wonder why there isn\u0027t a test with ``log_headers\u003dno``...In fact, the option is irrelevant to the assertions being made in these tests.","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"7f899aa6a4f29b755488e43b203299b0920057c4","unresolved":false,"context_lines":[{"line_number":2050,"context_line":"            return curr_time[0]"},{"line_number":2051,"context_line":""},{"line_number":2052,"context_line":"        conf \u003d {"},{"line_number":2053,"context_line":"            \u0027log_headers\u0027: \u0027yes\u0027,"},{"line_number":2054,"context_line":"            \u0027statsd_label_mode\u0027: \u0027dogstatsd\u0027,"},{"line_number":2055,"context_line":"            \u0027statsd_emit_buffer_xfer_bytes_ms\u0027: 5,"},{"line_number":2056,"context_line":"        }"}],"source_content_type":"text/x-python","patch_set":44,"id":"e249e5f4_9f5aca30","line":2053,"range":{"start_line":2053,"start_character":12,"end_line":2053,"end_character":33},"in_reply_to":"58fa4487_7f678e35","updated":"2025-06-25 21:43:07.000000000","message":"Agree, it isn\u0027t relevant and necessary","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":2054,"context_line":"            \u0027statsd_label_mode\u0027: \u0027dogstatsd\u0027,"},{"line_number":2055,"context_line":"            \u0027statsd_emit_buffer_xfer_bytes_ms\u0027: 5,"},{"line_number":2056,"context_line":"        }"},{"line_number":2057,"context_line":"        self.statsd \u003d debug_labeled_statsd_client(conf)"},{"line_number":2058,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":2059,"context_line":"            FakeApp(), conf, logger\u003dself.logger)"},{"line_number":2060,"context_line":"        app.statsd \u003d self.statsd"}],"source_content_type":"text/x-python","patch_set":44,"id":"48310421_0719cc64","line":2057,"updated":"2025-06-05 11:46:42.000000000","message":"done in setUp()","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"24c5d44d6b8c78a50f40cc5981234abb91f0d136","unresolved":false,"context_lines":[{"line_number":2054,"context_line":"            \u0027statsd_label_mode\u0027: \u0027dogstatsd\u0027,"},{"line_number":2055,"context_line":"            \u0027statsd_emit_buffer_xfer_bytes_ms\u0027: 5,"},{"line_number":2056,"context_line":"        }"},{"line_number":2057,"context_line":"        self.statsd \u003d debug_labeled_statsd_client(conf)"},{"line_number":2058,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":2059,"context_line":"            FakeApp(), conf, logger\u003dself.logger)"},{"line_number":2060,"context_line":"        app.statsd \u003d self.statsd"}],"source_content_type":"text/x-python","patch_set":44,"id":"48741181_804b9b54","line":2057,"in_reply_to":"48310421_0719cc64","updated":"2025-06-12 20:05:52.000000000","message":"Acknowledged","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":2070,"context_line":"        with mock.patch(\u0027time.time\u0027, patch_time):"},{"line_number":2071,"context_line":"            resp \u003d app(req.environ, start_response)"},{"line_number":2072,"context_line":"            # exhaust generator"},{"line_number":2073,"context_line":"            [x for x in resp]"},{"line_number":2074,"context_line":"        log_parts \u003d self._log_parts(app)"},{"line_number":2075,"context_line":"        self.assertEqual(log_parts[11], str(len(\u0027FAKE APP\u0027)))"},{"line_number":2076,"context_line":"        self.assertEqual(log_parts[10], str(buffer_len))"}],"source_content_type":"text/x-python","patch_set":44,"id":"6d1c9454_aba56570","line":2073,"updated":"2025-06-05 11:46:42.000000000","message":"as commented above, we may as well assert the body\n\n```\nself.assertEqual(b\u0027FAKE APP\u0027, b\u0027\u0027.join(resp))\n```\n\nditto everywhere there is ``[x for x in resp]``","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"c6325f932e7ffec038c4ebe1de235cbda134d44f","unresolved":false,"context_lines":[{"line_number":2070,"context_line":"        with mock.patch(\u0027time.time\u0027, patch_time):"},{"line_number":2071,"context_line":"            resp \u003d app(req.environ, start_response)"},{"line_number":2072,"context_line":"            # exhaust generator"},{"line_number":2073,"context_line":"            [x for x in resp]"},{"line_number":2074,"context_line":"        log_parts \u003d self._log_parts(app)"},{"line_number":2075,"context_line":"        self.assertEqual(log_parts[11], str(len(\u0027FAKE APP\u0027)))"},{"line_number":2076,"context_line":"        self.assertEqual(log_parts[10], str(buffer_len))"}],"source_content_type":"text/x-python","patch_set":44,"id":"432dc6ff_1aa57e73","line":2073,"in_reply_to":"6d1c9454_aba56570","updated":"2025-06-26 16:13:49.000000000","message":"Done","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":2073,"context_line":"            [x for x in resp]"},{"line_number":2074,"context_line":"        log_parts \u003d self._log_parts(app)"},{"line_number":2075,"context_line":"        self.assertEqual(log_parts[11], str(len(\u0027FAKE APP\u0027)))"},{"line_number":2076,"context_line":"        self.assertEqual(log_parts[10], str(buffer_len))"},{"line_number":2077,"context_line":"        self.assertUpdateStats(["},{"line_number":2078,"context_line":"            (\u0027container.POST.200.xfer\u0027,"},{"line_number":2079,"context_line":"             buffer_len + len(\u0027FAKE APP\u0027)),"}],"source_content_type":"text/x-python","patch_set":44,"id":"7e9ebafc_cbf8c24a","line":2076,"updated":"2025-06-05 11:46:42.000000000","message":"right! see line 2019 - much better to use str(buffer_len) here so the reader knows what the value in log_parts[10] is!\n\nAlso, this limited assertion of the log line parts does make sense as a cross-check since these are the byte count values","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"4b8b2a8d5dc5960c69f5cfbdcd2e05b666c34558","unresolved":false,"context_lines":[{"line_number":2073,"context_line":"            [x for x in resp]"},{"line_number":2074,"context_line":"        log_parts \u003d self._log_parts(app)"},{"line_number":2075,"context_line":"        self.assertEqual(log_parts[11], str(len(\u0027FAKE APP\u0027)))"},{"line_number":2076,"context_line":"        self.assertEqual(log_parts[10], str(buffer_len))"},{"line_number":2077,"context_line":"        self.assertUpdateStats(["},{"line_number":2078,"context_line":"            (\u0027container.POST.200.xfer\u0027,"},{"line_number":2079,"context_line":"             buffer_len + len(\u0027FAKE APP\u0027)),"}],"source_content_type":"text/x-python","patch_set":44,"id":"2ae58c8b_0304023f","line":2076,"in_reply_to":"7e9ebafc_cbf8c24a","updated":"2025-06-27 15:25:37.000000000","message":"Done","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":2089,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":2090,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":2091,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"},{"line_number":2092,"context_line":"                \u0027resource\u0027: \u0027container\u0027}),"},{"line_number":2093,"context_line":"            (\u0027swift_proxy_server_request_body_streaming_bytes\u0027, 25, {"},{"line_number":2094,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":2095,"context_line":"                \u0027container\u0027: \u0027c\u0027,"}],"source_content_type":"text/x-python","patch_set":44,"id":"fd97ddce_d641d06e","line":2092,"updated":"2025-06-05 11:46:42.000000000","message":"ok, so FakeApp reads 5 bytes at a time, and the first read will emit a stat because ``BufferXferEmitCallback.next_emit_time`` is initialised as zero (rather than ``time.time()``, hmmm?)","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"7f899aa6a4f29b755488e43b203299b0920057c4","unresolved":false,"context_lines":[{"line_number":2089,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":2090,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":2091,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"},{"line_number":2092,"context_line":"                \u0027resource\u0027: \u0027container\u0027}),"},{"line_number":2093,"context_line":"            (\u0027swift_proxy_server_request_body_streaming_bytes\u0027, 25, {"},{"line_number":2094,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":2095,"context_line":"                \u0027container\u0027: \u0027c\u0027,"}],"source_content_type":"text/x-python","patch_set":44,"id":"9209fde3_6ebe1967","line":2092,"in_reply_to":"fd97ddce_d641d06e","updated":"2025-06-25 21:43:07.000000000","message":"Done","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":2094,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":2095,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":2096,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"},{"line_number":2097,"context_line":"                \u0027resource\u0027: \u0027container\u0027}),"},{"line_number":2098,"context_line":"            (\u0027swift_proxy_server_request_body_streaming_bytes\u0027, 20, {"},{"line_number":2099,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":2100,"context_line":"                \u0027container\u0027: \u0027c\u0027,"}],"source_content_type":"text/x-python","patch_set":44,"id":"1400bf71_7c1d2e3f","line":2097,"updated":"2025-06-05 11:46:42.000000000","message":"ok, and then there\u0027s another 5 reads before the next stat -\u003e 25 accumulated bytes","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9237818e7872731319b58e2ec2b6f7976543e67d","unresolved":false,"context_lines":[{"line_number":2094,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":2095,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":2096,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"},{"line_number":2097,"context_line":"                \u0027resource\u0027: \u0027container\u0027}),"},{"line_number":2098,"context_line":"            (\u0027swift_proxy_server_request_body_streaming_bytes\u0027, 20, {"},{"line_number":2099,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":2100,"context_line":"                \u0027container\u0027: \u0027c\u0027,"}],"source_content_type":"text/x-python","patch_set":44,"id":"5543c672_9ea80637","line":2097,"in_reply_to":"1400bf71_7c1d2e3f","updated":"2025-06-25 20:41:54.000000000","message":"Done","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":2124,"context_line":"            def __iter__(self):"},{"line_number":2125,"context_line":"                yield self.buffers[0]"},{"line_number":2126,"context_line":"                yield self.buffers[1]"},{"line_number":2127,"context_line":"                yield self.buffers[2]"},{"line_number":2128,"context_line":""},{"line_number":2129,"context_line":"        curr_time \u003d [100.000]"},{"line_number":2130,"context_line":""}],"source_content_type":"text/x-python","patch_set":44,"id":"c90e7742_0f5eebd1","line":2127,"updated":"2025-06-05 11:46:42.000000000","message":"see comment here https://review.opendev.org/c/openstack/swift/+/930918/comment/0df7ddde_7753678c/","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"8d850855ef6a8d8c3488d4b31a3fc82df66487f3","unresolved":false,"context_lines":[{"line_number":2124,"context_line":"            def __iter__(self):"},{"line_number":2125,"context_line":"                yield self.buffers[0]"},{"line_number":2126,"context_line":"                yield self.buffers[1]"},{"line_number":2127,"context_line":"                yield self.buffers[2]"},{"line_number":2128,"context_line":""},{"line_number":2129,"context_line":"        curr_time \u003d [100.000]"},{"line_number":2130,"context_line":""}],"source_content_type":"text/x-python","patch_set":44,"id":"27147410_29f5a2d9","line":2127,"in_reply_to":"c90e7742_0f5eebd1","updated":"2025-07-01 17:33:41.000000000","message":"Done","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":2130,"context_line":""},{"line_number":2131,"context_line":"        def patch_time():"},{"line_number":2132,"context_line":"            curr_time[0] +\u003d 0.001"},{"line_number":2133,"context_line":"            return curr_time[0]"},{"line_number":2134,"context_line":""},{"line_number":2135,"context_line":"        buffers \u003d [b\u0027some stuff\\n\u0027,"},{"line_number":2136,"context_line":"                   b\u0027some other stuff\\n\u0027,"}],"source_content_type":"text/x-python","patch_set":44,"id":"fd5ab2dd_16127f90","line":2133,"updated":"2025-06-05 11:46:42.000000000","message":"see comment at line 2050","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"c6325f932e7ffec038c4ebe1de235cbda134d44f","unresolved":false,"context_lines":[{"line_number":2130,"context_line":""},{"line_number":2131,"context_line":"        def patch_time():"},{"line_number":2132,"context_line":"            curr_time[0] +\u003d 0.001"},{"line_number":2133,"context_line":"            return curr_time[0]"},{"line_number":2134,"context_line":""},{"line_number":2135,"context_line":"        buffers \u003d [b\u0027some stuff\\n\u0027,"},{"line_number":2136,"context_line":"                   b\u0027some other stuff\\n\u0027,"}],"source_content_type":"text/x-python","patch_set":44,"id":"592bee5f_8e069772","line":2133,"in_reply_to":"fd5ab2dd_16127f90","updated":"2025-06-26 16:13:49.000000000","message":"Done","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"7f899aa6a4f29b755488e43b203299b0920057c4","unresolved":false,"context_lines":[{"line_number":2130,"context_line":""},{"line_number":2131,"context_line":"        def patch_time():"},{"line_number":2132,"context_line":"            curr_time[0] +\u003d 0.001"},{"line_number":2133,"context_line":"            return curr_time[0]"},{"line_number":2134,"context_line":""},{"line_number":2135,"context_line":"        buffers \u003d [b\u0027some stuff\\n\u0027,"},{"line_number":2136,"context_line":"                   b\u0027some other stuff\\n\u0027,"}],"source_content_type":"text/x-python","patch_set":44,"id":"daf9d6f9_aeb7e7b0","line":2133,"in_reply_to":"fd5ab2dd_16127f90","updated":"2025-06-25 21:43:07.000000000","message":"Done","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":2135,"context_line":"        buffers \u003d [b\u0027some stuff\\n\u0027,"},{"line_number":2136,"context_line":"                   b\u0027some other stuff\\n\u0027,"},{"line_number":2137,"context_line":"                   b\u0027some additional stuff\\n\u0027]"},{"line_number":2138,"context_line":"        buffer_len \u003d len(buffers[0]) + len(buffers[1]) + len(buffers[2])"},{"line_number":2139,"context_line":"        conf \u003d {"},{"line_number":2140,"context_line":"            \u0027log_headers\u0027: \u0027yes\u0027,"},{"line_number":2141,"context_line":"            \u0027statsd_label_mode\u0027: \u0027dogstatsd\u0027,"}],"source_content_type":"text/x-python","patch_set":44,"id":"e0e2e8b6_48b1a340","line":2138,"updated":"2025-06-05 11:46:42.000000000","message":"use sum - see earlier comment","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"c6325f932e7ffec038c4ebe1de235cbda134d44f","unresolved":false,"context_lines":[{"line_number":2135,"context_line":"        buffers \u003d [b\u0027some stuff\\n\u0027,"},{"line_number":2136,"context_line":"                   b\u0027some other stuff\\n\u0027,"},{"line_number":2137,"context_line":"                   b\u0027some additional stuff\\n\u0027]"},{"line_number":2138,"context_line":"        buffer_len \u003d len(buffers[0]) + len(buffers[1]) + len(buffers[2])"},{"line_number":2139,"context_line":"        conf \u003d {"},{"line_number":2140,"context_line":"            \u0027log_headers\u0027: \u0027yes\u0027,"},{"line_number":2141,"context_line":"            \u0027statsd_label_mode\u0027: \u0027dogstatsd\u0027,"}],"source_content_type":"text/x-python","patch_set":44,"id":"b0af4a10_abfb7e92","line":2138,"in_reply_to":"e0e2e8b6_48b1a340","updated":"2025-06-26 16:13:49.000000000","message":"Done","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"7f899aa6a4f29b755488e43b203299b0920057c4","unresolved":false,"context_lines":[{"line_number":2135,"context_line":"        buffers \u003d [b\u0027some stuff\\n\u0027,"},{"line_number":2136,"context_line":"                   b\u0027some other stuff\\n\u0027,"},{"line_number":2137,"context_line":"                   b\u0027some additional stuff\\n\u0027]"},{"line_number":2138,"context_line":"        buffer_len \u003d len(buffers[0]) + len(buffers[1]) + len(buffers[2])"},{"line_number":2139,"context_line":"        conf \u003d {"},{"line_number":2140,"context_line":"            \u0027log_headers\u0027: \u0027yes\u0027,"},{"line_number":2141,"context_line":"            \u0027statsd_label_mode\u0027: \u0027dogstatsd\u0027,"}],"source_content_type":"text/x-python","patch_set":44,"id":"fe719d0d_6a5d4993","line":2138,"in_reply_to":"e0e2e8b6_48b1a340","updated":"2025-06-25 21:43:07.000000000","message":"Done","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":2141,"context_line":"            \u0027statsd_label_mode\u0027: \u0027dogstatsd\u0027,"},{"line_number":2142,"context_line":"            \u0027statsd_emit_buffer_xfer_bytes_ms\u0027: 5,"},{"line_number":2143,"context_line":"        }"},{"line_number":2144,"context_line":"        self.statsd \u003d debug_labeled_statsd_client(conf)"},{"line_number":2145,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":2146,"context_line":"            FakeApp("},{"line_number":2147,"context_line":"                body\u003dBodyGen(buffers),"}],"source_content_type":"text/x-python","patch_set":44,"id":"f183f903_2fa38cb9","line":2144,"updated":"2025-06-05 11:46:42.000000000","message":"done in setUp()","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"24c5d44d6b8c78a50f40cc5981234abb91f0d136","unresolved":false,"context_lines":[{"line_number":2141,"context_line":"            \u0027statsd_label_mode\u0027: \u0027dogstatsd\u0027,"},{"line_number":2142,"context_line":"            \u0027statsd_emit_buffer_xfer_bytes_ms\u0027: 5,"},{"line_number":2143,"context_line":"        }"},{"line_number":2144,"context_line":"        self.statsd \u003d debug_labeled_statsd_client(conf)"},{"line_number":2145,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":2146,"context_line":"            FakeApp("},{"line_number":2147,"context_line":"                body\u003dBodyGen(buffers),"}],"source_content_type":"text/x-python","patch_set":44,"id":"acd9d3b9_771940b5","line":2144,"in_reply_to":"f183f903_2fa38cb9","updated":"2025-06-12 20:05:52.000000000","message":"Done","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":2183,"context_line":"                \u0027policy\u0027: \u00270\u0027,"},{"line_number":2184,"context_line":"                \u0027resource\u0027: \u0027container\u0027,"},{"line_number":2185,"context_line":"                \u0027status\u0027: 200}),"},{"line_number":2186,"context_line":"        ])"},{"line_number":2187,"context_line":""},{"line_number":2188,"context_line":"    def test_xfer_stats_put_s3api(self):"},{"line_number":2189,"context_line":"        class PathRewritingApp(object):"}],"source_content_type":"text/x-python","patch_set":44,"id":"72b1f498_f1390961","line":2186,"updated":"2025-06-05 11:46:42.000000000","message":"let\u0027s list the stats in the expected order and not rely on the assertLabeledUpdateStats sorting them","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9237818e7872731319b58e2ec2b6f7976543e67d","unresolved":false,"context_lines":[{"line_number":2183,"context_line":"                \u0027policy\u0027: \u00270\u0027,"},{"line_number":2184,"context_line":"                \u0027resource\u0027: \u0027container\u0027,"},{"line_number":2185,"context_line":"                \u0027status\u0027: 200}),"},{"line_number":2186,"context_line":"        ])"},{"line_number":2187,"context_line":""},{"line_number":2188,"context_line":"    def test_xfer_stats_put_s3api(self):"},{"line_number":2189,"context_line":"        class PathRewritingApp(object):"}],"source_content_type":"text/x-python","patch_set":44,"id":"a7f88121_7c1cd85c","line":2186,"in_reply_to":"72b1f498_f1390961","updated":"2025-06-25 20:41:54.000000000","message":"Done","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":2208,"context_line":"            \u0027statsd_label_mode\u0027: \u0027dogstatsd\u0027,"},{"line_number":2209,"context_line":"            \u0027statsd_emit_buffer_xfer_bytes_ms\u0027: 0,"},{"line_number":2210,"context_line":"        }"},{"line_number":2211,"context_line":"        self.statsd \u003d debug_labeled_statsd_client(conf)"},{"line_number":2212,"context_line":"        buffer_str \u003d b\u0027some stuff\\n\u0027 + \\"},{"line_number":2213,"context_line":"                     b\u0027some other stuff\\n\u0027 + \\"},{"line_number":2214,"context_line":"                     b\u0027some additional stuff\\n\u0027"}],"source_content_type":"text/x-python","patch_set":44,"id":"d61bef31_acd32539","line":2211,"updated":"2025-06-05 11:46:42.000000000","message":"done in setUp()","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"24c5d44d6b8c78a50f40cc5981234abb91f0d136","unresolved":false,"context_lines":[{"line_number":2208,"context_line":"            \u0027statsd_label_mode\u0027: \u0027dogstatsd\u0027,"},{"line_number":2209,"context_line":"            \u0027statsd_emit_buffer_xfer_bytes_ms\u0027: 0,"},{"line_number":2210,"context_line":"        }"},{"line_number":2211,"context_line":"        self.statsd \u003d debug_labeled_statsd_client(conf)"},{"line_number":2212,"context_line":"        buffer_str \u003d b\u0027some stuff\\n\u0027 + \\"},{"line_number":2213,"context_line":"                     b\u0027some other stuff\\n\u0027 + \\"},{"line_number":2214,"context_line":"                     b\u0027some additional stuff\\n\u0027"}],"source_content_type":"text/x-python","patch_set":44,"id":"a98b3007_05554d6f","line":2211,"in_reply_to":"d61bef31_acd32539","updated":"2025-06-12 20:05:52.000000000","message":"Done","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":2250,"context_line":""},{"line_number":2251,"context_line":"        conf.update({"},{"line_number":2252,"context_line":"            \u0027access_log_route\u0027: \u0027proxy-access\u0027,"},{"line_number":2253,"context_line":"        })"},{"line_number":2254,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":2255,"context_line":"            app, conf, logger\u003dself.logger)"},{"line_number":2256,"context_line":"        app.logger \u003d self.logger"}],"source_content_type":"text/x-python","patch_set":44,"id":"3ed3dd33_d2601806","line":2253,"updated":"2025-06-05 11:46:42.000000000","message":"why? doesn\u0027t seem necessary","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"a45685bda3d2ab61fda1f43318276b1ad26ac3d5","unresolved":false,"context_lines":[{"line_number":2250,"context_line":""},{"line_number":2251,"context_line":"        conf.update({"},{"line_number":2252,"context_line":"            \u0027access_log_route\u0027: \u0027proxy-access\u0027,"},{"line_number":2253,"context_line":"        })"},{"line_number":2254,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":2255,"context_line":"            app, conf, logger\u003dself.logger)"},{"line_number":2256,"context_line":"        app.logger \u003d self.logger"}],"source_content_type":"text/x-python","patch_set":44,"id":"e061bcf7_8880e7a8","line":2253,"in_reply_to":"3ed3dd33_d2601806","updated":"2025-06-25 22:20:53.000000000","message":"Acknowledged","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"c6325f932e7ffec038c4ebe1de235cbda134d44f","unresolved":false,"context_lines":[{"line_number":2250,"context_line":""},{"line_number":2251,"context_line":"        conf.update({"},{"line_number":2252,"context_line":"            \u0027access_log_route\u0027: \u0027proxy-access\u0027,"},{"line_number":2253,"context_line":"        })"},{"line_number":2254,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":2255,"context_line":"            app, conf, logger\u003dself.logger)"},{"line_number":2256,"context_line":"        app.logger \u003d self.logger"}],"source_content_type":"text/x-python","patch_set":44,"id":"6f0f6ee9_269a7db0","line":2253,"in_reply_to":"3ed3dd33_d2601806","updated":"2025-06-26 16:13:49.000000000","message":"Done","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":2253,"context_line":"        })"},{"line_number":2254,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":2255,"context_line":"            app, conf, logger\u003dself.logger)"},{"line_number":2256,"context_line":"        app.logger \u003d self.logger"},{"line_number":2257,"context_line":"        app.statsd \u003d self.statsd"},{"line_number":2258,"context_line":"        status, headers, body \u003d self._do_test_call_app(req, app)"},{"line_number":2259,"context_line":""}],"source_content_type":"text/x-python","patch_set":44,"id":"ba44491d_04c033aa","line":2256,"range":{"start_line":2256,"start_character":8,"end_line":2256,"end_character":32},"updated":"2025-06-05 11:46:42.000000000","message":"not needed - self.logger was passed as an arg on the line above","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9237818e7872731319b58e2ec2b6f7976543e67d","unresolved":false,"context_lines":[{"line_number":2253,"context_line":"        })"},{"line_number":2254,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":2255,"context_line":"            app, conf, logger\u003dself.logger)"},{"line_number":2256,"context_line":"        app.logger \u003d self.logger"},{"line_number":2257,"context_line":"        app.statsd \u003d self.statsd"},{"line_number":2258,"context_line":"        status, headers, body \u003d self._do_test_call_app(req, app)"},{"line_number":2259,"context_line":""}],"source_content_type":"text/x-python","patch_set":44,"id":"df9ef47f_1f247a61","line":2256,"range":{"start_line":2256,"start_character":8,"end_line":2256,"end_character":32},"in_reply_to":"ba44491d_04c033aa","updated":"2025-06-25 20:41:54.000000000","message":"Done","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":2261,"context_line":""},{"line_number":2262,"context_line":"        self.assertEqual(\u0027/v1/AUTH_test/bucket/object\u0027,"},{"line_number":2263,"context_line":"                         req.environ[\u0027swift.backend_path\u0027])"},{"line_number":2264,"context_line":"        base_labels \u003d req.environ.get(\u0027swift.base_labels\u0027, None)"},{"line_number":2265,"context_line":"        self.assertTrue(base_labels is not None)"},{"line_number":2266,"context_line":""},{"line_number":2267,"context_line":"        self.assertEqual(swift.calls, ["}],"source_content_type":"text/x-python","patch_set":44,"id":"b71278aa_9874c817","line":2264,"range":{"start_line":2264,"start_character":57,"end_line":2264,"end_character":63},"updated":"2025-06-05 11:46:42.000000000","message":"dict.get() always defaults to None","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9237818e7872731319b58e2ec2b6f7976543e67d","unresolved":false,"context_lines":[{"line_number":2261,"context_line":""},{"line_number":2262,"context_line":"        self.assertEqual(\u0027/v1/AUTH_test/bucket/object\u0027,"},{"line_number":2263,"context_line":"                         req.environ[\u0027swift.backend_path\u0027])"},{"line_number":2264,"context_line":"        base_labels \u003d req.environ.get(\u0027swift.base_labels\u0027, None)"},{"line_number":2265,"context_line":"        self.assertTrue(base_labels is not None)"},{"line_number":2266,"context_line":""},{"line_number":2267,"context_line":"        self.assertEqual(swift.calls, ["}],"source_content_type":"text/x-python","patch_set":44,"id":"0dd571d9_8c5083be","line":2264,"range":{"start_line":2264,"start_character":57,"end_line":2264,"end_character":63},"in_reply_to":"b71278aa_9874c817","updated":"2025-06-25 20:41:54.000000000","message":"Acknowledged","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":2262,"context_line":"        self.assertEqual(\u0027/v1/AUTH_test/bucket/object\u0027,"},{"line_number":2263,"context_line":"                         req.environ[\u0027swift.backend_path\u0027])"},{"line_number":2264,"context_line":"        base_labels \u003d req.environ.get(\u0027swift.base_labels\u0027, None)"},{"line_number":2265,"context_line":"        self.assertTrue(base_labels is not None)"},{"line_number":2266,"context_line":""},{"line_number":2267,"context_line":"        self.assertEqual(swift.calls, ["},{"line_number":2268,"context_line":"            (\u0027PUT\u0027, \u0027/v1/AUTH_test/bucket+segments/object\u0027),"}],"source_content_type":"text/x-python","patch_set":44,"id":"85db3299_b9e6837b","line":2265,"range":{"start_line":2265,"start_character":8,"end_line":2265,"end_character":23},"updated":"2025-06-05 11:46:42.000000000","message":"use self.assertIsNotNone ... but better, use self.Equals and assert the expected value of base_labels like line 2393","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"4b8b2a8d5dc5960c69f5cfbdcd2e05b666c34558","unresolved":false,"context_lines":[{"line_number":2262,"context_line":"        self.assertEqual(\u0027/v1/AUTH_test/bucket/object\u0027,"},{"line_number":2263,"context_line":"                         req.environ[\u0027swift.backend_path\u0027])"},{"line_number":2264,"context_line":"        base_labels \u003d req.environ.get(\u0027swift.base_labels\u0027, None)"},{"line_number":2265,"context_line":"        self.assertTrue(base_labels is not None)"},{"line_number":2266,"context_line":""},{"line_number":2267,"context_line":"        self.assertEqual(swift.calls, ["},{"line_number":2268,"context_line":"            (\u0027PUT\u0027, \u0027/v1/AUTH_test/bucket+segments/object\u0027),"}],"source_content_type":"text/x-python","patch_set":44,"id":"ea963290_5579fb35","line":2265,"range":{"start_line":2265,"start_character":8,"end_line":2265,"end_character":23},"in_reply_to":"85db3299_b9e6837b","updated":"2025-06-27 15:25:37.000000000","message":"Done","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":2311,"context_line":"        self.assertEqual(status.split()[0], \u0027200\u0027)"},{"line_number":2312,"context_line":""},{"line_number":2313,"context_line":"    def test_xfer_stats_get_s3api(self):"},{"line_number":2314,"context_line":"        class InputIterator(object):"},{"line_number":2315,"context_line":"            def __init__(self, buffers):"},{"line_number":2316,"context_line":"                self.cnt \u003d 0"},{"line_number":2317,"context_line":"                self.buffers \u003d buffers"}],"source_content_type":"text/x-python","patch_set":44,"id":"28d6c18d_61a45c07","line":2314,"updated":"2025-06-05 11:46:42.000000000","message":"this isn\u0027t used","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9237818e7872731319b58e2ec2b6f7976543e67d","unresolved":false,"context_lines":[{"line_number":2311,"context_line":"        self.assertEqual(status.split()[0], \u0027200\u0027)"},{"line_number":2312,"context_line":""},{"line_number":2313,"context_line":"    def test_xfer_stats_get_s3api(self):"},{"line_number":2314,"context_line":"        class InputIterator(object):"},{"line_number":2315,"context_line":"            def __init__(self, buffers):"},{"line_number":2316,"context_line":"                self.cnt \u003d 0"},{"line_number":2317,"context_line":"                self.buffers \u003d buffers"}],"source_content_type":"text/x-python","patch_set":44,"id":"15489f7d_4a81a125","line":2314,"in_reply_to":"28d6c18d_61a45c07","updated":"2025-06-25 20:41:54.000000000","message":"Acknowledged","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":2327,"context_line":""},{"line_number":2328,"context_line":"            next \u003d __next__"},{"line_number":2329,"context_line":""},{"line_number":2330,"context_line":"        class BodyGen(object):"},{"line_number":2331,"context_line":"            def __init__(self, buffers):"},{"line_number":2332,"context_line":"                self.buffers \u003d buffers"},{"line_number":2333,"context_line":""}],"source_content_type":"text/x-python","patch_set":44,"id":"da7ae520_fdea676a","line":2330,"updated":"2025-06-05 11:46:42.000000000","message":"not necessary - see earlier comment","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9237818e7872731319b58e2ec2b6f7976543e67d","unresolved":false,"context_lines":[{"line_number":2327,"context_line":""},{"line_number":2328,"context_line":"            next \u003d __next__"},{"line_number":2329,"context_line":""},{"line_number":2330,"context_line":"        class BodyGen(object):"},{"line_number":2331,"context_line":"            def __init__(self, buffers):"},{"line_number":2332,"context_line":"                self.buffers \u003d buffers"},{"line_number":2333,"context_line":""}],"source_content_type":"text/x-python","patch_set":44,"id":"fb16dec7_91151680","line":2330,"in_reply_to":"da7ae520_fdea676a","updated":"2025-06-25 20:41:54.000000000","message":"Acknowledged","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":2350,"context_line":"        buffer_str \u003d b\u0027some stuff\\n\u0027 + \\"},{"line_number":2351,"context_line":"                     b\u0027some other stuff\\n\u0027 + \\"},{"line_number":2352,"context_line":"                     b\u0027some additional stuff\\n\u0027"},{"line_number":2353,"context_line":"        buffer_len \u003d len(buffer_str)"},{"line_number":2354,"context_line":""},{"line_number":2355,"context_line":"        swift \u003d FakeSwift()"},{"line_number":2356,"context_line":"        last_modified \u003d \u0027Fri, 01 Apr 2014 12:00:00 GMT\u0027"}],"source_content_type":"text/x-python","patch_set":44,"id":"1fa232ef_7442bec4","line":2353,"updated":"2025-06-05 11:46:42.000000000","message":"what\u0027s going on with buffers vs buffer_str - looks like buffers is what is used to serve bytes to the GET request, but buffer_str is used to calc the len??? I guess buffer_str is not necessary?","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"5a6a291f5a616b4ba8f14fea825d14cf68656b81","unresolved":false,"context_lines":[{"line_number":2350,"context_line":"        buffer_str \u003d b\u0027some stuff\\n\u0027 + \\"},{"line_number":2351,"context_line":"                     b\u0027some other stuff\\n\u0027 + \\"},{"line_number":2352,"context_line":"                     b\u0027some additional stuff\\n\u0027"},{"line_number":2353,"context_line":"        buffer_len \u003d len(buffer_str)"},{"line_number":2354,"context_line":""},{"line_number":2355,"context_line":"        swift \u003d FakeSwift()"},{"line_number":2356,"context_line":"        last_modified \u003d \u0027Fri, 01 Apr 2014 12:00:00 GMT\u0027"}],"source_content_type":"text/x-python","patch_set":44,"id":"8e164690_9c0014fe","line":2353,"in_reply_to":"1fa232ef_7442bec4","updated":"2025-07-09 16:30:59.000000000","message":"Agree","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":2370,"context_line":"        })"},{"line_number":2371,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":2372,"context_line":"            app, conf, logger\u003dself.logger)"},{"line_number":2373,"context_line":"        app.logger \u003d self.logger"},{"line_number":2374,"context_line":"        app.statsd \u003d self.statsd"},{"line_number":2375,"context_line":""},{"line_number":2376,"context_line":"        swift.register(\u0027GET\u0027, \u0027/v1/AUTH_test/bucket/object\u0027,"}],"source_content_type":"text/x-python","patch_set":44,"id":"4b238f9c_a8bb8b06","line":2373,"updated":"2025-06-05 11:46:42.000000000","message":"not necessary","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9237818e7872731319b58e2ec2b6f7976543e67d","unresolved":false,"context_lines":[{"line_number":2370,"context_line":"        })"},{"line_number":2371,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":2372,"context_line":"            app, conf, logger\u003dself.logger)"},{"line_number":2373,"context_line":"        app.logger \u003d self.logger"},{"line_number":2374,"context_line":"        app.statsd \u003d self.statsd"},{"line_number":2375,"context_line":""},{"line_number":2376,"context_line":"        swift.register(\u0027GET\u0027, \u0027/v1/AUTH_test/bucket/object\u0027,"}],"source_content_type":"text/x-python","patch_set":44,"id":"0b9b80a7_e31674df","line":2373,"in_reply_to":"4b238f9c_a8bb8b06","updated":"2025-06-25 20:41:54.000000000","message":"Acknowledged","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0365e0865edf899fcf27d47143e0f9b0d59ec422","unresolved":true,"context_lines":[{"line_number":2389,"context_line":"        self.assertEqual(\u0027/v1/AUTH_test/bucket/object\u0027,"},{"line_number":2390,"context_line":"                         req.environ[\u0027swift.backend_path\u0027])"},{"line_number":2391,"context_line":"        base_labels \u003d req.environ.get(\u0027swift.base_labels\u0027, None)"},{"line_number":2392,"context_line":"        self.assertTrue(base_labels is not None)"},{"line_number":2393,"context_line":"        self.assertEqual(base_labels, {"},{"line_number":2394,"context_line":"            \u0027resource\u0027: \u0027object\u0027,"},{"line_number":2395,"context_line":"            \u0027method\u0027: \u0027GET\u0027,"}],"source_content_type":"text/x-python","patch_set":44,"id":"bd462288_d21cf7bd","line":2392,"updated":"2025-06-05 11:46:42.000000000","message":"not necessary given that the next line makes a more specific assertion","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"a45685bda3d2ab61fda1f43318276b1ad26ac3d5","unresolved":false,"context_lines":[{"line_number":2389,"context_line":"        self.assertEqual(\u0027/v1/AUTH_test/bucket/object\u0027,"},{"line_number":2390,"context_line":"                         req.environ[\u0027swift.backend_path\u0027])"},{"line_number":2391,"context_line":"        base_labels \u003d req.environ.get(\u0027swift.base_labels\u0027, None)"},{"line_number":2392,"context_line":"        self.assertTrue(base_labels is not None)"},{"line_number":2393,"context_line":"        self.assertEqual(base_labels, {"},{"line_number":2394,"context_line":"            \u0027resource\u0027: \u0027object\u0027,"},{"line_number":2395,"context_line":"            \u0027method\u0027: \u0027GET\u0027,"}],"source_content_type":"text/x-python","patch_set":44,"id":"71064756_55c95a6b","line":2392,"in_reply_to":"bd462288_d21cf7bd","updated":"2025-06-25 22:20:53.000000000","message":"Acknowledged","commit_id":"51d715ab0656cf64b2283618fbc7624195e285d8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1432c12767bfa249bb2d1d29e769cd306b817b23","unresolved":true,"context_lines":[{"line_number":542,"context_line":"            statsd.increment(\u0027baz\u0027, labels\u003d{\u0027label_foo\u0027: \u0027foo\u0027})"},{"line_number":543,"context_line":"        self.assertEqual("},{"line_number":544,"context_line":"            [(b\u0027baz:1|c|#label_foo:foo,user_reqctx:subrequest\u0027,"},{"line_number":545,"context_line":"              (\u0027example.com\u0027, 1234))],"},{"line_number":546,"context_line":"            statsd.sendto_calls)"},{"line_number":547,"context_line":""},{"line_number":548,"context_line":"    def test_logger_statsd_prefix(self):"}],"source_content_type":"text/x-python","patch_set":57,"id":"33bdf3ca_88e35400","line":545,"updated":"2025-07-17 14:31:02.000000000","message":"please revert all unnecessary formatting changes","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9c175fca54bd4eec0f0d2e996f5cb2bb4fce3870","unresolved":false,"context_lines":[{"line_number":542,"context_line":"            statsd.increment(\u0027baz\u0027, labels\u003d{\u0027label_foo\u0027: \u0027foo\u0027})"},{"line_number":543,"context_line":"        self.assertEqual("},{"line_number":544,"context_line":"            [(b\u0027baz:1|c|#label_foo:foo,user_reqctx:subrequest\u0027,"},{"line_number":545,"context_line":"              (\u0027example.com\u0027, 1234))],"},{"line_number":546,"context_line":"            statsd.sendto_calls)"},{"line_number":547,"context_line":""},{"line_number":548,"context_line":"    def test_logger_statsd_prefix(self):"}],"source_content_type":"text/x-python","patch_set":57,"id":"95b61540_02749f98","line":545,"in_reply_to":"33bdf3ca_88e35400","updated":"2025-07-21 21:19:09.000000000","message":"Acknowledged","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1432c12767bfa249bb2d1d29e769cd306b817b23","unresolved":true,"context_lines":[{"line_number":1219,"context_line":"            # This would actually get set in the app, but w/e"},{"line_number":1220,"context_line":"            \u0027swift.backend_path\u0027: \u0027/v1/AUTH_test/bucket/path/to/key\u0027})"},{"line_number":1221,"context_line":"        with mock.patch(\"time.time\","},{"line_number":1222,"context_line":"                        side_effect\u003d[18.0, 18.5, 20.71828182846]):"},{"line_number":1223,"context_line":"            resp \u003d app(req.environ, start_response)"},{"line_number":1224,"context_line":"            # exhaust generator"},{"line_number":1225,"context_line":"            resp_body \u003d b\u0027\u0027.join(resp)"}],"source_content_type":"text/x-python","patch_set":57,"id":"e7220fcc_650886b3","line":1222,"updated":"2025-07-17 14:31:02.000000000","message":"these unnecessary and unrelated changes keep creeping in - please review your patch to avoid these","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9c175fca54bd4eec0f0d2e996f5cb2bb4fce3870","unresolved":false,"context_lines":[{"line_number":1219,"context_line":"            # This would actually get set in the app, but w/e"},{"line_number":1220,"context_line":"            \u0027swift.backend_path\u0027: \u0027/v1/AUTH_test/bucket/path/to/key\u0027})"},{"line_number":1221,"context_line":"        with mock.patch(\"time.time\","},{"line_number":1222,"context_line":"                        side_effect\u003d[18.0, 18.5, 20.71828182846]):"},{"line_number":1223,"context_line":"            resp \u003d app(req.environ, start_response)"},{"line_number":1224,"context_line":"            # exhaust generator"},{"line_number":1225,"context_line":"            resp_body \u003d b\u0027\u0027.join(resp)"}],"source_content_type":"text/x-python","patch_set":57,"id":"fcb33faf_731135ca","line":1222,"in_reply_to":"e7220fcc_650886b3","updated":"2025-07-21 21:19:09.000000000","message":"Acknowledged","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1432c12767bfa249bb2d1d29e769cd306b817b23","unresolved":true,"context_lines":[{"line_number":1897,"context_line":"        body \u003d b\u0027\u0027.join(body_iter)"},{"line_number":1898,"context_line":"        return status, headers, body"},{"line_number":1899,"context_line":""},{"line_number":1900,"context_line":"    def test_xfer_stats_post(self):"},{"line_number":1901,"context_line":"        buffer_str \u003d b\u0027some stuff\\n\u0027 + \\"},{"line_number":1902,"context_line":"                     b\u0027some other stuff\\n\u0027 + \\"},{"line_number":1903,"context_line":"                     b\u0027some additional stuff\\n\u0027"}],"source_content_type":"text/x-python","patch_set":57,"id":"b49f4369_87e9e23e","line":1900,"range":{"start_line":1900,"start_character":24,"end_line":1900,"end_character":28},"updated":"2025-07-17 14:31:02.000000000","message":"we don\u0027t tend to have POST requests with body content to the swift API, test would be more representative as a PUT","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9c175fca54bd4eec0f0d2e996f5cb2bb4fce3870","unresolved":false,"context_lines":[{"line_number":1897,"context_line":"        body \u003d b\u0027\u0027.join(body_iter)"},{"line_number":1898,"context_line":"        return status, headers, body"},{"line_number":1899,"context_line":""},{"line_number":1900,"context_line":"    def test_xfer_stats_post(self):"},{"line_number":1901,"context_line":"        buffer_str \u003d b\u0027some stuff\\n\u0027 + \\"},{"line_number":1902,"context_line":"                     b\u0027some other stuff\\n\u0027 + \\"},{"line_number":1903,"context_line":"                     b\u0027some additional stuff\\n\u0027"}],"source_content_type":"text/x-python","patch_set":57,"id":"baff2f74_18ef921e","line":1900,"range":{"start_line":1900,"start_character":24,"end_line":1900,"end_character":28},"in_reply_to":"b49f4369_87e9e23e","updated":"2025-07-21 21:19:09.000000000","message":"Acknowledged","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1432c12767bfa249bb2d1d29e769cd306b817b23","unresolved":true,"context_lines":[{"line_number":1900,"context_line":"    def test_xfer_stats_post(self):"},{"line_number":1901,"context_line":"        buffer_str \u003d b\u0027some stuff\\n\u0027 + \\"},{"line_number":1902,"context_line":"                     b\u0027some other stuff\\n\u0027 + \\"},{"line_number":1903,"context_line":"                     b\u0027some additional stuff\\n\u0027"},{"line_number":1904,"context_line":"        buffer_len \u003d len(buffer_str)"},{"line_number":1905,"context_line":"        read_calls \u003d 0"},{"line_number":1906,"context_line":"        read_bytes \u003d 0"}],"source_content_type":"text/x-python","patch_set":57,"id":"dfc70eca_3a0de933","line":1903,"updated":"2025-07-17 14:31:02.000000000","message":"this buffer_str is very conveniently sized so that the final (zero byte) read will occur at the exact time that a stat should be emitted.\n\nLet\u0027s change it so that is not the case:\n\n```\nbuffer_str \u003d b\u0027some stuff\\n\u0027 + \\\n             b\u0027some other stuff\\n\u0027 + \\\n             b\u0027some extra stuff\\n\u0027\n```\n\nand we\u0027ll find that one of the expected stats goes missing 😞","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9c175fca54bd4eec0f0d2e996f5cb2bb4fce3870","unresolved":false,"context_lines":[{"line_number":1900,"context_line":"    def test_xfer_stats_post(self):"},{"line_number":1901,"context_line":"        buffer_str \u003d b\u0027some stuff\\n\u0027 + \\"},{"line_number":1902,"context_line":"                     b\u0027some other stuff\\n\u0027 + \\"},{"line_number":1903,"context_line":"                     b\u0027some additional stuff\\n\u0027"},{"line_number":1904,"context_line":"        buffer_len \u003d len(buffer_str)"},{"line_number":1905,"context_line":"        read_calls \u003d 0"},{"line_number":1906,"context_line":"        read_bytes \u003d 0"}],"source_content_type":"text/x-python","patch_set":57,"id":"7d4d7e83_7f8519a1","line":1903,"in_reply_to":"dfc70eca_3a0de933","updated":"2025-07-21 21:19:09.000000000","message":"Done","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1432c12767bfa249bb2d1d29e769cd306b817b23","unresolved":true,"context_lines":[{"line_number":1951,"context_line":"                \u0027status\u0027: 200,"},{"line_number":1952,"context_line":"                \u0027policy\u0027: \u00270\u0027,"},{"line_number":1953,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":1954,"context_line":"                \u0027container\u0027: \u0027c\u0027}),"},{"line_number":1955,"context_line":"            (\u0027swift_proxy_server_request_body_bytes\u0027, buffer_len, {"},{"line_number":1956,"context_line":"                \u0027resource\u0027: \u0027container\u0027,"},{"line_number":1957,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"}],"source_content_type":"text/x-python","patch_set":57,"id":"7f6e5b82_2bd909bf","line":1954,"updated":"2025-07-17 14:31:02.000000000","message":"It seems unnecessary to emit these stats with a value of 0 - can we put a condition in the stats emitter class to only emit a stat when there is anon-zero count to report?","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9c175fca54bd4eec0f0d2e996f5cb2bb4fce3870","unresolved":false,"context_lines":[{"line_number":1951,"context_line":"                \u0027status\u0027: 200,"},{"line_number":1952,"context_line":"                \u0027policy\u0027: \u00270\u0027,"},{"line_number":1953,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":1954,"context_line":"                \u0027container\u0027: \u0027c\u0027}),"},{"line_number":1955,"context_line":"            (\u0027swift_proxy_server_request_body_bytes\u0027, buffer_len, {"},{"line_number":1956,"context_line":"                \u0027resource\u0027: \u0027container\u0027,"},{"line_number":1957,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"}],"source_content_type":"text/x-python","patch_set":57,"id":"27ef6bc4_a17ab627","line":1954,"in_reply_to":"7f6e5b82_2bd909bf","updated":"2025-07-21 21:19:09.000000000","message":"Done","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1432c12767bfa249bb2d1d29e769cd306b817b23","unresolved":true,"context_lines":[{"line_number":1971,"context_line":"        expect_stats_per_iter.append(iter_stats)"},{"line_number":1972,"context_line":"        callback_stats_per_iter \u003d []"},{"line_number":1973,"context_line":""},{"line_number":1974,"context_line":"        def assert_read_stats(nbytes):"},{"line_number":1975,"context_line":"            statsd_calls \u003d self.statsd.calls[\u0027update_stats\u0027]"},{"line_number":1976,"context_line":"            update_stats_calls \u003d sorted(statsd_calls)"},{"line_number":1977,"context_line":"            got_metrics_values_and_kwargs \u003d []"}],"source_content_type":"text/x-python","patch_set":57,"id":"f62c94d6_5653e1ba","line":1974,"updated":"2025-07-17 14:31:02.000000000","message":"nit: this function doesn\u0027t assert anything, perhaps rename to ``capture_stats``","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9c175fca54bd4eec0f0d2e996f5cb2bb4fce3870","unresolved":false,"context_lines":[{"line_number":1971,"context_line":"        expect_stats_per_iter.append(iter_stats)"},{"line_number":1972,"context_line":"        callback_stats_per_iter \u003d []"},{"line_number":1973,"context_line":""},{"line_number":1974,"context_line":"        def assert_read_stats(nbytes):"},{"line_number":1975,"context_line":"            statsd_calls \u003d self.statsd.calls[\u0027update_stats\u0027]"},{"line_number":1976,"context_line":"            update_stats_calls \u003d sorted(statsd_calls)"},{"line_number":1977,"context_line":"            got_metrics_values_and_kwargs \u003d []"}],"source_content_type":"text/x-python","patch_set":57,"id":"c1d9bdfb_7316b1df","line":1974,"in_reply_to":"f62c94d6_5653e1ba","updated":"2025-07-21 21:19:09.000000000","message":"Acknowledged","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1432c12767bfa249bb2d1d29e769cd306b817b23","unresolved":true,"context_lines":[{"line_number":1979,"context_line":"                got_metrics_values_and_kwargs.append((got[0][0],"},{"line_number":1980,"context_line":"                                                      got[0][1], got[1]))"},{"line_number":1981,"context_line":""},{"line_number":1982,"context_line":"            callback_stats_per_iter.append(got_metrics_values_and_kwargs)"},{"line_number":1983,"context_line":"            nonlocal read_calls"},{"line_number":1984,"context_line":"            nonlocal read_bytes"},{"line_number":1985,"context_line":"            read_calls +\u003d 1"}],"source_content_type":"text/x-python","patch_set":57,"id":"c8c3c7c6_b49c52aa","line":1982,"range":{"start_line":1982,"start_character":12,"end_line":1982,"end_character":35},"updated":"2025-07-17 14:31:02.000000000","message":"this isn\u0027t used??","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9c175fca54bd4eec0f0d2e996f5cb2bb4fce3870","unresolved":false,"context_lines":[{"line_number":1979,"context_line":"                got_metrics_values_and_kwargs.append((got[0][0],"},{"line_number":1980,"context_line":"                                                      got[0][1], got[1]))"},{"line_number":1981,"context_line":""},{"line_number":1982,"context_line":"            callback_stats_per_iter.append(got_metrics_values_and_kwargs)"},{"line_number":1983,"context_line":"            nonlocal read_calls"},{"line_number":1984,"context_line":"            nonlocal read_bytes"},{"line_number":1985,"context_line":"            read_calls +\u003d 1"}],"source_content_type":"text/x-python","patch_set":57,"id":"932d5e2c_cee9cf32","line":1982,"range":{"start_line":1982,"start_character":12,"end_line":1982,"end_character":35},"in_reply_to":"c8c3c7c6_b49c52aa","updated":"2025-07-21 21:19:09.000000000","message":"Right! Removed!","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1432c12767bfa249bb2d1d29e769cd306b817b23","unresolved":true,"context_lines":[{"line_number":2001,"context_line":"        # exhaust generator"},{"line_number":2002,"context_line":"        self.assertEqual(b\u0027FAKE APP\u0027, b\u0027\u0027.join(resp))"},{"line_number":2003,"context_line":"        self.assertEqual(read_bytes, buffer_len)"},{"line_number":2004,"context_line":"        self.assertLabeledUpdateStats(expect_stats_per_iter[read_calls])"},{"line_number":2005,"context_line":"        self.assertUpdateStats(["},{"line_number":2006,"context_line":"            (\u0027container.POST.200.xfer\u0027,"},{"line_number":2007,"context_line":"             buffer_len + len(\u0027FAKE APP\u0027)),"}],"source_content_type":"text/x-python","patch_set":57,"id":"37505164_70da7cfc","line":2004,"updated":"2025-07-17 14:31:02.000000000","message":"why did we build up a complex data structure with expected stats at every read if we\u0027re only asserting against the last item? and without verifying the value of read_calls, do we even know we\u0027re asserting the last item?\n\nI don\u0027t understand why this test is so complex in its setup but then makes apparently weak assertions.","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"a39c0feabac6f56fb66a4ceb2f85c8ec54bd4753","unresolved":false,"context_lines":[{"line_number":2001,"context_line":"        # exhaust generator"},{"line_number":2002,"context_line":"        self.assertEqual(b\u0027FAKE APP\u0027, b\u0027\u0027.join(resp))"},{"line_number":2003,"context_line":"        self.assertEqual(read_bytes, buffer_len)"},{"line_number":2004,"context_line":"        self.assertLabeledUpdateStats(expect_stats_per_iter[read_calls])"},{"line_number":2005,"context_line":"        self.assertUpdateStats(["},{"line_number":2006,"context_line":"            (\u0027container.POST.200.xfer\u0027,"},{"line_number":2007,"context_line":"             buffer_len + len(\u0027FAKE APP\u0027)),"}],"source_content_type":"text/x-python","patch_set":57,"id":"e54ba80e_ebe3cd3f","line":2004,"in_reply_to":"37505164_70da7cfc","updated":"2025-07-22 21:26:46.000000000","message":"Verified read_calls with\nself.assertEqual(read_calls, len(callback_stats_per_iter))\n\nexpect_stats_per_iter[read_calls] would be the last one which would have combined stats of all previous iteration.","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1432c12767bfa249bb2d1d29e769cd306b817b23","unresolved":true,"context_lines":[{"line_number":2088,"context_line":""},{"line_number":2089,"context_line":"        ])"},{"line_number":2090,"context_line":""},{"line_number":2091,"context_line":"    def test_xfer_stats_emit_frequency_post(self):"},{"line_number":2092,"context_line":""},{"line_number":2093,"context_line":"        conf \u003d {"},{"line_number":2094,"context_line":"            \u0027statsd_label_mode\u0027: \u0027dogstatsd\u0027,"}],"source_content_type":"text/x-python","patch_set":57,"id":"2bc94413_8eb523c4","line":2091,"updated":"2025-07-17 14:31:02.000000000","message":"probably better to use a PUT as the example rather than a POST - POSTs don\u0027t typically have body content","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9c175fca54bd4eec0f0d2e996f5cb2bb4fce3870","unresolved":false,"context_lines":[{"line_number":2088,"context_line":""},{"line_number":2089,"context_line":"        ])"},{"line_number":2090,"context_line":""},{"line_number":2091,"context_line":"    def test_xfer_stats_emit_frequency_post(self):"},{"line_number":2092,"context_line":""},{"line_number":2093,"context_line":"        conf \u003d {"},{"line_number":2094,"context_line":"            \u0027statsd_label_mode\u0027: \u0027dogstatsd\u0027,"}],"source_content_type":"text/x-python","patch_set":57,"id":"f6c1b11d_b9f126a0","line":2091,"in_reply_to":"2bc94413_8eb523c4","updated":"2025-07-21 21:19:09.000000000","message":"Done","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1432c12767bfa249bb2d1d29e769cd306b817b23","unresolved":true,"context_lines":[{"line_number":2884,"context_line":""},{"line_number":2885,"context_line":"    def test_body_iter_updates_environ_proxy_logging_status(self):"},{"line_number":2886,"context_line":"        conf \u003d {\u0027log_msg_template\u0027: \u0027{method} {path}\u0027"},{"line_number":2887,"context_line":"                                    \u0027{status_int} {wire_status_int}\u0027}"},{"line_number":2888,"context_line":""},{"line_number":2889,"context_line":"        def do_test(req, body_iter, updated_status):"},{"line_number":2890,"context_line":"            fake_app \u003d FakeApp(body\u003dbody_iter,"}],"source_content_type":"text/x-python","patch_set":57,"id":"b497089d_bcf7ece0","line":2887,"updated":"2025-07-17 14:31:02.000000000","message":"this change wasn\u0027t necessary AND it broke the test (whitespace has gone missing)\n\nsame elsewhere","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"9c175fca54bd4eec0f0d2e996f5cb2bb4fce3870","unresolved":false,"context_lines":[{"line_number":2884,"context_line":""},{"line_number":2885,"context_line":"    def test_body_iter_updates_environ_proxy_logging_status(self):"},{"line_number":2886,"context_line":"        conf \u003d {\u0027log_msg_template\u0027: \u0027{method} {path}\u0027"},{"line_number":2887,"context_line":"                                    \u0027{status_int} {wire_status_int}\u0027}"},{"line_number":2888,"context_line":""},{"line_number":2889,"context_line":"        def do_test(req, body_iter, updated_status):"},{"line_number":2890,"context_line":"            fake_app \u003d FakeApp(body\u003dbody_iter,"}],"source_content_type":"text/x-python","patch_set":57,"id":"4cefa4e0_9f0d12d9","line":2887,"in_reply_to":"b497089d_bcf7ece0","updated":"2025-07-21 21:19:09.000000000","message":"Acknowledged","commit_id":"4646c1774c0d41974b0389d518c90922a62fe3d3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed52e6f601100413157c728b3379848ae27d2538","unresolved":true,"context_lines":[{"line_number":1723,"context_line":"                self.data \u003d data"},{"line_number":1724,"context_line":""},{"line_number":1725,"context_line":"            def __iter__(self):"},{"line_number":1726,"context_line":"                yield self.data"},{"line_number":1727,"context_line":""},{"line_number":1728,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":1729,"context_line":"            FakeAppNoContentLengthNoTransferEncoding("}],"source_content_type":"text/x-python","patch_set":58,"id":"c66e2f96_7c8a363d","side":"PARENT","line":1726,"updated":"2025-07-24 09:38:58.000000000","message":"somehow this unrelated change has crept in - maybe because you backed out of this re-using this ``BodyGen`` pattern in new tests - but I don\u0027t think this should change:\n\nthe test is called ``test_no_content_length_no_transfer_encoding_with_generator`` so I think it is intentionally using a bespoke generator for the fake body.","commit_id":"f7c69412ad30693b81983366b2d173f85296d6c7"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"a37da6eb6c70194e35ae4422536f75ee9e681e35","unresolved":false,"context_lines":[{"line_number":1723,"context_line":"                self.data \u003d data"},{"line_number":1724,"context_line":""},{"line_number":1725,"context_line":"            def __iter__(self):"},{"line_number":1726,"context_line":"                yield self.data"},{"line_number":1727,"context_line":""},{"line_number":1728,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":1729,"context_line":"            FakeAppNoContentLengthNoTransferEncoding("}],"source_content_type":"text/x-python","patch_set":58,"id":"9b87ef73_b5436cef","side":"PARENT","line":1726,"in_reply_to":"c66e2f96_7c8a363d","updated":"2025-07-24 22:24:06.000000000","message":"Yes, I did not use BodyGen pattern in the rest of the tests but will keep this since its encoding with generator","commit_id":"f7c69412ad30693b81983366b2d173f85296d6c7"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed52e6f601100413157c728b3379848ae27d2538","unresolved":true,"context_lines":[{"line_number":738,"context_line":"                                           app)"},{"line_number":739,"context_line":"                else:"},{"line_number":740,"context_line":"                    self.assertUpdateStats([(\u0027%s.GET.321.xfer\u0027 % exp_type,"},{"line_number":741,"context_line":"                                             4 + 7)],"},{"line_number":742,"context_line":"                                           app)"},{"line_number":743,"context_line":"                exp_labels.update({"},{"line_number":744,"context_line":"                    \u0027method\u0027: \u0027GET\u0027,"}],"source_content_type":"text/x-python","patch_set":58,"id":"4163bc75_f62a3665","line":741,"updated":"2025-07-24 09:38:58.000000000","message":":( unrelated change","commit_id":"4641e0ca4aa3481f0bd66d4af9ff4a61e5267946"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"a37da6eb6c70194e35ae4422536f75ee9e681e35","unresolved":false,"context_lines":[{"line_number":738,"context_line":"                                           app)"},{"line_number":739,"context_line":"                else:"},{"line_number":740,"context_line":"                    self.assertUpdateStats([(\u0027%s.GET.321.xfer\u0027 % exp_type,"},{"line_number":741,"context_line":"                                             4 + 7)],"},{"line_number":742,"context_line":"                                           app)"},{"line_number":743,"context_line":"                exp_labels.update({"},{"line_number":744,"context_line":"                    \u0027method\u0027: \u0027GET\u0027,"}],"source_content_type":"text/x-python","patch_set":58,"id":"9982ce64_124fc18b","line":741,"in_reply_to":"4163bc75_f62a3665","updated":"2025-07-24 22:24:06.000000000","message":"Acknowledged","commit_id":"4641e0ca4aa3481f0bd66d4af9ff4a61e5267946"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"198b984c59b8a6fd4ba03b46d765c424b2ef8250","unresolved":true,"context_lines":[{"line_number":1949,"context_line":"        resp \u003d app(req.environ, start_response)"},{"line_number":1950,"context_line":"        self.assertEqual(b\u0027FAKE APP\u0027, b\u0027\u0027.join(resp))"},{"line_number":1951,"context_line":"        self.assertEqual(read_bytes, buffer_len)"},{"line_number":1952,"context_line":"        self.assertEqual(read_calls, len(callback_stats_per_iter))"},{"line_number":1953,"context_line":"        self.assertLabeledUpdateStats(expect_stats_per_iter[read_calls])"},{"line_number":1954,"context_line":"        self.assertUpdateStats(["},{"line_number":1955,"context_line":"            (\u0027container.PUT.200.xfer\u0027,"}],"source_content_type":"text/x-python","patch_set":61,"id":"d090f309_b450eaf1","line":1952,"range":{"start_line":1952,"start_character":41,"end_line":1952,"end_character":65},"updated":"2025-07-28 14:00:11.000000000","message":"this is the only assertion made about ``callback_stats_per_iter`` i.e. it\u0027s length - we ought to use it more than that ?","commit_id":"74e88a1633605f28d0d5eb95d1c889616245a54f"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"6cd17935952a72154c46b0576c8d1e4c49521cdc","unresolved":false,"context_lines":[{"line_number":1949,"context_line":"        resp \u003d app(req.environ, start_response)"},{"line_number":1950,"context_line":"        self.assertEqual(b\u0027FAKE APP\u0027, b\u0027\u0027.join(resp))"},{"line_number":1951,"context_line":"        self.assertEqual(read_bytes, buffer_len)"},{"line_number":1952,"context_line":"        self.assertEqual(read_calls, len(callback_stats_per_iter))"},{"line_number":1953,"context_line":"        self.assertLabeledUpdateStats(expect_stats_per_iter[read_calls])"},{"line_number":1954,"context_line":"        self.assertUpdateStats(["},{"line_number":1955,"context_line":"            (\u0027container.PUT.200.xfer\u0027,"}],"source_content_type":"text/x-python","patch_set":61,"id":"1495ab8a_b965f6dc","line":1952,"range":{"start_line":1952,"start_character":41,"end_line":1952,"end_character":65},"in_reply_to":"d090f309_b450eaf1","updated":"2025-08-01 15:49:03.000000000","message":"Acknowledged","commit_id":"74e88a1633605f28d0d5eb95d1c889616245a54f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"198b984c59b8a6fd4ba03b46d765c424b2ef8250","unresolved":true,"context_lines":[{"line_number":1950,"context_line":"        self.assertEqual(b\u0027FAKE APP\u0027, b\u0027\u0027.join(resp))"},{"line_number":1951,"context_line":"        self.assertEqual(read_bytes, buffer_len)"},{"line_number":1952,"context_line":"        self.assertEqual(read_calls, len(callback_stats_per_iter))"},{"line_number":1953,"context_line":"        self.assertLabeledUpdateStats(expect_stats_per_iter[read_calls])"},{"line_number":1954,"context_line":"        self.assertUpdateStats(["},{"line_number":1955,"context_line":"            (\u0027container.PUT.200.xfer\u0027,"},{"line_number":1956,"context_line":"             buffer_len + len(\u0027FAKE APP\u0027)),"}],"source_content_type":"text/x-python","patch_set":61,"id":"ee325a6e_64783f80","line":1953,"range":{"start_line":1953,"start_character":60,"end_line":1953,"end_character":70},"updated":"2025-07-28 14:00:11.000000000","message":"this is the only item in ``expect_stats_per_iter`` that is asserted - why collect all the other items\n\n```\ndiff --git a/test/unit/common/middleware/test_proxy_logging.py b/test/unit/common/middleware/test_proxy_logging.py\nindex a30866cd1..6ad8e6253 100644\n--- a/test/unit/common/middleware/test_proxy_logging.py\n+++ b/test/unit/common/middleware/test_proxy_logging.py\n@@ -1869,7 +1869,6 @@ class TestProxyLogging(BaseTestProxyLogging):\n         read_calls \u003d 0\n         read_bytes \u003d 0\n \n-        expect_stats_per_iter \u003d []\n         iter_stats \u003d []\n         nbytes \u003d 0\n         while nbytes + 5 \u003c\u003d buffer_len:\n@@ -1880,7 +1879,6 @@ class TestProxyLogging(BaseTestProxyLogging):\n                     \u0027method\u0027: \u0027PUT\u0027,\n                     \u0027resource\u0027: \u0027container\u0027})\n             ]\n-            expect_stats_per_iter.append(iter_stats)\n             nbytes +\u003d 5\n         if nbytes \u003c buffer_len:\n             iter_stats +\u003d [\n@@ -1891,8 +1889,6 @@ class TestProxyLogging(BaseTestProxyLogging):\n                      \u0027method\u0027: \u0027PUT\u0027,\n                      \u0027resource\u0027: \u0027container\u0027})\n             ]\n-            expect_stats_per_iter.append(iter_stats)\n-        expect_stats_per_iter.append(iter_stats)\n         iter_stats +\u003d [\n             (\u0027swift_proxy_server_response_body_streaming_bytes\u0027,\n              len(\u0027FAKE APP\u0027), {\n@@ -1916,9 +1912,7 @@ class TestProxyLogging(BaseTestProxyLogging):\n                  \u0027method\u0027: \u0027PUT\u0027,\n                  \u0027resource\u0027: \u0027container\u0027,\n                  \u0027status\u0027: 200}),\n-\n         ]\n-        expect_stats_per_iter.append(iter_stats)\n         callback_stats_per_iter \u003d []\n \n         def capture_stats(nbytes):\n@@ -1926,8 +1920,8 @@ class TestProxyLogging(BaseTestProxyLogging):\n             update_stats_calls \u003d sorted(statsd_calls)\n             got_metrics_values_and_kwargs \u003d []\n             for got in update_stats_calls:\n-                got_metrics_values_and_kwargs.append((got[0][0],\n-                                                      got[0][1], got[1]))\n+                got_metrics_values_and_kwargs.append(\n+                    (got[0][0], got[0][1], got[1][\u0027labels\u0027]))\n             callback_stats_per_iter.append(got_metrics_values_and_kwargs)\n             nonlocal read_calls\n             nonlocal read_bytes\n@@ -1950,7 +1944,8 @@ class TestProxyLogging(BaseTestProxyLogging):\n         self.assertEqual(b\u0027FAKE APP\u0027, b\u0027\u0027.join(resp))\n         self.assertEqual(read_bytes, buffer_len)\n         self.assertEqual(read_calls, len(callback_stats_per_iter))\n-        self.assertLabeledUpdateStats(expect_stats_per_iter[read_calls])\n+        self.assertEqual(iter_stats[:-3], callback_stats_per_iter[-1])\n+        self.assertLabeledUpdateStats(iter_stats)\n         self.assertUpdateStats([\n             (\u0027container.PUT.200.xfer\u0027,\n              buffer_len + len(\u0027FAKE APP\u0027)),\n\n```","commit_id":"74e88a1633605f28d0d5eb95d1c889616245a54f"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"6cd17935952a72154c46b0576c8d1e4c49521cdc","unresolved":false,"context_lines":[{"line_number":1950,"context_line":"        self.assertEqual(b\u0027FAKE APP\u0027, b\u0027\u0027.join(resp))"},{"line_number":1951,"context_line":"        self.assertEqual(read_bytes, buffer_len)"},{"line_number":1952,"context_line":"        self.assertEqual(read_calls, len(callback_stats_per_iter))"},{"line_number":1953,"context_line":"        self.assertLabeledUpdateStats(expect_stats_per_iter[read_calls])"},{"line_number":1954,"context_line":"        self.assertUpdateStats(["},{"line_number":1955,"context_line":"            (\u0027container.PUT.200.xfer\u0027,"},{"line_number":1956,"context_line":"             buffer_len + len(\u0027FAKE APP\u0027)),"}],"source_content_type":"text/x-python","patch_set":61,"id":"08eceb7a_2bffac6b","line":1953,"range":{"start_line":1953,"start_character":60,"end_line":1953,"end_character":70},"in_reply_to":"ee325a6e_64783f80","updated":"2025-08-01 15:49:03.000000000","message":"asserted callback stats along with current assertions","commit_id":"74e88a1633605f28d0d5eb95d1c889616245a54f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"131fbcc57b66ee676477aeb1b6bee5785ffcb7d5","unresolved":true,"context_lines":[{"line_number":317,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":318,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":319,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"},{"line_number":320,"context_line":"                \u0027resource\u0027: \u0027container\u0027})])"},{"line_number":321,"context_line":"        callback(buffers, eof\u003dTrue)"},{"line_number":322,"context_line":"        self.assertLabeledUpdateStats(["},{"line_number":323,"context_line":"            (\u0027swift_proxy_example_metric\u0027, buffer_len, {"}],"source_content_type":"text/x-python","patch_set":63,"id":"df286d43_2c0b7090","line":320,"updated":"2025-08-04 09:55:17.000000000","message":"Thanks for working on this test, it\u0027s heading exactly the right direction.\n\nHowever, for this assertion to be true the test is relying on less than 1ms elapsing between the ``callback()`` at line 307 and 315 ... and that cannot be relied upon every time this test runs because os process scheduling is unpredictable.\n\nTry putting time.sleep(0.002) at line 314\n\nSo you need to either:\n- increase the ``statsd_emit_buffer_xfer_bytes_ms`` value to something crazy (remember it is ms, so like 1000000!) to be pretty certain that time will not have elapsed between the two callbacks\n\nor\n- mock time in proxy_logging.py so that you can control what the perceived time is at each ``callback()``.\n\nin fact you could just \"freeze\" time:\n\n```\n        now \u003d time.time()\n        with mock.patch(\u0027swift.common.middleware.proxy_logging.time.time\u0027,\n                        return_value\u003dnow):\n\n```","commit_id":"06a569be3dd39ceec72aa75a3061100daa5c7c8a"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"203d2e18ce30234f4d9fc616b4fa97ca519a0fdc","unresolved":false,"context_lines":[{"line_number":317,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":318,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":319,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"},{"line_number":320,"context_line":"                \u0027resource\u0027: \u0027container\u0027})])"},{"line_number":321,"context_line":"        callback(buffers, eof\u003dTrue)"},{"line_number":322,"context_line":"        self.assertLabeledUpdateStats(["},{"line_number":323,"context_line":"            (\u0027swift_proxy_example_metric\u0027, buffer_len, {"}],"source_content_type":"text/x-python","patch_set":63,"id":"2b18cba5_99e0715c","line":320,"in_reply_to":"df286d43_2c0b7090","updated":"2025-08-04 20:35:53.000000000","message":"Acknowledged","commit_id":"06a569be3dd39ceec72aa75a3061100daa5c7c8a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"39f2ccece4cf04b118f66a5b48358098d758c9b7","unresolved":true,"context_lines":[{"line_number":326,"context_line":"                \u0027resource\u0027: \u0027container\u0027})])"},{"line_number":327,"context_line":"        now \u003d time.time()"},{"line_number":328,"context_line":"        with mock.patch(\u0027swift.common.middleware.proxy_logging.time.time\u0027,"},{"line_number":329,"context_line":"                        return_value\u003dnow):"},{"line_number":330,"context_line":"            callback(buffers, eof\u003dTrue)"},{"line_number":331,"context_line":"        self.assertLabeledUpdateStats(["},{"line_number":332,"context_line":"            (\u0027swift_proxy_example_metric\u0027, buffer_len, {"}],"source_content_type":"text/x-python","patch_set":64,"id":"141759f8_d9793b34","line":329,"updated":"2025-08-06 15:02:22.000000000","message":"yep, that looks better","commit_id":"89f2c7a2e176b641d2b0d2c5cd17c1c0e47747bb"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"5a2be1b55ca7dfdee0efbda8033b4833e0b2c6bc","unresolved":false,"context_lines":[{"line_number":326,"context_line":"                \u0027resource\u0027: \u0027container\u0027})])"},{"line_number":327,"context_line":"        now \u003d time.time()"},{"line_number":328,"context_line":"        with mock.patch(\u0027swift.common.middleware.proxy_logging.time.time\u0027,"},{"line_number":329,"context_line":"                        return_value\u003dnow):"},{"line_number":330,"context_line":"            callback(buffers, eof\u003dTrue)"},{"line_number":331,"context_line":"        self.assertLabeledUpdateStats(["},{"line_number":332,"context_line":"            (\u0027swift_proxy_example_metric\u0027, buffer_len, {"}],"source_content_type":"text/x-python","patch_set":64,"id":"0024d119_1f7b4cc8","line":329,"in_reply_to":"141759f8_d9793b34","updated":"2025-08-06 20:31:35.000000000","message":"Done","commit_id":"89f2c7a2e176b641d2b0d2c5cd17c1c0e47747bb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"94af435e5e843a4093f95790290a679681a01ea5","unresolved":true,"context_lines":[{"line_number":152,"context_line":"                value, statsd_calls[i][0][1], places\u003d4, msg\u003di)"},{"line_number":153,"context_line":""},{"line_number":154,"context_line":""},{"line_number":155,"context_line":"class TestCallbackInputProxy(unittest.TestCase):"},{"line_number":156,"context_line":"    def test_read_all(self):"},{"line_number":157,"context_line":"        self.assertEqual("},{"line_number":158,"context_line":"            proxy_logging.CallbackInputProxy("}],"source_content_type":"text/x-python","patch_set":66,"id":"868bd807_a19fdc77","line":155,"updated":"2025-08-08 17:38:52.000000000","message":"please reverse the order of the actual, expected args in the tests in this class so that they are ``(expected, actual)``\n\n* python unittest is ambivalent about the order. \n* Some people argue that expected should always be first https://stackoverflow.com/questions/2404978/why-are-assertequals-parameters-in-the-order-expected-actual \n* my IDE (pycharm) assumes expected is first when rendering test output\n* But the compelling reason is that other tests in this patch use (expected, actual)","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"4bcbfbcbc06a15be10d54b1253f8bd6a8e3bbcc3","unresolved":false,"context_lines":[{"line_number":152,"context_line":"                value, statsd_calls[i][0][1], places\u003d4, msg\u003di)"},{"line_number":153,"context_line":""},{"line_number":154,"context_line":""},{"line_number":155,"context_line":"class TestCallbackInputProxy(unittest.TestCase):"},{"line_number":156,"context_line":"    def test_read_all(self):"},{"line_number":157,"context_line":"        self.assertEqual("},{"line_number":158,"context_line":"            proxy_logging.CallbackInputProxy("}],"source_content_type":"text/x-python","patch_set":66,"id":"c1eb417f_c70c15dd","line":155,"in_reply_to":"868bd807_a19fdc77","updated":"2025-08-08 20:17:53.000000000","message":"Acknowledged","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"94af435e5e843a4093f95790290a679681a01ea5","unresolved":true,"context_lines":[{"line_number":156,"context_line":"    def test_read_all(self):"},{"line_number":157,"context_line":"        self.assertEqual("},{"line_number":158,"context_line":"            proxy_logging.CallbackInputProxy("},{"line_number":159,"context_line":"                io.BytesIO(b\u0027abc\u0027), callback\u003dNone).read(), b\u0027abc\u0027)"},{"line_number":160,"context_line":"        self.assertEqual("},{"line_number":161,"context_line":"            proxy_logging.CallbackInputProxy("},{"line_number":162,"context_line":"                io.BytesIO(b\u0027abc\u0027), callback\u003dNone).read(-1), b\u0027abc\u0027)"}],"source_content_type":"text/x-python","patch_set":66,"id":"fcb94299_5ac0850a","line":159,"range":{"start_line":159,"start_character":16,"end_line":159,"end_character":26},"updated":"2025-08-08 17:38:52.000000000","message":"BytesIO is already imported, so no need for io.BytesIO and no need to import io at line 23","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"4bcbfbcbc06a15be10d54b1253f8bd6a8e3bbcc3","unresolved":false,"context_lines":[{"line_number":156,"context_line":"    def test_read_all(self):"},{"line_number":157,"context_line":"        self.assertEqual("},{"line_number":158,"context_line":"            proxy_logging.CallbackInputProxy("},{"line_number":159,"context_line":"                io.BytesIO(b\u0027abc\u0027), callback\u003dNone).read(), b\u0027abc\u0027)"},{"line_number":160,"context_line":"        self.assertEqual("},{"line_number":161,"context_line":"            proxy_logging.CallbackInputProxy("},{"line_number":162,"context_line":"                io.BytesIO(b\u0027abc\u0027), callback\u003dNone).read(-1), b\u0027abc\u0027)"}],"source_content_type":"text/x-python","patch_set":66,"id":"1aaa2bd5_41c9484c","line":159,"range":{"start_line":159,"start_character":16,"end_line":159,"end_character":26},"in_reply_to":"fcb94299_5ac0850a","updated":"2025-08-08 20:17:53.000000000","message":"Done","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"94af435e5e843a4093f95790290a679681a01ea5","unresolved":true,"context_lines":[{"line_number":162,"context_line":"                io.BytesIO(b\u0027abc\u0027), callback\u003dNone).read(-1), b\u0027abc\u0027)"},{"line_number":163,"context_line":"        self.assertEqual("},{"line_number":164,"context_line":"            proxy_logging.CallbackInputProxy("},{"line_number":165,"context_line":"                io.BytesIO(b\u0027abc\u0027), callback\u003dNone).read(None), b\u0027abc\u0027)"},{"line_number":166,"context_line":""},{"line_number":167,"context_line":"    def test_read_all_with_callback(self):"},{"line_number":168,"context_line":"        callback \u003d MagicMock(return_value\u003d\u0027xyz\u0027)"}],"source_content_type":"text/x-python","patch_set":66,"id":"52f99d1e_aa0e3fcc","line":165,"updated":"2025-08-08 17:38:52.000000000","message":"this test should probably go now callback is required (if the default callback is removed)","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"4bcbfbcbc06a15be10d54b1253f8bd6a8e3bbcc3","unresolved":false,"context_lines":[{"line_number":162,"context_line":"                io.BytesIO(b\u0027abc\u0027), callback\u003dNone).read(-1), b\u0027abc\u0027)"},{"line_number":163,"context_line":"        self.assertEqual("},{"line_number":164,"context_line":"            proxy_logging.CallbackInputProxy("},{"line_number":165,"context_line":"                io.BytesIO(b\u0027abc\u0027), callback\u003dNone).read(None), b\u0027abc\u0027)"},{"line_number":166,"context_line":""},{"line_number":167,"context_line":"    def test_read_all_with_callback(self):"},{"line_number":168,"context_line":"        callback \u003d MagicMock(return_value\u003d\u0027xyz\u0027)"}],"source_content_type":"text/x-python","patch_set":66,"id":"36f45aef_7e4edc18","line":165,"in_reply_to":"52f99d1e_aa0e3fcc","updated":"2025-08-08 20:17:53.000000000","message":"Acknowledged","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"94af435e5e843a4093f95790290a679681a01ea5","unresolved":true,"context_lines":[{"line_number":165,"context_line":"                io.BytesIO(b\u0027abc\u0027), callback\u003dNone).read(None), b\u0027abc\u0027)"},{"line_number":166,"context_line":""},{"line_number":167,"context_line":"    def test_read_all_with_callback(self):"},{"line_number":168,"context_line":"        callback \u003d MagicMock(return_value\u003d\u0027xyz\u0027)"},{"line_number":169,"context_line":"        self.assertEqual("},{"line_number":170,"context_line":"            proxy_logging.CallbackInputProxy("},{"line_number":171,"context_line":"                io.BytesIO(b\u0027abc\u0027), callback).read(), \u0027xyz\u0027)"}],"source_content_type":"text/x-python","patch_set":66,"id":"fc27fcf9_959f78b5","line":168,"range":{"start_line":168,"start_character":19,"end_line":168,"end_character":28},"updated":"2025-08-08 17:38:52.000000000","message":"nit: elsewhere in this file we have mock.MagicMock; for consistency you could do the same here and avoid having to add the import at line 27\n\n...which I know is the opposite direction to the comment re io.BytesIO but sometimes its just best (and less lines of diff) to stick with the patterns already in the file.","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"94af435e5e843a4093f95790290a679681a01ea5","unresolved":true,"context_lines":[{"line_number":165,"context_line":"                io.BytesIO(b\u0027abc\u0027), callback\u003dNone).read(None), b\u0027abc\u0027)"},{"line_number":166,"context_line":""},{"line_number":167,"context_line":"    def test_read_all_with_callback(self):"},{"line_number":168,"context_line":"        callback \u003d MagicMock(return_value\u003d\u0027xyz\u0027)"},{"line_number":169,"context_line":"        self.assertEqual("},{"line_number":170,"context_line":"            proxy_logging.CallbackInputProxy("},{"line_number":171,"context_line":"                io.BytesIO(b\u0027abc\u0027), callback).read(), \u0027xyz\u0027)"}],"source_content_type":"text/x-python","patch_set":66,"id":"54011c1a_f5b69cf8","line":168,"range":{"start_line":168,"start_character":42,"end_line":168,"end_character":47},"updated":"2025-08-08 17:38:52.000000000","message":"the return value ought to be b\u0027xyx\u0027 (i.e. bytes) since that\u0027s the expected return type from a read()","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"4bcbfbcbc06a15be10d54b1253f8bd6a8e3bbcc3","unresolved":false,"context_lines":[{"line_number":165,"context_line":"                io.BytesIO(b\u0027abc\u0027), callback\u003dNone).read(None), b\u0027abc\u0027)"},{"line_number":166,"context_line":""},{"line_number":167,"context_line":"    def test_read_all_with_callback(self):"},{"line_number":168,"context_line":"        callback \u003d MagicMock(return_value\u003d\u0027xyz\u0027)"},{"line_number":169,"context_line":"        self.assertEqual("},{"line_number":170,"context_line":"            proxy_logging.CallbackInputProxy("},{"line_number":171,"context_line":"                io.BytesIO(b\u0027abc\u0027), callback).read(), \u0027xyz\u0027)"}],"source_content_type":"text/x-python","patch_set":66,"id":"7a55a3d1_8b6025eb","line":168,"range":{"start_line":168,"start_character":42,"end_line":168,"end_character":47},"in_reply_to":"54011c1a_f5b69cf8","updated":"2025-08-08 20:17:53.000000000","message":"Acknowledged","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"4bcbfbcbc06a15be10d54b1253f8bd6a8e3bbcc3","unresolved":false,"context_lines":[{"line_number":165,"context_line":"                io.BytesIO(b\u0027abc\u0027), callback\u003dNone).read(None), b\u0027abc\u0027)"},{"line_number":166,"context_line":""},{"line_number":167,"context_line":"    def test_read_all_with_callback(self):"},{"line_number":168,"context_line":"        callback \u003d MagicMock(return_value\u003d\u0027xyz\u0027)"},{"line_number":169,"context_line":"        self.assertEqual("},{"line_number":170,"context_line":"            proxy_logging.CallbackInputProxy("},{"line_number":171,"context_line":"                io.BytesIO(b\u0027abc\u0027), callback).read(), \u0027xyz\u0027)"}],"source_content_type":"text/x-python","patch_set":66,"id":"aaafbfff_069f64d8","line":168,"range":{"start_line":168,"start_character":19,"end_line":168,"end_character":28},"in_reply_to":"fc27fcf9_959f78b5","updated":"2025-08-08 20:17:53.000000000","message":"Done","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"94af435e5e843a4093f95790290a679681a01ea5","unresolved":true,"context_lines":[{"line_number":181,"context_line":"        self.assertEqual("},{"line_number":182,"context_line":"            proxy_logging.CallbackInputProxy("},{"line_number":183,"context_line":"                io.BytesIO(b\u0027abc\u0027), callback).read(None), \u0027xyz\u0027)"},{"line_number":184,"context_line":"        self.assertEqual([mock.call(b\u0027abc\u0027, True)], callback.call_args_list)"},{"line_number":185,"context_line":""},{"line_number":186,"context_line":""},{"line_number":187,"context_line":"class TestBufferXferEmitCallback(BaseTestProxyLogging):"}],"source_content_type":"text/x-python","patch_set":66,"id":"1ea24a70_c890e186","line":184,"updated":"2025-08-08 17:38:52.000000000","message":"that\u0027s nice!\n\ncould you add a ``test_read_size`` that shows ``mock.call(b\u0027a\u0027, False)`` (i.e. reading less than the complete buffer) followed by ``mock.call(b\u0027a\u0027, True)`` when the buffer is empty.\n\nIt might be helpful to use MagicMock\u0027s side_effect property:\n```\ncallback \u003d MagicMock(side_effect\u003d[b\u0027x\u0027, b\u0027yz\u0027, b\u0027\u0027])\n```\neach time you call ``callback()`` it will return the next in the list of ``side_effect``. So if you call read(1), read(2), read() then you\u0027ll get b\u0027x\u0027, b\u0027yz\u0027, b\u0027\u0027","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"4bcbfbcbc06a15be10d54b1253f8bd6a8e3bbcc3","unresolved":false,"context_lines":[{"line_number":181,"context_line":"        self.assertEqual("},{"line_number":182,"context_line":"            proxy_logging.CallbackInputProxy("},{"line_number":183,"context_line":"                io.BytesIO(b\u0027abc\u0027), callback).read(None), \u0027xyz\u0027)"},{"line_number":184,"context_line":"        self.assertEqual([mock.call(b\u0027abc\u0027, True)], callback.call_args_list)"},{"line_number":185,"context_line":""},{"line_number":186,"context_line":""},{"line_number":187,"context_line":"class TestBufferXferEmitCallback(BaseTestProxyLogging):"}],"source_content_type":"text/x-python","patch_set":66,"id":"2e302f1f_575d63b4","line":184,"in_reply_to":"1ea24a70_c890e186","updated":"2025-08-08 20:17:53.000000000","message":"Acknowledged","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"94af435e5e843a4093f95790290a679681a01ea5","unresolved":true,"context_lines":[{"line_number":203,"context_line":"        labels \u003d {"},{"line_number":204,"context_line":"            \u0027account\u0027: \u0027a\u0027,"},{"line_number":205,"context_line":"            \u0027container\u0027: \u0027c\u0027,"},{"line_number":206,"context_line":"            \u0027method\u0027: \u0027POST\u0027,"},{"line_number":207,"context_line":"            \u0027resource\u0027: \u0027container\u0027}"},{"line_number":208,"context_line":"        callback \u003d proxy_logging.BufferXferEmitCallback("},{"line_number":209,"context_line":"            \u0027swift_proxy_example_metric\u0027, labels, app.statsd,"}],"source_content_type":"text/x-python","patch_set":66,"id":"337c4a08_10a12827","line":206,"range":{"start_line":206,"start_character":22,"end_line":206,"end_character":28},"updated":"2025-08-08 17:38:52.000000000","message":"nit^2: it\u0027s a little odd that all these tests use \u0027POST\u0027 but typically a POST request has no body so IRL we\u0027d never expect to see any xfer stats for a POST (well, maybe some s3api requests). It doesn\u0027t matter, just struck me as odd.","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"4bcbfbcbc06a15be10d54b1253f8bd6a8e3bbcc3","unresolved":false,"context_lines":[{"line_number":203,"context_line":"        labels \u003d {"},{"line_number":204,"context_line":"            \u0027account\u0027: \u0027a\u0027,"},{"line_number":205,"context_line":"            \u0027container\u0027: \u0027c\u0027,"},{"line_number":206,"context_line":"            \u0027method\u0027: \u0027POST\u0027,"},{"line_number":207,"context_line":"            \u0027resource\u0027: \u0027container\u0027}"},{"line_number":208,"context_line":"        callback \u003d proxy_logging.BufferXferEmitCallback("},{"line_number":209,"context_line":"            \u0027swift_proxy_example_metric\u0027, labels, app.statsd,"}],"source_content_type":"text/x-python","patch_set":66,"id":"8847aa8c_6611b3b5","line":206,"range":{"start_line":206,"start_character":22,"end_line":206,"end_character":28},"in_reply_to":"337c4a08_10a12827","updated":"2025-08-08 20:17:53.000000000","message":"Acknowledged","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"94af435e5e843a4093f95790290a679681a01ea5","unresolved":true,"context_lines":[{"line_number":348,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":349,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"},{"line_number":350,"context_line":"                \u0027resource\u0027: \u0027container\u0027})])"},{"line_number":351,"context_line":"        now \u003d time.time()"},{"line_number":352,"context_line":"        with mock.patch(\u0027swift.common.middleware.proxy_logging.time.time\u0027,"},{"line_number":353,"context_line":"                        return_value\u003dnow):"},{"line_number":354,"context_line":"            callback(buffers, eof\u003dFalse)"}],"source_content_type":"text/x-python","patch_set":66,"id":"592a0553_00bdfe7d","line":351,"range":{"start_line":351,"start_character":8,"end_line":351,"end_character":25},"updated":"2025-08-08 17:38:52.000000000","message":"I didn\u0027t notice this before - advancing the mock time defeats the purpose of mocking it: if the test runner sleeps for \u003e\u003d 1s at line 351 then the test will fail because the stat *will* be emitted. The idea was to freeze time at the initial value of now (line 341).","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"4bcbfbcbc06a15be10d54b1253f8bd6a8e3bbcc3","unresolved":false,"context_lines":[{"line_number":348,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":349,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"},{"line_number":350,"context_line":"                \u0027resource\u0027: \u0027container\u0027})])"},{"line_number":351,"context_line":"        now \u003d time.time()"},{"line_number":352,"context_line":"        with mock.patch(\u0027swift.common.middleware.proxy_logging.time.time\u0027,"},{"line_number":353,"context_line":"                        return_value\u003dnow):"},{"line_number":354,"context_line":"            callback(buffers, eof\u003dFalse)"}],"source_content_type":"text/x-python","patch_set":66,"id":"ed6b4df0_14564a39","line":351,"range":{"start_line":351,"start_character":8,"end_line":351,"end_character":25},"in_reply_to":"592a0553_00bdfe7d","updated":"2025-08-08 20:17:53.000000000","message":"Acknowledged","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"94af435e5e843a4093f95790290a679681a01ea5","unresolved":true,"context_lines":[{"line_number":358,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":359,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"},{"line_number":360,"context_line":"                \u0027resource\u0027: \u0027container\u0027})])"},{"line_number":361,"context_line":"        now \u003d time.time()"},{"line_number":362,"context_line":"        with mock.patch(\u0027swift.common.middleware.proxy_logging.time.time\u0027,"},{"line_number":363,"context_line":"                        return_value\u003dnow):"},{"line_number":364,"context_line":"            callback(buffers, eof\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":66,"id":"531840c8_f3a44502","line":361,"updated":"2025-08-08 17:38:52.000000000","message":"this line also needs to be removed","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"4bcbfbcbc06a15be10d54b1253f8bd6a8e3bbcc3","unresolved":false,"context_lines":[{"line_number":358,"context_line":"                \u0027container\u0027: \u0027c\u0027,"},{"line_number":359,"context_line":"                \u0027method\u0027: \u0027POST\u0027,"},{"line_number":360,"context_line":"                \u0027resource\u0027: \u0027container\u0027})])"},{"line_number":361,"context_line":"        now \u003d time.time()"},{"line_number":362,"context_line":"        with mock.patch(\u0027swift.common.middleware.proxy_logging.time.time\u0027,"},{"line_number":363,"context_line":"                        return_value\u003dnow):"},{"line_number":364,"context_line":"            callback(buffers, eof\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":66,"id":"8f0e731c_259e6988","line":361,"in_reply_to":"531840c8_f3a44502","updated":"2025-08-08 20:17:53.000000000","message":"Acknowledged","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"94af435e5e843a4093f95790290a679681a01ea5","unresolved":true,"context_lines":[{"line_number":1442,"context_line":"        self.assertEqual(log_parts[10], str(len(\u0027some stuff\u0027)))"},{"line_number":1443,"context_line":"        self.assertUpdateStats(["},{"line_number":1444,"context_line":"            (\u0027object.PUT.200.xfer\u0027,"},{"line_number":1445,"context_line":"             len(\u0027some stuff\u0027) + len(\u0027FAKE APP\u0027)),"},{"line_number":1446,"context_line":"        ], app)"},{"line_number":1447,"context_line":"        self.assertLabeledUpdateStats(["},{"line_number":1448,"context_line":"            (\u0027swift_proxy_server_request_body_bytes\u0027, 10, {"}],"source_content_type":"text/x-python","patch_set":66,"id":"2556f585_bef930be","line":1445,"updated":"2025-08-08 17:38:52.000000000","message":"unnecessary change!\n\nIt\u0027s not that I mind the change, it looks better, but it concerns me that you\u0027ve apparently not managed to prevent these being *unintentionally* introduced to the patch.","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"4bcbfbcbc06a15be10d54b1253f8bd6a8e3bbcc3","unresolved":false,"context_lines":[{"line_number":1442,"context_line":"        self.assertEqual(log_parts[10], str(len(\u0027some stuff\u0027)))"},{"line_number":1443,"context_line":"        self.assertUpdateStats(["},{"line_number":1444,"context_line":"            (\u0027object.PUT.200.xfer\u0027,"},{"line_number":1445,"context_line":"             len(\u0027some stuff\u0027) + len(\u0027FAKE APP\u0027)),"},{"line_number":1446,"context_line":"        ], app)"},{"line_number":1447,"context_line":"        self.assertLabeledUpdateStats(["},{"line_number":1448,"context_line":"            (\u0027swift_proxy_server_request_body_bytes\u0027, 10, {"}],"source_content_type":"text/x-python","patch_set":66,"id":"e45b3dad_969844d9","line":1445,"in_reply_to":"2556f585_bef930be","updated":"2025-08-08 20:17:53.000000000","message":"Acknowledged","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"94af435e5e843a4093f95790290a679681a01ea5","unresolved":true,"context_lines":[{"line_number":1843,"context_line":"    def _do_test_base_labels_end_to_end(self, orig_path, new_path\u003dNone,"},{"line_number":1844,"context_line":"                                        req_hdrs\u003dNone):"},{"line_number":1845,"context_line":"        # if new_path is given then pretend an s3api/auth middleware"},{"line_number":1846,"context_line":""},{"line_number":1847,"context_line":"        # combination replaces the request path with new_path"},{"line_number":1848,"context_line":"        mw_conf \u003d {}"},{"line_number":1849,"context_line":"        base_labels \u003d []"}],"source_content_type":"text/x-python","patch_set":66,"id":"6c4de46e_65763028","line":1846,"updated":"2025-08-08 17:38:52.000000000","message":"please delete this blank line","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"4bcbfbcbc06a15be10d54b1253f8bd6a8e3bbcc3","unresolved":false,"context_lines":[{"line_number":1843,"context_line":"    def _do_test_base_labels_end_to_end(self, orig_path, new_path\u003dNone,"},{"line_number":1844,"context_line":"                                        req_hdrs\u003dNone):"},{"line_number":1845,"context_line":"        # if new_path is given then pretend an s3api/auth middleware"},{"line_number":1846,"context_line":""},{"line_number":1847,"context_line":"        # combination replaces the request path with new_path"},{"line_number":1848,"context_line":"        mw_conf \u003d {}"},{"line_number":1849,"context_line":"        base_labels \u003d []"}],"source_content_type":"text/x-python","patch_set":66,"id":"8f239d6e_40955ed7","line":1846,"in_reply_to":"6c4de46e_65763028","updated":"2025-08-08 20:17:53.000000000","message":"Done","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"94af435e5e843a4093f95790290a679681a01ea5","unresolved":true,"context_lines":[{"line_number":2054,"context_line":"        self.assertUpdateStats(["},{"line_number":2055,"context_line":"            (\u0027container.PUT.200.xfer\u0027,"},{"line_number":2056,"context_line":"             buffer_len + len(\u0027FAKE APP\u0027)),"},{"line_number":2057,"context_line":"        ], app)"},{"line_number":2058,"context_line":""},{"line_number":2059,"context_line":"    def test_xfer_stats_get(self):"},{"line_number":2060,"context_line":"        buffers \u003d [b\u0027some stuff\\n\u0027,"}],"source_content_type":"text/x-python","patch_set":66,"id":"3f38e2d1_8aed717c","line":2057,"updated":"2025-08-08 17:38:52.000000000","message":"every time I come to this test I get SO confused by all of the data structures. I\u0027m going to put up a suggested diff in a follow on which I find a little easier to follow.\n\n956947: sq: bytes xfer stats test fixups | https://review.opendev.org/c/openstack/swift/+/956947","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"4bcbfbcbc06a15be10d54b1253f8bd6a8e3bbcc3","unresolved":false,"context_lines":[{"line_number":2054,"context_line":"        self.assertUpdateStats(["},{"line_number":2055,"context_line":"            (\u0027container.PUT.200.xfer\u0027,"},{"line_number":2056,"context_line":"             buffer_len + len(\u0027FAKE APP\u0027)),"},{"line_number":2057,"context_line":"        ], app)"},{"line_number":2058,"context_line":""},{"line_number":2059,"context_line":"    def test_xfer_stats_get(self):"},{"line_number":2060,"context_line":"        buffers \u003d [b\u0027some stuff\\n\u0027,"}],"source_content_type":"text/x-python","patch_set":66,"id":"674cb9a4_510e9528","line":2057,"in_reply_to":"3f38e2d1_8aed717c","updated":"2025-08-08 20:17:53.000000000","message":"Acknowledged","commit_id":"decefdbe008aca089bb1da28ca05181d53d55a87"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c21f8ce79fd1904a2a8ea1a8f3a5eeedd48c8ff8","unresolved":true,"context_lines":[{"line_number":185,"context_line":"        self.assertEqual("},{"line_number":186,"context_line":"            b\u0027\u0027, cip.read())"},{"line_number":187,"context_line":"        self.assertEqual([mock.call(b\u0027a\u0027, False), mock.call(b\u0027bc\u0027, False),"},{"line_number":188,"context_line":"                          mock.call(b\u0027\u0027, True)], callback.call_args_list)"},{"line_number":189,"context_line":""},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"class TestBufferXferEmitCallback(BaseTestProxyLogging):"}],"source_content_type":"text/x-python","patch_set":67,"id":"e1fd4868_1aef071f","line":188,"updated":"2025-08-11 13:37:44.000000000","message":"great!\n\nnit: the callback could return different bytes than the BytesIO to verify the \"return modified chunk\" behavior","commit_id":"752531a59abaad6978e1e3ed6e0f0c47abd10472"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"504f1547325aa77e6e44f5dea300a57dda4ba0e4","unresolved":false,"context_lines":[{"line_number":185,"context_line":"        self.assertEqual("},{"line_number":186,"context_line":"            b\u0027\u0027, cip.read())"},{"line_number":187,"context_line":"        self.assertEqual([mock.call(b\u0027a\u0027, False), mock.call(b\u0027bc\u0027, False),"},{"line_number":188,"context_line":"                          mock.call(b\u0027\u0027, True)], callback.call_args_list)"},{"line_number":189,"context_line":""},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"class TestBufferXferEmitCallback(BaseTestProxyLogging):"}],"source_content_type":"text/x-python","patch_set":67,"id":"1ba446b2_b02d7837","line":188,"in_reply_to":"e1fd4868_1aef071f","updated":"2025-09-03 19:00:05.000000000","message":"Acknowledged","commit_id":"752531a59abaad6978e1e3ed6e0f0c47abd10472"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f719d84280a8c3c93378a84805a52e9720b34b4e","unresolved":true,"context_lines":[{"line_number":2158,"context_line":"             buffer_len + len(\u0027FAKE APP\u0027)),"},{"line_number":2159,"context_line":"        ], app)"},{"line_number":2160,"context_line":"        self.assertLabeledUpdateStats(["},{"line_number":2161,"context_line":""},{"line_number":2162,"context_line":"            (\u0027swift_proxy_server_request_body_streaming_bytes\u0027, 5, {"},{"line_number":2163,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":2164,"context_line":"                \u0027container\u0027: \u0027c\u0027,"}],"source_content_type":"text/x-python","patch_set":75,"id":"f76b5523_66a23385","line":2161,"updated":"2025-09-24 22:04:31.000000000","message":"Stray blank line is kinda weird -- maybe left over from some rebase/merge conflict resolution?","commit_id":"e4bac03afdc5b67284407a8a585eea20d624cddb"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"79e53f5d982a5df59c1b5b89ec7abbb7901bfdf1","unresolved":false,"context_lines":[{"line_number":2158,"context_line":"             buffer_len + len(\u0027FAKE APP\u0027)),"},{"line_number":2159,"context_line":"        ], app)"},{"line_number":2160,"context_line":"        self.assertLabeledUpdateStats(["},{"line_number":2161,"context_line":""},{"line_number":2162,"context_line":"            (\u0027swift_proxy_server_request_body_streaming_bytes\u0027, 5, {"},{"line_number":2163,"context_line":"                \u0027account\u0027: \u0027a\u0027,"},{"line_number":2164,"context_line":"                \u0027container\u0027: \u0027c\u0027,"}],"source_content_type":"text/x-python","patch_set":75,"id":"81eda617_2755285f","line":2161,"in_reply_to":"f76b5523_66a23385","updated":"2025-10-07 15:36:59.000000000","message":"Done","commit_id":"e4bac03afdc5b67284407a8a585eea20d624cddb"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f719d84280a8c3c93378a84805a52e9720b34b4e","unresolved":true,"context_lines":[{"line_number":2267,"context_line":"                orig_path \u003d env[\u0027PATH_INFO\u0027]"},{"line_number":2268,"context_line":"                req \u003d Request(env)"},{"line_number":2269,"context_line":"                parts \u003d req.split_path(4, rest_with_last\u003dTrue)"},{"line_number":2270,"context_line":"                parts[2] +\u003d \u0027+segments\u0027"},{"line_number":2271,"context_line":"                env[\u0027PATH_INFO\u0027] \u003d \u0027/\u0027 + \u0027/\u0027.join(parts)"},{"line_number":2272,"context_line":"                try:"},{"line_number":2273,"context_line":"                    resp \u003d req.get_response(self.app)"}],"source_content_type":"text/x-python","patch_set":75,"id":"4a2d3157_77646634","line":2270,"updated":"2025-09-24 22:04:31.000000000","message":"Can we just make the request we pass to the pipeline look more like a part upload, and let `s3api` handle the rewriting? IDK whether it\u0027d be simpler to mock out `_get_upload_info` or just register the extra response for the upload marker...","commit_id":"e4bac03afdc5b67284407a8a585eea20d624cddb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2e1de4e1078d779a18a1fd69377c7628c63b884e","unresolved":true,"context_lines":[{"line_number":2267,"context_line":"                orig_path \u003d env[\u0027PATH_INFO\u0027]"},{"line_number":2268,"context_line":"                req \u003d Request(env)"},{"line_number":2269,"context_line":"                parts \u003d req.split_path(4, rest_with_last\u003dTrue)"},{"line_number":2270,"context_line":"                parts[2] +\u003d \u0027+segments\u0027"},{"line_number":2271,"context_line":"                env[\u0027PATH_INFO\u0027] \u003d \u0027/\u0027 + \u0027/\u0027.join(parts)"},{"line_number":2272,"context_line":"                try:"},{"line_number":2273,"context_line":"                    resp \u003d req.get_response(self.app)"}],"source_content_type":"text/x-python","patch_set":75,"id":"ecef1862_d160bcc9","line":2270,"in_reply_to":"4a2d3157_77646634","updated":"2025-10-09 11:46:15.000000000","message":"IIRC the goal of the PathRewritingApp test is to verify that, once set by leftmost proxy-logging, the container base-label won\u0027t change even if the rightmost proxy-logging sees a different path *for whatever reason* (not just s3 mpu handling).\n\nI think I prefer it being explicit (as it is) rather than relying on a side-effect of s3api multipart upload (which will change with native mpu\u0027s, such that s3api will not re-write the path).\n\nAdded a comment in 963519: sq? proxy-logging tests: use pipeline helper | https://review.opendev.org/c/openstack/swift/+/963519","commit_id":"e4bac03afdc5b67284407a8a585eea20d624cddb"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"bb73cfefbee08032ad27edd00b6f5c0e9da82f79","unresolved":false,"context_lines":[{"line_number":2267,"context_line":"                orig_path \u003d env[\u0027PATH_INFO\u0027]"},{"line_number":2268,"context_line":"                req \u003d Request(env)"},{"line_number":2269,"context_line":"                parts \u003d req.split_path(4, rest_with_last\u003dTrue)"},{"line_number":2270,"context_line":"                parts[2] +\u003d \u0027+segments\u0027"},{"line_number":2271,"context_line":"                env[\u0027PATH_INFO\u0027] \u003d \u0027/\u0027 + \u0027/\u0027.join(parts)"},{"line_number":2272,"context_line":"                try:"},{"line_number":2273,"context_line":"                    resp \u003d req.get_response(self.app)"}],"source_content_type":"text/x-python","patch_set":75,"id":"caa61b94_4c6db58c","line":2270,"in_reply_to":"ecef1862_d160bcc9","updated":"2025-10-10 18:27:29.000000000","message":"Acknowledged","commit_id":"e4bac03afdc5b67284407a8a585eea20d624cddb"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f719d84280a8c3c93378a84805a52e9720b34b4e","unresolved":true,"context_lines":[{"line_number":2387,"context_line":"        last_modified \u003d \u0027Fri, 01 Apr 2014 12:00:00 GMT\u0027"},{"line_number":2388,"context_line":"        date_header \u003d email.utils.formatdate(time.time() + 0)"},{"line_number":2389,"context_line":""},{"line_number":2390,"context_line":"        subrequest_app \u003d proxy_logging.ProxyLoggingMiddleware(swift, {"},{"line_number":2391,"context_line":"            \u0027access_log_route\u0027: \u0027subrequest\u0027,"},{"line_number":2392,"context_line":"        }, logger\u003dself.logger)"},{"line_number":2393,"context_line":"        app \u003d FakeAuthApp(subrequest_app)"},{"line_number":2394,"context_line":"        app._pipeline_final_app \u003d swift"},{"line_number":2395,"context_line":"        app \u003d s3api_filter_factory({"},{"line_number":2396,"context_line":"            \u0027force_swift_request_proxy_log\u0027: False,"},{"line_number":2397,"context_line":"        })(app)"},{"line_number":2398,"context_line":""},{"line_number":2399,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":2400,"context_line":"            app, conf, logger\u003dself.logger)"},{"line_number":2401,"context_line":"        app.statsd \u003d self.statsd"},{"line_number":2402,"context_line":""},{"line_number":2403,"context_line":"        swift.register(\u0027GET\u0027, \u0027/v1/AUTH_test/bucket/object\u0027,"},{"line_number":2404,"context_line":"                       HTTPOk,"}],"source_content_type":"text/x-python","patch_set":75,"id":"78ff0a83_86353017","line":2401,"range":{"start_line":2390,"start_character":7,"end_line":2401,"end_character":32},"updated":"2025-09-24 22:04:31.000000000","message":"Might want to pull this out as a `make_logged_s3api_pipeline` helper so you can use it again in other tests.","commit_id":"e4bac03afdc5b67284407a8a585eea20d624cddb"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"bb73cfefbee08032ad27edd00b6f5c0e9da82f79","unresolved":false,"context_lines":[{"line_number":2387,"context_line":"        last_modified \u003d \u0027Fri, 01 Apr 2014 12:00:00 GMT\u0027"},{"line_number":2388,"context_line":"        date_header \u003d email.utils.formatdate(time.time() + 0)"},{"line_number":2389,"context_line":""},{"line_number":2390,"context_line":"        subrequest_app \u003d proxy_logging.ProxyLoggingMiddleware(swift, {"},{"line_number":2391,"context_line":"            \u0027access_log_route\u0027: \u0027subrequest\u0027,"},{"line_number":2392,"context_line":"        }, logger\u003dself.logger)"},{"line_number":2393,"context_line":"        app \u003d FakeAuthApp(subrequest_app)"},{"line_number":2394,"context_line":"        app._pipeline_final_app \u003d swift"},{"line_number":2395,"context_line":"        app \u003d s3api_filter_factory({"},{"line_number":2396,"context_line":"            \u0027force_swift_request_proxy_log\u0027: False,"},{"line_number":2397,"context_line":"        })(app)"},{"line_number":2398,"context_line":""},{"line_number":2399,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":2400,"context_line":"            app, conf, logger\u003dself.logger)"},{"line_number":2401,"context_line":"        app.statsd \u003d self.statsd"},{"line_number":2402,"context_line":""},{"line_number":2403,"context_line":"        swift.register(\u0027GET\u0027, \u0027/v1/AUTH_test/bucket/object\u0027,"},{"line_number":2404,"context_line":"                       HTTPOk,"}],"source_content_type":"text/x-python","patch_set":75,"id":"3535d2ee_bd2624a0","line":2401,"range":{"start_line":2390,"start_character":7,"end_line":2401,"end_character":32},"in_reply_to":"58530b25_08401c99","updated":"2025-10-10 18:27:29.000000000","message":"Done","commit_id":"e4bac03afdc5b67284407a8a585eea20d624cddb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2e1de4e1078d779a18a1fd69377c7628c63b884e","unresolved":true,"context_lines":[{"line_number":2387,"context_line":"        last_modified \u003d \u0027Fri, 01 Apr 2014 12:00:00 GMT\u0027"},{"line_number":2388,"context_line":"        date_header \u003d email.utils.formatdate(time.time() + 0)"},{"line_number":2389,"context_line":""},{"line_number":2390,"context_line":"        subrequest_app \u003d proxy_logging.ProxyLoggingMiddleware(swift, {"},{"line_number":2391,"context_line":"            \u0027access_log_route\u0027: \u0027subrequest\u0027,"},{"line_number":2392,"context_line":"        }, logger\u003dself.logger)"},{"line_number":2393,"context_line":"        app \u003d FakeAuthApp(subrequest_app)"},{"line_number":2394,"context_line":"        app._pipeline_final_app \u003d swift"},{"line_number":2395,"context_line":"        app \u003d s3api_filter_factory({"},{"line_number":2396,"context_line":"            \u0027force_swift_request_proxy_log\u0027: False,"},{"line_number":2397,"context_line":"        })(app)"},{"line_number":2398,"context_line":""},{"line_number":2399,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":2400,"context_line":"            app, conf, logger\u003dself.logger)"},{"line_number":2401,"context_line":"        app.statsd \u003d self.statsd"},{"line_number":2402,"context_line":""},{"line_number":2403,"context_line":"        swift.register(\u0027GET\u0027, \u0027/v1/AUTH_test/bucket/object\u0027,"},{"line_number":2404,"context_line":"                       HTTPOk,"}],"source_content_type":"text/x-python","patch_set":75,"id":"58530b25_08401c99","line":2401,"range":{"start_line":2390,"start_character":7,"end_line":2401,"end_character":32},"in_reply_to":"78ff0a83_86353017","updated":"2025-10-09 11:46:15.000000000","message":"+1, see 963519: sq? proxy-logging tests: use pipeline helper | https://review.opendev.org/c/openstack/swift/+/963519","commit_id":"e4bac03afdc5b67284407a8a585eea20d624cddb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2e1de4e1078d779a18a1fd69377c7628c63b884e","unresolved":true,"context_lines":[{"line_number":2322,"context_line":""},{"line_number":2323,"context_line":"        stats \u003d ["},{"line_number":2324,"context_line":""},{"line_number":2325,"context_line":"        ]"},{"line_number":2326,"context_line":"        for i in range(10):"},{"line_number":2327,"context_line":"            stats.append("},{"line_number":2328,"context_line":"                (\u0027swift_proxy_server_request_body_streaming_bytes\u0027, 5, {"}],"source_content_type":"text/x-python","patch_set":80,"id":"a4638938_f37e2d95","line":2325,"updated":"2025-10-09 11:46:15.000000000","message":"unnecessary whitespace\n\nfixed in 963519: sq? proxy-logging tests: use pipeline helper | https://review.opendev.org/c/openstack/swift/+/963519","commit_id":"0a724c02fbdf5c065f6d0a72b6ed2753379ee095"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"bb73cfefbee08032ad27edd00b6f5c0e9da82f79","unresolved":false,"context_lines":[{"line_number":2322,"context_line":""},{"line_number":2323,"context_line":"        stats \u003d ["},{"line_number":2324,"context_line":""},{"line_number":2325,"context_line":"        ]"},{"line_number":2326,"context_line":"        for i in range(10):"},{"line_number":2327,"context_line":"            stats.append("},{"line_number":2328,"context_line":"                (\u0027swift_proxy_server_request_body_streaming_bytes\u0027, 5, {"}],"source_content_type":"text/x-python","patch_set":80,"id":"37b81182_cbbe523d","line":2325,"in_reply_to":"a4638938_f37e2d95","updated":"2025-10-10 18:27:29.000000000","message":"Thank you","commit_id":"0a724c02fbdf5c065f6d0a72b6ed2753379ee095"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"76643d87c6df6f4e4763013d011e0eb171b67d10","unresolved":true,"context_lines":[{"line_number":37,"context_line":"    FakeLabeledStatsdClient, debug_labeled_statsd_client"},{"line_number":38,"context_line":"from test.unit import patch_policies"},{"line_number":39,"context_line":"from test.unit.common.middleware.helpers import FakeAppThatExcepts, \\"},{"line_number":40,"context_line":"    FakeSwift, FakeAuthApp"},{"line_number":41,"context_line":"from test.unit.common.middleware.s3api import filter_factory \\"},{"line_number":42,"context_line":"    as s3api_filter_factory"},{"line_number":43,"context_line":""}],"source_content_type":"text/x-python","patch_set":84,"id":"15c0c18c_fa72e3bb","line":40,"range":{"start_line":40,"start_character":15,"end_line":40,"end_character":26},"updated":"2025-10-13 15:54:33.000000000","message":"this is now back in test.unit.common.middleware.s3api so import will fail","commit_id":"042e31fd0d5e282c830fd7ca2186e4a7aec31533"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"bf6fcd6af598f6f2171b61e9ee5ae1889d99cfc0","unresolved":false,"context_lines":[{"line_number":37,"context_line":"    FakeLabeledStatsdClient, debug_labeled_statsd_client"},{"line_number":38,"context_line":"from test.unit import patch_policies"},{"line_number":39,"context_line":"from test.unit.common.middleware.helpers import FakeAppThatExcepts, \\"},{"line_number":40,"context_line":"    FakeSwift, FakeAuthApp"},{"line_number":41,"context_line":"from test.unit.common.middleware.s3api import filter_factory \\"},{"line_number":42,"context_line":"    as s3api_filter_factory"},{"line_number":43,"context_line":""}],"source_content_type":"text/x-python","patch_set":84,"id":"6a6815c2_555e9ed3","line":40,"range":{"start_line":40,"start_character":15,"end_line":40,"end_character":26},"in_reply_to":"15c0c18c_fa72e3bb","updated":"2025-10-13 16:29:50.000000000","message":"Fixed tests with import","commit_id":"042e31fd0d5e282c830fd7ca2186e4a7aec31533"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"76643d87c6df6f4e4763013d011e0eb171b67d10","unresolved":true,"context_lines":[{"line_number":131,"context_line":"    \"\"\""},{"line_number":132,"context_line":"    # note: tests deliberately use this explicit rewriting middleware rather"},{"line_number":133,"context_line":"    # than relying on the behavior of other middleware that might change"},{"line_number":134,"context_line":"    def __init__(self, app, logger):"},{"line_number":135,"context_line":"        self.app \u003d app"},{"line_number":136,"context_line":"        self.logger \u003d logger"},{"line_number":137,"context_line":""}],"source_content_type":"text/x-python","patch_set":84,"id":"d2f5ce66_e095c4ae","line":134,"updated":"2025-10-13 15:54:33.000000000","message":"nit: my bad: if I was doing this again I would have passed the replacement path in as an arg to the class rather than have it hard-coded \u0027+segments\u0027, but we only use it in one test, so I guess it\u0027ll do.","commit_id":"042e31fd0d5e282c830fd7ca2186e4a7aec31533"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"bf6fcd6af598f6f2171b61e9ee5ae1889d99cfc0","unresolved":false,"context_lines":[{"line_number":131,"context_line":"    \"\"\""},{"line_number":132,"context_line":"    # note: tests deliberately use this explicit rewriting middleware rather"},{"line_number":133,"context_line":"    # than relying on the behavior of other middleware that might change"},{"line_number":134,"context_line":"    def __init__(self, app, logger):"},{"line_number":135,"context_line":"        self.app \u003d app"},{"line_number":136,"context_line":"        self.logger \u003d logger"},{"line_number":137,"context_line":""}],"source_content_type":"text/x-python","patch_set":84,"id":"7fb31312_2b3209cf","line":134,"in_reply_to":"d2f5ce66_e095c4ae","updated":"2025-10-13 16:29:50.000000000","message":"Acknowledged","commit_id":"042e31fd0d5e282c830fd7ca2186e4a7aec31533"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"9a60c6b09c949ba1aebc3f4ccb0189d2ae644a8b","unresolved":false,"context_lines":[{"line_number":454,"context_line":"            \u0027/v1.0/a/c/o/p/p2\u0027: object_labels,"},{"line_number":455,"context_line":"        }"},{"line_number":456,"context_line":""},{"line_number":457,"context_line":"        self.maxDiff \u003d None"},{"line_number":458,"context_line":""},{"line_number":459,"context_line":"    def _clear(self):"},{"line_number":460,"context_line":"        self.logger.clear()"}],"source_content_type":"text/x-python","patch_set":86,"id":"5dda7a6b_a20334a9","line":457,"updated":"2025-10-28 08:26:30.000000000","message":"We probably don\u0027t need the `maxDiff \u003d None` anymore, I assume it was from debugging?","commit_id":"1a081d4e3f01893c0bd898b1b877b9a95b1339b3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"28e694101f4c34119d225ed95d41eeda3a786d68","unresolved":false,"context_lines":[{"line_number":454,"context_line":"            \u0027/v1.0/a/c/o/p/p2\u0027: object_labels,"},{"line_number":455,"context_line":"        }"},{"line_number":456,"context_line":""},{"line_number":457,"context_line":"        self.maxDiff \u003d None"},{"line_number":458,"context_line":""},{"line_number":459,"context_line":"    def _clear(self):"},{"line_number":460,"context_line":"        self.logger.clear()"}],"source_content_type":"text/x-python","patch_set":86,"id":"ea770452_f7b38025","line":457,"in_reply_to":"4bd674a3_93a41aab","updated":"2025-10-28 21:29:27.000000000","message":"Acknowledged","commit_id":"1a081d4e3f01893c0bd898b1b877b9a95b1339b3"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"851483495da99afc66fa59549c3dbe4822ebc57c","unresolved":true,"context_lines":[{"line_number":454,"context_line":"            \u0027/v1.0/a/c/o/p/p2\u0027: object_labels,"},{"line_number":455,"context_line":"        }"},{"line_number":456,"context_line":""},{"line_number":457,"context_line":"        self.maxDiff \u003d None"},{"line_number":458,"context_line":""},{"line_number":459,"context_line":"    def _clear(self):"},{"line_number":460,"context_line":"        self.logger.clear()"}],"source_content_type":"text/x-python","patch_set":86,"id":"4bd674a3_93a41aab","line":457,"in_reply_to":"5dda7a6b_a20334a9","updated":"2025-10-28 08:30:10.000000000","message":"gertty seems to have marked this resolved.","commit_id":"1a081d4e3f01893c0bd898b1b877b9a95b1339b3"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"9a60c6b09c949ba1aebc3f4ccb0189d2ae644a8b","unresolved":false,"context_lines":[{"line_number":1980,"context_line":"    def test_xfer_stats_put(self):"},{"line_number":1981,"context_line":"        buffer_str \u003d b\u0027some stuff\\n\u0027 + \\"},{"line_number":1982,"context_line":"                     b\u0027some other stuff\\n\u0027 + \\"},{"line_number":1983,"context_line":"                     b\u0027some additional extra stuff\\n\u0027"},{"line_number":1984,"context_line":"        buffer_len \u003d len(buffer_str)"},{"line_number":1985,"context_line":"        read_calls \u003d 0"},{"line_number":1986,"context_line":"        read_bytes \u003d 0"}],"source_content_type":"text/x-python","patch_set":86,"id":"82fdfe41_643b7347","line":1983,"updated":"2025-10-28 08:26:30.000000000","message":"NIT: Could just wrap this in a () and then wouldn\u0027t need to escape end of line:\n\n    buffer_str \u003d (b\u0027some stuff\\n\u0027\n                  b\u0027some other stuff\\n\u0027\n                  b\u0027some additional extra stuff\\n\u0027)","commit_id":"1a081d4e3f01893c0bd898b1b877b9a95b1339b3"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"28e694101f4c34119d225ed95d41eeda3a786d68","unresolved":false,"context_lines":[{"line_number":1980,"context_line":"    def test_xfer_stats_put(self):"},{"line_number":1981,"context_line":"        buffer_str \u003d b\u0027some stuff\\n\u0027 + \\"},{"line_number":1982,"context_line":"                     b\u0027some other stuff\\n\u0027 + \\"},{"line_number":1983,"context_line":"                     b\u0027some additional extra stuff\\n\u0027"},{"line_number":1984,"context_line":"        buffer_len \u003d len(buffer_str)"},{"line_number":1985,"context_line":"        read_calls \u003d 0"},{"line_number":1986,"context_line":"        read_bytes \u003d 0"}],"source_content_type":"text/x-python","patch_set":86,"id":"b7158d32_4acb0563","line":1983,"in_reply_to":"7b6bcad0_b99e582c","updated":"2025-10-28 21:29:27.000000000","message":"Acknowledged","commit_id":"1a081d4e3f01893c0bd898b1b877b9a95b1339b3"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"7b2531c7f28d0fb2ec9be24e13cb165840e1ade0","unresolved":true,"context_lines":[{"line_number":1980,"context_line":"    def test_xfer_stats_put(self):"},{"line_number":1981,"context_line":"        buffer_str \u003d b\u0027some stuff\\n\u0027 + \\"},{"line_number":1982,"context_line":"                     b\u0027some other stuff\\n\u0027 + \\"},{"line_number":1983,"context_line":"                     b\u0027some additional extra stuff\\n\u0027"},{"line_number":1984,"context_line":"        buffer_len \u003d len(buffer_str)"},{"line_number":1985,"context_line":"        read_calls \u003d 0"},{"line_number":1986,"context_line":"        read_bytes \u003d 0"}],"source_content_type":"text/x-python","patch_set":86,"id":"7b6bcad0_b99e582c","line":1983,"in_reply_to":"82fdfe41_643b7347","updated":"2025-10-28 08:31:04.000000000","message":"Doh and this.. I think I found a gertty bug.","commit_id":"1a081d4e3f01893c0bd898b1b877b9a95b1339b3"}],"test/unit/common/test_utils.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"fbfb2a73e3030a8ddeecea098b1d17d6043d82a1","unresolved":true,"context_lines":[{"line_number":3349,"context_line":"        self.assertEqual(\u0027boom\u0027, str(cm.exception))"},{"line_number":3350,"context_line":""},{"line_number":3351,"context_line":""},{"line_number":3352,"context_line":"class TestCallbackInputProxy(unittest.TestCase):"},{"line_number":3353,"context_line":"    def test_read_all(self):"},{"line_number":3354,"context_line":"        self.assertEqual("},{"line_number":3355,"context_line":"            utils.CallbackInputProxy(io.BytesIO(b\u0027abc\u0027)).read(), b\u0027abc\u0027)"}],"source_content_type":"text/x-python","patch_set":65,"id":"a1d41b55_74bfbe4c","line":3352,"updated":"2025-08-07 12:33:31.000000000","message":"this test case needs to cover the callback feature. None of the tests currently instantiate a CallbackInputProxy with a callback function.\n\nA simple way would be to use a MagicMock object as a callback\n\n```\ncallback \u003d MagicMock(return_value\u003d\u0027modified_chunk\u0027)\nip \u003d utils.CallbackInputProxy(io.BytesIO(b\u0027original_chunk\u0027), callback)\nactual_chunk \u003d ip.read()\n```\n\nand then assert that \n(a) the callback MagicMock has the expected call_args_list\n(b) the actual_chunk is \u0027modified_chunk\u0027\n\nOnce you have that basic test, then repeat but vary the read size etc and check eof gets passed correctly.","commit_id":"d8a8d7e051e290790b5e8df57fca28166015a6c8"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"42336a8cd9e9c574e3e1b551220f2baf412a2b0d","unresolved":false,"context_lines":[{"line_number":3349,"context_line":"        self.assertEqual(\u0027boom\u0027, str(cm.exception))"},{"line_number":3350,"context_line":""},{"line_number":3351,"context_line":""},{"line_number":3352,"context_line":"class TestCallbackInputProxy(unittest.TestCase):"},{"line_number":3353,"context_line":"    def test_read_all(self):"},{"line_number":3354,"context_line":"        self.assertEqual("},{"line_number":3355,"context_line":"            utils.CallbackInputProxy(io.BytesIO(b\u0027abc\u0027)).read(), b\u0027abc\u0027)"}],"source_content_type":"text/x-python","patch_set":65,"id":"2c884d3b_7b54d255","line":3352,"in_reply_to":"a1d41b55_74bfbe4c","updated":"2025-08-07 22:46:58.000000000","message":"Done","commit_id":"d8a8d7e051e290790b5e8df57fca28166015a6c8"}]}
