From b4faf9d7cb2953ceda47390f2929c9bc65ca252b Mon Sep 17 00:00:00 2001 From: Mehran Kholdi Date: Sat, 16 Jan 2021 02:45:31 +0330 Subject: [PATCH] Expose volume metrics through gRPC calls rather than metrics endpoint --- metrics.py | 83 ++++++--------------------------------------- rawfile_servicer.py | 7 ++-- 2 files changed, 15 insertions(+), 75 deletions(-) diff --git a/metrics.py b/metrics.py index a40adf1..fd18d16 100644 --- a/metrics.py +++ b/metrics.py @@ -4,10 +4,6 @@ import subprocess from prometheus_client.core import REGISTRY from prometheus_client.exposition import start_http_server -from prometheus_client.metrics_core import GaugeMetricFamily - -import rawfile_util -from rawfile_util import attached_loops def path_stats(path): @@ -20,74 +16,12 @@ def path_stats(path): } -def volume_stats(volume_id: str) -> dict: - img_file = rawfile_util.img_file(volume_id) - dev_stat = img_file.stat() - stats = { - "dev_size": dev_stat.st_size, - "dev_free": dev_stat.st_size - dev_stat.st_blocks * 512, - } - mountpoint = volume_to_mountpoint(img_file) - if mountpoint is not None: - stats.update(path_stats(mountpoint)) - return stats - - -class VolumeStatsCollector(object): - def collect(self): - VOLUME_ID = "volume_id" - fs_size = GaugeMetricFamily( - "rawfile_filesystem_size_bytes", - "Filesystem size in bytes.", - labels=[VOLUME_ID], - ) - fs_free = GaugeMetricFamily( - "rawfile_filesystem_avail_bytes", - "Filesystem free space in bytes", - labels=[VOLUME_ID], - ) - fs_files = GaugeMetricFamily( - "rawfile_filesystem_files", - "Filesystem total file nodes.", - labels=[VOLUME_ID], - ) - fs_files_free = GaugeMetricFamily( - "rawfile_filesystem_files_free", - "Filesystem total free file nodes", - labels=[VOLUME_ID], - ) - dev_size = GaugeMetricFamily( - "rawfile_device_size_bytes", "Device size in bytes.", labels=[VOLUME_ID] - ) - dev_free = GaugeMetricFamily( - "rawfile_device_free_bytes", - "Device free space in bytes.", - labels=[VOLUME_ID], - ) - - for volume_id in rawfile_util.list_all_volumes(): - labels = [volume_id] - key_to_gauge = { - "dev_size": dev_size, - "dev_free": dev_free, - "fs_size": fs_size, - "fs_free": fs_free, - "fs_files": fs_files, - "fs_files_free": fs_files_free, - } - stats = volume_stats(volume_id) - for key in stats.keys(): - key_to_gauge[key].add_metric(labels, stats[key]) - - return [fs_size, fs_free, fs_files, fs_files_free, dev_size, dev_free] - - -def volume_to_mountpoint(img_file): - for dev in attached_loops(img_file): - mountpoint = dev_to_mountpoint(dev) - if mountpoint is not None: - return mountpoint - return None +def device_stats(dev): + output = subprocess.run( + f"blockdev --getsize64 {dev}", shell=True, check=True, capture_output=True + ).stdout.decode() + dev_size = int(output) + return {"dev_size": dev_size} def dev_to_mountpoint(dev_name): @@ -116,6 +50,11 @@ def mountpoint_to_dev(mountpoint): return data["filesystems"][0]["source"] +class VolumeStatsCollector(object): + def collect(self): + return [] + + def expose_metrics(): REGISTRY.register(VolumeStatsCollector()) start_http_server(9100) diff --git a/rawfile_servicer.py b/rawfile_servicer.py index 39c0672..11a88d2 100644 --- a/rawfile_servicer.py +++ b/rawfile_servicer.py @@ -7,7 +7,7 @@ import rawfile_util from consts import PROVISIONER_VERSION, PROVISIONER_NAME from csi import csi_pb2, csi_pb2_grpc from declarative import be_symlink, be_absent -from metrics import volume_stats +from metrics import device_stats, mountpoint_to_dev from orchestrator.k8s import volume_to_node, run_on_node from rawfile_util import attach_loop, detach_loops from remote import init_rawfile, scrub, expand_rawfile @@ -105,8 +105,9 @@ class RawFileNodeServicer(csi_pb2_grpc.NodeServicer): # @log_grpc_request def NodeGetVolumeStats(self, request, context): - volume_id = request.volume_id - stats = volume_stats(volume_id) # FIXME + volume_path = request.volume_path + dev = mountpoint_to_dev(volume_path) + stats = device_stats(dev=dev) return csi_pb2.NodeGetVolumeStatsResponse( usage=[ csi_pb2.VolumeUsage(