]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/health.html
e41a1e2da5e2fc64cef1f75af00cfe9c06ec9206
[ceph.git] / ceph / src / pybind / mgr / dashboard / health.html
1
2 {% extends "base.html" %}
3
4 {% block content %}
5
6 <script>
7 $(document).ready(function(){
8 // Pre-populated initial data at page load
9 var content_data = {{ content_data }};
10
11 var refresh = function() {
12 $.get("/health_data", function(data) {
13 _.extend(content_data, data);
14 setTimeout(refresh, 5000);
15 });
16 };
17 setTimeout(refresh, 5000);
18
19 rivets.formatters.mon_summary = function(mon_status) {
20 var result = mon_status.monmap.mons.length.toString() + " (quorum ";
21 result += mon_status.quorum.join(", ");
22 result += ")";
23
24 return result;
25 };
26
27 rivets.formatters.log_color = function(log_line) {
28 if (log_line.priority == "[INF]") {
29 return "color: #000000";
30 } else if (log_line.priority == "[WRN]") {
31 return "color: #FFC200";
32 } else if (log_line.priority == "[ERR]") {
33 return "color: #FF2222";
34 } else {
35 return "";
36 }
37 };
38
39 rivets.formatters.osd_summary = function(osd_map) {
40 var in_count = 0;
41 var up_count = 0;
42 $.each(osd_map.osds, function(i, osd) {
43 if (osd.in) {
44 in_count++;
45 }
46 if (osd.up) {
47 up_count++;
48 }
49 });
50
51 return osd_map.osds.length + " (" + up_count + " up, " + in_count + " in)";
52 };
53
54 rivets.formatters.pg_status_style = function(pg_status) {
55 var unhealthy = false;
56 var scrubbing = false;
57 $.each(pg_status, function(state, count) {
58 if (state == "active+clean") {
59
60 } else if (state == "active+clean+scrubbing"
61 || state == "active+clean+scrubbing+deep") {
62 scrubbing = true;
63 } else {
64 unhealthy = true;
65 }
66 });
67
68 if (unhealthy) {
69 return "color: #FFC200";
70 } else if (scrubbing) {
71 return "color: #0000bb";
72 } else {
73 return "color: #00bb00";
74 }
75 };
76
77 rivets.formatters.pg_status = function(pg_status) {
78 var strings = [];
79 $.each(pg_status, function(state, count) {
80 strings.push(count + " " + state);
81 });
82
83 return strings.join(", ");
84 };
85
86 rivets.bind($("#content"), content_data);
87 });
88 </script>
89
90
91 <!-- Content Header (Page header) -->
92 <section class="content-header">
93 <h1>
94 Health
95 </h1>
96
97 </section>
98
99 <!-- Main content -->
100 <section class="content">
101
102 Overall status: <span rv-style="health.overall_status | health_color">{health.overall_status}</span>
103
104 <ul>
105 <li rv-each-summary="health.summary">
106 {summary.severity}: {summary.summary}
107 </li>
108 </ul>
109
110 <div class="row">
111 <div class="col-sm-3">
112 <div class="info-box">
113 <span class="info-box-icon bg-aqua"><i
114 class="fa fa-database"></i></span>
115
116 <div class="info-box-content">
117 <span class="info-box-text">Monitors</span>
118 <span class="info-box-number">{mon_status | mon_summary}</span>
119 </div>
120 <!-- /.info-box-content -->
121 </div>
122 </div>
123
124 <div class="col-sm-3">
125 <div class="info-box">
126 <span class="info-box-icon bg-aqua"><i
127 class="fa fa-hdd-o"></i></span>
128
129 <div class="info-box-content">
130 <span class="info-box-text">OSDs</span>
131 <span class="info-box-number">{osd_map | osd_summary}</span>
132 </div>
133 <!-- /.info-box-content -->
134 </div>
135 </div>
136 </div>
137
138 <div class="box">
139 <div class="box-header">
140 Pools
141 </div>
142 <div class="box-body">
143
144 <table class="table table-condensed">
145 <thead>
146 <th>Name</th>
147 <th>PG status</th>
148 <th>Usage</th>
149 <th>Activity</th>
150 </thead>
151 <tbody>
152 <tr rv-each-pool="pools">
153 <td style="text-align: right;">
154 {pool.pool_name}
155 </td>
156 <td rv-style="pool.pg_status | pg_status_style">
157 {pool.pg_status | pg_status}
158 </td>
159 <td>
160 {pool.stats.bytes_used.latest | dimless} /
161 {pool.stats.max_avail.latest | dimless }
162 </td>
163 <td>
164 {pool.stats.rd_bytes.rate | dimless } rd, {
165 pool.stats.wr_bytes.rate | dimless } wr
166 </td>
167 </tr>
168 </tbody>
169 </table>
170 </div>
171
172 </div>
173
174 <div class="box">
175 <div class="box-header">
176 Cluster log
177 </div>
178 <div class="box-body">
179 <ul class="nav nav-tabs">
180 <li class="active"><a data-toggle="tab" href="#clog">Cluster log</a></li>
181 <li><a data-toggle="tab" href="#audit_log">Audit log</a></li>
182 </ul>
183 <div class="tab-content" style="font-family:monospace; background-color: #ddd; color: #333">
184 <div id="clog" class="tab-pane fade in active">
185 <span>
186 <span rv-each-line="clog">
187 { line.stamp }&nbsp;{line.priority}&nbsp;
188 <span rv-style="line | log_color">
189 <span style="font-weight: bold;">
190 { line.message }
191 </span><br>
192 </span>
193 </span>
194 </span>
195 </div>
196 <div id="audit_log" class="tab-pane fade in">
197 <span>
198 <span rv-each-line="audit_log">
199 { line.stamp }&nbsp;{line.priority}&nbsp;
200 <span rv-style="line | log_color">
201 <span style="font-weight: bold;">
202 { line.message }
203 </span><br>
204 </span>
205 </span>
206 </span>
207
208 </div>
209 </div>
210
211 </div>
212
213 </div>
214
215 <!--
216
217 cluster ac15351a-571b-4393-9c71-815fc98dacd6
218 health HEALTH_WARN
219 noin,sortbitwise,require_jewel_osds,require_kraken_osds flag(s) set
220 monmap e2: 3 mons at {a=192.168.1.7:6789/0,b=192.168.1.7:6790/0,c=192.168.1.7:6791/0}
221 election epoch 6, quorum 0,1,2 a,b,c
222 fsmap e9: cephfs_a-1/1/1 up cephfs_b-1/1/1 up {[cephfs_a:0]=a=up:active,[cephfs_b:0]=d=up:active}, 2 up:standby
223 mgr active: x
224 osdmap e17: 3 osds: 3 up, 3 in
225 flags noin,sortbitwise,require_jewel_osds,require_kraken_osds
226 pgmap v115: 40 pgs, 5 pools, 4296 bytes data, 40 objects
227 279 GB used, 205 GB / 485 GB avail
228 40 active+clean
229 -->
230
231
232 </section>
233
234 {% endblock %}