)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"ad3f89585e29271466d0cb47deeeb68215272dc2","unresolved":true,"context_lines":[{"line_number":4,"context_line":"Commit:     shreeyad \u003cshreeyad@nvidia.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2026-05-15 13:29:10 -0500"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"add prom metrics to dispersion report"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Change-Id: I18206720b1fcffe63e6c0e968ec7de5cfd7786ed"},{"line_number":10,"context_line":"Signed-off-by: Shreeya Deshpande \u003cshreeyad@nvidia.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":13,"id":"0d077f37_111915d6","line":7,"updated":"2026-05-18 22:01:50.000000000","message":"I think it\u0027s useful to describe the scope of the change, what metrics are being emitted and why.","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"ec08556bc082dbf4c7572c5e0ff1d388a0f936c7","unresolved":true,"context_lines":[{"line_number":4,"context_line":"Commit:     shreeyad \u003cshreeyad@nvidia.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2026-05-15 13:29:10 -0500"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"add prom metrics to dispersion report"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Change-Id: I18206720b1fcffe63e6c0e968ec7de5cfd7786ed"},{"line_number":10,"context_line":"Signed-off-by: Shreeya Deshpande \u003cshreeyad@nvidia.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":13,"id":"a2b1c900_626278f6","line":7,"in_reply_to":"0d077f37_111915d6","updated":"2026-05-21 02:05:10.000000000","message":"Yeah, what Wael said. Here is the link to what openstack/opendev commit messages should look like:\nhttps://wiki.openstack.org/wiki/GitCommitMessages#Summary_of_Git_commit_message_structure","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"c3e08cd5bf3119b0547abbde356f6fdedb898b44","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     shreeyad \u003cshreeyad@nvidia.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2026-05-15 13:29:10 -0500"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"add prom metrics to dispersion report"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Change-Id: I18206720b1fcffe63e6c0e968ec7de5cfd7786ed"},{"line_number":10,"context_line":"Signed-off-by: Shreeya Deshpande \u003cshreeyad@nvidia.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":13,"id":"28db8a81_fad54552","line":7,"in_reply_to":"a2b1c900_626278f6","updated":"2026-05-21 21:49:26.000000000","message":"Done","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"ad3f89585e29271466d0cb47deeeb68215272dc2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":13,"id":"8b0bf3e2_ab50161d","updated":"2026-05-18 22:01:50.000000000","message":"Most of my comments are about clarification of scope. I think the integration work with `PrometheusClient` LGTM modulo a few minor comments. Happy to take another look once these comments are addressed.","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d7553688a4dd66be2c1630cf986c5d31061ecb06","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":20,"id":"c2bf8a76_b1c410fb","updated":"2026-05-27 06:36:17.000000000","message":"I think we have to get the dispersion report tests better situated before we can add these new behaviors; a lot of the \"how should this behave\" questions would be easier to explore if we had some test infra to help us out.","commit_id":"a92db4071a3dcf4e4e7da3e0d0dc8be5b0c1e360"}],"swift/cli/dispersion_report.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"c36d34ba7ab384f3d592ac4775ecb5a642410a49","unresolved":true,"context_lines":[{"line_number":38,"context_line":"json_output \u003d False"},{"line_number":39,"context_line":"debug \u003d False"},{"line_number":40,"context_line":"insecure \u003d False"},{"line_number":41,"context_line":"prom_client \u003d None"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"def get_error_log(prefix):"}],"source_content_type":"text/x-python","patch_set":13,"id":"880a2e99_ba3c2b25","line":41,"updated":"2026-05-18 19:09:31.000000000","message":"i would try to avoid addig new globals if possible","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"c3e08cd5bf3119b0547abbde356f6fdedb898b44","unresolved":false,"context_lines":[{"line_number":38,"context_line":"json_output \u003d False"},{"line_number":39,"context_line":"debug \u003d False"},{"line_number":40,"context_line":"insecure \u003d False"},{"line_number":41,"context_line":"prom_client \u003d None"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"def get_error_log(prefix):"}],"source_content_type":"text/x-python","patch_set":13,"id":"ca89fa6e_22b82f48","line":41,"in_reply_to":"880a2e99_ba3c2b25","updated":"2026-05-21 21:49:26.000000000","message":"Done","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"ad3f89585e29271466d0cb47deeeb68215272dc2","unresolved":true,"context_lines":[{"line_number":146,"context_line":"                           copies_found, labels)"},{"line_number":147,"context_line":"        prom_client.record(\u0027swift_dispersion_container_copies_expected\u0027,"},{"line_number":148,"context_line":"                           copies_expected, labels)"},{"line_number":149,"context_line":"        prom_client.record(\u0027swift_dispersion_container_pct_found\u0027,"},{"line_number":150,"context_line":"                           value, labels)"},{"line_number":151,"context_line":"        prom_client.record(\u0027swift_dispersion_container_retries\u0027,"},{"line_number":152,"context_line":"                           retries_done[0], labels)"}],"source_content_type":"text/x-python","patch_set":13,"id":"35199f47_a20c43a1","line":149,"updated":"2026-05-18 22:01:50.000000000","message":"Seems like a redundant stream. Can be derived from the first two metrics.","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"c3e08cd5bf3119b0547abbde356f6fdedb898b44","unresolved":false,"context_lines":[{"line_number":146,"context_line":"                           copies_found, labels)"},{"line_number":147,"context_line":"        prom_client.record(\u0027swift_dispersion_container_copies_expected\u0027,"},{"line_number":148,"context_line":"                           copies_expected, labels)"},{"line_number":149,"context_line":"        prom_client.record(\u0027swift_dispersion_container_pct_found\u0027,"},{"line_number":150,"context_line":"                           value, labels)"},{"line_number":151,"context_line":"        prom_client.record(\u0027swift_dispersion_container_retries\u0027,"},{"line_number":152,"context_line":"                           retries_done[0], labels)"}],"source_content_type":"text/x-python","patch_set":13,"id":"e48484f4_1d718c82","line":149,"in_reply_to":"35199f47_a20c43a1","updated":"2026-05-21 21:49:26.000000000","message":"Acknowledged","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"ad3f89585e29271466d0cb47deeeb68215272dc2","unresolved":true,"context_lines":[{"line_number":275,"context_line":"                           copies_found, labels)"},{"line_number":276,"context_line":"        prom_client.record(\u0027swift_dispersion_object_copies_expected\u0027,"},{"line_number":277,"context_line":"                           copies_expected, labels)"},{"line_number":278,"context_line":"        prom_client.record(\u0027swift_dispersion_object_pct_found\u0027,"},{"line_number":279,"context_line":"                           value, labels)"},{"line_number":280,"context_line":"        prom_client.record(\u0027swift_dispersion_object_retries\u0027,"},{"line_number":281,"context_line":"                           retries_done[0], labels)"}],"source_content_type":"text/x-python","patch_set":13,"id":"22811627_8417e04c","line":278,"updated":"2026-05-18 22:01:50.000000000","message":"Seems like a redundant stream. Can be derived from the first two metrics.","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"c3e08cd5bf3119b0547abbde356f6fdedb898b44","unresolved":false,"context_lines":[{"line_number":275,"context_line":"                           copies_found, labels)"},{"line_number":276,"context_line":"        prom_client.record(\u0027swift_dispersion_object_copies_expected\u0027,"},{"line_number":277,"context_line":"                           copies_expected, labels)"},{"line_number":278,"context_line":"        prom_client.record(\u0027swift_dispersion_object_pct_found\u0027,"},{"line_number":279,"context_line":"                           value, labels)"},{"line_number":280,"context_line":"        prom_client.record(\u0027swift_dispersion_object_retries\u0027,"},{"line_number":281,"context_line":"                           retries_done[0], labels)"}],"source_content_type":"text/x-python","patch_set":13,"id":"0456e341_ac2c3ec2","line":278,"in_reply_to":"22811627_8417e04c","updated":"2026-05-21 21:49:26.000000000","message":"Acknowledged","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"c36d34ba7ab384f3d592ac4775ecb5a642410a49","unresolved":true,"context_lines":[{"line_number":401,"context_line":"        from swiftclient import get_auth"},{"line_number":402,"context_line":"    except ImportError:"},{"line_number":403,"context_line":"        from swift.common.internal_client import get_auth"},{"line_number":404,"context_line":"    global json_output, prom_client"},{"line_number":405,"context_line":"    json_output \u003d config_true_value(conf.get(\u0027dump_json\u0027, \u0027no\u0027))"},{"line_number":406,"context_line":"    if policy_name is None:"},{"line_number":407,"context_line":"        policy \u003d POLICIES.default"}],"source_content_type":"text/x-python","patch_set":13,"id":"b3f7f203_6f1c7e5e","line":404,"updated":"2026-05-18 19:09:31.000000000","message":"i *think* all the plumbing for `prom_client` is already done - you can just define `prom_client \u003d None` here?","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"c3e08cd5bf3119b0547abbde356f6fdedb898b44","unresolved":false,"context_lines":[{"line_number":401,"context_line":"        from swiftclient import get_auth"},{"line_number":402,"context_line":"    except ImportError:"},{"line_number":403,"context_line":"        from swift.common.internal_client import get_auth"},{"line_number":404,"context_line":"    global json_output, prom_client"},{"line_number":405,"context_line":"    json_output \u003d config_true_value(conf.get(\u0027dump_json\u0027, \u0027no\u0027))"},{"line_number":406,"context_line":"    if policy_name is None:"},{"line_number":407,"context_line":"        policy \u003d POLICIES.default"}],"source_content_type":"text/x-python","patch_set":13,"id":"779906f5_fade9076","line":404,"in_reply_to":"b3f7f203_6f1c7e5e","updated":"2026-05-21 21:49:26.000000000","message":"Done","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"c36d34ba7ab384f3d592ac4775ecb5a642410a49","unresolved":true,"context_lines":[{"line_number":411,"context_line":"            exit(\u0027Unable to find policy: %s\u0027 % policy_name)"},{"line_number":412,"context_line":""},{"line_number":413,"context_line":"    if conf.get(\u0027metrics_filename\u0027):"},{"line_number":414,"context_line":"        prom_client \u003d get_prometheus_client(conf)"},{"line_number":415,"context_line":""},{"line_number":416,"context_line":"    if not json_output:"},{"line_number":417,"context_line":"        print(\u0027Using storage policy: %s \u0027 % policy.name)"}],"source_content_type":"text/x-python","patch_set":13,"id":"7843de36_bf5dfae4","line":414,"updated":"2026-05-18 19:09:31.000000000","message":"maybe a cool think we could do here is:\n\n```\nconf[\u0027filename\u0027] \u003d conf.get(\u0027metrics_filename\u0027, \u0027/dev/null\u0027)\n```\n\n... then we could *unconditionally* create/use a `prom_client` and then the \"dump to disk\" just has no side-effect.","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d7553688a4dd66be2c1630cf986c5d31061ecb06","unresolved":true,"context_lines":[{"line_number":411,"context_line":"            exit(\u0027Unable to find policy: %s\u0027 % policy_name)"},{"line_number":412,"context_line":""},{"line_number":413,"context_line":"    if conf.get(\u0027metrics_filename\u0027):"},{"line_number":414,"context_line":"        prom_client \u003d get_prometheus_client(conf)"},{"line_number":415,"context_line":""},{"line_number":416,"context_line":"    if not json_output:"},{"line_number":417,"context_line":"        print(\u0027Using storage policy: %s \u0027 % policy.name)"}],"source_content_type":"text/x-python","patch_set":13,"id":"d337868b_ce76bb9e","line":414,"in_reply_to":"3115d2f6_abc10171","updated":"2026-05-27 06:36:17.000000000","message":"\u003e write_all_stats already returns early when self.filename is None\n\nI think it raises a RuntimeError\n\n\u003e we would still construct the client and accumulate records in self._stats\n\nok, good - that\u0027s what I want\n\n\u003e write_all_stats becomes the only conditional\n\nthat would be better; create the client regardless, update the stats as we go - maybe `write_all_stats` (if configured to do so)\n\n\u003e Making this change: ... just adds extra work!\n\nI\u0027m not sure I understand this correctly, the \"work\" I want to minimize is me reading diffs with a bunch of `if prom_client` - I want the prom client to be created unconditionally, I want the stats to be accumulated unconditionally - this makes the instrumentation the minimum amount of tedious to read - and also maintain; because I can just add `prom_client.record(...)` instead of `if prom_client: prom_client.record(...)`.\n\n\u003e os.rename ... /dev/null would probably fail\n\nthat is *so true* - kudos for calling out a bad idea when you see it!\n\n\u003e might need to modify write_all_stats for that\n\nI\u0027d hesitate on that; we clearly have a use-case for \"instrument code with prom_client w/o having to constantly check `if prom_client`\" - but that doesn\u0027t mean we have a use-case for \"`prom_client.write_all_stats()` must silently noop if you accidentally typed `metircs_filename \u003d /opt/important.prom` in your config file\"\n\n... the answer might be something like:\n\n```\nself.logger.debug(\u0027Prometheus metrics filename: ...\u0027)\n```\n\nhttps://github.com/NVIDIA/swift/blob/master/swift/common/statsd_client.py#L546C13-L546C51\n\nso that if you\u0027re not getting metrics you can throw a `-v` on there and get a clue from debug logging:  \"wait why is filename \u003d None!?  I configured metircs_fi.... OOOOOHHHHHH\"\n\nif we find everywhere we want to call `metrics.write_all_metrics()` we end up just always having to write `if metrics.filename: metrics.write_all_metrics()` then maybe we should rethink the `RuntimeError` - especially if there\u0027s a better/obvious way to debug \"why does write_all_metrics not do anything and not error\" - maybe an info log line about all the awesome metrics you *would* be getting dumped if you\u0027d had configured a `metrics_filename` ???","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"c3e08cd5bf3119b0547abbde356f6fdedb898b44","unresolved":true,"context_lines":[{"line_number":411,"context_line":"            exit(\u0027Unable to find policy: %s\u0027 % policy_name)"},{"line_number":412,"context_line":""},{"line_number":413,"context_line":"    if conf.get(\u0027metrics_filename\u0027):"},{"line_number":414,"context_line":"        prom_client \u003d get_prometheus_client(conf)"},{"line_number":415,"context_line":""},{"line_number":416,"context_line":"    if not json_output:"},{"line_number":417,"context_line":"        print(\u0027Using storage policy: %s \u0027 % policy.name)"}],"source_content_type":"text/x-python","patch_set":13,"id":"3115d2f6_abc10171","line":414,"in_reply_to":"7843de36_bf5dfae4","updated":"2026-05-21 21:49:26.000000000","message":"write_all_stats already returns early when self.filename is None or self._stats is empty. When metrics_filename is unset, we would still construct the client and accumulate records in self._stats. write_all_stats becomes the only conditional! \nMaking this change: not checking if filename exisits and let write_all_stats figure it out just adds extra work!\n\nwrite_all_stats writes via tempfile + os.rename into os.path.dirname(filename), so /dev/null would probably fail. we might need to modify write_all_stats for that?","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"ad3f89585e29271466d0cb47deeeb68215272dc2","unresolved":true,"context_lines":[{"line_number":466,"context_line":"            conf.get(\u0027partitions\u0027), policy, prom_client)"},{"line_number":467,"context_line":""},{"line_number":468,"context_line":"    if prom_client:"},{"line_number":469,"context_line":"        prom_client.write_all_stats()"},{"line_number":470,"context_line":""},{"line_number":471,"context_line":"    return output"},{"line_number":472,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"0059f89f_6d97235c","line":469,"updated":"2026-05-18 22:01:50.000000000","message":"We should handle errors here so that this method can still return its output and the tool can finish execution.","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"c3e08cd5bf3119b0547abbde356f6fdedb898b44","unresolved":false,"context_lines":[{"line_number":466,"context_line":"            conf.get(\u0027partitions\u0027), policy, prom_client)"},{"line_number":467,"context_line":""},{"line_number":468,"context_line":"    if prom_client:"},{"line_number":469,"context_line":"        prom_client.write_all_stats()"},{"line_number":470,"context_line":""},{"line_number":471,"context_line":"    return output"},{"line_number":472,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"4978917a_d60da7da","line":469,"in_reply_to":"0059f89f_6d97235c","updated":"2026-05-21 21:49:26.000000000","message":"Acknowledged","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d7553688a4dd66be2c1630cf986c5d31061ecb06","unresolved":true,"context_lines":[{"line_number":48,"context_line":"            identifier \u003d \u0027%s:%s/%s\u0027 % (msg_or_exc.http_host,"},{"line_number":49,"context_line":"                                       msg_or_exc.http_port,"},{"line_number":50,"context_line":"                                       msg_or_exc.http_device)"},{"line_number":51,"context_line":"            if msg_or_exc.http_status \u003d\u003d 507:"},{"line_number":52,"context_line":"                if identifier not in unmounted:"},{"line_number":53,"context_line":"                    unmounted.append(identifier)"},{"line_number":54,"context_line":"                    print(\u0027ERROR: %s is unmounted -- This will \u0027"}],"source_content_type":"text/x-python","patch_set":20,"id":"588b41fd_6426d0ec","line":51,"updated":"2026-05-27 06:36:17.000000000","message":"it\u0027d be nice if we could some instrumentation counters on the observed errors by status label","commit_id":"a92db4071a3dcf4e4e7da3e0d0dc8be5b0c1e360"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d7553688a4dd66be2c1630cf986c5d31061ecb06","unresolved":true,"context_lines":[{"line_number":67,"context_line":"    return error_log"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"def container_dispersion_report(coropool, connpool, account, container_ring,"},{"line_number":71,"context_line":"                                retries, output_missing_partitions, policy,"},{"line_number":72,"context_line":"                                prom_client\u003dNone):"},{"line_number":73,"context_line":"    with connpool.item() as conn:"}],"source_content_type":"text/x-python","patch_set":20,"id":"e8fe2140_23f8a3de","line":70,"updated":"2026-05-27 06:36:17.000000000","message":"wow there\u0027s not an `account_dispersion_report`","commit_id":"a92db4071a3dcf4e4e7da3e0d0dc8be5b0c1e360"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d7553688a4dd66be2c1630cf986c5d31061ecb06","unresolved":true,"context_lines":[{"line_number":69,"context_line":""},{"line_number":70,"context_line":"def container_dispersion_report(coropool, connpool, account, container_ring,"},{"line_number":71,"context_line":"                                retries, output_missing_partitions, policy,"},{"line_number":72,"context_line":"                                prom_client\u003dNone):"},{"line_number":73,"context_line":"    with connpool.item() as conn:"},{"line_number":74,"context_line":"        containers \u003d [c[\u0027name\u0027] for c in conn.get_account("},{"line_number":75,"context_line":"            prefix\u003d\u0027dispersion_%d\u0027 % policy.idx, full_listing\u003dTrue)[1]]"}],"source_content_type":"text/x-python","patch_set":20,"id":"50e30c02_67b62a82","line":72,"updated":"2026-05-27 06:36:17.000000000","message":"I don\u0027t think prom_client should be kwarg - it\u0027s always passed in and the implementation is simpler if it\u0027s a required arg","commit_id":"a92db4071a3dcf4e4e7da3e0d0dc8be5b0c1e360"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d7553688a4dd66be2c1630cf986c5d31061ecb06","unresolved":true,"context_lines":[{"line_number":94,"context_line":"            try:"},{"line_number":95,"context_line":"                attempts, _junk \u003d direct_client.retry("},{"line_number":96,"context_line":"                    direct_client.direct_head_container, node, part, account,"},{"line_number":97,"context_line":"                    container, error_log\u003derror_log, retries\u003dretries)"},{"line_number":98,"context_line":"                retries_done[0] +\u003d attempts - 1"},{"line_number":99,"context_line":"                found_count +\u003d 1"},{"line_number":100,"context_line":"            except ClientException as err:"}],"source_content_type":"text/x-python","patch_set":20,"id":"f69020da_06b30a75","line":97,"updated":"2026-05-27 06:36:17.000000000","message":"this `error_log` kwarg is *wild*\n\nhttps://github.com/NVIDIA/swift/blob/master/swift/common/direct_client.py#L633","commit_id":"a92db4071a3dcf4e4e7da3e0d0dc8be5b0c1e360"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d7553688a4dd66be2c1630cf986c5d31061ecb06","unresolved":true,"context_lines":[{"line_number":154,"context_line":"        prom_client.record(\u0027swift_dispersion_container_distinct_partitions\u0027,"},{"line_number":155,"context_line":"                           distinct_partitions, labels)"},{"line_number":156,"context_line":""},{"line_number":157,"context_line":"    if not json_output:"},{"line_number":158,"context_line":"        print(\u0027\\r\\x1B[KQueried %d containers for dispersion reporting, \u0027"},{"line_number":159,"context_line":"              \u0027%d%s, %d retries\u0027 % (containers_listed, round(elapsed),"},{"line_number":160,"context_line":"                                    elapsed_unit, retries_done[0]))"}],"source_content_type":"text/x-python","patch_set":20,"id":"1ce45a55_c9e1d345","line":157,"updated":"2026-05-27 06:36:17.000000000","message":"something bothers me about making `metrics_filename` completely orthogonal to human/json output vs `stdout`\n\nit seems like there should be a \"pick one\" semantic","commit_id":"a92db4071a3dcf4e4e7da3e0d0dc8be5b0c1e360"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d7553688a4dd66be2c1630cf986c5d31061ecb06","unresolved":true,"context_lines":[{"line_number":177,"context_line":"                   \u0027copies_found\u0027: copies_found,"},{"line_number":178,"context_line":"                   \u0027copies_expected\u0027: copies_expected}"},{"line_number":179,"context_line":"        for missing_copies, num_parts in container_copies_missing.items():"},{"line_number":180,"context_line":"            results[\u0027missing_%d\u0027 % (missing_copies)] \u003d num_parts"},{"line_number":181,"context_line":"        return results"},{"line_number":182,"context_line":""},{"line_number":183,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"8c694cfe_59c848c8","line":180,"updated":"2026-05-27 06:36:17.000000000","message":"I think this is an import/key metric that I don\u0027t see represented in the prom output.\n\nit\u0027s the perfect candidate for a label:\n\n```\nmissing{num_copies\u003dN} num_parts\n```","commit_id":"a92db4071a3dcf4e4e7da3e0d0dc8be5b0c1e360"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d7553688a4dd66be2c1630cf986c5d31061ecb06","unresolved":true,"context_lines":[{"line_number":203,"context_line":"              \u0027been run?\u0027, file\u003dstderr)"},{"line_number":204,"context_line":"        stderr.flush()"},{"line_number":205,"context_line":"        return"},{"line_number":206,"context_line":"    retries_done \u003d [0]"},{"line_number":207,"context_line":"    objects_queried \u003d [0]"},{"line_number":208,"context_line":"    object_copies_found \u003d [0]"},{"line_number":209,"context_line":"    object_copies_expected \u003d [0]"}],"source_content_type":"text/x-python","patch_set":20,"id":"3e5a2985_f95431fc","line":206,"updated":"2026-05-27 06:36:17.000000000","message":"FWIW i\u0027m *pretty* sure this is just an ancient python spelling of `nonlocal` so that `retries_done +\u003d 1` in the closure doesn\u0027t define a new var in that scope.","commit_id":"a92db4071a3dcf4e4e7da3e0d0dc8be5b0c1e360"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d7553688a4dd66be2c1630cf986c5d31061ecb06","unresolved":true,"context_lines":[{"line_number":349,"context_line":""},{"line_number":350,"context_line":"[conf_file] defaults to %s\u0027\u0027\u0027.strip() % conffile)"},{"line_number":351,"context_line":"    parser.add_option(\u0027-j\u0027, \u0027--dump-json\u0027, action\u003d\u0027store_true\u0027, default\u003dFalse,"},{"line_number":352,"context_line":"                      help\u003d\u0027dump dispersion report in json format\u0027)"},{"line_number":353,"context_line":"    parser.add_option(\u0027-d\u0027, \u0027--debug\u0027, action\u003d\u0027store_true\u0027, default\u003dFalse,"},{"line_number":354,"context_line":"                      help\u003d\u0027print 404s to standard error\u0027)"},{"line_number":355,"context_line":"    parser.add_option(\u0027-p\u0027, \u0027--partitions\u0027, action\u003d\u0027store_true\u0027, default\u003dFalse,"}],"source_content_type":"text/x-python","patch_set":20,"id":"308e1d58_a6f512bf","line":352,"updated":"2026-05-27 06:36:17.000000000","message":"OMG ^\u0026*(ing OptionParser\n\nI think what I want to see is ArgumentParser\u0027s \"Mutual exclusion\"\n\nhttps://docs.python.org/3/library/argparse.html#mutual-exclusion\n\ni.e. \n\n```\ns-d-r --dump-json\ns-d-r --dump-prom\n```\n\nI\u0027m indifferent/unsure about:\n\n```\ns-d-r --dump-prom metrics.prom\n```\n\nvs.\n\n```\ns-d-r --dump-prom \u003e metrics.prom\n```\n\nin our cron file\n\n... but if we want to support `metrics_filename` from the config then we have to decide what to output to the console, and either of the two existing options seems like a waste if all we care about is what get\u0027s rendered into the metrics filename\n\n... I guess `2\u003e report.err` would still be useful","commit_id":"a92db4071a3dcf4e4e7da3e0d0dc8be5b0c1e360"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d7553688a4dd66be2c1630cf986c5d31061ecb06","unresolved":true,"context_lines":[{"line_number":467,"context_line":"        prom_client.write_all_stats()"},{"line_number":468,"context_line":"    except Exception as err:"},{"line_number":469,"context_line":"        print(\u0027ERROR: failed to write prometheus metrics: %s\u0027 % err,"},{"line_number":470,"context_line":"              file\u003dstderr)"},{"line_number":471,"context_line":"        stderr.flush()"},{"line_number":472,"context_line":""},{"line_number":473,"context_line":"    return output"}],"source_content_type":"text/x-python","patch_set":20,"id":"7323e677_229a1c33","line":470,"updated":"2026-05-27 06:36:17.000000000","message":"this is ohkay, but seems sort of noisy if the config didn\u0027t define `metrics_filename` and the cli didn\u0027t ask for `--dump-prom`\n\nOTOH, if they *did* configure `metrics_filename` or ask for `--dump-prom` it\u0027s really ugly to print an `ERROR` and then exit 0\n\nI don\u0027t think this is the right way to achive what ever we\u0027re going for.","commit_id":"a92db4071a3dcf4e4e7da3e0d0dc8be5b0c1e360"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d7553688a4dd66be2c1630cf986c5d31061ecb06","unresolved":true,"context_lines":[{"line_number":468,"context_line":"    except Exception as err:"},{"line_number":469,"context_line":"        print(\u0027ERROR: failed to write prometheus metrics: %s\u0027 % err,"},{"line_number":470,"context_line":"              file\u003dstderr)"},{"line_number":471,"context_line":"        stderr.flush()"},{"line_number":472,"context_line":""},{"line_number":473,"context_line":"    return output"},{"line_number":474,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"898b31bf_d7f5b42a","line":471,"updated":"2026-05-27 06:36:17.000000000","message":"I\u0027m not sure I\u0027m convinced that `print` would\u0027t do this to the stream/file already most of the time, but if it\u0027s the last thing we do before we exit it can\u0027t matter.","commit_id":"a92db4071a3dcf4e4e7da3e0d0dc8be5b0c1e360"}],"test/unit/cli/test_dispersion_report.py":[{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"ad3f89585e29271466d0cb47deeeb68215272dc2","unresolved":true,"context_lines":[{"line_number":64,"context_line":"    return ring"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"class TestMissingString(unittest.TestCase):"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"    def test_all_copies_missing(self):"},{"line_number":70,"context_line":"        result \u003d dispersion_report.missing_string(1, 3, 3)"}],"source_content_type":"text/x-python","patch_set":13,"id":"c18e9949_890ce24f","line":67,"range":{"start_line":67,"start_character":0,"end_line":67,"end_character":43},"updated":"2026-05-18 22:01:50.000000000","message":"I don\u0027t see an associated diff in the implementation file. Is this a rogue change or did you intend to expand test coverage for `missing_string`?","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"c3e08cd5bf3119b0547abbde356f6fdedb898b44","unresolved":false,"context_lines":[{"line_number":64,"context_line":"    return ring"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"class TestMissingString(unittest.TestCase):"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"    def test_all_copies_missing(self):"},{"line_number":70,"context_line":"        result \u003d dispersion_report.missing_string(1, 3, 3)"}],"source_content_type":"text/x-python","patch_set":13,"id":"e9400b2b_93c4e564","line":67,"range":{"start_line":67,"start_character":0,"end_line":67,"end_character":43},"in_reply_to":"c18e9949_890ce24f","updated":"2026-05-21 21:49:26.000000000","message":"just adding test coverage, not exactly related with the changes!","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"ad3f89585e29271466d0cb47deeeb68215272dc2","unresolved":true,"context_lines":[{"line_number":109,"context_line":"        p.idx \u003d idx"},{"line_number":110,"context_line":"        return p"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"    def test_no_containers_returns_none(self):"},{"line_number":113,"context_line":"        result \u003d dispersion_report.container_dispersion_report("},{"line_number":114,"context_line":"            make_coropool(), make_connpool(containers\u003d[]),"},{"line_number":115,"context_line":"            \u0027AUTH_test\u0027, make_ring(), 3, False, self._policy())"}],"source_content_type":"text/x-python","patch_set":13,"id":"39192f6b_dd44e3ae","line":112,"updated":"2026-05-18 22:01:50.000000000","message":"None of the following three tests assert new behavior. Is it intentional that you\u0027re expanding test coverage?","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"c3e08cd5bf3119b0547abbde356f6fdedb898b44","unresolved":false,"context_lines":[{"line_number":109,"context_line":"        p.idx \u003d idx"},{"line_number":110,"context_line":"        return p"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"    def test_no_containers_returns_none(self):"},{"line_number":113,"context_line":"        result \u003d dispersion_report.container_dispersion_report("},{"line_number":114,"context_line":"            make_coropool(), make_connpool(containers\u003d[]),"},{"line_number":115,"context_line":"            \u0027AUTH_test\u0027, make_ring(), 3, False, self._policy())"}],"source_content_type":"text/x-python","patch_set":13,"id":"31196041_1a373311","line":112,"in_reply_to":"39192f6b_dd44e3ae","updated":"2026-05-21 21:49:26.000000000","message":"yes, test coverage for dispersion_report is null! Writing tests here and there as I find feasible!","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"ad3f89585e29271466d0cb47deeeb68215272dc2","unresolved":true,"context_lines":[{"line_number":154,"context_line":"        prom_client.write_all_stats()"},{"line_number":155,"context_line":"        metrics \u003d read_metrics(metrics_file)"},{"line_number":156,"context_line":"        labels \u003d {\u0027policy\u0027: \u0027default\u0027}"},{"line_number":157,"context_line":"        for name in (\u0027swift_dispersion_container_copies_found\u0027,"},{"line_number":158,"context_line":"                     \u0027swift_dispersion_container_copies_expected\u0027,"},{"line_number":159,"context_line":"                     \u0027swift_dispersion_container_pct_found\u0027,"},{"line_number":160,"context_line":"                     \u0027swift_dispersion_container_retries\u0027,"}],"source_content_type":"text/x-python","patch_set":13,"id":"bf97499e_9187189e","line":157,"updated":"2026-05-18 22:01:50.000000000","message":"How about an assertion on the metric values, too?","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"c3e08cd5bf3119b0547abbde356f6fdedb898b44","unresolved":false,"context_lines":[{"line_number":154,"context_line":"        prom_client.write_all_stats()"},{"line_number":155,"context_line":"        metrics \u003d read_metrics(metrics_file)"},{"line_number":156,"context_line":"        labels \u003d {\u0027policy\u0027: \u0027default\u0027}"},{"line_number":157,"context_line":"        for name in (\u0027swift_dispersion_container_copies_found\u0027,"},{"line_number":158,"context_line":"                     \u0027swift_dispersion_container_copies_expected\u0027,"},{"line_number":159,"context_line":"                     \u0027swift_dispersion_container_pct_found\u0027,"},{"line_number":160,"context_line":"                     \u0027swift_dispersion_container_retries\u0027,"}],"source_content_type":"text/x-python","patch_set":13,"id":"29e754fc_c677459d","line":157,"in_reply_to":"bf97499e_9187189e","updated":"2026-05-21 21:49:26.000000000","message":"Done","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"ad3f89585e29271466d0cb47deeeb68215272dc2","unresolved":true,"context_lines":[{"line_number":179,"context_line":"        p.__int__ \u003d mock.Mock(return_value\u003didx)"},{"line_number":180,"context_line":"        return p"},{"line_number":181,"context_line":""},{"line_number":182,"context_line":"    def test_no_objects_returns_none(self):"},{"line_number":183,"context_line":"        result \u003d dispersion_report.object_dispersion_report("},{"line_number":184,"context_line":"            make_coropool(), make_connpool(objects\u003d[]),"},{"line_number":185,"context_line":"            \u0027AUTH_test\u0027, make_ring(), 3, False, self._policy())"}],"source_content_type":"text/x-python","patch_set":13,"id":"45201c09_f63d745d","line":182,"updated":"2026-05-18 22:01:50.000000000","message":"Are the three following tests just for expanding coverage? It would be useful to describe the scope of this patch in the commit message.","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"c3e08cd5bf3119b0547abbde356f6fdedb898b44","unresolved":false,"context_lines":[{"line_number":179,"context_line":"        p.__int__ \u003d mock.Mock(return_value\u003didx)"},{"line_number":180,"context_line":"        return p"},{"line_number":181,"context_line":""},{"line_number":182,"context_line":"    def test_no_objects_returns_none(self):"},{"line_number":183,"context_line":"        result \u003d dispersion_report.object_dispersion_report("},{"line_number":184,"context_line":"            make_coropool(), make_connpool(objects\u003d[]),"},{"line_number":185,"context_line":"            \u0027AUTH_test\u0027, make_ring(), 3, False, self._policy())"}],"source_content_type":"text/x-python","patch_set":13,"id":"4be35e5e_3ab809f5","line":182,"in_reply_to":"45201c09_f63d745d","updated":"2026-05-21 21:49:26.000000000","message":"Acknowledged","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"ad3f89585e29271466d0cb47deeeb68215272dc2","unresolved":true,"context_lines":[{"line_number":231,"context_line":"            self.assertIn(metric_key(name, **labels), metrics)"},{"line_number":232,"context_line":""},{"line_number":233,"context_line":""},{"line_number":234,"context_line":"# maybe not needed?"},{"line_number":235,"context_line":"class TestPrometheusClient(unittest.TestCase):"},{"line_number":236,"context_line":""},{"line_number":237,"context_line":"    @with_tempdir"}],"source_content_type":"text/x-python","patch_set":13,"id":"c8e4d5e6_168869cd","line":234,"updated":"2026-05-18 22:01:50.000000000","message":"Because they test the client itself? Seems reasonable to move them somewhere else. None of these tests depend on `dispersion_report.py`.","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"c3e08cd5bf3119b0547abbde356f6fdedb898b44","unresolved":false,"context_lines":[{"line_number":231,"context_line":"            self.assertIn(metric_key(name, **labels), metrics)"},{"line_number":232,"context_line":""},{"line_number":233,"context_line":""},{"line_number":234,"context_line":"# maybe not needed?"},{"line_number":235,"context_line":"class TestPrometheusClient(unittest.TestCase):"},{"line_number":236,"context_line":""},{"line_number":237,"context_line":"    @with_tempdir"}],"source_content_type":"text/x-python","patch_set":13,"id":"cff86713_bc4b4b6a","line":234,"in_reply_to":"1b907828_eee81337","updated":"2026-05-21 21:49:26.000000000","message":"I feel that the prom client is well tested in test_prom_metrics.py already!","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"ec08556bc082dbf4c7572c5e0ff1d388a0f936c7","unresolved":true,"context_lines":[{"line_number":231,"context_line":"            self.assertIn(metric_key(name, **labels), metrics)"},{"line_number":232,"context_line":""},{"line_number":233,"context_line":""},{"line_number":234,"context_line":"# maybe not needed?"},{"line_number":235,"context_line":"class TestPrometheusClient(unittest.TestCase):"},{"line_number":236,"context_line":""},{"line_number":237,"context_line":"    @with_tempdir"}],"source_content_type":"text/x-python","patch_set":13,"id":"1b907828_eee81337","line":234,"in_reply_to":"c8e4d5e6_168869cd","updated":"2026-05-21 02:05:10.000000000","message":"If it\u0027s generic enough, maybe it could be placed in test_prom_metrics maybe? but if there is specific tests for dispersion related metrics then it could stay, seems `test_records_metrics_to_prom_client` does a pretty good job of getting dispersion metrics, serialising them to the prom file and pulling them back out. So maybe these could be moved.","commit_id":"d43b4af67d87eb1f98707fed6b3ff433f00a6d5f"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"ec08556bc082dbf4c7572c5e0ff1d388a0f936c7","unresolved":true,"context_lines":[{"line_number":236,"context_line":""},{"line_number":237,"context_line":"    @with_tempdir"},{"line_number":238,"context_line":"    def test_initializes_from_conf(self, tempdir):"},{"line_number":239,"context_line":"        metrics_file \u003d os.path.join(tempdir, \u0027metrics.txt\u0027)"},{"line_number":240,"context_line":"        client \u003d get_prometheus_client({\u0027metrics_filename\u0027: metrics_file})"},{"line_number":241,"context_line":"        self.assertIsNotNone(client)"},{"line_number":242,"context_line":"        self.assertEqual(client.filename, metrics_file)"}],"source_content_type":"text/x-python","patch_set":16,"id":"f7d79526_49247a82","line":239,"range":{"start_line":239,"start_character":46,"end_line":239,"end_character":57},"updated":"2026-05-21 02:05:10.000000000","message":"Are we expecting these to be .txt files in real life, or should be make them .prom or something?\n\nI know it probably doesn\u0027t matter. But feel .txt seems wrong here.","commit_id":"04622259f9d7182666e8f0c6b675cda3ffcf36f9"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d7553688a4dd66be2c1630cf986c5d31061ecb06","unresolved":true,"context_lines":[{"line_number":236,"context_line":""},{"line_number":237,"context_line":"    @with_tempdir"},{"line_number":238,"context_line":"    def test_initializes_from_conf(self, tempdir):"},{"line_number":239,"context_line":"        metrics_file \u003d os.path.join(tempdir, \u0027metrics.txt\u0027)"},{"line_number":240,"context_line":"        client \u003d get_prometheus_client({\u0027metrics_filename\u0027: metrics_file})"},{"line_number":241,"context_line":"        self.assertIsNotNone(client)"},{"line_number":242,"context_line":"        self.assertEqual(client.filename, metrics_file)"}],"source_content_type":"text/x-python","patch_set":16,"id":"74b4e884_ce40f9ae","line":239,"range":{"start_line":239,"start_character":46,"end_line":239,"end_character":57},"in_reply_to":"2e1bba15_ed7907b0","updated":"2026-05-27 06:36:17.000000000","message":"look in `/opt/ss/support/metrics`","commit_id":"04622259f9d7182666e8f0c6b675cda3ffcf36f9"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"c3e08cd5bf3119b0547abbde356f6fdedb898b44","unresolved":true,"context_lines":[{"line_number":236,"context_line":""},{"line_number":237,"context_line":"    @with_tempdir"},{"line_number":238,"context_line":"    def test_initializes_from_conf(self, tempdir):"},{"line_number":239,"context_line":"        metrics_file \u003d os.path.join(tempdir, \u0027metrics.txt\u0027)"},{"line_number":240,"context_line":"        client \u003d get_prometheus_client({\u0027metrics_filename\u0027: metrics_file})"},{"line_number":241,"context_line":"        self.assertIsNotNone(client)"},{"line_number":242,"context_line":"        self.assertEqual(client.filename, metrics_file)"}],"source_content_type":"text/x-python","patch_set":16,"id":"2e1bba15_ed7907b0","line":239,"range":{"start_line":239,"start_character":46,"end_line":239,"end_character":57},"in_reply_to":"f7d79526_49247a82","updated":"2026-05-21 21:49:26.000000000","message":"Yep! .prom would look better! I dont know if they are goinf to be .txt in real life. @clay.gerrard@gmail.com any idea?","commit_id":"04622259f9d7182666e8f0c6b675cda3ffcf36f9"}]}
