summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJohn Spray <jspray@redhat.com>2018-01-26 12:05:28 +0100
committerGitHub <noreply@github.com>2018-01-26 12:05:28 +0100
commit367c462882d6dcf99c9f6eace768f77195a9fa47 (patch)
treed3e72561689190de115aff2c6275e02d39dfa412 /src
parentMerge pull request #20009 from Liuchang0812/fix-22727 (diff)
parentmgr/dashboard: performance counter browsers (diff)
downloadceph-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.py42
-rw-r--r--src/pybind/mgr/dashboard/monitors.html4
-rw-r--r--src/pybind/mgr/dashboard/osd_perf.html10
-rw-r--r--src/pybind/mgr/dashboard/perf_counters.html58
-rw-r--r--src/pybind/mgr/dashboard/rgw_detail.html1
-rw-r--r--src/pybind/mgr/dashboard/servers.html10
-rw-r--r--src/pybind/mgr/mgr_module.py15
-rw-r--r--src/pybind/mgr/prometheus/module.py15
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(