)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"5186b18716915021ffc30b6e1e032e0a4d3089b9","unresolved":false,"context_lines":[{"line_number":9,"context_line":"This patch adds metrics to ironic-lib, so that it can be used by both"},{"line_number":10,"context_line":"Ironic and IPA. It implements a generic MetricLogger including timers,"},{"line_number":11,"context_line":"counters, and gauges with their respective decorators and context"},{"line_number":12,"context_line":"managers. Two default MetricLogger are included: NoopMetricLogger and"},{"line_number":13,"context_line":"StatsdMetricLogger."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Change-Id: I8a62414e6c03acb6f3457f1b8f81c03a9d3a8576"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":16,"id":"bab6814e_9e398c44","line":12,"updated":"2016-05-24 17:48:49.000000000","message":"Nit: \"MetricLoggers\"","commit_id":"1d6f48ae3b5d4373473319b6a19bbc6199975d1d"}],"ironic_lib/exception.py":[{"author":{"_account_id":13295,"name":"Mario Villaplana","email":"mario.villaplana@gmail.com","username":"mariojv"},"change_message_id":"8acf5a19dfdd35159c633dca5631ad7b04672ee1","unresolved":false,"context_lines":[{"line_number":106,"context_line":""},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"class SendMetricFailure(IronicException):"},{"line_number":109,"context_line":"    message \u003d _(\"Failed to send the metric value to the metric backed\")"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_823e0d8a","line":109,"updated":"2016-04-06 16:18:24.000000000","message":"s/backed/backend","commit_id":"03e699b79393b3b7067bbae1b63848b5df2c33b2"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"0ec67bc5131f383bec44ece4b7d379bbc9a4e243","unresolved":false,"context_lines":[{"line_number":102,"context_line":""},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"class MetricInvalidConfig(IronicException):"},{"line_number":105,"context_line":"    message \u003d _(\"Invalid value for config option %(value_name)\")"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a061dce_6338c9d3","line":105,"updated":"2016-04-07 20:07:37.000000000","message":"This makes me think that \u0027value_name\u0027 is a value name. But in reality it appears to be a message. At least how it is used in the code.","commit_id":"ac076f08c0a99730a82b638e5f97534708831ea7"},{"author":{"_account_id":19686,"name":"Ramamani Yeleswarapu","email":"ramamani.yeleswarapu@intel.com","username":"Rama_Y"},"change_message_id":"f8c5c1e9d76a293f9690e9515931df02f3b494f1","unresolved":false,"context_lines":[{"line_number":101,"context_line":"                \"File system %(fs)s is not supported.\")"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"class MetricInvalidConfig(IronicException):"},{"line_number":105,"context_line":"    message \u003d _(\"Invalid value for metrics config option: %(reason)s\")"}],"source_content_type":"text/x-python","patch_set":13,"id":"dab17558_db721249","line":104,"updated":"2016-05-12 21:57:59.000000000","message":"Nit: InvalidMetricConfig sounds better in my opinion.","commit_id":"00a119032511f2038d7aadeef0a12993e9b1fc4f"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2dffffff58b20b4a0e8fd79b7a97d4618f658296","unresolved":false,"context_lines":[{"line_number":101,"context_line":"                \"File system %(fs)s is not supported.\")"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"class MetricInvalidConfig(IronicException):"},{"line_number":105,"context_line":"    message \u003d _(\"Invalid value for metrics config option: %(reason)s\")"}],"source_content_type":"text/x-python","patch_set":13,"id":"dab17558_752c7299","line":104,"in_reply_to":"dab17558_db721249","updated":"2016-05-16 10:08:11.000000000","message":"Done","commit_id":"00a119032511f2038d7aadeef0a12993e9b1fc4f"}],"ironic_lib/metrics.py":[{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"3a8cdfa7e35f10713cd77bde7f9b8bfaa424d233","unresolved":false,"context_lines":[{"line_number":20,"context_line":"import socket"},{"line_number":21,"context_line":"import time"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"from contextlib import contextmanager"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"from oslo_config import cfg"},{"line_number":26,"context_line":"from oslo_log import log"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a061dce_13456d16","line":23,"updated":"2016-04-05 15:55:54.000000000","message":"This should be in the first section, not here by itself.","commit_id":"d6c7dc2d82d709585c9499386c29e309f3135339"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"3a8cdfa7e35f10713cd77bde7f9b8bfaa424d233","unresolved":false,"context_lines":[{"line_number":25,"context_line":"from oslo_config import cfg"},{"line_number":26,"context_line":"from oslo_log import log"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"import six"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"metrics_opts \u003d ["},{"line_number":31,"context_line":"    cfg.StrOpt(\u0027backend\u0027,"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a061dce_93517ddb","line":28,"updated":"2016-04-05 15:55:54.000000000","message":"This should be with the oslo_config section.","commit_id":"d6c7dc2d82d709585c9499386c29e309f3135339"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"b2fdcb6ecd38c7f32ab7690ebf5c76bd3319fd33","unresolved":false,"context_lines":[{"line_number":15,"context_line":""},{"line_number":16,"context_line":"import abc"},{"line_number":17,"context_line":"import contextlib"},{"line_number":18,"context_line":"from contextlib import contextmanager"},{"line_number":19,"context_line":"import functools"},{"line_number":20,"context_line":"import random"},{"line_number":21,"context_line":"import socket"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a061dce_ce086cdc","line":18,"updated":"2016-04-05 16:15:41.000000000","message":"Bikeshedding:\n\nSeems like with only two uses could just do:\n\n @contextlib.contextmanager\n\nbelow","commit_id":"95dc18ccf5a71a5897fbc13ffd5a3b8772cf35c7"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2dc85b7542df116a2419e9da4a52c0f273f4ee62","unresolved":false,"context_lines":[{"line_number":15,"context_line":""},{"line_number":16,"context_line":"import abc"},{"line_number":17,"context_line":"import contextlib"},{"line_number":18,"context_line":"from contextlib import contextmanager"},{"line_number":19,"context_line":"import functools"},{"line_number":20,"context_line":"import random"},{"line_number":21,"context_line":"import socket"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a061dce_3665d61d","line":18,"in_reply_to":"9a061dce_4973b6e7","updated":"2016-04-06 11:14:48.000000000","message":"Done","commit_id":"95dc18ccf5a71a5897fbc13ffd5a3b8772cf35c7"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"11810d6d7bad80baeeabc9b94e631d43a0f87c77","unresolved":false,"context_lines":[{"line_number":15,"context_line":""},{"line_number":16,"context_line":"import abc"},{"line_number":17,"context_line":"import contextlib"},{"line_number":18,"context_line":"from contextlib import contextmanager"},{"line_number":19,"context_line":"import functools"},{"line_number":20,"context_line":"import random"},{"line_number":21,"context_line":"import socket"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a061dce_4973b6e7","line":18,"in_reply_to":"9a061dce_ce086cdc","updated":"2016-04-05 16:36:19.000000000","message":"+1, I think it\u0027s better to just do one import","commit_id":"95dc18ccf5a71a5897fbc13ffd5a3b8772cf35c7"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"b2fdcb6ecd38c7f32ab7690ebf5c76bd3319fd33","unresolved":false,"context_lines":[{"line_number":32,"context_line":"                    \u0027backends are \"noop\" and \"statsd\".\u0027),"},{"line_number":33,"context_line":"    cfg.BoolOpt(\u0027prepend_host\u0027,"},{"line_number":34,"context_line":"                default\u003dFalse,"},{"line_number":35,"context_line":"                help\u003d\u0027Prepend the value of CONF.host to all metric names. \u0027"},{"line_number":36,"context_line":"                     \u0027The format of metric names is \u0027"},{"line_number":37,"context_line":"                     \u0027[global_prefix.][host_name.]prefix.metric_name.\u0027),"},{"line_number":38,"context_line":"    cfg.BoolOpt(\u0027prepend_host_reverse\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a061dce_535a4551","line":35,"updated":"2016-04-05 16:15:41.000000000","message":"Will the user know what \u0027CONF.host\u0027 is?  Is that an internal thing?\n\nFor the user what will CONF.host correspond to in the config file?","commit_id":"95dc18ccf5a71a5897fbc13ffd5a3b8772cf35c7"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2dc85b7542df116a2419e9da4a52c0f273f4ee62","unresolved":false,"context_lines":[{"line_number":32,"context_line":"                    \u0027backends are \"noop\" and \"statsd\".\u0027),"},{"line_number":33,"context_line":"    cfg.BoolOpt(\u0027prepend_host\u0027,"},{"line_number":34,"context_line":"                default\u003dFalse,"},{"line_number":35,"context_line":"                help\u003d\u0027Prepend the value of CONF.host to all metric names. \u0027"},{"line_number":36,"context_line":"                     \u0027The format of metric names is \u0027"},{"line_number":37,"context_line":"                     \u0027[global_prefix.][host_name.]prefix.metric_name.\u0027),"},{"line_number":38,"context_line":"    cfg.BoolOpt(\u0027prepend_host_reverse\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a061dce_364cb69d","line":35,"in_reply_to":"9a061dce_535a4551","updated":"2016-04-06 11:14:48.000000000","message":"I updated the comment to make it clearer. Is it ok?\n\nIt corresponds to the \"host\" option in the config file.","commit_id":"95dc18ccf5a71a5897fbc13ffd5a3b8772cf35c7"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"df5fd2a3683ef4aee915217d6dd11dfd6626da5e","unresolved":false,"context_lines":[{"line_number":41,"context_line":"                \u0027(to better match the reverse hierarchical form of domain \u0027"},{"line_number":42,"context_line":"                \u0027names).\u0027),"},{"line_number":43,"context_line":"    cfg.StrOpt(\u0027global_prefix\u0027,"},{"line_number":44,"context_line":"               default\u003d\u0027\u0027,"},{"line_number":45,"context_line":"               help\u003d\u0027Prefix all metric names with this value \u0027"},{"line_number":46,"context_line":"                    \u0027The format of metric names is \u0027"},{"line_number":47,"context_line":"                    \u0027[global_prefix.][host_name.]prefix.metric_name.\u0027),"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a061dce_0ecee4b3","line":44,"updated":"2016-04-05 16:12:43.000000000","message":"nit: default empty string is not needed here, will be None if not set, will work for your code l310.","commit_id":"95dc18ccf5a71a5897fbc13ffd5a3b8772cf35c7"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2dc85b7542df116a2419e9da4a52c0f273f4ee62","unresolved":false,"context_lines":[{"line_number":41,"context_line":"                \u0027(to better match the reverse hierarchical form of domain \u0027"},{"line_number":42,"context_line":"                \u0027names).\u0027),"},{"line_number":43,"context_line":"    cfg.StrOpt(\u0027global_prefix\u0027,"},{"line_number":44,"context_line":"               default\u003d\u0027\u0027,"},{"line_number":45,"context_line":"               help\u003d\u0027Prefix all metric names with this value \u0027"},{"line_number":46,"context_line":"                    \u0027The format of metric names is \u0027"},{"line_number":47,"context_line":"                    \u0027[global_prefix.][host_name.]prefix.metric_name.\u0027),"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a061dce_5647aa76","line":44,"in_reply_to":"9a061dce_0ecee4b3","updated":"2016-04-06 11:14:48.000000000","message":"Done","commit_id":"95dc18ccf5a71a5897fbc13ffd5a3b8772cf35c7"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"df5fd2a3683ef4aee915217d6dd11dfd6626da5e","unresolved":false,"context_lines":[{"line_number":48,"context_line":"    cfg.StrOpt(\u0027statsd_host\u0027,"},{"line_number":49,"context_line":"               default\u003d\u0027localhost\u0027,"},{"line_number":50,"context_line":"               help\u003d\u0027Host for use with the statsd backend.\u0027),"},{"line_number":51,"context_line":"    cfg.IntOpt(\u0027statsd_port\u0027,"},{"line_number":52,"context_line":"               default\u003d8125,"},{"line_number":53,"context_line":"               help\u003d\u0027Port to use with the statsd backend.\u0027)"},{"line_number":54,"context_line":"]"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a061dce_0e454416","line":51,"updated":"2016-04-05 16:12:43.000000000","message":"Please use PortOpt here.","commit_id":"95dc18ccf5a71a5897fbc13ffd5a3b8772cf35c7"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"b2fdcb6ecd38c7f32ab7690ebf5c76bd3319fd33","unresolved":false,"context_lines":[{"line_number":48,"context_line":"    cfg.StrOpt(\u0027statsd_host\u0027,"},{"line_number":49,"context_line":"               default\u003d\u0027localhost\u0027,"},{"line_number":50,"context_line":"               help\u003d\u0027Host for use with the statsd backend.\u0027),"},{"line_number":51,"context_line":"    cfg.IntOpt(\u0027statsd_port\u0027,"},{"line_number":52,"context_line":"               default\u003d8125,"},{"line_number":53,"context_line":"               help\u003d\u0027Port to use with the statsd backend.\u0027)"},{"line_number":54,"context_line":"]"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a061dce_ceecec2b","line":51,"updated":"2016-04-05 16:15:41.000000000","message":"Use cfg.PortOpt","commit_id":"95dc18ccf5a71a5897fbc13ffd5a3b8772cf35c7"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2dc85b7542df116a2419e9da4a52c0f273f4ee62","unresolved":false,"context_lines":[{"line_number":48,"context_line":"    cfg.StrOpt(\u0027statsd_host\u0027,"},{"line_number":49,"context_line":"               default\u003d\u0027localhost\u0027,"},{"line_number":50,"context_line":"               help\u003d\u0027Host for use with the statsd backend.\u0027),"},{"line_number":51,"context_line":"    cfg.IntOpt(\u0027statsd_port\u0027,"},{"line_number":52,"context_line":"               default\u003d8125,"},{"line_number":53,"context_line":"               help\u003d\u0027Port to use with the statsd backend.\u0027)"},{"line_number":54,"context_line":"]"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a061dce_b660c602","line":51,"in_reply_to":"9a061dce_ceecec2b","updated":"2016-04-06 11:14:48.000000000","message":"Done","commit_id":"95dc18ccf5a71a5897fbc13ffd5a3b8772cf35c7"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"b2fdcb6ecd38c7f32ab7690ebf5c76bd3319fd33","unresolved":false,"context_lines":[{"line_number":59,"context_line":"LOG \u003d log.getLogger(__name__)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"def _time():"},{"line_number":63,"context_line":"    return time.time()"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"9a061dce_0eb424cf","line":62,"updated":"2016-04-05 16:15:41.000000000","message":"I assume this is here to help with testing/mocking. Can a comment be made to that effect if so.","commit_id":"95dc18ccf5a71a5897fbc13ffd5a3b8772cf35c7"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2dc85b7542df116a2419e9da4a52c0f273f4ee62","unresolved":false,"context_lines":[{"line_number":59,"context_line":"LOG \u003d log.getLogger(__name__)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"def _time():"},{"line_number":63,"context_line":"    return time.time()"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"9a061dce_965dc249","line":62,"in_reply_to":"9a061dce_0eb424cf","updated":"2016-04-06 11:14:48.000000000","message":"Done","commit_id":"95dc18ccf5a71a5897fbc13ffd5a3b8772cf35c7"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"df5fd2a3683ef4aee915217d6dd11dfd6626da5e","unresolved":false,"context_lines":[{"line_number":71,"context_line":"        if isinstance(prefix_parts, six.string_types):"},{"line_number":72,"context_line":"            self._prefix_parts \u003d [prefix_parts]"},{"line_number":73,"context_line":"        else:"},{"line_number":74,"context_line":"            self._prefix_parts \u003d list(prefix_parts)"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"        self._delimiter \u003d delimiter"},{"line_number":77,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"9a061dce_6e732081","line":74,"updated":"2016-04-05 16:12:43.000000000","message":"Is prefix_parts a list already?","commit_id":"95dc18ccf5a71a5897fbc13ffd5a3b8772cf35c7"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2dc85b7542df116a2419e9da4a52c0f273f4ee62","unresolved":false,"context_lines":[{"line_number":71,"context_line":"        if isinstance(prefix_parts, six.string_types):"},{"line_number":72,"context_line":"            self._prefix_parts \u003d [prefix_parts]"},{"line_number":73,"context_line":"        else:"},{"line_number":74,"context_line":"            self._prefix_parts \u003d list(prefix_parts)"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"        self._delimiter \u003d delimiter"},{"line_number":77,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"9a061dce_76390ef2","line":74,"in_reply_to":"9a061dce_6e732081","updated":"2016-04-06 11:14:48.000000000","message":"Yes, the prefix can be passed as a list. If not, the list is created in init.","commit_id":"95dc18ccf5a71a5897fbc13ffd5a3b8772cf35c7"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"df5fd2a3683ef4aee915217d6dd11dfd6626da5e","unresolved":false,"context_lines":[{"line_number":82,"context_line":"        return self._delimiter.join(self._prefix_parts + list(m_parts))"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"    def gauge(self, m_parts, m_value):"},{"line_number":85,"context_line":"        \"\"\"Send gauge metric data.\"\"\""},{"line_number":86,"context_line":"        self._gauge(self._getMetricName(m_parts), m_value)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def counter(self, m_parts, m_value, sample_rate\u003dNone):"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a061dce_8e72f447","line":85,"updated":"2016-04-05 16:12:43.000000000","message":"Please add parameters description to docstring for all public methods.","commit_id":"95dc18ccf5a71a5897fbc13ffd5a3b8772cf35c7"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2dc85b7542df116a2419e9da4a52c0f273f4ee62","unresolved":false,"context_lines":[{"line_number":82,"context_line":"        return self._delimiter.join(self._prefix_parts + list(m_parts))"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"    def gauge(self, m_parts, m_value):"},{"line_number":85,"context_line":"        \"\"\"Send gauge metric data.\"\"\""},{"line_number":86,"context_line":"        self._gauge(self._getMetricName(m_parts), m_value)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def counter(self, m_parts, m_value, sample_rate\u003dNone):"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a061dce_563e8ada","line":85,"in_reply_to":"9a061dce_8e72f447","updated":"2016-04-06 11:14:48.000000000","message":"Done","commit_id":"95dc18ccf5a71a5897fbc13ffd5a3b8772cf35c7"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"df5fd2a3683ef4aee915217d6dd11dfd6626da5e","unresolved":false,"context_lines":[{"line_number":98,"context_line":"        \"\"\""},{"line_number":99,"context_line":"        if (sample_rate is not None and"},{"line_number":100,"context_line":"                (sample_rate \u003c 0.0 or sample_rate \u003e 1.0)):"},{"line_number":101,"context_line":"            raise ValueError(\"sample_rate must be None, or in the interval \""},{"line_number":102,"context_line":"                             \"[0.0, 1.0]\")"},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"        if sample_rate is None or random.random() \u003c sample_rate:"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a061dce_8ea9547e","line":101,"updated":"2016-04-05 16:12:43.000000000","message":"Message should be translated with _(). Also please use custom IronicException here.","commit_id":"95dc18ccf5a71a5897fbc13ffd5a3b8772cf35c7"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2dc85b7542df116a2419e9da4a52c0f273f4ee62","unresolved":false,"context_lines":[{"line_number":98,"context_line":"        \"\"\""},{"line_number":99,"context_line":"        if (sample_rate is not None and"},{"line_number":100,"context_line":"                (sample_rate \u003c 0.0 or sample_rate \u003e 1.0)):"},{"line_number":101,"context_line":"            raise ValueError(\"sample_rate must be None, or in the interval \""},{"line_number":102,"context_line":"                             \"[0.0, 1.0]\")"},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"        if sample_rate is None or random.random() \u003c sample_rate:"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a061dce_b62726c9","line":101,"in_reply_to":"9a061dce_8ea9547e","updated":"2016-04-06 11:14:48.000000000","message":"Done","commit_id":"95dc18ccf5a71a5897fbc13ffd5a3b8772cf35c7"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"b2fdcb6ecd38c7f32ab7690ebf5c76bd3319fd33","unresolved":false,"context_lines":[{"line_number":226,"context_line":"            do_something()"},{"line_number":227,"context_line":"        \"\"\""},{"line_number":228,"context_line":"        self.counter(parts, 1, sample_rate\u003dsample_rate)"},{"line_number":229,"context_line":"        yield"},{"line_number":230,"context_line":""},{"line_number":231,"context_line":""},{"line_number":232,"context_line":"class NoopMetricLogger(MetricLogger):"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a061dce_2ea00843","line":229,"updated":"2016-04-05 16:15:41.000000000","message":"I guess I\u0027m being dumb, but what does this do? I\u0027m used to something happening after the yield, so I\u0027m a little confused.","commit_id":"95dc18ccf5a71a5897fbc13ffd5a3b8772cf35c7"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2dc85b7542df116a2419e9da4a52c0f273f4ee62","unresolved":false,"context_lines":[{"line_number":226,"context_line":"            do_something()"},{"line_number":227,"context_line":"        \"\"\""},{"line_number":228,"context_line":"        self.counter(parts, 1, sample_rate\u003dsample_rate)"},{"line_number":229,"context_line":"        yield"},{"line_number":230,"context_line":""},{"line_number":231,"context_line":""},{"line_number":232,"context_line":"class NoopMetricLogger(MetricLogger):"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a061dce_161ff26c","line":229,"in_reply_to":"9a061dce_2ea00843","updated":"2016-04-06 11:14:48.000000000","message":"Not at all :) This function is supposed to count the number of calls happening, so the context manager increments the counter, then yield (which calls do_something() in the example). I am not sure we need to add something after that: what do you think?","commit_id":"95dc18ccf5a71a5897fbc13ffd5a3b8772cf35c7"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"df5fd2a3683ef4aee915217d6dd11dfd6626da5e","unresolved":false,"context_lines":[{"line_number":272,"context_line":"        # Ideally, we\u0027d cache a sending socket in self, but that"},{"line_number":273,"context_line":"        # results in a socket getting shared by multiple green threads."},{"line_number":274,"context_line":"        with contextlib.closing(self._open_socket()) as sock:"},{"line_number":275,"context_line":"            return sock.sendto(metric, self._target)"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"    def _open_socket(self):"},{"line_number":278,"context_line":"        return socket.socket(socket.AF_INET, socket.SOCK_DGRAM)"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a061dce_eedd7015","line":275,"updated":"2016-04-05 16:12:43.000000000","message":"Please convert socket.error here to IronicException.","commit_id":"95dc18ccf5a71a5897fbc13ffd5a3b8772cf35c7"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2dc85b7542df116a2419e9da4a52c0f273f4ee62","unresolved":false,"context_lines":[{"line_number":272,"context_line":"        # Ideally, we\u0027d cache a sending socket in self, but that"},{"line_number":273,"context_line":"        # results in a socket getting shared by multiple green threads."},{"line_number":274,"context_line":"        with contextlib.closing(self._open_socket()) as sock:"},{"line_number":275,"context_line":"            return sock.sendto(metric, self._target)"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"    def _open_socket(self):"},{"line_number":278,"context_line":"        return socket.socket(socket.AF_INET, socket.SOCK_DGRAM)"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a061dce_f604fe18","line":275,"in_reply_to":"9a061dce_eedd7015","updated":"2016-04-06 11:14:48.000000000","message":"Done","commit_id":"95dc18ccf5a71a5897fbc13ffd5a3b8772cf35c7"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"df5fd2a3683ef4aee915217d6dd11dfd6626da5e","unresolved":false,"context_lines":[{"line_number":313,"context_line":"    elif CONF.metrics.backend \u003d\u003d \u0027noop\u0027:"},{"line_number":314,"context_line":"        return NoopMetricLogger(prefix, \u0027.\u0027)"},{"line_number":315,"context_line":"    else:"},{"line_number":316,"context_line":"        raise ValueError(\"Backend %s is not supported. Value should be \""},{"line_number":317,"context_line":"                         \"\u0027noop\u0027 or \u0027statsd\u0027.\" % CONF.metrics.backend)"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a061dce_0e02646f","line":316,"updated":"2016-04-05 16:12:43.000000000","message":"ditto l101","commit_id":"95dc18ccf5a71a5897fbc13ffd5a3b8772cf35c7"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2dc85b7542df116a2419e9da4a52c0f273f4ee62","unresolved":false,"context_lines":[{"line_number":313,"context_line":"    elif CONF.metrics.backend \u003d\u003d \u0027noop\u0027:"},{"line_number":314,"context_line":"        return NoopMetricLogger(prefix, \u0027.\u0027)"},{"line_number":315,"context_line":"    else:"},{"line_number":316,"context_line":"        raise ValueError(\"Backend %s is not supported. Value should be \""},{"line_number":317,"context_line":"                         \"\u0027noop\u0027 or \u0027statsd\u0027.\" % CONF.metrics.backend)"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a061dce_4101a604","line":316,"in_reply_to":"9a061dce_0e02646f","updated":"2016-04-06 11:14:48.000000000","message":"Done","commit_id":"95dc18ccf5a71a5897fbc13ffd5a3b8772cf35c7"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"2292a97db7b0732e8ebca3245d85874bba5e3eb6","unresolved":false,"context_lines":[{"line_number":283,"context_line":"        :param sample_rate: Probabilistic rate at which the values will be sent"},{"line_number":284,"context_line":"        \"\"\""},{"line_number":285,"context_line":"        self.counter(parts, 1, sample_rate\u003dsample_rate)"},{"line_number":286,"context_line":"        yield"},{"line_number":287,"context_line":""},{"line_number":288,"context_line":""},{"line_number":289,"context_line":"class NoopMetricLogger(MetricLogger):"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_a90b4429","line":286,"updated":"2016-04-06 12:49:35.000000000","message":"I guess I still don\u0027t know what benefit this has as a contextmanager.\n\nSeems like all the user has to do is:\n\n METRICS.counter(\u0027foo\u0027, 1)\n do_something()\n\nI guess the one benefit is that we have a somewhat consistent method of calling the functions.","commit_id":"03e699b79393b3b7067bbae1b63848b5df2c33b2"},{"author":{"_account_id":13295,"name":"Mario Villaplana","email":"mario.villaplana@gmail.com","username":"mariojv"},"change_message_id":"90142cfa0985a2dd4dc5b737aa853adf0e0e7f3d","unresolved":false,"context_lines":[{"line_number":283,"context_line":"        :param sample_rate: Probabilistic rate at which the values will be sent"},{"line_number":284,"context_line":"        \"\"\""},{"line_number":285,"context_line":"        self.counter(parts, 1, sample_rate\u003dsample_rate)"},{"line_number":286,"context_line":"        yield"},{"line_number":287,"context_line":""},{"line_number":288,"context_line":""},{"line_number":289,"context_line":"class NoopMetricLogger(MetricLogger):"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_c3eac20e","line":286,"in_reply_to":"9a061dce_2db8d729","updated":"2016-04-06 17:17:51.000000000","message":"I think using a context manager here is good. If we want to address the exception handling not bubbling up to ironic when an exception is raised, we can do the try/except here and the ironic code using this won\u0027t have to worry about it.","commit_id":"03e699b79393b3b7067bbae1b63848b5df2c33b2"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"4e1f25ba1a8b3a66726e27f46a50019f43e1ffe2","unresolved":false,"context_lines":[{"line_number":283,"context_line":"        :param sample_rate: Probabilistic rate at which the values will be sent"},{"line_number":284,"context_line":"        \"\"\""},{"line_number":285,"context_line":"        self.counter(parts, 1, sample_rate\u003dsample_rate)"},{"line_number":286,"context_line":"        yield"},{"line_number":287,"context_line":""},{"line_number":288,"context_line":""},{"line_number":289,"context_line":"class NoopMetricLogger(MetricLogger):"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_2db8d729","line":286,"in_reply_to":"9a061dce_a90b4429","updated":"2016-04-06 14:33:48.000000000","message":"Yes, I see what you mean. However, the spec mentions the context manager for the counter, so I think we should keep it? And maybe it can be improved in some way?","commit_id":"03e699b79393b3b7067bbae1b63848b5df2c33b2"},{"author":{"_account_id":13295,"name":"Mario Villaplana","email":"mario.villaplana@gmail.com","username":"mariojv"},"change_message_id":"8acf5a19dfdd35159c633dca5631ad7b04672ee1","unresolved":false,"context_lines":[{"line_number":330,"context_line":"        # results in a socket getting shared by multiple green threads."},{"line_number":331,"context_line":"        with contextlib.closing(self._open_socket()) as sock:"},{"line_number":332,"context_line":"            try:"},{"line_number":333,"context_line":"                sock.sendto(metric, self._target)"},{"line_number":334,"context_line":"            except socket.error as e:"},{"line_number":335,"context_line":"                msg \u003d (_(\"Failed to send the metric value to \""},{"line_number":336,"context_line":"                         \"host %(host) port %(port). Error: %(error)s\") %"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_7b8f202a","line":333,"updated":"2016-04-06 16:18:24.000000000","message":"I think it might be useful to allow a config option for setting the timeout as described here: https://docs.python.org/2/library/socket.html#socket.socket.settimeout\n\nOtherwise, the socket will always block any further operations until the system itself times out.","commit_id":"03e699b79393b3b7067bbae1b63848b5df2c33b2"},{"author":{"_account_id":13295,"name":"Mario Villaplana","email":"mario.villaplana@gmail.com","username":"mariojv"},"change_message_id":"90142cfa0985a2dd4dc5b737aa853adf0e0e7f3d","unresolved":false,"context_lines":[{"line_number":330,"context_line":"        # results in a socket getting shared by multiple green threads."},{"line_number":331,"context_line":"        with contextlib.closing(self._open_socket()) as sock:"},{"line_number":332,"context_line":"            try:"},{"line_number":333,"context_line":"                sock.sendto(metric, self._target)"},{"line_number":334,"context_line":"            except socket.error as e:"},{"line_number":335,"context_line":"                msg \u003d (_(\"Failed to send the metric value to \""},{"line_number":336,"context_line":"                         \"host %(host) port %(port). Error: %(error)s\") %"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_47051f12","line":333,"in_reply_to":"9a061dce_2c02900b","updated":"2016-04-06 17:17:51.000000000","message":"Good point. I looked into this a bit and found that UDP may potentially block in certain cases though (if the OS send buffer is full, or perhaps if we\u0027re sending metrics to an IP on the same subnet and waiting for ARP): https://stackoverflow.com/questions/4165174/when-does-a-udp-sendto-block\n\nI do think the buffer being full block is really unlikely in any use case here, but maybe there\u0027s a case where we try to send a metric to a statsd host on the same subnet, this is the first time the ironic host has sent a metric (so the MAC address isn\u0027t cached), ARP fails for some reason, and the send times out. I may be overly worried here though.","commit_id":"03e699b79393b3b7067bbae1b63848b5df2c33b2"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"39b427b9c556910cae3431b863cf5b5bbb28dff0","unresolved":false,"context_lines":[{"line_number":330,"context_line":"        # results in a socket getting shared by multiple green threads."},{"line_number":331,"context_line":"        with contextlib.closing(self._open_socket()) as sock:"},{"line_number":332,"context_line":"            try:"},{"line_number":333,"context_line":"                sock.sendto(metric, self._target)"},{"line_number":334,"context_line":"            except socket.error as e:"},{"line_number":335,"context_line":"                msg \u003d (_(\"Failed to send the metric value to \""},{"line_number":336,"context_line":"                         \"host %(host) port %(port). Error: %(error)s\") %"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_2c02900b","line":333,"in_reply_to":"9a061dce_7b8f202a","updated":"2016-04-06 16:54:57.000000000","message":"Mario,\n\nIt seems to be a DGRAM socket, which I think is UDP. So isn\u0027t that a fire and forget type operation? Please correct me if I am wrong.","commit_id":"03e699b79393b3b7067bbae1b63848b5df2c33b2"},{"author":{"_account_id":13295,"name":"Mario Villaplana","email":"mario.villaplana@gmail.com","username":"mariojv"},"change_message_id":"8acf5a19dfdd35159c633dca5631ad7b04672ee1","unresolved":false,"context_lines":[{"line_number":336,"context_line":"                         \"host %(host) port %(port). Error: %(error)s\") %"},{"line_number":337,"context_line":"                       {\u0027host\u0027: self._host, \u0027port\u0027: self._port,"},{"line_number":338,"context_line":"                        \u0027error\u0027: e})"},{"line_number":339,"context_line":"                raise exception.MetricInvalidConfig(msg)"},{"line_number":340,"context_line":""},{"line_number":341,"context_line":"    def _open_socket(self):"},{"line_number":342,"context_line":"        return socket.socket(socket.AF_INET, socket.SOCK_DGRAM)"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_b6cd4fb9","line":339,"updated":"2016-04-06 16:18:24.000000000","message":"This may not always be an issue with invalid config. I think a SendMetricFailure may be more appropriate. For example,  if during normal operation the socket operates correctly, but the configured statsd address relies on something like an internal DNS to resolve where to send the metrics to and there\u0027s a DNS error, I think a socket.gaierror would be raised, but that\u0027s not really an issue with the configuration itself. I may be wrong about what classes of errors can happen with the sendto operation though.","commit_id":"03e699b79393b3b7067bbae1b63848b5df2c33b2"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2d6e8cb662d9de621b20f254169d7b3d1f516e7a","unresolved":false,"context_lines":[{"line_number":336,"context_line":"                         \"host %(host) port %(port). Error: %(error)s\") %"},{"line_number":337,"context_line":"                       {\u0027host\u0027: self._host, \u0027port\u0027: self._port,"},{"line_number":338,"context_line":"                        \u0027error\u0027: e})"},{"line_number":339,"context_line":"                raise exception.MetricInvalidConfig(msg)"},{"line_number":340,"context_line":""},{"line_number":341,"context_line":"    def _open_socket(self):"},{"line_number":342,"context_line":"        return socket.socket(socket.AF_INET, socket.SOCK_DGRAM)"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_e7539369","line":339,"in_reply_to":"9a061dce_a7f6bbf6","updated":"2016-04-06 17:12:58.000000000","message":"Ok, that makes sense: I will replace that with an error in the next patch, thanks!","commit_id":"03e699b79393b3b7067bbae1b63848b5df2c33b2"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"44d0296b3b31407d8d8dcbb0ee08ae1b660c9192","unresolved":false,"context_lines":[{"line_number":336,"context_line":"                         \"host %(host) port %(port). Error: %(error)s\") %"},{"line_number":337,"context_line":"                       {\u0027host\u0027: self._host, \u0027port\u0027: self._port,"},{"line_number":338,"context_line":"                        \u0027error\u0027: e})"},{"line_number":339,"context_line":"                raise exception.MetricInvalidConfig(msg)"},{"line_number":340,"context_line":""},{"line_number":341,"context_line":"    def _open_socket(self):"},{"line_number":342,"context_line":"        return socket.socket(socket.AF_INET, socket.SOCK_DGRAM)"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_a7f6bbf6","line":339,"in_reply_to":"9a061dce_b6cd4fb9","updated":"2016-04-06 17:00:39.000000000","message":"+1, also, we should *not* blow up Ironic / IPA for failure to send statistics. If it\u0027s misconfigured at startup, sure, but after that point, metric sending issues should *never* impact the normal operations of Ironic or IPA.\n\nLoud errors are very fine though :)","commit_id":"03e699b79393b3b7067bbae1b63848b5df2c33b2"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"a17d3720404378a42f9e35a132a0ff483121f631","unresolved":false,"context_lines":[{"line_number":352,"context_line":"        return self._send(m_name, m_value, self.TIMER_TYPE)"},{"line_number":353,"context_line":""},{"line_number":354,"context_line":""},{"line_number":355,"context_line":"def getLogger(prefix):"},{"line_number":356,"context_line":"    \"\"\"Return a metric logger with the specified prefix."},{"line_number":357,"context_line":""},{"line_number":358,"context_line":"    The format of the prefix is [global_prefix.][host_name.]prefix."}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_36badf0a","line":355,"updated":"2016-04-06 16:08:05.000000000","message":"What happens if I pass in as the prefix:\n  1\n  (1, 2)\n  None","commit_id":"03e699b79393b3b7067bbae1b63848b5df2c33b2"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2d6e8cb662d9de621b20f254169d7b3d1f516e7a","unresolved":false,"context_lines":[{"line_number":352,"context_line":"        return self._send(m_name, m_value, self.TIMER_TYPE)"},{"line_number":353,"context_line":""},{"line_number":354,"context_line":""},{"line_number":355,"context_line":"def getLogger(prefix):"},{"line_number":356,"context_line":"    \"\"\"Return a metric logger with the specified prefix."},{"line_number":357,"context_line":""},{"line_number":358,"context_line":"    The format of the prefix is [global_prefix.][host_name.]prefix."}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_c7b48f83","line":355,"in_reply_to":"9a061dce_36badf0a","updated":"2016-04-06 17:12:58.000000000","message":"Thanks for catching these missing cases! Do you think it would be better to allow numeric/None values or to have an error?","commit_id":"03e699b79393b3b7067bbae1b63848b5df2c33b2"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"a17d3720404378a42f9e35a132a0ff483121f631","unresolved":false,"context_lines":[{"line_number":363,"context_line":"    if isinstance(prefix, six.string_types):"},{"line_number":364,"context_line":"        prefix \u003d [prefix]"},{"line_number":365,"context_line":""},{"line_number":366,"context_line":"    if CONF.metrics.prepend_host:"},{"line_number":367,"context_line":"        host \u003d CONF.host"},{"line_number":368,"context_line":""},{"line_number":369,"context_line":"        if CONF.metrics.prepend_host_reverse:"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_b6126f07","line":366,"updated":"2016-04-06 16:08:05.000000000","message":"Can we get a unit test for this prefix code?","commit_id":"03e699b79393b3b7067bbae1b63848b5df2c33b2"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"617e1961731003e07a6378e5d30139b0f005876d","unresolved":false,"context_lines":[{"line_number":297,"context_line":"        \"\"\""},{"line_number":298,"context_line":"        self.counter(parts, 1, sample_rate\u003dsample_rate)"},{"line_number":299,"context_line":"        try:"},{"line_number":300,"context_line":"            yield"},{"line_number":301,"context_line":"        except exception.MetricInvalidConfig as e:"},{"line_number":302,"context_line":"            LOG.warning(_LW(\"Exception: %(error)s\"), {\u0027error\u0027: e})"},{"line_number":303,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9a061dce_b9db407b","line":300,"updated":"2016-04-07 15:44:33.000000000","message":"Why would the yield have a metric exception.\n\nWouldn\u0027t that exception happen on line 298?","commit_id":"112c3f733fb0540d65ae4e2feffff37bef13c526"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"8efb91e82ea255d9e2d0f33771010bf77dfb7fe6","unresolved":false,"context_lines":[{"line_number":30,"context_line":""},{"line_number":31,"context_line":"metrics_opts \u003d ["},{"line_number":32,"context_line":"    cfg.StrOpt(\u0027host\u0027,"},{"line_number":33,"context_line":"               default\u003dsocket.getfqdn(),"},{"line_number":34,"context_line":"               help\u003d\u0027Name of this node. This can be an opaque identifier. \u0027"},{"line_number":35,"context_line":"               \u0027It is not necessarily a hostname, FQDN, or IP address.\u0027),"},{"line_number":36,"context_line":"    cfg.StrOpt(\u0027backend\u0027,"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a061dce_99710a0f","line":33,"updated":"2016-04-07 21:25:18.000000000","message":"I /think/ config generation is supposed to be deterministic. Using socket.getfqdn() here will vary the output per machine. Maybe $my_ip could be a better default?","commit_id":"ac076f08c0a99730a82b638e5f97534708831ea7"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"8dd71d326ffffb75377921622e4f9c66723bc7c0","unresolved":false,"context_lines":[{"line_number":30,"context_line":""},{"line_number":31,"context_line":"metrics_opts \u003d ["},{"line_number":32,"context_line":"    cfg.StrOpt(\u0027host\u0027,"},{"line_number":33,"context_line":"               default\u003dsocket.getfqdn(),"},{"line_number":34,"context_line":"               help\u003d\u0027Name of this node. This can be an opaque identifier. \u0027"},{"line_number":35,"context_line":"               \u0027It is not necessarily a hostname, FQDN, or IP address.\u0027),"},{"line_number":36,"context_line":"    cfg.StrOpt(\u0027backend\u0027,"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a061dce_e6918248","line":33,"in_reply_to":"9a061dce_0643d613","updated":"2016-04-07 22:51:14.000000000","message":"WFM","commit_id":"ac076f08c0a99730a82b638e5f97534708831ea7"},{"author":{"_account_id":13295,"name":"Mario Villaplana","email":"mario.villaplana@gmail.com","username":"mariojv"},"change_message_id":"415013483a0f921c94d597aee9b923dd565de14f","unresolved":false,"context_lines":[{"line_number":30,"context_line":""},{"line_number":31,"context_line":"metrics_opts \u003d ["},{"line_number":32,"context_line":"    cfg.StrOpt(\u0027host\u0027,"},{"line_number":33,"context_line":"               default\u003dsocket.getfqdn(),"},{"line_number":34,"context_line":"               help\u003d\u0027Name of this node. This can be an opaque identifier. \u0027"},{"line_number":35,"context_line":"               \u0027It is not necessarily a hostname, FQDN, or IP address.\u0027),"},{"line_number":36,"context_line":"    cfg.StrOpt(\u0027backend\u0027,"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a061dce_0643d613","line":33,"in_reply_to":"9a061dce_99710a0f","updated":"2016-04-07 22:45:07.000000000","message":"This is allowed in ironic itself, so I think it\u0027s OK:\n\nhttps://github.com/openstack/ironic/blob/56380f0e12587618b71c0347518324a50cf2769e/ironic/common/service.py#L46","commit_id":"ac076f08c0a99730a82b638e5f97534708831ea7"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"0ec67bc5131f383bec44ece4b7d379bbc9a4e243","unresolved":false,"context_lines":[{"line_number":147,"context_line":"        \"\"\""},{"line_number":148,"context_line":"        if (sample_rate is not None and"},{"line_number":149,"context_line":"                (sample_rate \u003c 0.0 or sample_rate \u003e 1.0)):"},{"line_number":150,"context_line":"            msg \u003d _(\"sample_rate must be None, or in the interval \""},{"line_number":151,"context_line":"                    \"[0.0, 1.0]\")"},{"line_number":152,"context_line":"            raise exception.MetricInvalidConfig(msg)"},{"line_number":153,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"9a061dce_431f855a","line":150,"updated":"2016-04-07 20:07:37.000000000","message":"I think should say what is the value found.","commit_id":"ac076f08c0a99730a82b638e5f97534708831ea7"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"0ec67bc5131f383bec44ece4b7d379bbc9a4e243","unresolved":false,"context_lines":[{"line_number":225,"context_line":"                try:"},{"line_number":226,"context_line":"                    self.counter(parts, 1, sample_rate\u003dsample_rate)"},{"line_number":227,"context_line":"                except exception.MetricInvalidConfig as e:"},{"line_number":228,"context_line":"                    LOG.warning(_LW(\"Exception: %(error)s\"), {\u0027error\u0027: e})"},{"line_number":229,"context_line":""},{"line_number":230,"context_line":"                result \u003d f(*args, **kwargs)"},{"line_number":231,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"9a061dce_237ed169","line":228,"updated":"2016-04-07 20:07:37.000000000","message":"I don\u0027t think this log message will be that informative. I don\u0027t think it will make it clear is it a metric related error.","commit_id":"ac076f08c0a99730a82b638e5f97534708831ea7"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"8efb91e82ea255d9e2d0f33771010bf77dfb7fe6","unresolved":false,"context_lines":[{"line_number":225,"context_line":"                try:"},{"line_number":226,"context_line":"                    self.counter(parts, 1, sample_rate\u003dsample_rate)"},{"line_number":227,"context_line":"                except exception.MetricInvalidConfig as e:"},{"line_number":228,"context_line":"                    LOG.warning(_LW(\"Exception: %(error)s\"), {\u0027error\u0027: e})"},{"line_number":229,"context_line":""},{"line_number":230,"context_line":"                result \u003d f(*args, **kwargs)"},{"line_number":231,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"9a061dce_1d568505","line":228,"in_reply_to":"9a061dce_237ed169","updated":"2016-04-07 21:25:18.000000000","message":"agreed","commit_id":"ac076f08c0a99730a82b638e5f97534708831ea7"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"8efb91e82ea255d9e2d0f33771010bf77dfb7fe6","unresolved":false,"context_lines":[{"line_number":274,"context_line":"        :param parts: Metric name"},{"line_number":275,"context_line":"        \"\"\""},{"line_number":276,"context_line":"        start \u003d _time()"},{"line_number":277,"context_line":"        yield"},{"line_number":278,"context_line":"        duration \u003d _time() - start"},{"line_number":279,"context_line":"        # Log the timing data (in ms)"},{"line_number":280,"context_line":"        self.timer(parts, duration * 1000)"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a061dce_bda039f5","line":277,"updated":"2016-04-07 21:25:18.000000000","message":"Why is this yield here?","commit_id":"ac076f08c0a99730a82b638e5f97534708831ea7"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"bcf6932d6dbb27a1444aaf3dd3b5c8e3e292013f","unresolved":false,"context_lines":[{"line_number":274,"context_line":"        :param parts: Metric name"},{"line_number":275,"context_line":"        \"\"\""},{"line_number":276,"context_line":"        start \u003d _time()"},{"line_number":277,"context_line":"        yield"},{"line_number":278,"context_line":"        duration \u003d _time() - start"},{"line_number":279,"context_line":"        # Log the timing data (in ms)"},{"line_number":280,"context_line":"        self.timer(parts, duration * 1000)"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a061dce_2656da05","line":277,"in_reply_to":"9a061dce_26089a27","updated":"2016-04-07 22:32:06.000000000","message":"Of course. This makes sense. Thanks! The only stupid question is the one left unasked :P","commit_id":"ac076f08c0a99730a82b638e5f97534708831ea7"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"570da6db549481f38b0f0e4169ee88b1ca90a17e","unresolved":false,"context_lines":[{"line_number":274,"context_line":"        :param parts: Metric name"},{"line_number":275,"context_line":"        \"\"\""},{"line_number":276,"context_line":"        start \u003d _time()"},{"line_number":277,"context_line":"        yield"},{"line_number":278,"context_line":"        duration \u003d _time() - start"},{"line_number":279,"context_line":"        # Log the timing data (in ms)"},{"line_number":280,"context_line":"        self.timer(parts, duration * 1000)"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a061dce_26089a27","line":277,"in_reply_to":"9a061dce_bda039f5","updated":"2016-04-07 22:30:18.000000000","message":"I think the yield causes it to return to the context.  Then when the context is done it comes back here.\n\nFor example in this case.  The yield will give control starting at foo()\n\n with timer_c():\n     foo()\n     spam()\n\nAnd return back after spam() returns it will go to the line after the yield.","commit_id":"ac076f08c0a99730a82b638e5f97534708831ea7"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"0ec67bc5131f383bec44ece4b7d379bbc9a4e243","unresolved":false,"context_lines":[{"line_number":298,"context_line":"        try:"},{"line_number":299,"context_line":"            self.counter(parts, 1, sample_rate\u003dsample_rate)"},{"line_number":300,"context_line":"        except exception.MetricInvalidConfig as e:"},{"line_number":301,"context_line":"            LOG.warning(_LW(\"Exception: %(error)s\"), {\u0027error\u0027: e})"},{"line_number":302,"context_line":"        yield"},{"line_number":303,"context_line":""},{"line_number":304,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"9a061dce_c38f1573","line":301,"updated":"2016-04-07 20:07:37.000000000","message":"I don\u0027t think this log message will be that informative. I don\u0027t think it will make it clear is it a metric related error.","commit_id":"ac076f08c0a99730a82b638e5f97534708831ea7"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"8efb91e82ea255d9e2d0f33771010bf77dfb7fe6","unresolved":false,"context_lines":[{"line_number":299,"context_line":"            self.counter(parts, 1, sample_rate\u003dsample_rate)"},{"line_number":300,"context_line":"        except exception.MetricInvalidConfig as e:"},{"line_number":301,"context_line":"            LOG.warning(_LW(\"Exception: %(error)s\"), {\u0027error\u0027: e})"},{"line_number":302,"context_line":"        yield"},{"line_number":303,"context_line":""},{"line_number":304,"context_line":""},{"line_number":305,"context_line":"class NoopMetricLogger(MetricLogger):"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a061dce_bd795995","line":302,"updated":"2016-04-07 21:25:18.000000000","message":"Why is this yield here?","commit_id":"ac076f08c0a99730a82b638e5f97534708831ea7"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"bcf6932d6dbb27a1444aaf3dd3b5c8e3e292013f","unresolved":false,"context_lines":[{"line_number":299,"context_line":"            self.counter(parts, 1, sample_rate\u003dsample_rate)"},{"line_number":300,"context_line":"        except exception.MetricInvalidConfig as e:"},{"line_number":301,"context_line":"            LOG.warning(_LW(\"Exception: %(error)s\"), {\u0027error\u0027: e})"},{"line_number":302,"context_line":"        yield"},{"line_number":303,"context_line":""},{"line_number":304,"context_line":""},{"line_number":305,"context_line":"class NoopMetricLogger(MetricLogger):"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a061dce_66445249","line":302,"in_reply_to":"9a061dce_bd795995","updated":"2016-04-07 22:32:06.000000000","message":"ty to JLV above for answering my question","commit_id":"ac076f08c0a99730a82b638e5f97534708831ea7"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"0ec67bc5131f383bec44ece4b7d379bbc9a4e243","unresolved":false,"context_lines":[{"line_number":396,"context_line":"    elif CONF.metrics.backend \u003d\u003d \u0027noop\u0027:"},{"line_number":397,"context_line":"        return NoopMetricLogger(prefix, \u0027.\u0027)"},{"line_number":398,"context_line":"    else:"},{"line_number":399,"context_line":"        msg \u003d _(\"Backend %s is not supported. Value should be \""},{"line_number":400,"context_line":"                \"\u0027noop\u0027 or \u0027statsd\u0027.\") % CONF.metrics.backend"},{"line_number":401,"context_line":"        raise exception.MetricInvalidConfig(msg)"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a061dce_e3a059f6","line":399,"updated":"2016-04-07 20:07:37.000000000","message":"Please tell the user what value was specified.","commit_id":"ac076f08c0a99730a82b638e5f97534708831ea7"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"8efb91e82ea255d9e2d0f33771010bf77dfb7fe6","unresolved":false,"context_lines":[{"line_number":396,"context_line":"    elif CONF.metrics.backend \u003d\u003d \u0027noop\u0027:"},{"line_number":397,"context_line":"        return NoopMetricLogger(prefix, \u0027.\u0027)"},{"line_number":398,"context_line":"    else:"},{"line_number":399,"context_line":"        msg \u003d _(\"Backend %s is not supported. Value should be \""},{"line_number":400,"context_line":"                \"\u0027noop\u0027 or \u0027statsd\u0027.\") % CONF.metrics.backend"},{"line_number":401,"context_line":"        raise exception.MetricInvalidConfig(msg)"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a061dce_9d19f524","line":399,"in_reply_to":"9a061dce_e3a059f6","updated":"2016-04-07 21:25:18.000000000","message":"We should probably also be more explicit about exactly what value is bad, i.e.\n\n\"CONF.metrics.backend is set to an unsupported backend type: %s. Value should be \u0027noop\u0027 or \u0027statsd\u0027\"","commit_id":"ac076f08c0a99730a82b638e5f97534708831ea7"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"811c7c2c996398f956e098e5f7af7a56189acd61","unresolved":false,"context_lines":[{"line_number":57,"context_line":"    cfg.PortOpt(\u0027statsd_port\u0027,"},{"line_number":58,"context_line":"                default\u003d8125,"},{"line_number":59,"context_line":"                help\u003d\u0027Port to use with the statsd backend.\u0027),"},{"line_number":60,"context_line":"    # Agent options"},{"line_number":61,"context_line":"    cfg.StrOpt(\u0027agent_backend\u0027,"},{"line_number":62,"context_line":"               default\u003d\u0027noop\u0027,"},{"line_number":63,"context_line":"               help\u003d\u0027Backend to use for the metrics system. Default possible \u0027"}],"source_content_type":"text/x-python","patch_set":6,"id":"5a18252c_e9ebfdae","line":60,"updated":"2016-04-12 00:16:34.000000000","message":"What are \"Agent options\"? Can this be explained.","commit_id":"5975e9c01479ab06d9c881965250503f739685a9"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"b59e802888ee07e33297311c235f51606d3ef89b","unresolved":false,"context_lines":[{"line_number":57,"context_line":"    cfg.PortOpt(\u0027statsd_port\u0027,"},{"line_number":58,"context_line":"                default\u003d8125,"},{"line_number":59,"context_line":"                help\u003d\u0027Port to use with the statsd backend.\u0027),"},{"line_number":60,"context_line":"    # Agent options"},{"line_number":61,"context_line":"    cfg.StrOpt(\u0027agent_backend\u0027,"},{"line_number":62,"context_line":"               default\u003d\u0027noop\u0027,"},{"line_number":63,"context_line":"               help\u003d\u0027Backend to use for the metrics system. Default possible \u0027"}],"source_content_type":"text/x-python","patch_set":6,"id":"5a18252c_f6d74321","line":60,"in_reply_to":"5a18252c_e9ebfdae","updated":"2016-04-12 12:52:51.000000000","message":"These options are used to configure how IPA reports metric data. I’ve changed the comment, let me know if it’s better. The options are also defined in the spec.","commit_id":"5975e9c01479ab06d9c881965250503f739685a9"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"811c7c2c996398f956e098e5f7af7a56189acd61","unresolved":false,"context_lines":[{"line_number":104,"context_line":"class MetricLogger(object):"},{"line_number":105,"context_line":"    \"\"\"Abstract class representing a metrics logger.\"\"\""},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"    def __init__(self, prefix_parts, delimiter):"},{"line_number":108,"context_line":"        if isinstance(prefix_parts, six.string_types):"},{"line_number":109,"context_line":"            self._prefix_parts \u003d [prefix_parts]"},{"line_number":110,"context_line":"        elif isinstance(prefix_parts, six.integer_types):"}],"source_content_type":"text/x-python","patch_set":6,"id":"5a18252c_69d88d1e","line":107,"updated":"2016-04-12 00:16:34.000000000","message":"Bikshedding: Here and other places. Any reason to not just have delimiter default to \".\" ?\n\n  delimiter\u003d\u0027.\u0027\n\nMaybe it is a bad idea, I\u0027m not sure.","commit_id":"5975e9c01479ab06d9c881965250503f739685a9"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"b59e802888ee07e33297311c235f51606d3ef89b","unresolved":false,"context_lines":[{"line_number":104,"context_line":"class MetricLogger(object):"},{"line_number":105,"context_line":"    \"\"\"Abstract class representing a metrics logger.\"\"\""},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"    def __init__(self, prefix_parts, delimiter):"},{"line_number":108,"context_line":"        if isinstance(prefix_parts, six.string_types):"},{"line_number":109,"context_line":"            self._prefix_parts \u003d [prefix_parts]"},{"line_number":110,"context_line":"        elif isinstance(prefix_parts, six.integer_types):"}],"source_content_type":"text/x-python","patch_set":6,"id":"5a18252c_36e25b04","line":107,"in_reply_to":"5a18252c_69d88d1e","updated":"2016-04-12 12:52:51.000000000","message":"Done","commit_id":"5975e9c01479ab06d9c881965250503f739685a9"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"811c7c2c996398f956e098e5f7af7a56189acd61","unresolved":false,"context_lines":[{"line_number":105,"context_line":"    \"\"\"Abstract class representing a metrics logger.\"\"\""},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"    def __init__(self, prefix_parts, delimiter):"},{"line_number":108,"context_line":"        if isinstance(prefix_parts, six.string_types):"},{"line_number":109,"context_line":"            self._prefix_parts \u003d [prefix_parts]"},{"line_number":110,"context_line":"        elif isinstance(prefix_parts, six.integer_types):"},{"line_number":111,"context_line":"            self._prefix_parts \u003d [str(prefix_parts)]"}],"source_content_type":"text/x-python","patch_set":6,"id":"5a18252c_29adf531","line":108,"updated":"2016-04-12 00:16:34.000000000","message":"It would be nice if this bundle of logic could be used for anywhere parts is passed in.\n\nFor example in _getMetricName","commit_id":"5975e9c01479ab06d9c881965250503f739685a9"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"b59e802888ee07e33297311c235f51606d3ef89b","unresolved":false,"context_lines":[{"line_number":105,"context_line":"    \"\"\"Abstract class representing a metrics logger.\"\"\""},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"    def __init__(self, prefix_parts, delimiter):"},{"line_number":108,"context_line":"        if isinstance(prefix_parts, six.string_types):"},{"line_number":109,"context_line":"            self._prefix_parts \u003d [prefix_parts]"},{"line_number":110,"context_line":"        elif isinstance(prefix_parts, six.integer_types):"},{"line_number":111,"context_line":"            self._prefix_parts \u003d [str(prefix_parts)]"}],"source_content_type":"text/x-python","patch_set":6,"id":"5a18252c_96e7ef11","line":108,"in_reply_to":"5a18252c_29adf531","updated":"2016-04-12 12:52:51.000000000","message":"Done","commit_id":"5975e9c01479ab06d9c881965250503f739685a9"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"811c7c2c996398f956e098e5f7af7a56189acd61","unresolved":false,"context_lines":[{"line_number":116,"context_line":""},{"line_number":117,"context_line":"        self._delimiter \u003d delimiter"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"    def _getMetricName(self, m_parts):"},{"line_number":120,"context_line":"        if isinstance(m_parts, six.string_types):"},{"line_number":121,"context_line":"            m_parts \u003d [m_parts]"},{"line_number":122,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"5a18252c_a9674524","line":119,"updated":"2016-04-12 00:16:34.000000000","message":"Can this be a PEP8 compatible function name.\n\nFunction names should be lowercase, with words separated by underscores as necessary to improve readability.","commit_id":"5975e9c01479ab06d9c881965250503f739685a9"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"b59e802888ee07e33297311c235f51606d3ef89b","unresolved":false,"context_lines":[{"line_number":116,"context_line":""},{"line_number":117,"context_line":"        self._delimiter \u003d delimiter"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"    def _getMetricName(self, m_parts):"},{"line_number":120,"context_line":"        if isinstance(m_parts, six.string_types):"},{"line_number":121,"context_line":"            m_parts \u003d [m_parts]"},{"line_number":122,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"5a18252c_b6ee6bea","line":119,"in_reply_to":"5a18252c_a9674524","updated":"2016-04-12 12:52:51.000000000","message":"Done","commit_id":"5975e9c01479ab06d9c881965250503f739685a9"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"811c7c2c996398f956e098e5f7af7a56189acd61","unresolved":false,"context_lines":[{"line_number":373,"context_line":"        return self._send(m_name, m_value, self.TIMER_TYPE)"},{"line_number":374,"context_line":""},{"line_number":375,"context_line":""},{"line_number":376,"context_line":"def getLogger(prefix):"},{"line_number":377,"context_line":"    \"\"\"Return a metric logger with the specified prefix."},{"line_number":378,"context_line":""},{"line_number":379,"context_line":"    The format of the prefix is [global_prefix.][host_name.]prefix."}],"source_content_type":"text/x-python","patch_set":6,"id":"5a18252c_29cb3574","line":376,"updated":"2016-04-12 00:16:34.000000000","message":"What happens if I pass in as the prefix:\n  1\n  (1, 2)\n  None\n\nI notice that the base class (MetricLogger) does allow an integer value.","commit_id":"5975e9c01479ab06d9c881965250503f739685a9"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"b59e802888ee07e33297311c235f51606d3ef89b","unresolved":false,"context_lines":[{"line_number":373,"context_line":"        return self._send(m_name, m_value, self.TIMER_TYPE)"},{"line_number":374,"context_line":""},{"line_number":375,"context_line":""},{"line_number":376,"context_line":"def getLogger(prefix):"},{"line_number":377,"context_line":"    \"\"\"Return a metric logger with the specified prefix."},{"line_number":378,"context_line":""},{"line_number":379,"context_line":"    The format of the prefix is [global_prefix.][host_name.]prefix."}],"source_content_type":"text/x-python","patch_set":6,"id":"5a18252c_76cb3373","line":376,"in_reply_to":"5a18252c_29cb3574","updated":"2016-04-12 12:52:51.000000000","message":"For 1 and (1, 2), the prefix will be “1” or “1.2”.\nFor None, the prefix will be an empty string.","commit_id":"5975e9c01479ab06d9c881965250503f739685a9"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"811c7c2c996398f956e098e5f7af7a56189acd61","unresolved":false,"context_lines":[{"line_number":378,"context_line":""},{"line_number":379,"context_line":"    The format of the prefix is [global_prefix.][host_name.]prefix."},{"line_number":380,"context_line":""},{"line_number":381,"context_line":"    :param prefix: Prefix for this metric logger"},{"line_number":382,"context_line":"    \"\"\""},{"line_number":383,"context_line":""},{"line_number":384,"context_line":"    if isinstance(prefix, six.string_types):"}],"source_content_type":"text/x-python","patch_set":6,"id":"5a18252c_899fe95e","line":381,"updated":"2016-04-12 00:16:34.000000000","message":"What type is expected? Is it supposed to be a string? An int? A list of strings? A list of dicts?","commit_id":"5975e9c01479ab06d9c881965250503f739685a9"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"b59e802888ee07e33297311c235f51606d3ef89b","unresolved":false,"context_lines":[{"line_number":378,"context_line":""},{"line_number":379,"context_line":"    The format of the prefix is [global_prefix.][host_name.]prefix."},{"line_number":380,"context_line":""},{"line_number":381,"context_line":"    :param prefix: Prefix for this metric logger"},{"line_number":382,"context_line":"    \"\"\""},{"line_number":383,"context_line":""},{"line_number":384,"context_line":"    if isinstance(prefix, six.string_types):"}],"source_content_type":"text/x-python","patch_set":6,"id":"5a18252c_7679732f","line":381,"in_reply_to":"5a18252c_899fe95e","updated":"2016-04-12 12:52:51.000000000","message":"Prefix can be a string, an int, or a list of strings/ints. I’ve updated the comment, but let me know if you think different types should be accepted.","commit_id":"5975e9c01479ab06d9c881965250503f739685a9"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"b7354803a3c424049c780a3ec258889b1742e356","unresolved":false,"context_lines":[{"line_number":109,"context_line":""},{"line_number":110,"context_line":"        self._delimiter \u003d delimiter"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"    def _format_metric_name(self, prefix_parts):"},{"line_number":113,"context_line":"        if isinstance(prefix_parts, six.string_types):"},{"line_number":114,"context_line":"            m_parts \u003d [prefix_parts]"},{"line_number":115,"context_line":"        elif isinstance(prefix_parts, six.integer_types):"}],"source_content_type":"text/x-python","patch_set":7,"id":"5a18252c_d677a700","line":112,"updated":"2016-04-12 12:56:57.000000000","message":"Maybe this should not be a class method, but a module method, so that it could also be used by getLogger() below?  Seems like very similar code.","commit_id":"fbcfeea820f29055062dc70d956f7e976360c3e8"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"b7354803a3c424049c780a3ec258889b1742e356","unresolved":false,"context_lines":[{"line_number":377,"context_line":"        return self._send(m_name, m_value, self.TIMER_TYPE)"},{"line_number":378,"context_line":""},{"line_number":379,"context_line":""},{"line_number":380,"context_line":"def getLogger(prefix):"},{"line_number":381,"context_line":"    \"\"\"Return a metric logger with the specified prefix."},{"line_number":382,"context_line":""},{"line_number":383,"context_line":"    The format of the prefix is [global_prefix.][host_name.]prefix."}],"source_content_type":"text/x-python","patch_set":7,"id":"5a18252c_96d1affe","line":380,"updated":"2016-04-12 12:56:57.000000000","message":"Not a PEP8 compliant method name.","commit_id":"fbcfeea820f29055062dc70d956f7e976360c3e8"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"5608e00dd7e393a392bd860c9a9a259d467e8130","unresolved":false,"context_lines":[{"line_number":100,"context_line":"    return time.time()"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"def _format_metric_name(prefix_parts):"},{"line_number":104,"context_line":"    if isinstance(prefix_parts, six.string_types):"},{"line_number":105,"context_line":"        m_parts \u003d [prefix_parts]"},{"line_number":106,"context_line":"    elif isinstance(prefix_parts, six.integer_types):"}],"source_content_type":"text/x-python","patch_set":8,"id":"5a18252c_f9ef33ae","line":103,"updated":"2016-04-12 13:21:30.000000000","message":"Can we get a unit test for this?\n\nOr am I just not seeing it.  Thanks.","commit_id":"bda714fd0b30f34302b5c6b0418629d983ac0226"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"6ecf1e681c4c88d3c07a4f75a7a7d9739b4d4107","unresolved":false,"context_lines":[{"line_number":100,"context_line":"    return time.time()"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"def _format_metric_name(prefix_parts):"},{"line_number":104,"context_line":"    if isinstance(prefix_parts, six.string_types):"},{"line_number":105,"context_line":"        m_parts \u003d [prefix_parts]"},{"line_number":106,"context_line":"    elif isinstance(prefix_parts, six.integer_types):"}],"source_content_type":"text/x-python","patch_set":9,"id":"5a18252c_bf091b34","line":103,"updated":"2016-04-12 14:12:15.000000000","message":"docstring would be nice. Maybe the info from get_logger() below on what prefix_parts can be.\n\nAnd what this returns.","commit_id":"2ab44739360fb068a8cda693113ddd78193aa366"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"74eca256f1a9d1165ec87859cc2651b966082e90","unresolved":false,"context_lines":[{"line_number":100,"context_line":"    return time.time()"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"def _format_metric_name(prefix_parts):"},{"line_number":104,"context_line":"    if isinstance(prefix_parts, six.string_types):"},{"line_number":105,"context_line":"        m_parts \u003d [prefix_parts]"},{"line_number":106,"context_line":"    elif isinstance(prefix_parts, six.integer_types):"}],"source_content_type":"text/x-python","patch_set":9,"id":"5a18252c_aa8f0922","line":103,"in_reply_to":"5a18252c_bf091b34","updated":"2016-04-12 17:40:02.000000000","message":"Done","commit_id":"2ab44739360fb068a8cda693113ddd78193aa366"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"6ecf1e681c4c88d3c07a4f75a7a7d9739b4d4107","unresolved":false,"context_lines":[{"line_number":117,"context_line":"class MetricLogger(object):"},{"line_number":118,"context_line":"    \"\"\"Abstract class representing a metrics logger.\"\"\""},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"    def __init__(self, prefix_parts, delimiter\u003d\u0027.\u0027):"},{"line_number":121,"context_line":"        self._prefix_parts \u003d _format_metric_name(prefix_parts)"},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"        self._delimiter \u003d delimiter"}],"source_content_type":"text/x-python","patch_set":9,"id":"5a18252c_42946c36","line":120,"updated":"2016-04-12 14:12:15.000000000","message":"Can we get a docstring?","commit_id":"2ab44739360fb068a8cda693113ddd78193aa366"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"74eca256f1a9d1165ec87859cc2651b966082e90","unresolved":false,"context_lines":[{"line_number":117,"context_line":"class MetricLogger(object):"},{"line_number":118,"context_line":"    \"\"\"Abstract class representing a metrics logger.\"\"\""},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"    def __init__(self, prefix_parts, delimiter\u003d\u0027.\u0027):"},{"line_number":121,"context_line":"        self._prefix_parts \u003d _format_metric_name(prefix_parts)"},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"        self._delimiter \u003d delimiter"}],"source_content_type":"text/x-python","patch_set":9,"id":"5a18252c_ea990170","line":120,"in_reply_to":"5a18252c_42946c36","updated":"2016-04-12 17:40:02.000000000","message":"Done","commit_id":"2ab44739360fb068a8cda693113ddd78193aa366"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"6ecf1e681c4c88d3c07a4f75a7a7d9739b4d4107","unresolved":false,"context_lines":[{"line_number":122,"context_line":""},{"line_number":123,"context_line":"        self._delimiter \u003d delimiter"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    def _get_metric_name(self, m_parts):"},{"line_number":126,"context_line":"        m_parts \u003d _format_metric_name(m_parts)"},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"        return self._delimiter.join(self._prefix_parts + list(m_parts))"}],"source_content_type":"text/x-python","patch_set":9,"id":"5a18252c_2277b03b","line":125,"updated":"2016-04-12 14:12:15.000000000","message":"Can we get a docstring. I\u0027m not quite sure what this function is for.\n\nAlso it seems more like it \u0027creates\u0027 a metric name, then gets it.","commit_id":"2ab44739360fb068a8cda693113ddd78193aa366"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"74eca256f1a9d1165ec87859cc2651b966082e90","unresolved":false,"context_lines":[{"line_number":122,"context_line":""},{"line_number":123,"context_line":"        self._delimiter \u003d delimiter"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    def _get_metric_name(self, m_parts):"},{"line_number":126,"context_line":"        m_parts \u003d _format_metric_name(m_parts)"},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"        return self._delimiter.join(self._prefix_parts + list(m_parts))"}],"source_content_type":"text/x-python","patch_set":9,"id":"5a18252c_0aa1dd94","line":125,"in_reply_to":"5a18252c_2277b03b","updated":"2016-04-12 17:40:02.000000000","message":"The method joins the logger prefix and the metric name to get the complete metric name. If you think it describes the method better, I can change its name to _create_metric_name()?","commit_id":"2ab44739360fb068a8cda693113ddd78193aa366"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ec427a8b5781f70c9fb3e559af0a1c0bd14365b0","unresolved":false,"context_lines":[{"line_number":32,"context_line":"    cfg.StrOpt(\u0027host\u0027,"},{"line_number":33,"context_line":"               default\u003dsocket.getfqdn(),"},{"line_number":34,"context_line":"               help\u003d\u0027Name of this node. This can be an opaque identifier. \u0027"},{"line_number":35,"context_line":"               \u0027It is not necessarily a hostname, FQDN, or IP address.\u0027),"},{"line_number":36,"context_line":"    cfg.StrOpt(\u0027backend\u0027,"},{"line_number":37,"context_line":"               default\u003d\u0027noop\u0027,"},{"line_number":38,"context_line":"               help\u003d\u0027Backend to use for the metrics system. Default possible \u0027"}],"source_content_type":"text/x-python","patch_set":10,"id":"5a18252c_816310b1","line":35,"updated":"2016-04-12 19:35:25.000000000","message":"If Ironic uses this library, is this value the same as the value for the \u0027host\u0027 config in ironic? What if they are different values?","commit_id":"b189d3216751c3ae9e3ff609110bb0edb84b8fdd"},{"author":{"_account_id":11642,"name":"Jesse J. Cook","email":"jesse.cook@rackspace.com","username":"crashenx"},"change_message_id":"ad8a8e9b440e9df622235d5c9c377b947ea7492d","unresolved":false,"context_lines":[{"line_number":32,"context_line":"    cfg.StrOpt(\u0027host\u0027,"},{"line_number":33,"context_line":"               default\u003dsocket.getfqdn(),"},{"line_number":34,"context_line":"               help\u003d\u0027Name of this node. This can be an opaque identifier. \u0027"},{"line_number":35,"context_line":"               \u0027It is not necessarily a hostname, FQDN, or IP address.\u0027),"},{"line_number":36,"context_line":"    cfg.StrOpt(\u0027backend\u0027,"},{"line_number":37,"context_line":"               default\u003d\u0027noop\u0027,"},{"line_number":38,"context_line":"               help\u003d\u0027Backend to use for the metrics system. Default possible \u0027"}],"source_content_type":"text/x-python","patch_set":10,"id":"1a122d0e_3be48daa","line":35,"in_reply_to":"1a122d0e_4644241a","updated":"2016-04-19 16:15:07.000000000","message":"Perhaps as Aline says in her first comment, it shouldn\u0027t matter, for now, since it\u0027s just the metric name? From there we could consider a follow-up patch to have Ironic and IPA leverage the ironic_lib for the hostname for consistency, if that makes sense?","commit_id":"b189d3216751c3ae9e3ff609110bb0edb84b8fdd"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"726269d5d3dc68a13f1c414aaad5abaa36f3e32a","unresolved":false,"context_lines":[{"line_number":32,"context_line":"    cfg.StrOpt(\u0027host\u0027,"},{"line_number":33,"context_line":"               default\u003dsocket.getfqdn(),"},{"line_number":34,"context_line":"               help\u003d\u0027Name of this node. This can be an opaque identifier. \u0027"},{"line_number":35,"context_line":"               \u0027It is not necessarily a hostname, FQDN, or IP address.\u0027),"},{"line_number":36,"context_line":"    cfg.StrOpt(\u0027backend\u0027,"},{"line_number":37,"context_line":"               default\u003d\u0027noop\u0027,"},{"line_number":38,"context_line":"               help\u003d\u0027Backend to use for the metrics system. Default possible \u0027"}],"source_content_type":"text/x-python","patch_set":10,"id":"1a122d0e_4644241a","line":35,"in_reply_to":"1a122d0e_91f6ddd5","updated":"2016-04-19 11:29:04.000000000","message":"I don’t know if it would work, but since the option can be used by both Ironic and IPA, maybe it could be moved to ironic-lib (in utils.py)? And have Ironic and IPA use that value?","commit_id":"b189d3216751c3ae9e3ff609110bb0edb84b8fdd"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"13524b6c913541d614ab20ef91fecd405e84baf3","unresolved":false,"context_lines":[{"line_number":32,"context_line":"    cfg.StrOpt(\u0027host\u0027,"},{"line_number":33,"context_line":"               default\u003dsocket.getfqdn(),"},{"line_number":34,"context_line":"               help\u003d\u0027Name of this node. This can be an opaque identifier. \u0027"},{"line_number":35,"context_line":"               \u0027It is not necessarily a hostname, FQDN, or IP address.\u0027),"},{"line_number":36,"context_line":"    cfg.StrOpt(\u0027backend\u0027,"},{"line_number":37,"context_line":"               default\u003d\u0027noop\u0027,"},{"line_number":38,"context_line":"               help\u003d\u0027Backend to use for the metrics system. Default possible \u0027"}],"source_content_type":"text/x-python","patch_set":10,"id":"5a18252c_91e6a6b2","line":35,"in_reply_to":"5a18252c_816310b1","updated":"2016-04-13 10:24:30.000000000","message":"I think this value should be the same as the one in Ironic (https://github.com/openstack/ironic/blob/56380f0e12587618b71c0347518324a50cf2769e/ironic/common/service.py#L46). But if they are different, there shouldn’t be any error since the value is only used in the metric name?","commit_id":"b189d3216751c3ae9e3ff609110bb0edb84b8fdd"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"94dd21da914a6402e4100c04a8cc77d2d87a52f5","unresolved":false,"context_lines":[{"line_number":32,"context_line":"    cfg.StrOpt(\u0027host\u0027,"},{"line_number":33,"context_line":"               default\u003dsocket.getfqdn(),"},{"line_number":34,"context_line":"               help\u003d\u0027Name of this node. This can be an opaque identifier. \u0027"},{"line_number":35,"context_line":"               \u0027It is not necessarily a hostname, FQDN, or IP address.\u0027),"},{"line_number":36,"context_line":"    cfg.StrOpt(\u0027backend\u0027,"},{"line_number":37,"context_line":"               default\u003d\u0027noop\u0027,"},{"line_number":38,"context_line":"               help\u003d\u0027Backend to use for the metrics system. Default possible \u0027"}],"source_content_type":"text/x-python","patch_set":10,"id":"1a122d0e_91f6ddd5","line":35,"in_reply_to":"5a18252c_91e6a6b2","updated":"2016-04-15 17:31:16.000000000","message":"I\u0027m pretty curious generally how we should address this. I think in a perfect world, this value would automatically be set to what Ironic has it set to, but given we want ironic-lib to be independent of Ironic IDK what the best thing is to do here.","commit_id":"b189d3216751c3ae9e3ff609110bb0edb84b8fdd"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"0d62d0de0877fcd1788cf23d0756592e5a53dfbd","unresolved":false,"context_lines":[{"line_number":34,"context_line":"               help\u003d\u0027Name of this node. This can be an opaque identifier. \u0027"},{"line_number":35,"context_line":"               \u0027It is not necessarily a hostname, FQDN, or IP address.\u0027),"},{"line_number":36,"context_line":"    cfg.StrOpt(\u0027backend\u0027,"},{"line_number":37,"context_line":"               default\u003d\u0027noop\u0027,"},{"line_number":38,"context_line":"               help\u003d\u0027Backend to use for the metrics system. Default possible \u0027"},{"line_number":39,"context_line":"                    \u0027backends are \"noop\" and \"statsd\".\u0027),"},{"line_number":40,"context_line":"    cfg.BoolOpt(\u0027prepend_host\u0027,"}],"source_content_type":"text/x-python","patch_set":10,"id":"5a18252c_41e3b8a3","line":37,"updated":"2016-04-12 19:43:16.000000000","message":"Maybe use the \u0027choices\u0027 value.\n\n  default\u003d\u0027noop\u0027, choices\u003d[\u0027noop\u0027, \u0027statsd\u0027],","commit_id":"b189d3216751c3ae9e3ff609110bb0edb84b8fdd"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ec427a8b5781f70c9fb3e559af0a1c0bd14365b0","unresolved":false,"context_lines":[{"line_number":36,"context_line":"    cfg.StrOpt(\u0027backend\u0027,"},{"line_number":37,"context_line":"               default\u003d\u0027noop\u0027,"},{"line_number":38,"context_line":"               help\u003d\u0027Backend to use for the metrics system. Default possible \u0027"},{"line_number":39,"context_line":"                    \u0027backends are \"noop\" and \"statsd\".\u0027),"},{"line_number":40,"context_line":"    cfg.BoolOpt(\u0027prepend_host\u0027,"},{"line_number":41,"context_line":"                default\u003dFalse,"},{"line_number":42,"context_line":"                help\u003d\u0027Prepend the hostname to all metric names. \u0027"}],"source_content_type":"text/x-python","patch_set":10,"id":"5a18252c_b6bbf471","line":39,"updated":"2016-04-12 19:35:25.000000000","message":"I don\u0027t understand what \u0027Default possible backends\u0027 means. The default value, if not specified, is \u0027noop\u0027. Are these the two possible values for this config?","commit_id":"b189d3216751c3ae9e3ff609110bb0edb84b8fdd"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ec427a8b5781f70c9fb3e559af0a1c0bd14365b0","unresolved":false,"context_lines":[{"line_number":48,"context_line":"                     \u0027(to better match the reverse hierarchical form of \u0027"},{"line_number":49,"context_line":"                     \u0027domain names).\u0027),"},{"line_number":50,"context_line":"    cfg.StrOpt(\u0027global_prefix\u0027,"},{"line_number":51,"context_line":"               help\u003d\u0027Prefix all metric names with this value \u0027"},{"line_number":52,"context_line":"                    \u0027The format of metric names is \u0027"},{"line_number":53,"context_line":"                    \u0027[global_prefix.][host_name.]prefix.metric_name.\u0027),"},{"line_number":54,"context_line":"    cfg.StrOpt(\u0027statsd_host\u0027,"}],"source_content_type":"text/x-python","patch_set":10,"id":"5a18252c_764f9c92","line":51,"updated":"2016-04-12 19:35:25.000000000","message":"I think you\u0027re missing a period at the end of \u0027value\u0027.","commit_id":"b189d3216751c3ae9e3ff609110bb0edb84b8fdd"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ec427a8b5781f70c9fb3e559af0a1c0bd14365b0","unresolved":false,"context_lines":[{"line_number":50,"context_line":"    cfg.StrOpt(\u0027global_prefix\u0027,"},{"line_number":51,"context_line":"               help\u003d\u0027Prefix all metric names with this value \u0027"},{"line_number":52,"context_line":"                    \u0027The format of metric names is \u0027"},{"line_number":53,"context_line":"                    \u0027[global_prefix.][host_name.]prefix.metric_name.\u0027),"},{"line_number":54,"context_line":"    cfg.StrOpt(\u0027statsd_host\u0027,"},{"line_number":55,"context_line":"               default\u003d\u0027localhost\u0027,"},{"line_number":56,"context_line":"               help\u003d\u0027Host for use with the statsd backend.\u0027),"}],"source_content_type":"text/x-python","patch_set":10,"id":"5a18252c_9631980e","line":53,"updated":"2016-04-12 19:35:25.000000000","message":"So the default is not to prefix with anything, right? Would it be useful to mention that? And/or add \u0027default\u003dNone\u0027?","commit_id":"b189d3216751c3ae9e3ff609110bb0edb84b8fdd"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"30f3df678786ca72836dac4dc66d7713c80764f4","unresolved":false,"context_lines":[{"line_number":50,"context_line":"    cfg.StrOpt(\u0027global_prefix\u0027,"},{"line_number":51,"context_line":"               help\u003d\u0027Prefix all metric names with this value \u0027"},{"line_number":52,"context_line":"                    \u0027The format of metric names is \u0027"},{"line_number":53,"context_line":"                    \u0027[global_prefix.][host_name.]prefix.metric_name.\u0027),"},{"line_number":54,"context_line":"    cfg.StrOpt(\u0027statsd_host\u0027,"},{"line_number":55,"context_line":"               default\u003d\u0027localhost\u0027,"},{"line_number":56,"context_line":"               help\u003d\u0027Host for use with the statsd backend.\u0027),"}],"source_content_type":"text/x-python","patch_set":10,"id":"1a122d0e_d961a1aa","line":53,"in_reply_to":"5a18252c_71a66a54","updated":"2016-04-21 17:51:50.000000000","message":"No need to add \u0027default\u003dNone\u0027 since you mentioned it in the help string. I wanted some indication that we knew what the default was, and bonus if the user knew it too :)","commit_id":"b189d3216751c3ae9e3ff609110bb0edb84b8fdd"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"13524b6c913541d614ab20ef91fecd405e84baf3","unresolved":false,"context_lines":[{"line_number":50,"context_line":"    cfg.StrOpt(\u0027global_prefix\u0027,"},{"line_number":51,"context_line":"               help\u003d\u0027Prefix all metric names with this value \u0027"},{"line_number":52,"context_line":"                    \u0027The format of metric names is \u0027"},{"line_number":53,"context_line":"                    \u0027[global_prefix.][host_name.]prefix.metric_name.\u0027),"},{"line_number":54,"context_line":"    cfg.StrOpt(\u0027statsd_host\u0027,"},{"line_number":55,"context_line":"               default\u003d\u0027localhost\u0027,"},{"line_number":56,"context_line":"               help\u003d\u0027Host for use with the statsd backend.\u0027),"}],"source_content_type":"text/x-python","patch_set":10,"id":"5a18252c_71a66a54","line":53,"in_reply_to":"5a18252c_9631980e","updated":"2016-04-13 10:24:30.000000000","message":"I’ve changed the comment to mention the default value, but I’m not sure about adding ‘default\u003dNone’ since a previous review mentioned it wasn’t needed.","commit_id":"b189d3216751c3ae9e3ff609110bb0edb84b8fdd"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ec427a8b5781f70c9fb3e559af0a1c0bd14365b0","unresolved":false,"context_lines":[{"line_number":58,"context_line":"                default\u003d8125,"},{"line_number":59,"context_line":"                help\u003d\u0027Port to use with the statsd backend.\u0027),"},{"line_number":60,"context_line":"    # IPA config options: used by IPA to configure how it reports metric data"},{"line_number":61,"context_line":"    cfg.StrOpt(\u0027agent_backend\u0027,"},{"line_number":62,"context_line":"               default\u003d\u0027noop\u0027,"},{"line_number":63,"context_line":"               help\u003d\u0027Backend to use for the metrics system. Default possible \u0027"},{"line_number":64,"context_line":"                    \u0027backends are \"noop\" and \"statsd\".\u0027),"}],"source_content_type":"text/x-python","patch_set":10,"id":"5a18252c_61f234d4","line":61,"updated":"2016-04-12 19:35:25.000000000","message":"I think I am missing something. This is a library, to be used with ironic or ipa.\n\nIf it is used with ironic, would ironic care about these agent_* configs? And if it is used with ipa, would ipa care about the above \u0027statsd_host\u0027, \u0027statsd_port\u0027, etc configs?","commit_id":"b189d3216751c3ae9e3ff609110bb0edb84b8fdd"},{"author":{"_account_id":13362,"name":"Tan Lin","email":"lin.tan@intel.com","username":"zero"},"change_message_id":"8cdc64855a72b32717495c1434b15491ee8d6a7e","unresolved":false,"context_lines":[{"line_number":36,"context_line":"    cfg.StrOpt(\u0027backend\u0027,"},{"line_number":37,"context_line":"               default\u003d\u0027noop\u0027,"},{"line_number":38,"context_line":"               choices\u003d[\u0027noop\u0027, \u0027statsd\u0027],"},{"line_number":39,"context_line":"               help\u003d\u0027Backend to use for the metrics system. Possible \u0027"},{"line_number":40,"context_line":"                    \u0027values are \"noop\" and \"statsd\".\u0027),"},{"line_number":41,"context_line":"    cfg.BoolOpt(\u0027prepend_host\u0027,"},{"line_number":42,"context_line":"                default\u003dFalse,"},{"line_number":43,"context_line":"                help\u003d\u0027Prepend the hostname to all metric names. \u0027"}],"source_content_type":"text/x-python","patch_set":11,"id":"1a122d0e_2b0136af","line":40,"range":{"start_line":39,"start_character":59,"end_line":40,"end_character":54},"updated":"2016-04-18 06:45:39.000000000","message":"This is not necessary need, since we are using oslo-config-generator which will automatic create a list of allowed values from choices.","commit_id":"1ea6fb23173ce5a872fb2625fa4f906eaf44c982"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"58a7b20674e4fd2fe0cb002b701ecda89cac9c45","unresolved":false,"context_lines":[{"line_number":72,"context_line":""},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"def _format_name(parts):"},{"line_number":75,"context_line":"    \"\"\"Format prefix parts to a list of strings."},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    :param parts: Prefix or name parts. Valid values are a string,"},{"line_number":78,"context_line":"        an int, a list of strings / integers, and None."}],"source_content_type":"text/x-python","patch_set":12,"id":"1a122d0e_19867913","line":75,"updated":"2016-04-21 17:51:26.000000000","message":"Might just be me, but I have a hard time parsing this string.","commit_id":"055bbdff1593d92d61e8b3ddf8f8fb8bcf4557e6"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2e1ce43362aa5b64f1e22ce2634cdd665b58f5ff","unresolved":false,"context_lines":[{"line_number":72,"context_line":""},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"def _format_name(parts):"},{"line_number":75,"context_line":"    \"\"\"Format prefix parts to a list of strings."},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    :param parts: Prefix or name parts. Valid values are a string,"},{"line_number":78,"context_line":"        an int, a list of strings / integers, and None."}],"source_content_type":"text/x-python","patch_set":12,"id":"1a122d0e_1309a331","line":75,"in_reply_to":"1a122d0e_19867913","updated":"2016-05-06 08:43:32.000000000","message":"Done","commit_id":"055bbdff1593d92d61e8b3ddf8f8fb8bcf4557e6"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"58a7b20674e4fd2fe0cb002b701ecda89cac9c45","unresolved":false,"context_lines":[{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    :param parts: Prefix or name parts. Valid values are a string,"},{"line_number":78,"context_line":"        an int, a list of strings / integers, and None."},{"line_number":79,"context_line":"    :return: Parts formatted as a list of strings."},{"line_number":80,"context_line":"    \"\"\""},{"line_number":81,"context_line":"    if isinstance(parts, six.string_types):"},{"line_number":82,"context_line":"        m_parts \u003d [parts]"}],"source_content_type":"text/x-python","patch_set":12,"id":"1a122d0e_d907e17f","line":79,"updated":"2016-04-21 17:51:26.000000000","message":"it is odd to use the term \u0027format\u0027 when you are returning a list of strings. If it was a string being returned, it\u0027d make more sense to me to use \u0027format\u0027.\n\n\"A list of strings that represent the parts\" ?","commit_id":"055bbdff1593d92d61e8b3ddf8f8fb8bcf4557e6"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2e1ce43362aa5b64f1e22ce2634cdd665b58f5ff","unresolved":false,"context_lines":[{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    :param parts: Prefix or name parts. Valid values are a string,"},{"line_number":78,"context_line":"        an int, a list of strings / integers, and None."},{"line_number":79,"context_line":"    :return: Parts formatted as a list of strings."},{"line_number":80,"context_line":"    \"\"\""},{"line_number":81,"context_line":"    if isinstance(parts, six.string_types):"},{"line_number":82,"context_line":"        m_parts \u003d [parts]"}],"source_content_type":"text/x-python","patch_set":12,"id":"1a122d0e_53ff9b01","line":79,"in_reply_to":"1a122d0e_d907e17f","updated":"2016-05-06 08:43:32.000000000","message":"Done","commit_id":"055bbdff1593d92d61e8b3ddf8f8fb8bcf4557e6"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"58a7b20674e4fd2fe0cb002b701ecda89cac9c45","unresolved":false,"context_lines":[{"line_number":119,"context_line":"        \"\"\""},{"line_number":120,"context_line":"        m_parts \u003d _format_name(m_parts)"},{"line_number":121,"context_line":""},{"line_number":122,"context_line":"        return self._delimiter.join(self._prefix_parts + list(m_parts))"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    def gauge(self, m_parts, m_value):"},{"line_number":125,"context_line":"        \"\"\"Send gauge metric data."}],"source_content_type":"text/x-python","patch_set":12,"id":"1a122d0e_595ab151","line":122,"updated":"2016-04-21 17:51:26.000000000","message":"So self._prefix_parts never changes, right? Once it is set in __init__, you just use it? I don\u0027t see why you just don\u0027t generate the prefix string once, in the __init__(), and then use it. To me, that would be clearer and more efficient. (I mean, why generate that substring every time you need it.)\n\nAnd then if you call it _prefix instead of _prefix_parts, it would be simpler and easier to describe :)","commit_id":"055bbdff1593d92d61e8b3ddf8f8fb8bcf4557e6"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2e1ce43362aa5b64f1e22ce2634cdd665b58f5ff","unresolved":false,"context_lines":[{"line_number":119,"context_line":"        \"\"\""},{"line_number":120,"context_line":"        m_parts \u003d _format_name(m_parts)"},{"line_number":121,"context_line":""},{"line_number":122,"context_line":"        return self._delimiter.join(self._prefix_parts + list(m_parts))"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    def gauge(self, m_parts, m_value):"},{"line_number":125,"context_line":"        \"\"\"Send gauge metric data."}],"source_content_type":"text/x-python","patch_set":12,"id":"1a122d0e_2613bf5d","line":122,"in_reply_to":"1a122d0e_595ab151","updated":"2016-05-06 08:43:32.000000000","message":"Done","commit_id":"055bbdff1593d92d61e8b3ddf8f8fb8bcf4557e6"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"58a7b20674e4fd2fe0cb002b701ecda89cac9c45","unresolved":false,"context_lines":[{"line_number":121,"context_line":""},{"line_number":122,"context_line":"        return self._delimiter.join(self._prefix_parts + list(m_parts))"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    def gauge(self, m_parts, m_value):"},{"line_number":125,"context_line":"        \"\"\"Send gauge metric data."},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"        :param m_parts: Metric name"}],"source_content_type":"text/x-python","patch_set":12,"id":"1a122d0e_f4baa470","line":124,"updated":"2016-04-21 17:51:26.000000000","message":"I am just skimming through, and I have to admit, I\u0027m puzzled by \u0027m_parts\u0027. That seems to be the metric name, so similar question I have wrt the prefix_parts. Why not generate it once -- does it change often? Maybe I don\u0027t understand the use case where this would be used.","commit_id":"055bbdff1593d92d61e8b3ddf8f8fb8bcf4557e6"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2e1ce43362aa5b64f1e22ce2634cdd665b58f5ff","unresolved":false,"context_lines":[{"line_number":121,"context_line":""},{"line_number":122,"context_line":"        return self._delimiter.join(self._prefix_parts + list(m_parts))"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    def gauge(self, m_parts, m_value):"},{"line_number":125,"context_line":"        \"\"\"Send gauge metric data."},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"        :param m_parts: Metric name"}],"source_content_type":"text/x-python","patch_set":12,"id":"1a122d0e_0610434d","line":124,"in_reply_to":"1a122d0e_f4baa470","updated":"2016-05-06 08:43:32.000000000","message":"Done","commit_id":"055bbdff1593d92d61e8b3ddf8f8fb8bcf4557e6"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"58a7b20674e4fd2fe0cb002b701ecda89cac9c45","unresolved":false,"context_lines":[{"line_number":308,"context_line":"class NoopMetricLogger(MetricLogger):"},{"line_number":309,"context_line":"    \"\"\"Noop metric logger that throws away all metric data.\"\"\""},{"line_number":310,"context_line":"    def __init__(self, prefix, delimiter\u003d\u0027.\u0027):"},{"line_number":311,"context_line":"        super(NoopMetricLogger, self).__init__(prefix, delimiter)"},{"line_number":312,"context_line":""},{"line_number":313,"context_line":"    def _gauge(self, m_name, m_value):"},{"line_number":314,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":12,"id":"1a122d0e_3456dc06","line":311,"updated":"2016-04-21 17:51:26.000000000","message":"slightly? better to do s/delimiter/delimiter\u003ddelimiter/","commit_id":"055bbdff1593d92d61e8b3ddf8f8fb8bcf4557e6"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2e1ce43362aa5b64f1e22ce2634cdd665b58f5ff","unresolved":false,"context_lines":[{"line_number":308,"context_line":"class NoopMetricLogger(MetricLogger):"},{"line_number":309,"context_line":"    \"\"\"Noop metric logger that throws away all metric data.\"\"\""},{"line_number":310,"context_line":"    def __init__(self, prefix, delimiter\u003d\u0027.\u0027):"},{"line_number":311,"context_line":"        super(NoopMetricLogger, self).__init__(prefix, delimiter)"},{"line_number":312,"context_line":""},{"line_number":313,"context_line":"    def _gauge(self, m_name, m_value):"},{"line_number":314,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":12,"id":"1a122d0e_c6200b9d","line":311,"in_reply_to":"1a122d0e_3456dc06","updated":"2016-05-06 08:43:32.000000000","message":"Done","commit_id":"055bbdff1593d92d61e8b3ddf8f8fb8bcf4557e6"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"58a7b20674e4fd2fe0cb002b701ecda89cac9c45","unresolved":false,"context_lines":[{"line_number":331,"context_line":"        \"\"\"Initialize a StatsdMetricLogger"},{"line_number":332,"context_line":""},{"line_number":333,"context_line":"        The logger uses the given prefix list, delimiter, host, and port."},{"line_number":334,"context_line":"        \"\"\""},{"line_number":335,"context_line":"        super(StatsdMetricLogger, self).__init__(prefix_parts, delimiter)"},{"line_number":336,"context_line":""},{"line_number":337,"context_line":"        self._host \u003d host or CONF.metrics.statsd_host"}],"source_content_type":"text/x-python","patch_set":12,"id":"1a122d0e_34a41c07","line":334,"updated":"2016-04-21 17:51:26.000000000","message":"please describe all the parameters.","commit_id":"055bbdff1593d92d61e8b3ddf8f8fb8bcf4557e6"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2e1ce43362aa5b64f1e22ce2634cdd665b58f5ff","unresolved":false,"context_lines":[{"line_number":331,"context_line":"        \"\"\"Initialize a StatsdMetricLogger"},{"line_number":332,"context_line":""},{"line_number":333,"context_line":"        The logger uses the given prefix list, delimiter, host, and port."},{"line_number":334,"context_line":"        \"\"\""},{"line_number":335,"context_line":"        super(StatsdMetricLogger, self).__init__(prefix_parts, delimiter)"},{"line_number":336,"context_line":""},{"line_number":337,"context_line":"        self._host \u003d host or CONF.metrics.statsd_host"}],"source_content_type":"text/x-python","patch_set":12,"id":"1a122d0e_0637a3e3","line":334,"in_reply_to":"1a122d0e_34a41c07","updated":"2016-05-06 08:43:32.000000000","message":"Done","commit_id":"055bbdff1593d92d61e8b3ddf8f8fb8bcf4557e6"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"58a7b20674e4fd2fe0cb002b701ecda89cac9c45","unresolved":false,"context_lines":[{"line_number":383,"context_line":"    prefix \u003d _format_name(prefix)"},{"line_number":384,"context_line":""},{"line_number":385,"context_line":"    if CONF.metrics.prepend_host:"},{"line_number":386,"context_line":"        host \u003d CONF.metrics.host"},{"line_number":387,"context_line":""},{"line_number":388,"context_line":"        if CONF.metrics.prepend_host_reverse:"},{"line_number":389,"context_line":"            host \u003d \u0027.\u0027.join(reversed(host.split(\u0027.\u0027)))"}],"source_content_type":"text/x-python","patch_set":12,"id":"1a122d0e_f4774406","line":386,"updated":"2016-04-21 17:51:26.000000000","message":"Why not add a \u0027host\u0027 parameter to get_logger()?\n\nI\u0027m actually wondering about parameters that correspond to the other configs too. Not sure, I\u0027m not an expert on how to put together a general purpose library.","commit_id":"055bbdff1593d92d61e8b3ddf8f8fb8bcf4557e6"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2e1ce43362aa5b64f1e22ce2634cdd665b58f5ff","unresolved":false,"context_lines":[{"line_number":383,"context_line":"    prefix \u003d _format_name(prefix)"},{"line_number":384,"context_line":""},{"line_number":385,"context_line":"    if CONF.metrics.prepend_host:"},{"line_number":386,"context_line":"        host \u003d CONF.metrics.host"},{"line_number":387,"context_line":""},{"line_number":388,"context_line":"        if CONF.metrics.prepend_host_reverse:"},{"line_number":389,"context_line":"            host \u003d \u0027.\u0027.join(reversed(host.split(\u0027.\u0027)))"}],"source_content_type":"text/x-python","patch_set":12,"id":"1a122d0e_06f683d6","line":386,"in_reply_to":"1a122d0e_f4774406","updated":"2016-05-06 08:43:32.000000000","message":"I’ve looked at how oslo libraries handle config options and, from what I understand, the options are defined in the lib, but their value is specified in Ironic’s config file (for instance, in sections [oslo_concurrency] or [disk_partitioner]). \nSo, I’m not sure we should pass the options using parameters: I think the caller should be able to specify it in Ironic config file (in a [metrics] section)? \nWhat do you think?","commit_id":"055bbdff1593d92d61e8b3ddf8f8fb8bcf4557e6"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"58a7b20674e4fd2fe0cb002b701ecda89cac9c45","unresolved":false,"context_lines":[{"line_number":396,"context_line":"    if CONF.metrics.backend \u003d\u003d \u0027statsd\u0027:"},{"line_number":397,"context_line":"        return StatsdMetricLogger(prefix)"},{"line_number":398,"context_line":"    elif CONF.metrics.backend \u003d\u003d \u0027noop\u0027:"},{"line_number":399,"context_line":"        return NoopMetricLogger(prefix)"},{"line_number":400,"context_line":"    else:"},{"line_number":401,"context_line":"        msg \u003d (_(\"CONF.metrics.backend is set to an unsupported backend type: \""},{"line_number":402,"context_line":"                 \"%s. Value should be \u0027noop\u0027 or \u0027statsd\u0027.\")"}],"source_content_type":"text/x-python","patch_set":12,"id":"1a122d0e_74cdf485","line":399,"updated":"2016-04-21 17:51:26.000000000","message":"I am wondering why we even need CONF.metrics.backend. Or at the very least, why not allow the caller to specify the backend via a parameter, eg: get_logger(backend\u003dNone). If not specified, then use the CONF value.\n\n(Not sure how other eg oslo libraries deal with this. I\u0027d say be consistent if there is a consistent way.)","commit_id":"055bbdff1593d92d61e8b3ddf8f8fb8bcf4557e6"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"9a7fc915d7d157bf242ed6397f0a5f1ced176951","unresolved":false,"context_lines":[{"line_number":71,"context_line":"    return time.time()"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"def _format_name(parts):"},{"line_number":75,"context_line":"    \"\"\"Generate a list of string representing a prefix or name."},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    :param parts: Prefix or name parts. Valid values are a string,"}],"source_content_type":"text/x-python","patch_set":13,"id":"dab17558_d6af9629","line":74,"updated":"2016-05-12 17:30:43.000000000","message":"I wish a better name could be done for this function. When I think \u0027format\u0027 I am thinking a string is being returned.\n\n _parts_to_list()  ??\n _prefixes_to_list() ??\n\nAnd \u0027parts\u0027 as a name is not great to me.\n\nI see \u0027parts\u0027, \u0027name_parts\u0027, and \u0027prefix_parts\u0027 used in this file. Are they all different things?","commit_id":"00a119032511f2038d7aadeef0a12993e9b1fc4f"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2dffffff58b20b4a0e8fd79b7a97d4618f658296","unresolved":false,"context_lines":[{"line_number":71,"context_line":"    return time.time()"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"def _format_name(parts):"},{"line_number":75,"context_line":"    \"\"\"Generate a list of string representing a prefix or name."},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    :param parts: Prefix or name parts. Valid values are a string,"}],"source_content_type":"text/x-python","patch_set":13,"id":"dab17558_95ef5686","line":74,"in_reply_to":"dab17558_d6af9629","updated":"2016-05-16 10:08:11.000000000","message":"‘parts’, ‘name_parts’, and ‘prefix_parts’ are almost the same, except that ‘name_parts’ applies to the metric name, ‘prefix_parts’ to the metric prefix, and ‘parts’ can be both. But you’re right, it’s not very clear. \nI’ve changed ‘parts’ to ‘name_parts’ when it can be either a name or a prefix, and I have kept ‘prefix_parts’ when it can only be a prefix. Let me know if it makes more sense, or if you think using the same name everywhere would be better. Thanks!","commit_id":"00a119032511f2038d7aadeef0a12993e9b1fc4f"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"9a7fc915d7d157bf242ed6397f0a5f1ced176951","unresolved":false,"context_lines":[{"line_number":72,"context_line":""},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"def _format_name(parts):"},{"line_number":75,"context_line":"    \"\"\"Generate a list of string representing a prefix or name."},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    :param parts: Prefix or name parts. Valid values are a string,"},{"line_number":78,"context_line":"        an int, a list of strings / integers, and None."}],"source_content_type":"text/x-python","patch_set":13,"id":"dab17558_16775e03","line":75,"range":{"start_line":75,"start_character":26,"end_line":75,"end_character":32},"updated":"2016-05-12 17:30:43.000000000","message":"strings\n\nplural I think","commit_id":"00a119032511f2038d7aadeef0a12993e9b1fc4f"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2dffffff58b20b4a0e8fd79b7a97d4618f658296","unresolved":false,"context_lines":[{"line_number":72,"context_line":""},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"def _format_name(parts):"},{"line_number":75,"context_line":"    \"\"\"Generate a list of string representing a prefix or name."},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    :param parts: Prefix or name parts. Valid values are a string,"},{"line_number":78,"context_line":"        an int, a list of strings / integers, and None."}],"source_content_type":"text/x-python","patch_set":13,"id":"dab17558_b559ba37","line":75,"range":{"start_line":75,"start_character":26,"end_line":75,"end_character":32},"in_reply_to":"dab17558_16775e03","updated":"2016-05-16 10:08:11.000000000","message":"Done","commit_id":"00a119032511f2038d7aadeef0a12993e9b1fc4f"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"9a7fc915d7d157bf242ed6397f0a5f1ced176951","unresolved":false,"context_lines":[{"line_number":118,"context_line":"        \"\"\""},{"line_number":119,"context_line":"        m_name_parts \u003d _format_name(m_name_parts)"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"        if (self._prefix \u003d\u003d \u0027\u0027):"},{"line_number":122,"context_line":"            return self._delimiter.join(list(m_name_parts))"},{"line_number":123,"context_line":"        return self._delimiter.join([self._prefix] + list(m_name_parts))"},{"line_number":124,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"dab17558_56a0c6a5","line":121,"updated":"2016-05-12 17:30:43.000000000","message":"nit: No need for parens.\n\nCould be fixed in follow-up patch.\n\nMight be able to do:\n\n if not self._prefix:\n    return ...","commit_id":"00a119032511f2038d7aadeef0a12993e9b1fc4f"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2dffffff58b20b4a0e8fd79b7a97d4618f658296","unresolved":false,"context_lines":[{"line_number":118,"context_line":"        \"\"\""},{"line_number":119,"context_line":"        m_name_parts \u003d _format_name(m_name_parts)"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"        if (self._prefix \u003d\u003d \u0027\u0027):"},{"line_number":122,"context_line":"            return self._delimiter.join(list(m_name_parts))"},{"line_number":123,"context_line":"        return self._delimiter.join([self._prefix] + list(m_name_parts))"},{"line_number":124,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"dab17558_352f8a89","line":121,"in_reply_to":"dab17558_56a0c6a5","updated":"2016-05-16 10:08:11.000000000","message":"Done","commit_id":"00a119032511f2038d7aadeef0a12993e9b1fc4f"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"9a7fc915d7d157bf242ed6397f0a5f1ced176951","unresolved":false,"context_lines":[{"line_number":119,"context_line":"        m_name_parts \u003d _format_name(m_name_parts)"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"        if (self._prefix \u003d\u003d \u0027\u0027):"},{"line_number":122,"context_line":"            return self._delimiter.join(list(m_name_parts))"},{"line_number":123,"context_line":"        return self._delimiter.join([self._prefix] + list(m_name_parts))"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    def gauge(self, m_name, m_value):"}],"source_content_type":"text/x-python","patch_set":13,"id":"dab17558_16e59ea7","line":122,"range":{"start_line":122,"start_character":40,"end_line":122,"end_character":44},"updated":"2016-05-12 17:30:43.000000000","message":"Seems redundant to use \u0027list\u0027 as the function returns a list.","commit_id":"00a119032511f2038d7aadeef0a12993e9b1fc4f"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2dffffff58b20b4a0e8fd79b7a97d4618f658296","unresolved":false,"context_lines":[{"line_number":119,"context_line":"        m_name_parts \u003d _format_name(m_name_parts)"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"        if (self._prefix \u003d\u003d \u0027\u0027):"},{"line_number":122,"context_line":"            return self._delimiter.join(list(m_name_parts))"},{"line_number":123,"context_line":"        return self._delimiter.join([self._prefix] + list(m_name_parts))"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    def gauge(self, m_name, m_value):"}],"source_content_type":"text/x-python","patch_set":13,"id":"dab17558_954e366d","line":122,"range":{"start_line":122,"start_character":40,"end_line":122,"end_character":44},"in_reply_to":"dab17558_16e59ea7","updated":"2016-05-16 10:08:11.000000000","message":"Done","commit_id":"00a119032511f2038d7aadeef0a12993e9b1fc4f"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"9a7fc915d7d157bf242ed6397f0a5f1ced176951","unresolved":false,"context_lines":[{"line_number":120,"context_line":""},{"line_number":121,"context_line":"        if (self._prefix \u003d\u003d \u0027\u0027):"},{"line_number":122,"context_line":"            return self._delimiter.join(list(m_name_parts))"},{"line_number":123,"context_line":"        return self._delimiter.join([self._prefix] + list(m_name_parts))"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    def gauge(self, m_name, m_value):"},{"line_number":126,"context_line":"        \"\"\"Send gauge metric data."}],"source_content_type":"text/x-python","patch_set":13,"id":"dab17558_96d06ecb","line":123,"range":{"start_line":123,"start_character":53,"end_line":123,"end_character":57},"updated":"2016-05-12 17:30:43.000000000","message":"Seems redundant to use \u0027list\u0027 as the function returns a list.","commit_id":"00a119032511f2038d7aadeef0a12993e9b1fc4f"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2dffffff58b20b4a0e8fd79b7a97d4618f658296","unresolved":false,"context_lines":[{"line_number":120,"context_line":""},{"line_number":121,"context_line":"        if (self._prefix \u003d\u003d \u0027\u0027):"},{"line_number":122,"context_line":"            return self._delimiter.join(list(m_name_parts))"},{"line_number":123,"context_line":"        return self._delimiter.join([self._prefix] + list(m_name_parts))"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    def gauge(self, m_name, m_value):"},{"line_number":126,"context_line":"        \"\"\"Send gauge metric data."}],"source_content_type":"text/x-python","patch_set":13,"id":"dab17558_7553d217","line":123,"range":{"start_line":123,"start_character":53,"end_line":123,"end_character":57},"in_reply_to":"dab17558_96d06ecb","updated":"2016-05-16 10:08:11.000000000","message":"Done","commit_id":"00a119032511f2038d7aadeef0a12993e9b1fc4f"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"4dfb4eb18e515c75245298bf479ebce7c81ada75","unresolved":false,"context_lines":[{"line_number":94,"context_line":"class MetricLogger(object):"},{"line_number":95,"context_line":"    \"\"\"Abstract class representing a metrics logger.\"\"\""},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"    def __init__(self, prefix_parts, delimiter\u003d\u0027.\u0027):"},{"line_number":98,"context_line":"        \"\"\"Init a MetricLogger."},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"        :param prefix_parts: Prefix parts for this metric logger. Valid values"}],"source_content_type":"text/x-python","patch_set":14,"id":"dab17558_651dbc61","line":97,"updated":"2016-05-16 20:58:32.000000000","message":"Hmm. Just thinking. If you allow the delimiter to change so that it isn\u0027t necessarily \u0027.\u0027, it means that everywhere the name is described with \u0027.\u0027, it needs to be changed or documented that it might not be \u0027.\u0027 but that it will be whatever delimiter is specified.\n\nEg, line 113 below, \"[global_prefix.][uuid.][host_name.]prefix\". It will be something like \"[global_prefix\u003cdelimiter\u003e][host_name\u003cdelimiter\u003e]prefix\".\n\n I suppose you could mention something like \u0027where \".\" is the delimiter\u0027","commit_id":"ab14ed749842c797a370de39b468359a3032211c"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"1484b4dfbc91261294fca85c23d3f91c22582aa9","unresolved":false,"context_lines":[{"line_number":94,"context_line":"class MetricLogger(object):"},{"line_number":95,"context_line":"    \"\"\"Abstract class representing a metrics logger.\"\"\""},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"    def __init__(self, prefix_parts, delimiter\u003d\u0027.\u0027):"},{"line_number":98,"context_line":"        \"\"\"Init a MetricLogger."},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"        :param prefix_parts: Prefix parts for this metric logger. Valid values"}],"source_content_type":"text/x-python","patch_set":14,"id":"bab6814e_5d110a5d","line":97,"in_reply_to":"dab17558_651dbc61","updated":"2016-05-24 10:13:32.000000000","message":"Done","commit_id":"ab14ed749842c797a370de39b468359a3032211c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"4dfb4eb18e515c75245298bf479ebce7c81ada75","unresolved":false,"context_lines":[{"line_number":155,"context_line":"            return self._counter(m_name, m_value,"},{"line_number":156,"context_line":"                                 sample_rate\u003dsample_rate)"},{"line_number":157,"context_line":""},{"line_number":158,"context_line":"    def timer(self, m_name, m_value):"},{"line_number":159,"context_line":"        \"\"\"Send timer data."},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"        :param m_name: Metric name"}],"source_content_type":"text/x-python","patch_set":14,"id":"dab17558_20ea820f","line":158,"updated":"2016-05-16 20:58:32.000000000","message":"Is this meant to be called via the timer_d decorator only?","commit_id":"ab14ed749842c797a370de39b468359a3032211c"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"1484b4dfbc91261294fca85c23d3f91c22582aa9","unresolved":false,"context_lines":[{"line_number":155,"context_line":"            return self._counter(m_name, m_value,"},{"line_number":156,"context_line":"                                 sample_rate\u003dsample_rate)"},{"line_number":157,"context_line":""},{"line_number":158,"context_line":"    def timer(self, m_name, m_value):"},{"line_number":159,"context_line":"        \"\"\"Send timer data."},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"        :param m_name: Metric name"}],"source_content_type":"text/x-python","patch_set":14,"id":"bab6814e_f829ec8a","line":158,"in_reply_to":"dab17558_20ea820f","updated":"2016-05-24 10:13:32.000000000","message":"This is also called in the \"timer_c\" context manager","commit_id":"ab14ed749842c797a370de39b468359a3032211c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"4dfb4eb18e515c75245298bf479ebce7c81ada75","unresolved":false,"context_lines":[{"line_number":175,"context_line":"    def _timer(self, m_name, m_value):"},{"line_number":176,"context_line":"        \"\"\"Abstract method for backends to implement timer behavior.\"\"\""},{"line_number":177,"context_line":""},{"line_number":178,"context_line":"    def timer_d(self, name_parts):"},{"line_number":179,"context_line":"        \"\"\"Returns a timer decorator that instruments a function."},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"        It is bound to this MetricLogger.  For example:"}],"source_content_type":"text/x-python","patch_set":14,"id":"dab17558_650f7c39","line":178,"updated":"2016-05-16 20:58:32.000000000","message":"what is the \u0027_d\u0027 for? To indicate that it is a decorator? Is that a standard thing, or would it be OK to just use \u0027timer\u0027?","commit_id":"ab14ed749842c797a370de39b468359a3032211c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"a51c10bfbd7ae99709af92c70ef8dc04283d834b","unresolved":false,"context_lines":[{"line_number":175,"context_line":"    def _timer(self, m_name, m_value):"},{"line_number":176,"context_line":"        \"\"\"Abstract method for backends to implement timer behavior.\"\"\""},{"line_number":177,"context_line":""},{"line_number":178,"context_line":"    def timer_d(self, name_parts):"},{"line_number":179,"context_line":"        \"\"\"Returns a timer decorator that instruments a function."},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"        It is bound to this MetricLogger.  For example:"}],"source_content_type":"text/x-python","patch_set":14,"id":"bab6814e_85a58205","line":178,"in_reply_to":"bab6814e_1ce60fb4","updated":"2016-05-25 15:39:58.000000000","message":"\u0027timed\u0027 would work. \u0027time_it\u0027? \u0027time_spent\u0027? \u0027time_this\u0027, \u0027time\u0027? \u0027timer\u0027 might work here (I can only think of \u0027timer\u0027 as a noun, if you saw \u0027timer\u0027 would you think that the thing was being timed?).\n\nI am also wondering if timer() (at line 158) is right, since that method isn\u0027t a timer. It is just getting timing information, right? Hence, my question about what terminology existing metrics software uses.","commit_id":"ab14ed749842c797a370de39b468359a3032211c"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"fa5b5ceb9ca2b4e14d06709bf38b14c75d448270","unresolved":false,"context_lines":[{"line_number":175,"context_line":"    def _timer(self, m_name, m_value):"},{"line_number":176,"context_line":"        \"\"\"Abstract method for backends to implement timer behavior.\"\"\""},{"line_number":177,"context_line":""},{"line_number":178,"context_line":"    def timer_d(self, name_parts):"},{"line_number":179,"context_line":"        \"\"\"Returns a timer decorator that instruments a function."},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"        It is bound to this MetricLogger.  For example:"}],"source_content_type":"text/x-python","patch_set":14,"id":"bab6814e_1ce60fb4","line":178,"in_reply_to":"bab6814e_b1fc7a3f","updated":"2016-05-25 15:06:44.000000000","message":"There doesn\u0027t appear to be any standard convention for naming decorators, but one common pattern seems to be \"a word or phrase describing the wrapped function\" - in this case, that might be \"timed\". The other two could be \"counted\" and \"gauged\", though I don\u0027t think the last one is very clear.","commit_id":"ab14ed749842c797a370de39b468359a3032211c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1682b333ae443ee567bb51c4f7148e83bc9bbda8","unresolved":false,"context_lines":[{"line_number":175,"context_line":"    def _timer(self, m_name, m_value):"},{"line_number":176,"context_line":"        \"\"\"Abstract method for backends to implement timer behavior.\"\"\""},{"line_number":177,"context_line":""},{"line_number":178,"context_line":"    def timer_d(self, name_parts):"},{"line_number":179,"context_line":"        \"\"\"Returns a timer decorator that instruments a function."},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"        It is bound to this MetricLogger.  For example:"}],"source_content_type":"text/x-python","patch_set":14,"id":"bab6814e_b1fc7a3f","line":178,"in_reply_to":"bab6814e_d84a2855","updated":"2016-05-24 21:22:48.000000000","message":"why not think of a name that describes what that decorator is doing.\n\nSo for example, this is what I might do if I were writing this. I\u0027d take a look at existing documentation for metrics, so that I would use similar terminology. Looking at statsd [1], I see that they refer to a \u0027timing\u0027 method. What is the difference between a \u0027timer\u0027 and \u0027timing\u0027? Maybe one of the methods should not have \u0027timer\u0027 in its name? (Maybe look at other metrics documentation for other ideas.)\n\nSimilar questions for the other metric-related methods.\n\nhttps://statsd.readthedocs.io/en/v3.2.1/timing.html","commit_id":"ab14ed749842c797a370de39b468359a3032211c"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"1484b4dfbc91261294fca85c23d3f91c22582aa9","unresolved":false,"context_lines":[{"line_number":175,"context_line":"    def _timer(self, m_name, m_value):"},{"line_number":176,"context_line":"        \"\"\"Abstract method for backends to implement timer behavior.\"\"\""},{"line_number":177,"context_line":""},{"line_number":178,"context_line":"    def timer_d(self, name_parts):"},{"line_number":179,"context_line":"        \"\"\"Returns a timer decorator that instruments a function."},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"        It is bound to this MetricLogger.  For example:"}],"source_content_type":"text/x-python","patch_set":14,"id":"bab6814e_d84a2855","line":178,"in_reply_to":"dab17558_650f7c39","updated":"2016-05-24 10:13:32.000000000","message":"Yes, it’s supposed to indicate that it’s a decorator, since I haven’t found any standard way to name a decorator and it was the name suggested in the spec. \nI am ok with naming it “timer” but then the naming between the decorator and the context manager (“timer_c”) won’t be consistent: what do you think is best?","commit_id":"ab14ed749842c797a370de39b468359a3032211c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"4dfb4eb18e515c75245298bf479ebce7c81ada75","unresolved":false,"context_lines":[{"line_number":389,"context_line":"        return self._send(m_name, m_value, self.TIMER_TYPE)"},{"line_number":390,"context_line":""},{"line_number":391,"context_line":""},{"line_number":392,"context_line":"def get_logger(prefix):"},{"line_number":393,"context_line":"    \"\"\"Return a metric logger with the specified prefix."},{"line_number":394,"context_line":""},{"line_number":395,"context_line":"    The format of the prefix is [global_prefix.][host_name.]prefix."}],"source_content_type":"text/x-python","patch_set":14,"id":"dab17558_a5968449","line":392,"updated":"2016-05-16 20:58:32.000000000","message":"To continue the comments from revision 12.\n\nWhat I was wondering is why bother having most of the configs. Why not have something like\n\n    get_logger(backend\u003d\"noop\", host\u003dNone, prefix\u003dNone)","commit_id":"ab14ed749842c797a370de39b468359a3032211c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"6a821710632e4e69a209d157d4fccac0795b5773","unresolved":false,"context_lines":[{"line_number":389,"context_line":"        return self._send(m_name, m_value, self.TIMER_TYPE)"},{"line_number":390,"context_line":""},{"line_number":391,"context_line":""},{"line_number":392,"context_line":"def get_logger(prefix):"},{"line_number":393,"context_line":"    \"\"\"Return a metric logger with the specified prefix."},{"line_number":394,"context_line":""},{"line_number":395,"context_line":"    The format of the prefix is [global_prefix.][host_name.]prefix."}],"source_content_type":"text/x-python","patch_set":14,"id":"bab6814e_4e72cfe4","line":392,"in_reply_to":"bab6814e_189af0c5","updated":"2016-05-24 21:11:34.000000000","message":"thanks for adding those as options. As far as the configs go, my thinking is that unless there is a need/demand for them, I would prefer not to put them in. Eg, ironic already has a \u0027host\u0027 config as was mentioned before. I would prefer that the operator doesn\u0027t have to understand why there are two different \u0027host\u0027 configs in ironic.\n\n(The \u0027host\u0027 config wasn\u0027t mentioned in the spec.)","commit_id":"ab14ed749842c797a370de39b468359a3032211c"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"1484b4dfbc91261294fca85c23d3f91c22582aa9","unresolved":false,"context_lines":[{"line_number":389,"context_line":"        return self._send(m_name, m_value, self.TIMER_TYPE)"},{"line_number":390,"context_line":""},{"line_number":391,"context_line":""},{"line_number":392,"context_line":"def get_logger(prefix):"},{"line_number":393,"context_line":"    \"\"\"Return a metric logger with the specified prefix."},{"line_number":394,"context_line":""},{"line_number":395,"context_line":"    The format of the prefix is [global_prefix.][host_name.]prefix."}],"source_content_type":"text/x-python","patch_set":14,"id":"bab6814e_189af0c5","line":392,"in_reply_to":"dab17558_a5968449","updated":"2016-05-24 10:13:32.000000000","message":"I think having the config options defined in the library avoids duplicate code: if they are not defined in the library, both Ironic and IPA would have to define them. \nAs you suggested, I’ve added the ability to override the config options via parameters. WDYT?","commit_id":"ab14ed749842c797a370de39b468359a3032211c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"4dfb4eb18e515c75245298bf479ebce7c81ada75","unresolved":false,"context_lines":[{"line_number":395,"context_line":"    The format of the prefix is [global_prefix.][host_name.]prefix."},{"line_number":396,"context_line":""},{"line_number":397,"context_line":"    :param prefix: Prefix for this metric logger. Valid values are a string,"},{"line_number":398,"context_line":"        an int, a list of strings / integers, and None."},{"line_number":399,"context_line":"    \"\"\""},{"line_number":400,"context_line":"    prefix \u003d _parts_to_list(prefix)"},{"line_number":401,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"dab17558_65965c3f","line":398,"updated":"2016-05-16 20:58:32.000000000","message":"I have to admit, I really don\u0027t like that this can be different types. It just seems to be a bad api.","commit_id":"ab14ed749842c797a370de39b468359a3032211c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"6a821710632e4e69a209d157d4fccac0795b5773","unresolved":false,"context_lines":[{"line_number":395,"context_line":"    The format of the prefix is [global_prefix.][host_name.]prefix."},{"line_number":396,"context_line":""},{"line_number":397,"context_line":"    :param prefix: Prefix for this metric logger. Valid values are a string,"},{"line_number":398,"context_line":"        an int, a list of strings / integers, and None."},{"line_number":399,"context_line":"    \"\"\""},{"line_number":400,"context_line":"    prefix \u003d _parts_to_list(prefix)"},{"line_number":401,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"bab6814e_4e592f5b","line":398,"in_reply_to":"bab6814e_98aee0e5","updated":"2016-05-24 21:11:34.000000000","message":"why not change it so that prefix is just a string?","commit_id":"ab14ed749842c797a370de39b468359a3032211c"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"1484b4dfbc91261294fca85c23d3f91c22582aa9","unresolved":false,"context_lines":[{"line_number":395,"context_line":"    The format of the prefix is [global_prefix.][host_name.]prefix."},{"line_number":396,"context_line":""},{"line_number":397,"context_line":"    :param prefix: Prefix for this metric logger. Valid values are a string,"},{"line_number":398,"context_line":"        an int, a list of strings / integers, and None."},{"line_number":399,"context_line":"    \"\"\""},{"line_number":400,"context_line":"    prefix \u003d _parts_to_list(prefix)"},{"line_number":401,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"bab6814e_98aee0e5","line":398,"in_reply_to":"dab17558_65965c3f","updated":"2016-05-24 10:13:32.000000000","message":"I’ve changed that so that integers aren’t accepted anymore.","commit_id":"ab14ed749842c797a370de39b468359a3032211c"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"5186b18716915021ffc30b6e1e032e0a4d3089b9","unresolved":false,"context_lines":[{"line_number":133,"context_line":"        return self._delimiter.join([self._prefix] + name_parts)"},{"line_number":134,"context_line":""},{"line_number":135,"context_line":"    def gauge(self, m_name, m_value):"},{"line_number":136,"context_line":"        \"\"\"Send gauge metric data."},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"        :param m_name: Metric name"},{"line_number":139,"context_line":"        :param m_value: Metric value that will be sent to the backend"}],"source_content_type":"text/x-python","patch_set":16,"id":"bab6814e_7eedc88d","line":136,"updated":"2016-05-24 17:48:49.000000000","message":"Is this term well-known enough not to need explanation? I had to Google it.","commit_id":"1d6f48ae3b5d4373473319b6a19bbc6199975d1d"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ce64fd90d64042ea10b61c3ce6e91597feb347d1","unresolved":false,"context_lines":[{"line_number":213,"context_line":"class MetricLogger(object):"},{"line_number":214,"context_line":"    \"\"\"Abstract class representing a metrics logger.\"\"\""},{"line_number":215,"context_line":""},{"line_number":216,"context_line":"    def __init__(self, prefix, delimiter\u003d\u0027.\u0027):"},{"line_number":217,"context_line":"        \"\"\"Init a MetricLogger."},{"line_number":218,"context_line":""},{"line_number":219,"context_line":"        :param prefix: Prefix for this metric logger."}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_1b1007a8","line":216,"updated":"2016-06-06 19:09:30.000000000","message":"what do you think about making prefix optional, eg \u0027prefix\u003d\u0027\u0027\u0027 or \u0027prefix\u003dNone\u0027?","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"c17d3a124fed648987fd877254c0ca2796ffc8ef","unresolved":false,"context_lines":[{"line_number":213,"context_line":"class MetricLogger(object):"},{"line_number":214,"context_line":"    \"\"\"Abstract class representing a metrics logger.\"\"\""},{"line_number":215,"context_line":""},{"line_number":216,"context_line":"    def __init__(self, prefix, delimiter\u003d\u0027.\u0027):"},{"line_number":217,"context_line":"        \"\"\"Init a MetricLogger."},{"line_number":218,"context_line":""},{"line_number":219,"context_line":"        :param prefix: Prefix for this metric logger."}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_b3861e11","line":216,"in_reply_to":"7aa08908_1b1007a8","updated":"2016-06-07 11:53:04.000000000","message":"Done","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ce64fd90d64042ea10b61c3ce6e91597feb347d1","unresolved":false,"context_lines":[{"line_number":216,"context_line":"    def __init__(self, prefix, delimiter\u003d\u0027.\u0027):"},{"line_number":217,"context_line":"        \"\"\"Init a MetricLogger."},{"line_number":218,"context_line":""},{"line_number":219,"context_line":"        :param prefix: Prefix for this metric logger."},{"line_number":220,"context_line":"        :param delimiter: Delimiter."},{"line_number":221,"context_line":"        \"\"\""},{"line_number":222,"context_line":"        self._prefix \u003d prefix or \u0027\u0027"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_bbf3b39d","line":219,"updated":"2016-06-06 19:09:30.000000000","message":"All metric names will be prefixed by this string, right?","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"c17d3a124fed648987fd877254c0ca2796ffc8ef","unresolved":false,"context_lines":[{"line_number":216,"context_line":"    def __init__(self, prefix, delimiter\u003d\u0027.\u0027):"},{"line_number":217,"context_line":"        \"\"\"Init a MetricLogger."},{"line_number":218,"context_line":""},{"line_number":219,"context_line":"        :param prefix: Prefix for this metric logger."},{"line_number":220,"context_line":"        :param delimiter: Delimiter."},{"line_number":221,"context_line":"        \"\"\""},{"line_number":222,"context_line":"        self._prefix \u003d prefix or \u0027\u0027"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_93b7a2d7","line":219,"in_reply_to":"7aa08908_bbf3b39d","updated":"2016-06-07 11:53:04.000000000","message":"Yes, you\u0027re right. I\u0027ve updated the comment to mention it.","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ce64fd90d64042ea10b61c3ce6e91597feb347d1","unresolved":false,"context_lines":[{"line_number":217,"context_line":"        \"\"\"Init a MetricLogger."},{"line_number":218,"context_line":""},{"line_number":219,"context_line":"        :param prefix: Prefix for this metric logger."},{"line_number":220,"context_line":"        :param delimiter: Delimiter."},{"line_number":221,"context_line":"        \"\"\""},{"line_number":222,"context_line":"        self._prefix \u003d prefix or \u0027\u0027"},{"line_number":223,"context_line":"        self._delimiter \u003d delimiter"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_db079f7f","line":220,"updated":"2016-06-06 19:09:30.000000000","message":"Delimiter for what? To be used to generate the full metric name, which consists of \u003cprefix\u003e\u003cdelimiter\u003e etc.","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"c17d3a124fed648987fd877254c0ca2796ffc8ef","unresolved":false,"context_lines":[{"line_number":217,"context_line":"        \"\"\"Init a MetricLogger."},{"line_number":218,"context_line":""},{"line_number":219,"context_line":"        :param prefix: Prefix for this metric logger."},{"line_number":220,"context_line":"        :param delimiter: Delimiter."},{"line_number":221,"context_line":"        \"\"\""},{"line_number":222,"context_line":"        self._prefix \u003d prefix or \u0027\u0027"},{"line_number":223,"context_line":"        self._delimiter \u003d delimiter"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_e77d791d","line":220,"in_reply_to":"7aa08908_db079f7f","updated":"2016-06-07 11:53:04.000000000","message":"Done","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ce64fd90d64042ea10b61c3ce6e91597feb347d1","unresolved":false,"context_lines":[{"line_number":226,"context_line":"        \"\"\"Get the metric name."},{"line_number":227,"context_line":""},{"line_number":228,"context_line":"        The format of the metric name is:"},{"line_number":229,"context_line":"           _prefix\u003cdelim\u003emetric_name"},{"line_number":230,"context_line":"        where:"},{"line_number":231,"context_line":"           _prefix: [global_prefix\u003cdelim\u003e][uuid\u003cdelim\u003e][host_name\u003cdelim\u003e]prefix"},{"line_number":232,"context_line":"           metric_name: the name of this metric"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_1bec878e","line":229,"updated":"2016-06-06 19:09:30.000000000","message":"the parameter being passed is called \u0027name\u0027, so to be consistent, either name this \u0027name\u0027 or the parameter \u0027metric_name\u0027. Note that if you call this \u0027name\u0027 the \u0027metric_name\u0027, then you have a problem (confusing) with calling the prefix.metric_name as the metric name. \n\nYou could call it \u0027full metric name\u0027. Or something else. Just make sure you are consistent and it is clear what your terminology is for prefix.name vs name.","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"c17d3a124fed648987fd877254c0ca2796ffc8ef","unresolved":false,"context_lines":[{"line_number":226,"context_line":"        \"\"\"Get the metric name."},{"line_number":227,"context_line":""},{"line_number":228,"context_line":"        The format of the metric name is:"},{"line_number":229,"context_line":"           _prefix\u003cdelim\u003emetric_name"},{"line_number":230,"context_line":"        where:"},{"line_number":231,"context_line":"           _prefix: [global_prefix\u003cdelim\u003e][uuid\u003cdelim\u003e][host_name\u003cdelim\u003e]prefix"},{"line_number":232,"context_line":"           metric_name: the name of this metric"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_932cc203","line":229,"in_reply_to":"7aa08908_1bec878e","updated":"2016-06-07 11:53:04.000000000","message":"Done","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ce64fd90d64042ea10b61c3ce6e91597feb347d1","unresolved":false,"context_lines":[{"line_number":239,"context_line":"            if not self._prefix:"},{"line_number":240,"context_line":"                return \u0027\u0027"},{"line_number":241,"context_line":"            else:"},{"line_number":242,"context_line":"                return self._prefix"},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"        if not self._prefix:"},{"line_number":245,"context_line":"            return name"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_3b6ea301","line":242,"updated":"2016-06-06 19:09:30.000000000","message":"I wonder about this logic. Are you allowing the name to be empty? That could mean that the user will be emitting metrics for various things with the same string, ._prefix.","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"c17d3a124fed648987fd877254c0ca2796ffc8ef","unresolved":false,"context_lines":[{"line_number":239,"context_line":"            if not self._prefix:"},{"line_number":240,"context_line":"                return \u0027\u0027"},{"line_number":241,"context_line":"            else:"},{"line_number":242,"context_line":"                return self._prefix"},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"        if not self._prefix:"},{"line_number":245,"context_line":"            return name"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_f6fa49bc","line":242,"in_reply_to":"7aa08908_3b6ea301","updated":"2016-06-07 11:53:04.000000000","message":"You\u0027re right, that shouldn\u0027t be allowed. I\u0027ve changed it so that the metric name will be None in that case, which prevents the metrics from being sent to the backend.","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ce64fd90d64042ea10b61c3ce6e91597feb347d1","unresolved":false,"context_lines":[{"line_number":245,"context_line":"            return name"},{"line_number":246,"context_line":"        return self._delimiter.join([self._prefix, name])"},{"line_number":247,"context_line":""},{"line_number":248,"context_line":"    def send_gauge(self, m_name, m_value):"},{"line_number":249,"context_line":"        \"\"\"Send gauge metric data."},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"        Gauges are simple values."}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_cd4c0273","line":248,"updated":"2016-06-06 19:09:30.000000000","message":"if you can\u0027t use name, value, what about gauge_name, gauge_value? (this might just be a nit, but m_* doesn\u0027t seem that useful)","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"c17d3a124fed648987fd877254c0ca2796ffc8ef","unresolved":false,"context_lines":[{"line_number":245,"context_line":"            return name"},{"line_number":246,"context_line":"        return self._delimiter.join([self._prefix, name])"},{"line_number":247,"context_line":""},{"line_number":248,"context_line":"    def send_gauge(self, m_name, m_value):"},{"line_number":249,"context_line":"        \"\"\"Send gauge metric data."},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"        Gauges are simple values."}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_1328d2e1","line":248,"in_reply_to":"7aa08908_cd4c0273","updated":"2016-06-07 11:53:04.000000000","message":"I\u0027ve changed this to \u0027name\u0027 and \u0027value\u0027","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ce64fd90d64042ea10b61c3ce6e91597feb347d1","unresolved":false,"context_lines":[{"line_number":252,"context_line":"        The backend will set the value of gauge \u0027m_name\u0027 to \u0027m_value\u0027."},{"line_number":253,"context_line":""},{"line_number":254,"context_line":"        :param m_name: Metric name"},{"line_number":255,"context_line":"        :param m_value: Metric value that will be sent to the backend"},{"line_number":256,"context_line":"        \"\"\""},{"line_number":257,"context_line":"        self._gauge(m_name, m_value)"},{"line_number":258,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_cd3522db","line":255,"updated":"2016-06-06 19:09:30.000000000","message":"can this value be any type?","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"c17d3a124fed648987fd877254c0ca2796ffc8ef","unresolved":false,"context_lines":[{"line_number":252,"context_line":"        The backend will set the value of gauge \u0027m_name\u0027 to \u0027m_value\u0027."},{"line_number":253,"context_line":""},{"line_number":254,"context_line":"        :param m_name: Metric name"},{"line_number":255,"context_line":"        :param m_value: Metric value that will be sent to the backend"},{"line_number":256,"context_line":"        \"\"\""},{"line_number":257,"context_line":"        self._gauge(m_name, m_value)"},{"line_number":258,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_df9acb62","line":255,"in_reply_to":"7aa08908_cd3522db","updated":"2016-06-07 11:53:04.000000000","message":"It\u0027s supposed to be a numeric value: i\u0027ve updated the comment.","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ce64fd90d64042ea10b61c3ce6e91597feb347d1","unresolved":false,"context_lines":[{"line_number":259,"context_line":"    def send_counter(self, m_name, m_value, sample_rate\u003dNone):"},{"line_number":260,"context_line":"        \"\"\"Send counter metric data."},{"line_number":261,"context_line":""},{"line_number":262,"context_line":"        Counters are used to count how many times an event occured."},{"line_number":263,"context_line":"        The backend will increment the counter \u0027m_name\u0027 the value \u0027m_value\u0027."},{"line_number":264,"context_line":""},{"line_number":265,"context_line":"        Optionally, specify sample_rate in the interval [0.0, 1.0] to"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_4d6f72c5","line":262,"updated":"2016-06-06 19:09:30.000000000","message":"s/occured/occurred/","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"c17d3a124fed648987fd877254c0ca2796ffc8ef","unresolved":false,"context_lines":[{"line_number":259,"context_line":"    def send_counter(self, m_name, m_value, sample_rate\u003dNone):"},{"line_number":260,"context_line":"        \"\"\"Send counter metric data."},{"line_number":261,"context_line":""},{"line_number":262,"context_line":"        Counters are used to count how many times an event occured."},{"line_number":263,"context_line":"        The backend will increment the counter \u0027m_name\u0027 the value \u0027m_value\u0027."},{"line_number":264,"context_line":""},{"line_number":265,"context_line":"        Optionally, specify sample_rate in the interval [0.0, 1.0] to"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_53225a01","line":262,"in_reply_to":"7aa08908_4d6f72c5","updated":"2016-06-07 11:53:04.000000000","message":"Done","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ce64fd90d64042ea10b61c3ce6e91597feb347d1","unresolved":false,"context_lines":[{"line_number":260,"context_line":"        \"\"\"Send counter metric data."},{"line_number":261,"context_line":""},{"line_number":262,"context_line":"        Counters are used to count how many times an event occured."},{"line_number":263,"context_line":"        The backend will increment the counter \u0027m_name\u0027 the value \u0027m_value\u0027."},{"line_number":264,"context_line":""},{"line_number":265,"context_line":"        Optionally, specify sample_rate in the interval [0.0, 1.0] to"},{"line_number":266,"context_line":"        sample data probabilistically where:"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_6dc06e7d","line":263,"updated":"2016-06-06 19:09:30.000000000","message":"s/the value/by the value/","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"c17d3a124fed648987fd877254c0ca2796ffc8ef","unresolved":false,"context_lines":[{"line_number":260,"context_line":"        \"\"\"Send counter metric data."},{"line_number":261,"context_line":""},{"line_number":262,"context_line":"        Counters are used to count how many times an event occured."},{"line_number":263,"context_line":"        The backend will increment the counter \u0027m_name\u0027 the value \u0027m_value\u0027."},{"line_number":264,"context_line":""},{"line_number":265,"context_line":"        Optionally, specify sample_rate in the interval [0.0, 1.0] to"},{"line_number":266,"context_line":"        sample data probabilistically where:"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_737dd6e6","line":263,"in_reply_to":"7aa08908_6dc06e7d","updated":"2016-06-07 11:53:04.000000000","message":"Done","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ce64fd90d64042ea10b61c3ce6e91597feb347d1","unresolved":false,"context_lines":[{"line_number":271,"context_line":"        have the backend send sample rate information (if supported)."},{"line_number":272,"context_line":""},{"line_number":273,"context_line":"        :param m_name: Metric name"},{"line_number":274,"context_line":"        :param m_value: Metric value that will be sent to the backend"},{"line_number":275,"context_line":"        :param sample_rate: Probabilistic rate at which the values will be sent"},{"line_number":276,"context_line":"        \"\"\""},{"line_number":277,"context_line":"        if (sample_rate is not None and"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_ad51b6da","line":274,"updated":"2016-06-06 19:09:30.000000000","message":"this is a numeric value, right? Do we need to check for that, or let the backend check/barf?","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"c17d3a124fed648987fd877254c0ca2796ffc8ef","unresolved":false,"context_lines":[{"line_number":271,"context_line":"        have the backend send sample rate information (if supported)."},{"line_number":272,"context_line":""},{"line_number":273,"context_line":"        :param m_name: Metric name"},{"line_number":274,"context_line":"        :param m_value: Metric value that will be sent to the backend"},{"line_number":275,"context_line":"        :param sample_rate: Probabilistic rate at which the values will be sent"},{"line_number":276,"context_line":"        \"\"\""},{"line_number":277,"context_line":"        if (sample_rate is not None and"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_f10d3b3f","line":274,"in_reply_to":"7aa08908_ad51b6da","updated":"2016-06-07 11:53:04.000000000","message":"Yes, it\u0027s supposed to be a numeric value. \nIt looks like statsd is checking that the value is a number, but I\u0027m not sure if we should add checks in this library too.","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ce64fd90d64042ea10b61c3ce6e91597feb347d1","unresolved":false,"context_lines":[{"line_number":272,"context_line":""},{"line_number":273,"context_line":"        :param m_name: Metric name"},{"line_number":274,"context_line":"        :param m_value: Metric value that will be sent to the backend"},{"line_number":275,"context_line":"        :param sample_rate: Probabilistic rate at which the values will be sent"},{"line_number":276,"context_line":"        \"\"\""},{"line_number":277,"context_line":"        if (sample_rate is not None and"},{"line_number":278,"context_line":"                (sample_rate \u003c 0.0 or sample_rate \u003e 1.0)):"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_6d6eae97","line":275,"updated":"2016-06-06 19:09:30.000000000","message":"Please mention the possible values here (since this is a library we should take more care with our docstrings)","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"c17d3a124fed648987fd877254c0ca2796ffc8ef","unresolved":false,"context_lines":[{"line_number":272,"context_line":""},{"line_number":273,"context_line":"        :param m_name: Metric name"},{"line_number":274,"context_line":"        :param m_value: Metric value that will be sent to the backend"},{"line_number":275,"context_line":"        :param sample_rate: Probabilistic rate at which the values will be sent"},{"line_number":276,"context_line":"        \"\"\""},{"line_number":277,"context_line":"        if (sample_rate is not None and"},{"line_number":278,"context_line":"                (sample_rate \u003c 0.0 or sample_rate \u003e 1.0)):"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_f4e889e4","line":275,"in_reply_to":"7aa08908_6d6eae97","updated":"2016-06-07 11:53:04.000000000","message":"Done","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ce64fd90d64042ea10b61c3ce6e91597feb347d1","unresolved":false,"context_lines":[{"line_number":344,"context_line":"        The logger uses the given prefix list, delimiter, host, and port."},{"line_number":345,"context_line":""},{"line_number":346,"context_line":"        :param prefix: Prefix for this metric logger."},{"line_number":347,"context_line":"        :param delimiter: Delimiter used for the prefix."},{"line_number":348,"context_line":"        :param host: The statsd host"},{"line_number":349,"context_line":"        :param port: The statsd port"},{"line_number":350,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_cdf3629d","line":347,"updated":"2016-06-06 19:09:30.000000000","message":"not just for the prefix?","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"c17d3a124fed648987fd877254c0ca2796ffc8ef","unresolved":false,"context_lines":[{"line_number":344,"context_line":"        The logger uses the given prefix list, delimiter, host, and port."},{"line_number":345,"context_line":""},{"line_number":346,"context_line":"        :param prefix: Prefix for this metric logger."},{"line_number":347,"context_line":"        :param delimiter: Delimiter used for the prefix."},{"line_number":348,"context_line":"        :param host: The statsd host"},{"line_number":349,"context_line":"        :param port: The statsd port"},{"line_number":350,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_149c3568","line":347,"in_reply_to":"7aa08908_cdf3629d","updated":"2016-06-07 11:53:04.000000000","message":"Done","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ce64fd90d64042ea10b61c3ce6e91597feb347d1","unresolved":false,"context_lines":[{"line_number":405,"context_line":""},{"line_number":406,"context_line":"    :param prefix: Prefix for this metric logger."},{"line_number":407,"context_line":"        Value should be a string or None."},{"line_number":408,"context_line":"    :param backend: Backend to use for the metrics system."},{"line_number":409,"context_line":"    :param host: Name of this node."},{"line_number":410,"context_line":"    :param delimiter: Delimiter to use for the metrics name."},{"line_number":411,"context_line":"    :return: The nez MetricLogger."}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_2d1026a8","line":408,"updated":"2016-06-06 19:09:30.000000000","message":"what are the possible values for this?","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"c17d3a124fed648987fd877254c0ca2796ffc8ef","unresolved":false,"context_lines":[{"line_number":405,"context_line":""},{"line_number":406,"context_line":"    :param prefix: Prefix for this metric logger."},{"line_number":407,"context_line":"        Value should be a string or None."},{"line_number":408,"context_line":"    :param backend: Backend to use for the metrics system."},{"line_number":409,"context_line":"    :param host: Name of this node."},{"line_number":410,"context_line":"    :param delimiter: Delimiter to use for the metrics name."},{"line_number":411,"context_line":"    :return: The nez MetricLogger."}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_3374eefb","line":408,"in_reply_to":"7aa08908_2d1026a8","updated":"2016-06-07 11:53:04.000000000","message":"Done","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ce64fd90d64042ea10b61c3ce6e91597feb347d1","unresolved":false,"context_lines":[{"line_number":408,"context_line":"    :param backend: Backend to use for the metrics system."},{"line_number":409,"context_line":"    :param host: Name of this node."},{"line_number":410,"context_line":"    :param delimiter: Delimiter to use for the metrics name."},{"line_number":411,"context_line":"    :return: The nez MetricLogger."},{"line_number":412,"context_line":"    \"\"\""},{"line_number":413,"context_line":"    if not isinstance(prefix, six.string_types) and prefix is not None:"},{"line_number":414,"context_line":"        msg \u003d (_(\"This metric prefix (%s) is of unsupported type. \""}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_0d7a8af1","line":411,"updated":"2016-06-06 19:09:30.000000000","message":"what is \u0027nez\u0027?","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"c17d3a124fed648987fd877254c0ca2796ffc8ef","unresolved":false,"context_lines":[{"line_number":408,"context_line":"    :param backend: Backend to use for the metrics system."},{"line_number":409,"context_line":"    :param host: Name of this node."},{"line_number":410,"context_line":"    :param delimiter: Delimiter to use for the metrics name."},{"line_number":411,"context_line":"    :return: The nez MetricLogger."},{"line_number":412,"context_line":"    \"\"\""},{"line_number":413,"context_line":"    if not isinstance(prefix, six.string_types) and prefix is not None:"},{"line_number":414,"context_line":"        msg \u003d (_(\"This metric prefix (%s) is of unsupported type. \""}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_1356125c","line":411,"in_reply_to":"7aa08908_0d7a8af1","updated":"2016-06-07 11:53:04.000000000","message":"Done","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ce64fd90d64042ea10b61c3ce6e91597feb347d1","unresolved":false,"context_lines":[{"line_number":417,"context_line":"        raise exception.InvalidMetricConfig(msg)"},{"line_number":418,"context_line":""},{"line_number":419,"context_line":"    if CONF.metrics.prepend_host:"},{"line_number":420,"context_line":"        host \u003d host"},{"line_number":421,"context_line":""},{"line_number":422,"context_line":"        if CONF.metrics.prepend_host_reverse:"},{"line_number":423,"context_line":"            host \u003d \u0027.\u0027.join(reversed(host.split(\u0027.\u0027)))"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_cdfd223c","line":420,"updated":"2016-06-06 19:09:30.000000000","message":"Why do you need this?","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"c17d3a124fed648987fd877254c0ca2796ffc8ef","unresolved":false,"context_lines":[{"line_number":417,"context_line":"        raise exception.InvalidMetricConfig(msg)"},{"line_number":418,"context_line":""},{"line_number":419,"context_line":"    if CONF.metrics.prepend_host:"},{"line_number":420,"context_line":"        host \u003d host"},{"line_number":421,"context_line":""},{"line_number":422,"context_line":"        if CONF.metrics.prepend_host_reverse:"},{"line_number":423,"context_line":"            host \u003d \u0027.\u0027.join(reversed(host.split(\u0027.\u0027)))"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_73f2f670","line":420,"in_reply_to":"7aa08908_cdfd223c","updated":"2016-06-07 11:53:04.000000000","message":"Done","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ce64fd90d64042ea10b61c3ce6e91597feb347d1","unresolved":false,"context_lines":[{"line_number":420,"context_line":"        host \u003d host"},{"line_number":421,"context_line":""},{"line_number":422,"context_line":"        if CONF.metrics.prepend_host_reverse:"},{"line_number":423,"context_line":"            host \u003d \u0027.\u0027.join(reversed(host.split(\u0027.\u0027)))"},{"line_number":424,"context_line":""},{"line_number":425,"context_line":"        prefix \u003d delimiter.join([host, prefix])"},{"line_number":426,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_cdab621c","line":423,"updated":"2016-06-06 19:09:30.000000000","message":"will this work if host is None?","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"c17d3a124fed648987fd877254c0ca2796ffc8ef","unresolved":false,"context_lines":[{"line_number":420,"context_line":"        host \u003d host"},{"line_number":421,"context_line":""},{"line_number":422,"context_line":"        if CONF.metrics.prepend_host_reverse:"},{"line_number":423,"context_line":"            host \u003d \u0027.\u0027.join(reversed(host.split(\u0027.\u0027)))"},{"line_number":424,"context_line":""},{"line_number":425,"context_line":"        prefix \u003d delimiter.join([host, prefix])"},{"line_number":426,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_d9102b04","line":423,"in_reply_to":"7aa08908_cdab621c","updated":"2016-06-07 11:53:04.000000000","message":"Done","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ce64fd90d64042ea10b61c3ce6e91597feb347d1","unresolved":false,"context_lines":[{"line_number":422,"context_line":"        if CONF.metrics.prepend_host_reverse:"},{"line_number":423,"context_line":"            host \u003d \u0027.\u0027.join(reversed(host.split(\u0027.\u0027)))"},{"line_number":424,"context_line":""},{"line_number":425,"context_line":"        prefix \u003d delimiter.join([host, prefix])"},{"line_number":426,"context_line":""},{"line_number":427,"context_line":"    if CONF.metrics.global_prefix:"},{"line_number":428,"context_line":"        prefix \u003d delimiter.join([CONF.metrics.global_prefix, prefix])"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_0dbd6a68","line":425,"updated":"2016-06-06 19:09:30.000000000","message":"if prefix is None, this won\u0027t work.","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"c17d3a124fed648987fd877254c0ca2796ffc8ef","unresolved":false,"context_lines":[{"line_number":422,"context_line":"        if CONF.metrics.prepend_host_reverse:"},{"line_number":423,"context_line":"            host \u003d \u0027.\u0027.join(reversed(host.split(\u0027.\u0027)))"},{"line_number":424,"context_line":""},{"line_number":425,"context_line":"        prefix \u003d delimiter.join([host, prefix])"},{"line_number":426,"context_line":""},{"line_number":427,"context_line":"    if CONF.metrics.global_prefix:"},{"line_number":428,"context_line":"        prefix \u003d delimiter.join([CONF.metrics.global_prefix, prefix])"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_249822c0","line":425,"in_reply_to":"7aa08908_0dbd6a68","updated":"2016-06-07 11:53:04.000000000","message":"Done","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ce64fd90d64042ea10b61c3ce6e91597feb347d1","unresolved":false,"context_lines":[{"line_number":433,"context_line":"    elif backend \u003d\u003d \u0027noop\u0027:"},{"line_number":434,"context_line":"        return NoopMetricLogger(prefix, delimiter\u003ddelimiter)"},{"line_number":435,"context_line":"    else:"},{"line_number":436,"context_line":"        msg \u003d (_(\"CONF.metrics.backend is set to an unsupported backend type: \""},{"line_number":437,"context_line":"                 \"%s. Value should be \u0027noop\u0027 or \u0027statsd\u0027.\")"},{"line_number":438,"context_line":"               % backend)"},{"line_number":439,"context_line":"        raise exception.InvalidMetricConfig(msg)"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_8d0dda40","line":436,"updated":"2016-06-06 19:09:30.000000000","message":"backend could be wrong, not the config.","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"c17d3a124fed648987fd877254c0ca2796ffc8ef","unresolved":false,"context_lines":[{"line_number":433,"context_line":"    elif backend \u003d\u003d \u0027noop\u0027:"},{"line_number":434,"context_line":"        return NoopMetricLogger(prefix, delimiter\u003ddelimiter)"},{"line_number":435,"context_line":"    else:"},{"line_number":436,"context_line":"        msg \u003d (_(\"CONF.metrics.backend is set to an unsupported backend type: \""},{"line_number":437,"context_line":"                 \"%s. Value should be \u0027noop\u0027 or \u0027statsd\u0027.\")"},{"line_number":438,"context_line":"               % backend)"},{"line_number":439,"context_line":"        raise exception.InvalidMetricConfig(msg)"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_bf725fab","line":436,"in_reply_to":"7aa08908_8d0dda40","updated":"2016-06-07 11:53:04.000000000","message":"Done","commit_id":"9ea843e7e7409b7f99f0becb047b6ca8b8a5b609"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"182a3b01eb67704a8a92e65991f10835441f329c","unresolved":false,"context_lines":[{"line_number":349,"context_line":"        pass"},{"line_number":350,"context_line":""},{"line_number":351,"context_line":""},{"line_number":352,"context_line":"class StatsdMetricLogger(MetricLogger):"},{"line_number":353,"context_line":"    \"\"\"Metric logger that reports data via the statsd protocol.\"\"\""},{"line_number":354,"context_line":""},{"line_number":355,"context_line":"    GAUGE_TYPE \u003d \u0027g\u0027"}],"source_content_type":"text/x-python","patch_set":18,"id":"7aa08908_6c481ecd","line":352,"updated":"2016-06-07 23:07:49.000000000","message":"Nit: Maybe would make sense to put the statsd backend into it\u0027s own module file?","commit_id":"ff743812c4c103611405aa80f55abca7b8b8c52e"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"825014b50c0760620c2a301631819bd4d9bab437","unresolved":false,"context_lines":[{"line_number":62,"context_line":"            duration \u003d _time() - start"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"            # Log the timing data (in ms)"},{"line_number":65,"context_line":"            self.metrics.send_timer(self.metrics._get_metric_name(self.name),"},{"line_number":66,"context_line":"                                    duration * 1000)"},{"line_number":67,"context_line":"            return result"},{"line_number":68,"context_line":"        return wrapped"}],"source_content_type":"text/x-python","patch_set":19,"id":"3aaa91ec_38f53ecb","line":65,"range":{"start_line":65,"start_character":49,"end_line":65,"end_character":50},"updated":"2016-06-27 15:50:30.000000000","message":"it\u0027s assumed that methods starting with _ are private, please remove _ from this method\u0027s name if it\u0027s intended to be used outside of the class","commit_id":"530f79e9f19aff398e195816c083976918e57c49"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2d15ba24b4b187911e2644115992c7f7260a2bbc","unresolved":false,"context_lines":[{"line_number":62,"context_line":"            duration \u003d _time() - start"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"            # Log the timing data (in ms)"},{"line_number":65,"context_line":"            self.metrics.send_timer(self.metrics._get_metric_name(self.name),"},{"line_number":66,"context_line":"                                    duration * 1000)"},{"line_number":67,"context_line":"            return result"},{"line_number":68,"context_line":"        return wrapped"}],"source_content_type":"text/x-python","patch_set":19,"id":"3aaa91ec_9c499f91","line":65,"range":{"start_line":65,"start_character":49,"end_line":65,"end_character":50},"in_reply_to":"3aaa91ec_38f53ecb","updated":"2016-06-28 10:28:16.000000000","message":"Done","commit_id":"530f79e9f19aff398e195816c083976918e57c49"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"825014b50c0760620c2a301631819bd4d9bab437","unresolved":false,"context_lines":[{"line_number":194,"context_line":"        \u003cdelim\u003e: the delimiter. Default is \u0027.\u0027"},{"line_number":195,"context_line":"    \"\"\""},{"line_number":196,"context_line":""},{"line_number":197,"context_line":"    def __init__(self, prefix\u003dNone, delimiter\u003d\u0027.\u0027):"},{"line_number":198,"context_line":"        \"\"\"Init a MetricLogger."},{"line_number":199,"context_line":""},{"line_number":200,"context_line":"        :param prefix: Prefix for this metric logger. This string will prefix"}],"source_content_type":"text/x-python","patch_set":19,"id":"3aaa91ec_58a2ca9b","line":197,"range":{"start_line":197,"start_character":30,"end_line":197,"end_character":34},"updated":"2016-06-27 15:50:30.000000000","message":"the actual default value is \u0027\u0027","commit_id":"530f79e9f19aff398e195816c083976918e57c49"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2d15ba24b4b187911e2644115992c7f7260a2bbc","unresolved":false,"context_lines":[{"line_number":194,"context_line":"        \u003cdelim\u003e: the delimiter. Default is \u0027.\u0027"},{"line_number":195,"context_line":"    \"\"\""},{"line_number":196,"context_line":""},{"line_number":197,"context_line":"    def __init__(self, prefix\u003dNone, delimiter\u003d\u0027.\u0027):"},{"line_number":198,"context_line":"        \"\"\"Init a MetricLogger."},{"line_number":199,"context_line":""},{"line_number":200,"context_line":"        :param prefix: Prefix for this metric logger. This string will prefix"}],"source_content_type":"text/x-python","patch_set":19,"id":"3aaa91ec_bc48db88","line":197,"range":{"start_line":197,"start_character":30,"end_line":197,"end_character":34},"in_reply_to":"3aaa91ec_58a2ca9b","updated":"2016-06-28 10:28:16.000000000","message":"Done","commit_id":"530f79e9f19aff398e195816c083976918e57c49"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"825014b50c0760620c2a301631819bd4d9bab437","unresolved":false,"context_lines":[{"line_number":218,"context_line":"        :return: The full metric name, with logger prefix, as a string."},{"line_number":219,"context_line":"        \"\"\""},{"line_number":220,"context_line":"        if not isinstance(name, six.string_types):"},{"line_number":221,"context_line":"            LOG.warning(_LW(\"The metric name is expected to be a string. \""},{"line_number":222,"context_line":"                            \"Value is %s\") % name)"},{"line_number":223,"context_line":"            return None"},{"line_number":224,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"3aaa91ec_f87f3664","line":221,"range":{"start_line":221,"start_character":12,"end_line":221,"end_character":24},"updated":"2016-06-27 15:50:30.000000000","message":"this should be an exception (TypeError). also such validation should happen in e.g. Counter.__init__, not on usage","commit_id":"530f79e9f19aff398e195816c083976918e57c49"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"825014b50c0760620c2a301631819bd4d9bab437","unresolved":false,"context_lines":[{"line_number":235,"context_line":"        :param name: Metric name"},{"line_number":236,"context_line":"        :param value: Metric numeric value that will be sent to the backend"},{"line_number":237,"context_line":"        \"\"\""},{"line_number":238,"context_line":"        if name:"},{"line_number":239,"context_line":"            self._gauge(name, value)"},{"line_number":240,"context_line":""},{"line_number":241,"context_line":"    def send_counter(self, name, value, sample_rate\u003dNone):"}],"source_content_type":"text/x-python","patch_set":19,"id":"3aaa91ec_58ae4ae8","line":238,"range":{"start_line":238,"start_character":8,"end_line":238,"end_character":16},"updated":"2016-06-27 15:50:30.000000000","message":"I\u0027m not sure what this implies.. isn\u0027t name mandatory? I think we can drop this check","commit_id":"530f79e9f19aff398e195816c083976918e57c49"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2d15ba24b4b187911e2644115992c7f7260a2bbc","unresolved":false,"context_lines":[{"line_number":235,"context_line":"        :param name: Metric name"},{"line_number":236,"context_line":"        :param value: Metric numeric value that will be sent to the backend"},{"line_number":237,"context_line":"        \"\"\""},{"line_number":238,"context_line":"        if name:"},{"line_number":239,"context_line":"            self._gauge(name, value)"},{"line_number":240,"context_line":""},{"line_number":241,"context_line":"    def send_counter(self, name, value, sample_rate\u003dNone):"}],"source_content_type":"text/x-python","patch_set":19,"id":"3aaa91ec_fc5a634f","line":238,"range":{"start_line":238,"start_character":8,"end_line":238,"end_character":16},"in_reply_to":"3aaa91ec_58ae4ae8","updated":"2016-06-28 10:28:16.000000000","message":"Done","commit_id":"530f79e9f19aff398e195816c083976918e57c49"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"825014b50c0760620c2a301631819bd4d9bab437","unresolved":false,"context_lines":[{"line_number":257,"context_line":"        :param sample_rate: Probabilistic rate at which the values will be"},{"line_number":258,"context_line":"            sent. Value must be None or in the interval [0.0, 1.0]."},{"line_number":259,"context_line":"        \"\"\""},{"line_number":260,"context_line":"        if (sample_rate is not None and"},{"line_number":261,"context_line":"                (sample_rate \u003c 0.0 or sample_rate \u003e 1.0)):"},{"line_number":262,"context_line":"            msg \u003d _(\"sample_rate is set to %s. Value must be None \""},{"line_number":263,"context_line":"                    \"or in the interval [0.0, 1.0]\") % sample_rate"},{"line_number":264,"context_line":"            raise exception.InvalidMetricConfig(msg)"},{"line_number":265,"context_line":""},{"line_number":266,"context_line":"        if (sample_rate is None or random.random() \u003c sample_rate) and name:"},{"line_number":267,"context_line":"            return self._counter(name, value,"}],"source_content_type":"text/x-python","patch_set":19,"id":"3aaa91ec_b88bee1d","line":264,"range":{"start_line":260,"start_character":0,"end_line":264,"end_character":52},"updated":"2016-06-27 15:50:30.000000000","message":"this validation should happen in Counter.__init__. there is also no point to make it IronicException, ValueError feels more appropriate to me.","commit_id":"530f79e9f19aff398e195816c083976918e57c49"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"ccaf1d44d05074efe1d7dadda08093c9fe20a742","unresolved":false,"context_lines":[{"line_number":257,"context_line":"        :param sample_rate: Probabilistic rate at which the values will be"},{"line_number":258,"context_line":"            sent. Value must be None or in the interval [0.0, 1.0]."},{"line_number":259,"context_line":"        \"\"\""},{"line_number":260,"context_line":"        if (sample_rate is not None and"},{"line_number":261,"context_line":"                (sample_rate \u003c 0.0 or sample_rate \u003e 1.0)):"},{"line_number":262,"context_line":"            msg \u003d _(\"sample_rate is set to %s. Value must be None \""},{"line_number":263,"context_line":"                    \"or in the interval [0.0, 1.0]\") % sample_rate"},{"line_number":264,"context_line":"            raise exception.InvalidMetricConfig(msg)"},{"line_number":265,"context_line":""},{"line_number":266,"context_line":"        if (sample_rate is None or random.random() \u003c sample_rate) and name:"},{"line_number":267,"context_line":"            return self._counter(name, value,"}],"source_content_type":"text/x-python","patch_set":19,"id":"3aaa91ec_ea78cbfa","line":264,"range":{"start_line":260,"start_character":0,"end_line":264,"end_character":52},"in_reply_to":"3aaa91ec_3d9342fc","updated":"2016-06-28 12:22:47.000000000","message":"Ok, thanks a lot for the explanation. I will correct that in the next patch.","commit_id":"530f79e9f19aff398e195816c083976918e57c49"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2d15ba24b4b187911e2644115992c7f7260a2bbc","unresolved":false,"context_lines":[{"line_number":257,"context_line":"        :param sample_rate: Probabilistic rate at which the values will be"},{"line_number":258,"context_line":"            sent. Value must be None or in the interval [0.0, 1.0]."},{"line_number":259,"context_line":"        \"\"\""},{"line_number":260,"context_line":"        if (sample_rate is not None and"},{"line_number":261,"context_line":"                (sample_rate \u003c 0.0 or sample_rate \u003e 1.0)):"},{"line_number":262,"context_line":"            msg \u003d _(\"sample_rate is set to %s. Value must be None \""},{"line_number":263,"context_line":"                    \"or in the interval [0.0, 1.0]\") % sample_rate"},{"line_number":264,"context_line":"            raise exception.InvalidMetricConfig(msg)"},{"line_number":265,"context_line":""},{"line_number":266,"context_line":"        if (sample_rate is None or random.random() \u003c sample_rate) and name:"},{"line_number":267,"context_line":"            return self._counter(name, value,"}],"source_content_type":"text/x-python","patch_set":19,"id":"3aaa91ec_c2afbd7b","line":264,"range":{"start_line":260,"start_character":0,"end_line":264,"end_character":52},"in_reply_to":"3aaa91ec_b88bee1d","updated":"2016-06-28 10:28:16.000000000","message":"Regarding which exception to use, I\u0027m fine with ValueError but a previous comment asked to use custom Ironic exceptions (https://review.openstack.org/#/c/301526/2/ironic_lib/metrics.py@101), so I\u0027m not sure what to do: what do you think?","commit_id":"530f79e9f19aff398e195816c083976918e57c49"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"141e1396bf081f65493b8cb800cb248e185c1ebb","unresolved":false,"context_lines":[{"line_number":257,"context_line":"        :param sample_rate: Probabilistic rate at which the values will be"},{"line_number":258,"context_line":"            sent. Value must be None or in the interval [0.0, 1.0]."},{"line_number":259,"context_line":"        \"\"\""},{"line_number":260,"context_line":"        if (sample_rate is not None and"},{"line_number":261,"context_line":"                (sample_rate \u003c 0.0 or sample_rate \u003e 1.0)):"},{"line_number":262,"context_line":"            msg \u003d _(\"sample_rate is set to %s. Value must be None \""},{"line_number":263,"context_line":"                    \"or in the interval [0.0, 1.0]\") % sample_rate"},{"line_number":264,"context_line":"            raise exception.InvalidMetricConfig(msg)"},{"line_number":265,"context_line":""},{"line_number":266,"context_line":"        if (sample_rate is None or random.random() \u003c sample_rate) and name:"},{"line_number":267,"context_line":"            return self._counter(name, value,"}],"source_content_type":"text/x-python","patch_set":19,"id":"3aaa91ec_3d9342fc","line":264,"range":{"start_line":260,"start_character":0,"end_line":264,"end_character":52},"in_reply_to":"3aaa91ec_c2afbd7b","updated":"2016-06-28 10:47:33.000000000","message":"It depends on when exception happens. Right now exception will happen during request processing, and indeed it\u0027s better be IronicException. However, it\u0027s useless to show such exception to a user. I suggest moving this validation to start up time, and it no longer makes sense using IronicExceptions.","commit_id":"530f79e9f19aff398e195816c083976918e57c49"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"825014b50c0760620c2a301631819bd4d9bab437","unresolved":false,"context_lines":[{"line_number":263,"context_line":"                    \"or in the interval [0.0, 1.0]\") % sample_rate"},{"line_number":264,"context_line":"            raise exception.InvalidMetricConfig(msg)"},{"line_number":265,"context_line":""},{"line_number":266,"context_line":"        if (sample_rate is None or random.random() \u003c sample_rate) and name:"},{"line_number":267,"context_line":"            return self._counter(name, value,"},{"line_number":268,"context_line":"                                 sample_rate\u003dsample_rate)"},{"line_number":269,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"3aaa91ec_78e34634","line":266,"range":{"start_line":266,"start_character":65,"end_line":266,"end_character":74},"updated":"2016-06-27 15:50:30.000000000","message":"ditto about name","commit_id":"530f79e9f19aff398e195816c083976918e57c49"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2d15ba24b4b187911e2644115992c7f7260a2bbc","unresolved":false,"context_lines":[{"line_number":263,"context_line":"                    \"or in the interval [0.0, 1.0]\") % sample_rate"},{"line_number":264,"context_line":"            raise exception.InvalidMetricConfig(msg)"},{"line_number":265,"context_line":""},{"line_number":266,"context_line":"        if (sample_rate is None or random.random() \u003c sample_rate) and name:"},{"line_number":267,"context_line":"            return self._counter(name, value,"},{"line_number":268,"context_line":"                                 sample_rate\u003dsample_rate)"},{"line_number":269,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"3aaa91ec_3c550b1d","line":266,"range":{"start_line":266,"start_character":65,"end_line":266,"end_character":74},"in_reply_to":"3aaa91ec_78e34634","updated":"2016-06-28 10:28:16.000000000","message":"Done","commit_id":"530f79e9f19aff398e195816c083976918e57c49"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"825014b50c0760620c2a301631819bd4d9bab437","unresolved":false,"context_lines":[{"line_number":302,"context_line":""},{"line_number":303,"context_line":"class NoopMetricLogger(MetricLogger):"},{"line_number":304,"context_line":"    \"\"\"Noop metric logger that throws away all metric data.\"\"\""},{"line_number":305,"context_line":"    def __init__(self, prefix, delimiter\u003d\u0027.\u0027):"},{"line_number":306,"context_line":"        super(NoopMetricLogger, self).__init__(prefix, delimiter\u003ddelimiter)"},{"line_number":307,"context_line":""},{"line_number":308,"context_line":"    def _gauge(self, name, value):"},{"line_number":309,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":19,"id":"3aaa91ec_587bea29","line":306,"range":{"start_line":305,"start_character":0,"end_line":306,"end_character":75},"updated":"2016-06-27 15:50:30.000000000","message":"this is not needed","commit_id":"530f79e9f19aff398e195816c083976918e57c49"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2d15ba24b4b187911e2644115992c7f7260a2bbc","unresolved":false,"context_lines":[{"line_number":302,"context_line":""},{"line_number":303,"context_line":"class NoopMetricLogger(MetricLogger):"},{"line_number":304,"context_line":"    \"\"\"Noop metric logger that throws away all metric data.\"\"\""},{"line_number":305,"context_line":"    def __init__(self, prefix, delimiter\u003d\u0027.\u0027):"},{"line_number":306,"context_line":"        super(NoopMetricLogger, self).__init__(prefix, delimiter\u003ddelimiter)"},{"line_number":307,"context_line":""},{"line_number":308,"context_line":"    def _gauge(self, name, value):"},{"line_number":309,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":19,"id":"3aaa91ec_dc3a07e7","line":306,"range":{"start_line":305,"start_character":0,"end_line":306,"end_character":75},"in_reply_to":"3aaa91ec_587bea29","updated":"2016-06-28 10:28:16.000000000","message":"Done","commit_id":"530f79e9f19aff398e195816c083976918e57c49"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"bb18212a1641ff80c979707f21c646ee3876ca4c","unresolved":false,"context_lines":[{"line_number":252,"context_line":"        :param sample_rate: Probabilistic rate at which the values will be"},{"line_number":253,"context_line":"            sent. Value must be None or in the interval [0.0, 1.0]."},{"line_number":254,"context_line":"        \"\"\""},{"line_number":255,"context_line":"        if (sample_rate is None or random.random() \u003c sample_rate):"},{"line_number":256,"context_line":"            return self._counter(name, value,"},{"line_number":257,"context_line":"                                 sample_rate\u003dsample_rate)"},{"line_number":258,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"3aaa91ec_ab5e8c42","line":255,"updated":"2016-06-29 11:44:38.000000000","message":"nit: brackets are not required any more","commit_id":"fb46000e24f8d5d0fea437aa30eab95cb54eb934"}],"ironic_lib/metrics_utils.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"825014b50c0760620c2a301631819bd4d9bab437","unresolved":false,"context_lines":[{"line_number":47,"context_line":"CONF.register_opts(metrics_opts, group\u003d\u0027metrics\u0027)"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"def get_logger(prefix\u003dNone, backend\u003dNone, host\u003dNone, delimiter\u003d\u0027.\u0027):"},{"line_number":51,"context_line":"    \"\"\"Return a metric logger with the specified prefix."},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    The format of the prefix is:"}],"source_content_type":"text/x-python","patch_set":19,"id":"3aaa91ec_188202c9","line":50,"range":{"start_line":50,"start_character":22,"end_line":50,"end_character":26},"updated":"2016-06-27 15:50:30.000000000","message":"also prefix\u003d\u0027\u0027","commit_id":"530f79e9f19aff398e195816c083976918e57c49"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"825014b50c0760620c2a301631819bd4d9bab437","unresolved":false,"context_lines":[{"line_number":47,"context_line":"CONF.register_opts(metrics_opts, group\u003d\u0027metrics\u0027)"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"def get_logger(prefix\u003dNone, backend\u003dNone, host\u003dNone, delimiter\u003d\u0027.\u0027):"},{"line_number":51,"context_line":"    \"\"\"Return a metric logger with the specified prefix."},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    The format of the prefix is:"}],"source_content_type":"text/x-python","patch_set":19,"id":"3aaa91ec_981f12b7","line":50,"range":{"start_line":50,"start_character":4,"end_line":50,"end_character":14},"updated":"2016-06-27 15:50:30.000000000","message":"this name is confusing with python stdlib logging.get_logger. why not call it get_metrics?","commit_id":"530f79e9f19aff398e195816c083976918e57c49"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2d15ba24b4b187911e2644115992c7f7260a2bbc","unresolved":false,"context_lines":[{"line_number":47,"context_line":"CONF.register_opts(metrics_opts, group\u003d\u0027metrics\u0027)"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"def get_logger(prefix\u003dNone, backend\u003dNone, host\u003dNone, delimiter\u003d\u0027.\u0027):"},{"line_number":51,"context_line":"    \"\"\"Return a metric logger with the specified prefix."},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    The format of the prefix is:"}],"source_content_type":"text/x-python","patch_set":19,"id":"3aaa91ec_5c2f37a1","line":50,"range":{"start_line":50,"start_character":22,"end_line":50,"end_character":26},"in_reply_to":"3aaa91ec_188202c9","updated":"2016-06-28 10:28:16.000000000","message":"Done","commit_id":"530f79e9f19aff398e195816c083976918e57c49"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2d15ba24b4b187911e2644115992c7f7260a2bbc","unresolved":false,"context_lines":[{"line_number":47,"context_line":"CONF.register_opts(metrics_opts, group\u003d\u0027metrics\u0027)"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"def get_logger(prefix\u003dNone, backend\u003dNone, host\u003dNone, delimiter\u003d\u0027.\u0027):"},{"line_number":51,"context_line":"    \"\"\"Return a metric logger with the specified prefix."},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    The format of the prefix is:"}],"source_content_type":"text/x-python","patch_set":19,"id":"3aaa91ec_3f069a20","line":50,"range":{"start_line":50,"start_character":4,"end_line":50,"end_character":14},"in_reply_to":"3aaa91ec_981f12b7","updated":"2016-06-28 10:28:16.000000000","message":"I changed it to get_metrics_logger (to try to keep a name close to the one in the spec): is that ok or would you prefer get_metrics?","commit_id":"530f79e9f19aff398e195816c083976918e57c49"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"825014b50c0760620c2a301631819bd4d9bab437","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    :param delimiter: Delimiter to use for the metrics name."},{"line_number":63,"context_line":"    :return: The new MetricLogger."},{"line_number":64,"context_line":"    \"\"\""},{"line_number":65,"context_line":"    if not isinstance(prefix, six.string_types) and prefix is not None:"},{"line_number":66,"context_line":"        msg \u003d (_(\"This metric prefix (%s) is of unsupported type. \""},{"line_number":67,"context_line":"                 \"Value should be a string or None\")"},{"line_number":68,"context_line":"               % str(prefix))"}],"source_content_type":"text/x-python","patch_set":19,"id":"3aaa91ec_d85eba78","line":65,"range":{"start_line":65,"start_character":70,"end_line":65,"end_character":71},"updated":"2016-06-27 15:50:30.000000000","message":"check on None is not needed if you use a proper default","commit_id":"530f79e9f19aff398e195816c083976918e57c49"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"2d15ba24b4b187911e2644115992c7f7260a2bbc","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    :param delimiter: Delimiter to use for the metrics name."},{"line_number":63,"context_line":"    :return: The new MetricLogger."},{"line_number":64,"context_line":"    \"\"\""},{"line_number":65,"context_line":"    if not isinstance(prefix, six.string_types) and prefix is not None:"},{"line_number":66,"context_line":"        msg \u003d (_(\"This metric prefix (%s) is of unsupported type. \""},{"line_number":67,"context_line":"                 \"Value should be a string or None\")"},{"line_number":68,"context_line":"               % str(prefix))"}],"source_content_type":"text/x-python","patch_set":19,"id":"3aaa91ec_1795883f","line":65,"range":{"start_line":65,"start_character":70,"end_line":65,"end_character":71},"in_reply_to":"3aaa91ec_d85eba78","updated":"2016-06-28 10:28:16.000000000","message":"Done","commit_id":"530f79e9f19aff398e195816c083976918e57c49"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"bb18212a1641ff80c979707f21c646ee3876ca4c","unresolved":false,"context_lines":[{"line_number":66,"context_line":"        msg \u003d (_(\"This metric prefix (%s) is of unsupported type. \""},{"line_number":67,"context_line":"                 \"Value should be a string or None\")"},{"line_number":68,"context_line":"               % str(prefix))"},{"line_number":69,"context_line":"        raise exception.InvalidMetricConfig(msg)"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"    if CONF.metrics.prepend_host and host:"},{"line_number":72,"context_line":"        if CONF.metrics.prepend_host_reverse:"}],"source_content_type":"text/x-python","patch_set":21,"id":"3aaa91ec_2b4a9c83","line":69,"updated":"2016-06-29 11:44:38.000000000","message":"nit: this call happens on start up, so I\u0027d slightly prefer this to be TypeError as well. will leave it up to other reviewers though","commit_id":"fb46000e24f8d5d0fea437aa30eab95cb54eb934"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"bb18212a1641ff80c979707f21c646ee3876ca4c","unresolved":false,"context_lines":[{"line_number":92,"context_line":"        msg \u003d (_(\"The backend is set to an unsupported type: \""},{"line_number":93,"context_line":"                 \"%s. Value should be \u0027noop\u0027 or \u0027statsd\u0027.\")"},{"line_number":94,"context_line":"               % backend)"},{"line_number":95,"context_line":"        raise exception.InvalidMetricConfig(msg)"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"def list_opts():"}],"source_content_type":"text/x-python","patch_set":21,"id":"3aaa91ec_0b4d2099","line":95,"updated":"2016-06-29 11:44:38.000000000","message":"ditto, but ValueError","commit_id":"fb46000e24f8d5d0fea437aa30eab95cb54eb934"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"ee393282a013b480e982ad3bf3592c23ca13d1dd","unresolved":false,"context_lines":[{"line_number":92,"context_line":"        msg \u003d (_(\"The backend is set to an unsupported type: \""},{"line_number":93,"context_line":"                 \"%s. Value should be \u0027noop\u0027 or \u0027statsd\u0027.\")"},{"line_number":94,"context_line":"               % backend)"},{"line_number":95,"context_line":"        raise exception.InvalidMetricConfig(msg)"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"def list_opts():"}],"source_content_type":"text/x-python","patch_set":21,"id":"1aa78d24_8147574a","line":95,"in_reply_to":"3aaa91ec_0b4d2099","updated":"2016-07-05 09:54:26.000000000","message":"Maybe it\u0027s only me, but it seems a little strange that we support setting the backend via configuration file or function parameter no?\n\nTo me it sounds like that the configuration option should be enough","commit_id":"fb46000e24f8d5d0fea437aa30eab95cb54eb934"}],"ironic_lib/tests/test_metrics.py":[{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"3a8cdfa7e35f10713cd77bde7f9b8bfaa424d233","unresolved":false,"context_lines":[{"line_number":13,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":14,"context_line":"#    under the License."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"import mock"},{"line_number":17,"context_line":"import socket"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"from oslo_config import cfg"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a061dce_93685d89","line":16,"updated":"2016-04-05 15:55:54.000000000","message":"mock is not a builtin. Well at least not for Python 2. So should be with the oslo_config section","commit_id":"d6c7dc2d82d709585c9499386c29e309f3135339"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"a17d3720404378a42f9e35a132a0ff483121f631","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        self.ml.timer(\u0027metric\u0027, 10)"},{"line_number":111,"context_line":"        self.ml._timer.assert_called_once_with(\u0027prefix.metric\u0027, 10)"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"    @mock.patch(\u0027ironic_lib.metrics._time\u0027)"},{"line_number":114,"context_line":"    @mock.patch(\u0027ironic_lib.metrics.MetricLogger.timer\u0027)"},{"line_number":115,"context_line":"    def test_timer_d(self, mock_timer, mock_time):"},{"line_number":116,"context_line":"        mock_time.side_effect \u003d [1, 43]"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_9bb834ca","line":113,"updated":"2016-04-06 16:08:05.000000000","message":"Can \u0027autospec\u003dTrue\u0027 be added to the mocks?\n\nAll of the @mock.patch ones in the file.","commit_id":"03e699b79393b3b7067bbae1b63848b5df2c33b2"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"6ecf1e681c4c88d3c07a4f75a7a7d9739b4d4107","unresolved":false,"context_lines":[{"line_number":26,"context_line":""},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"class MockedMetricLogger(metricslib.MetricLogger):"},{"line_number":29,"context_line":"    _gauge \u003d mock.Mock()"},{"line_number":30,"context_line":"    _counter \u003d mock.Mock()"},{"line_number":31,"context_line":"    _timer \u003d mock.Mock()"},{"line_number":32,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"5a18252c_4dd5bd41","line":29,"updated":"2016-04-12 14:12:15.000000000","message":"Could these be like:\n\n _gauge \u003d mock.Mock(spec_set\u003dtypes.FunctionType)\n\nAnd the next two also.\n\nWill require importing the type module.","commit_id":"2ab44739360fb068a8cda693113ddd78193aa366"},{"author":{"_account_id":20522,"name":"Aline Bousquet","email":"albousque@gmail.com","username":"alineb"},"change_message_id":"74eca256f1a9d1165ec87859cc2651b966082e90","unresolved":false,"context_lines":[{"line_number":26,"context_line":""},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"class MockedMetricLogger(metricslib.MetricLogger):"},{"line_number":29,"context_line":"    _gauge \u003d mock.Mock()"},{"line_number":30,"context_line":"    _counter \u003d mock.Mock()"},{"line_number":31,"context_line":"    _timer \u003d mock.Mock()"},{"line_number":32,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"5a18252c_4a747534","line":29,"in_reply_to":"5a18252c_4dd5bd41","updated":"2016-04-12 17:40:02.000000000","message":"Done","commit_id":"2ab44739360fb068a8cda693113ddd78193aa366"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"5186b18716915021ffc30b6e1e032e0a4d3089b9","unresolved":false,"context_lines":[{"line_number":218,"context_line":"        self.assertEqual(self.ml._port, 4321)"},{"line_number":219,"context_line":"        self.assertEqual(self.ml._target, (\u0027test-host\u0027, 4321))"},{"line_number":220,"context_line":""},{"line_number":221,"context_line":"    @mock.patch(\u0027ironic_lib.metrics.StatsdMetricLogger._send\u0027, autospec\u003dTrue)"},{"line_number":222,"context_line":"    def test_gauge(self, mock_send):"},{"line_number":223,"context_line":"        self.ml._gauge(\u0027metric\u0027, 10)"},{"line_number":224,"context_line":"        mock_send.assert_called_once_with(self.ml, \u0027metric\u0027, 10, \u0027g\u0027)"}],"source_content_type":"text/x-python","patch_set":16,"id":"bab6814e_d9368ee6","line":221,"updated":"2016-05-24 17:48:49.000000000","message":"Are the next three tests useful? They seem to mock out the statsd-specific code, and so could equally run at the MetricLogger level.","commit_id":"1d6f48ae3b5d4373473319b6a19bbc6199975d1d"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"bb18212a1641ff80c979707f21c646ee3876ca4c","unresolved":false,"context_lines":[{"line_number":44,"context_line":""},{"line_number":45,"context_line":"        self.assertEqual(self.ml_no_prefix._prefix, \u0027\u0027)"},{"line_number":46,"context_line":"        self.assertEqual(self.ml_other_delim._delimiter, \u0027*\u0027)"},{"line_number":47,"context_line":"        self.assertEqual(self.ml_default._prefix, \u0027\u0027)"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    def test_get_metric_name(self):"},{"line_number":50,"context_line":"        self.assertEqual("}],"source_content_type":"text/x-python","patch_set":21,"id":"3aaa91ec_eb81b490","line":47,"updated":"2016-06-29 11:44:38.000000000","message":"nit: we tend to use the reverse order of arguments because of how our testing libraries show them: first expected, then actual.","commit_id":"fb46000e24f8d5d0fea437aa30eab95cb54eb934"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"bb18212a1641ff80c979707f21c646ee3876ca4c","unresolved":false,"context_lines":[{"line_number":84,"context_line":"        self.ml._timer.assert_called_once_with(\u0027prefix.metric\u0027, 10)"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    @mock.patch(\u0027ironic_lib.metrics._time\u0027, autospec\u003dTrue)"},{"line_number":87,"context_line":"    @mock.patch(\u0027ironic_lib.metrics.MetricLogger.send_timer\u0027, autospec\u003dTrue)"},{"line_number":88,"context_line":"    def test_decorator_timer(self, mock_timer, mock_time):"},{"line_number":89,"context_line":"        mock_time.side_effect \u003d [1, 43]"},{"line_number":90,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"3aaa91ec_cb7cb8b7","line":87,"updated":"2016-06-29 11:44:38.000000000","message":"nit: I tend to think @mock.patch.object looks a bit better:\n\n @mock.patch.object(metricslib.MetricLogger, \u0027send_time\u0027, autospec\u003dTrue)","commit_id":"fb46000e24f8d5d0fea437aa30eab95cb54eb934"}],"ironic_lib/tests/test_metrics_statsd.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"bb18212a1641ff80c979707f21c646ee3876ca4c","unresolved":false,"context_lines":[{"line_number":44,"context_line":"        self.ml._counter(\u0027metric\u0027, 10)"},{"line_number":45,"context_line":"        mock_send.assert_called_once_with(self.ml, \u0027metric\u0027, 10, \u0027c\u0027,"},{"line_number":46,"context_line":"                                          sample_rate\u003dNone)"},{"line_number":47,"context_line":"        mock_send.reset_mock()"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"        self.ml._counter(\u0027metric\u0027, 10, sample_rate\u003d1.0)"},{"line_number":50,"context_line":"        mock_send.assert_called_once_with(self.ml, \u0027metric\u0027, 10, \u0027c\u0027,"}],"source_content_type":"text/x-python","patch_set":21,"id":"3aaa91ec_6b44a473","line":47,"updated":"2016-06-29 11:44:38.000000000","message":"usually when you use reset_mock, it\u0027s a sign that the test function should be split :) the second part could be def test_counter_with_sample_rate","commit_id":"fb46000e24f8d5d0fea437aa30eab95cb54eb934"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"bb18212a1641ff80c979707f21c646ee3876ca4c","unresolved":false,"context_lines":[{"line_number":73,"context_line":"            \u0027part1.part2:2|type\u0027,"},{"line_number":74,"context_line":"            (\u0027test-host\u0027, 4321))"},{"line_number":75,"context_line":"        mock_socket.close.assert_called_once_with()"},{"line_number":76,"context_line":"        mock_socket.reset_mock()"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"        self.ml._send(\u0027part1.part2\u0027, 3.14159, \u0027type\u0027)"},{"line_number":79,"context_line":"        mock_socket.sendto.assert_called_once_with("}],"source_content_type":"text/x-python","patch_set":21,"id":"3aaa91ec_4b472877","line":76,"updated":"2016-06-29 11:44:38.000000000","message":"see above about splitting the test function instead of using reset_mock","commit_id":"fb46000e24f8d5d0fea437aa30eab95cb54eb934"}]}
