diff options
author | John Spray <jspray@redhat.com> | 2018-01-26 12:05:28 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-01-26 12:05:28 +0100 |
commit | 367c462882d6dcf99c9f6eace768f77195a9fa47 (patch) | |
tree | d3e72561689190de115aff2c6275e02d39dfa412 /src | |
parent | Merge pull request #20009 from Liuchang0812/fix-22727 (diff) | |
parent | mgr/dashboard: performance counter browsers (diff) | |
download | ceph-367c462882d6dcf99c9f6eace768f77195a9fa47.tar.xz ceph-367c462882d6dcf99c9f6eace768f77195a9fa47.zip |
Merge pull request #19922 from Rubab-Syed/performance_counter_browser
mgr/dashboard: performance counter browsers
Reviewed-by: John Spray <john.spray@redhat.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/pybind/mgr/dashboard/module.py | 42 | ||||
-rw-r--r-- | src/pybind/mgr/dashboard/monitors.html | 4 | ||||
-rw-r--r-- | src/pybind/mgr/dashboard/osd_perf.html | 10 | ||||
-rw-r--r-- | src/pybind/mgr/dashboard/perf_counters.html | 58 | ||||
-rw-r--r-- | src/pybind/mgr/dashboard/rgw_detail.html | 1 | ||||
-rw-r--r-- | src/pybind/mgr/dashboard/servers.html | 10 | ||||
-rw-r--r-- | src/pybind/mgr/mgr_module.py | 15 | ||||
-rw-r--r-- | src/pybind/mgr/prometheus/module.py | 15 |
8 files changed, 128 insertions, 27 deletions
diff --git a/src/pybind/mgr/dashboard/module.py b/src/pybind/mgr/dashboard/module.py index de9b889a2ee..257abfed05c 100644 --- a/src/pybind/mgr/dashboard/module.py +++ b/src/pybind/mgr/dashboard/module.py @@ -776,6 +776,7 @@ class Module(MgrModule): mon_status = global_instance().get_sync_object(MonStatus).data for mon in mon_status["monmap"]["mons"]: mon["stats"] = {} + mon["url_perf"] = "/perf_counters/mon/" + mon["name"] for counter in counters: data = global_instance().get_counter("mon", mon["name"], counter) if data is not None: @@ -803,6 +804,43 @@ class Module(MgrModule): def servers_data(self): return self._servers() + @cherrypy.expose + def perf_counters(self, service_type, service_id): + template = env.get_template("perf_counters.html") + toplevel_data = self._toplevel_data() + + return template.render( + url_prefix = global_instance().url_prefix, + ceph_version=global_instance().version, + path_info=cherrypy.request.path_info, + toplevel_data=json.dumps(toplevel_data, indent=2), + content_data=json.dumps(self.perf_counters_data(service_type, service_id), indent=2) + ) + + @cherrypy.expose + @cherrypy.tools.json_out() + def perf_counters_data(self, service_type, service_id): + schema = global_instance().get_perf_schema(service_type, str(service_id)).values()[0] + counters = [] + + for key, value in sorted(schema.items()): + counter = dict() + counter["name"] = str(key) + counter["description"] = value["description"] + if global_instance()._stattype_to_str(value["type"]) == 'counter': + counter["value"] = global_instance().get_rate(service_type, service_id, key) + counter["unit"] = "/s" + else: + counter["value"] = global_instance().get_latest(service_type, service_id, key) + counter["unit"] = "" + counters.append(counter) + + return { + 'service_type': service_type, + 'service_id': service_id, + 'counters': counters, + } + def _health(self): # Fuse osdmap with pg_summary to get description of pools # including their PG states @@ -1022,7 +1060,8 @@ class Module(MgrModule): return { "osd": osd, "osd_metadata": osd_metadata, - "osd_histogram": histogram + "osd_histogram": histogram, + "url_perf": "/perf_counters/osd/" + str(osd_id) } @cherrypy.expose @@ -1196,6 +1235,7 @@ class Module(MgrModule): return { "rgw_id": rgw_id, + "url_perf": "/perf_counters/rgw/" + str(rgw_id), "rgw_metadata": to_sorted_array(rgw_metadata), "rgw_status": to_sorted_array(rgw_status), } diff --git a/src/pybind/mgr/dashboard/monitors.html b/src/pybind/mgr/dashboard/monitors.html index 40a26551d4c..60b34ad62c5 100644 --- a/src/pybind/mgr/dashboard/monitors.html +++ b/src/pybind/mgr/dashboard/monitors.html @@ -67,7 +67,7 @@ <th>Open Sessions</th> </thead> <tr rv-each-mon="in_quorum" style="font-size:15px;height:80px"> - <td style="font-weight:bold">{mon.name}</td> + <td style="font-weight:bold"><a rv-href="mon.url_perf">{mon.name}</a></td> <td>{mon.rank}</td> <td>{mon.public_addr}</td> <td><span class="inlinesparkline" style="font-size:30px">{ mon.stats.num_sessions | sparkline_data }</span></td> @@ -87,7 +87,7 @@ <th>Public Addr</th> </thead> <tr rv-each-mon="out_quorum" class="font-size:15px;height:80px"> - <td style="font-weight:bold">{mon.name}</td> + <td style="font-weight:bold"><a rv-href="mon.url_perf">{mon.name}</a></td> <td>{mon.rank}</td> <td>{mon.public_addr}</td> </tr> diff --git a/src/pybind/mgr/dashboard/osd_perf.html b/src/pybind/mgr/dashboard/osd_perf.html index b13ad17e1fd..2c36613517f 100644 --- a/src/pybind/mgr/dashboard/osd_perf.html +++ b/src/pybind/mgr/dashboard/osd_perf.html @@ -104,11 +104,12 @@ post_load(); setTimeout(refresh, 3000); }); - }; + }; // Wait 1s to load irrespective of normal frequency, // to promptly load our first delta - setTimeout(refresh, 1000); + setTimeout(refresh, 1000); + }); </script> @@ -116,11 +117,12 @@ <section class="content-header"> <h1> osd.{osd.osd} + <button class="pull-right btn btn-default"><a rv-href="url_perf">Performance Counters</a></button> </h1> </section> <section class="content"> - + <table> <tr> <td> @@ -150,7 +152,7 @@ <tbody> <tr rv-each-item="osd_list"> <td>{item.key}</td> - <td>{item.value}</td> + <td>{item.value}</td> </tr> </tbody> </table> diff --git a/src/pybind/mgr/dashboard/perf_counters.html b/src/pybind/mgr/dashboard/perf_counters.html new file mode 100644 index 00000000000..40638b6b2d8 --- /dev/null +++ b/src/pybind/mgr/dashboard/perf_counters.html @@ -0,0 +1,58 @@ +{% extends "base.html" %} + +{% block content %} + +<script> + $(document).ready(function(){ + // Pre-populated initial data at page load + var content_data = {{ content_data }}; + + rivets.bind($("div#content"), content_data); + + var refresh = function() { + $.get("{{ url_prefix }}/perf_counters/" + content_data.service_type + "/" + content_data.service_id, function(data) { + _.extend(content_data, data); + setTimeout(refresh, 3000); + }); + }; + + setTimeout(refresh, 1000); + }); +</script> + + +<section class="content-header"> + <h1> + {service_type}.{service_id} + </h1> +</section> + +<section class="content"> +<div class="box"> + <div class="box-header"> + <h3 class="box-title">Performance Counters</h3> + </div> + <div class="box-body"> + <table class="table table-bordered"> + <thead> + <tr> + <th>Name</th> + <th>Description</th> + <th>Value</th> + </tr> + </thead> + <tbody> + <tr rv-each-item="counters"> + <td>{item.name}</td> + <td>{item.description}</td> + <td>{item.value | dimless} {item.unit}</td> + </tr> + </tbody> + </table> + </div> +</div> + +</section> +<!-- /.content --> + +{% endblock %} diff --git a/src/pybind/mgr/dashboard/rgw_detail.html b/src/pybind/mgr/dashboard/rgw_detail.html index 986dc90da07..3f224ac4c59 100644 --- a/src/pybind/mgr/dashboard/rgw_detail.html +++ b/src/pybind/mgr/dashboard/rgw_detail.html @@ -20,6 +20,7 @@ </script> <section class="content-header"> + <button class="pull-right btn btn-default"><a rv-href="url_perf">Performance Counters</a></button> <h1 rv-text="rgw_id"></h1> </section> diff --git a/src/pybind/mgr/dashboard/servers.html b/src/pybind/mgr/dashboard/servers.html index 421d3389c35..dcecac40943 100644 --- a/src/pybind/mgr/dashboard/servers.html +++ b/src/pybind/mgr/dashboard/servers.html @@ -16,11 +16,12 @@ setTimeout(refresh, 5000); rivets.formatters.service_list = function(services) { - var strings = []; + var result = "" $.each(services, function(i, svc) { - strings.push(svc.type + "." + svc.id); + result += "<a href={{url_prefix}}/perf_counters/" + svc.type + "/" + svc.id + ">" + svc.type + "." + svc.id + "</a>, " ; }); - return strings.join(", "); + result = result.slice(0, -2); + return result; }; rivets.bind($("#content"), content_data); @@ -55,8 +56,7 @@ <td> {server.hostname} </td> - <td> - {server.services | service_list} + <td rv-html="server.services | service_list"> </td> <td> {server.ceph_version | short_version} diff --git a/src/pybind/mgr/mgr_module.py b/src/pybind/mgr/mgr_module.py index ea72df830a0..60cc2202847 100644 --- a/src/pybind/mgr/mgr_module.py +++ b/src/pybind/mgr/mgr_module.py @@ -308,6 +308,21 @@ class MgrModule(ceph_module.BaseMgrModule): """ return self._ceph_get(data_name) + def _stattype_to_str(self, stattype): + + typeonly = stattype & self.PERFCOUNTER_TYPE_MASK + if typeonly == 0: + return 'gauge' + if typeonly == self.PERFCOUNTER_LONGRUNAVG: + # this lie matches the DaemonState decoding: only val, no counts + return 'counter' + if typeonly == self.PERFCOUNTER_COUNTER: + return 'counter' + if typeonly == self.PERFCOUNTER_HISTOGRAM: + return 'histogram' + + return '' + def get_server(self, hostname): """ Called by the plugin to fetch metadata about a particular hostname from diff --git a/src/pybind/mgr/prometheus/module.py b/src/pybind/mgr/prometheus/module.py index 5396d685175..74aceeaad44 100644 --- a/src/pybind/mgr/prometheus/module.py +++ b/src/pybind/mgr/prometheus/module.py @@ -144,21 +144,6 @@ class Module(MgrModule): self.schema = OrderedDict() _global_instance['plugin'] = self - def _stattype_to_str(self, stattype): - - typeonly = stattype & self.PERFCOUNTER_TYPE_MASK - if typeonly == 0: - return 'gauge' - if typeonly == self.PERFCOUNTER_LONGRUNAVG: - # this lie matches the DaemonState decoding: only val, no counts - return 'counter' - if typeonly == self.PERFCOUNTER_COUNTER: - return 'counter' - if typeonly == self.PERFCOUNTER_HISTOGRAM: - return 'histogram' - - return '' - def _setup_static_metrics(self): metrics = {} metrics['health_status'] = Metric( |