From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 6245B64F9F for ; Tue, 21 Jul 2020 15:06:50 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 52A7018DEB for ; Tue, 21 Jul 2020 15:06:20 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [212.186.127.180]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id A66BA18DE3 for ; Tue, 21 Jul 2020 15:06:19 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 6BD51432D1 for ; Tue, 21 Jul 2020 15:06:19 +0200 (CEST) From: Dominik Csapak To: pve-devel@lists.proxmox.com Date: Tue, 21 Jul 2020 15:06:18 +0200 Message-Id: <20200721130618.14361-1-d.csapak@proxmox.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL -0.001 Adjusted score from AWL reputation of From: address KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment KAM_LAZY_DOMAIN_SECURITY 1 Sending domain does not have any anti-forgery methods NO_DNS_FOR_FROM 0.379 Envelope sender has no MX or A DNS records RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_NONE 0.001 SPF: sender does not publish an SPF Record Subject: [pve-devel] [PATCH manager] ui: add ceph recovery graph and progressbar X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 21 Jul 2020 13:06:50 -0000 shows a runningChart (like for reads) for the recovery speed also shows a progressbar of the health percentage of the cluster with an estimate of how long the recovery might need (unhealthy objects) / (objects per second) only show them when a recovery is ongoing or there are unhealthy objects Signed-off-by: Dominik Csapak --- we could also opt to only show it when there is really recovery going on (recovering_objects_per_sec !== undefined) but in my tests sometimes during recovery, ceph would not return those values intermittently, making the panel flicker, so i opted to show it also when there are unhealthy objects (though i am not opposed to to the first and have some counter to catch intermittent missing values) www/manager6/ceph/Status.js | 63 +++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/www/manager6/ceph/Status.js b/www/manager6/ceph/Status.js index e75fe5c0..7d1474eb 100644 --- a/www/manager6/ceph/Status.js +++ b/www/manager6/ceph/Status.js @@ -188,9 +188,37 @@ Ext.define('PVE.node.CephStatus', { items: [ { flex: 1, - xtype: 'proxmoxGauge', - itemId: 'space', - title: gettext('Usage') + xtype: 'container', + items: [ + { + xtype: 'proxmoxGauge', + itemId: 'space', + title: gettext('Usage') + }, + { + flex: 1, + border: false, + }, + { + xtype: 'container', + itemId: 'recovery', + hidden: true, + padding: 25, + items: [ + { + itemId: 'recoverychart', + xtype: 'pveRunningChart', + title: gettext('Recovery'), + renderer: PVE.Utils.render_bandwidth, + height: 100, + }, + { + xtype: 'progressbar', + itemId: 'recoveryprogress', + }, + ] + }, + ] }, { flex: 2, @@ -297,6 +325,35 @@ Ext.define('PVE.node.CephStatus', { me.writes.addDataPoint(writes); me.readiops.addDataPoint(readiops); me.writeiops.addDataPoint(writeiops); + + let degraded = pgmap.degraded_objects || 0; + let misplaced = pgmap.misplaced_objects || 0; + let unfound = pgmap.unfound_objects || 0; + let unhealthy = degraded + unfound + misplaced; + // update recovery + if (pgmap.recovering_objects_per_sec !== undefined || unhealthy > 0) { + let total = pgmap.misplaced_total || pgmap.unfound_total || pgmap.degraded_total || 0; + if (total === 0) return; + let recovered = (total - unhealthy) || 0; + let speed = pgmap.recovering_bytes_per_sec || 0; + let speedTxt = PVE.Utils.render_bandwidth(speed); + let obj_per_sec = speed / (4*1024*1024); // 4MiB per Object + let duration = Proxmox.Utils.format_duration_human(unhealthy/obj_per_sec); + + let percentage = recovered/total; + let txt = `${(percentage*100).toFixed(2)}%`; + if (speed > 0) { + txt += ` (${speedTxt} - ${duration} left)`; + } + + me.down('#recovery').setVisible(true); + me.down('#recoveryprogress').updateValue(percentage); + me.down('#recoveryprogress').updateText(txt); + me.down('#recoverychart').addDataPoint(speed); + } else { + me.down('#recovery').setVisible(false); + me.down('#recoverychart').addDataPoint(0); + } }, initComponent: function() { -- 2.20.1