Implement basic metrics
This commit is contained in:
parent
c9da83b19b
commit
9deaefc203
@ -17,7 +17,7 @@ Features
|
|||||||
- [ ] Volume modes
|
- [ ] Volume modes
|
||||||
- [x] `Filesystem` mode
|
- [x] `Filesystem` mode
|
||||||
- [ ] `Block` mode
|
- [ ] `Block` mode
|
||||||
- [ ] Volume metrics
|
- [x] Volume metrics
|
||||||
- [ ] Supports fsTypes
|
- [ ] Supports fsTypes
|
||||||
- [ ] Online expansion: If fs supports it (e.g. ext4, btrfs)
|
- [ ] Online expansion: If fs supports it (e.g. ext4, btrfs)
|
||||||
- [ ] Online shrinking: If fs supports it (e.g. btrfs)
|
- [ ] Online shrinking: If fs supports it (e.g. btrfs)
|
||||||
|
61
metrics.py
Normal file
61
metrics.py
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
import threading
|
||||||
|
from os.path import basename
|
||||||
|
|
||||||
|
from prometheus_client import Gauge
|
||||||
|
from prometheus_client.exposition import start_http_server
|
||||||
|
|
||||||
|
import rawfile_util
|
||||||
|
from rawfile_util import attached_loops
|
||||||
|
from util import run_out
|
||||||
|
|
||||||
|
VOLUME_ID = "volume_id"
|
||||||
|
|
||||||
|
fs_size = Gauge(
|
||||||
|
"rawfile_filesystem_size_bytes", "Filesystem size in bytes.", [VOLUME_ID]
|
||||||
|
)
|
||||||
|
fs_free = Gauge(
|
||||||
|
"rawfile_filesystem_avail_bytes", "Filesystem free space in bytes", [VOLUME_ID]
|
||||||
|
)
|
||||||
|
dev_size = Gauge("rawfile_device_size_bytes", "Device size in bytes.", [VOLUME_ID])
|
||||||
|
dev_free = Gauge(
|
||||||
|
"rawfile_device_free_bytes", "Device free space in bytes.", [VOLUME_ID]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def collect_stats():
|
||||||
|
blockdevices = json.loads(run_out("lsblk --json").stdout.decode())["blockdevices"]
|
||||||
|
|
||||||
|
def dev_to_mountpoint(dev_name):
|
||||||
|
dev_name = basename(dev_name)
|
||||||
|
matches = list(filter(lambda bd: bd["name"] == dev_name, blockdevices))
|
||||||
|
if len(matches) == 0:
|
||||||
|
return None
|
||||||
|
return matches[0]["mountpoint"]
|
||||||
|
|
||||||
|
for volume_id in rawfile_util.list_all_volumes():
|
||||||
|
img_file = rawfile_util.img_file(volume_id)
|
||||||
|
labels = {VOLUME_ID: volume_id}
|
||||||
|
dev_stat = img_file.stat()
|
||||||
|
dev_size.labels(**labels).set(dev_stat.st_size)
|
||||||
|
dev_free.labels(**labels).set(
|
||||||
|
dev_stat.st_size - dev_stat.st_blocks * dev_stat.st_blksize
|
||||||
|
)
|
||||||
|
for dev in attached_loops(img_file):
|
||||||
|
mountpoint = dev_to_mountpoint(dev)
|
||||||
|
if mountpoint is None:
|
||||||
|
continue
|
||||||
|
fs_stat = os.statvfs(mountpoint)
|
||||||
|
fs_size.labels(**labels).set(fs_stat.f_frsize * fs_stat.f_blocks)
|
||||||
|
fs_free.labels(**labels).set(fs_stat.f_frsize * fs_stat.f_bfree)
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def expose_metrics():
|
||||||
|
def collector_loop():
|
||||||
|
collect_stats()
|
||||||
|
threading.Timer(10, collector_loop).start()
|
||||||
|
|
||||||
|
collector_loop()
|
||||||
|
start_http_server(9100)
|
@ -7,6 +7,7 @@ import grpc
|
|||||||
|
|
||||||
import rawfile_servicer
|
import rawfile_servicer
|
||||||
from csi import csi_pb2_grpc
|
from csi import csi_pb2_grpc
|
||||||
|
from metrics import expose_metrics
|
||||||
|
|
||||||
|
|
||||||
@click.group()
|
@click.group()
|
||||||
@ -17,7 +18,10 @@ def cli():
|
|||||||
@cli.command()
|
@cli.command()
|
||||||
@click.option("--endpoint", envvar="CSI_ENDPOINT", default="0.0.0.0:5000")
|
@click.option("--endpoint", envvar="CSI_ENDPOINT", default="0.0.0.0:5000")
|
||||||
@click.option("--nodeid", envvar="NODE_ID")
|
@click.option("--nodeid", envvar="NODE_ID")
|
||||||
def csi_driver(endpoint, nodeid):
|
@click.option("--enable-metrics/--disable-metrics", default=True)
|
||||||
|
def csi_driver(endpoint, nodeid, enable_metrics):
|
||||||
|
if enable_metrics:
|
||||||
|
expose_metrics()
|
||||||
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
|
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
|
||||||
csi_pb2_grpc.add_IdentityServicer_to_server(
|
csi_pb2_grpc.add_IdentityServicer_to_server(
|
||||||
rawfile_servicer.RawFileIdentityServicer(), server
|
rawfile_servicer.RawFileIdentityServicer(), server
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
|
import glob
|
||||||
import json
|
import json
|
||||||
|
from os.path import basename, dirname
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from consts import DATA_DIR
|
from consts import DATA_DIR
|
||||||
@ -53,3 +55,8 @@ def attach_loop(file) -> str:
|
|||||||
return devs[0]
|
return devs[0]
|
||||||
next_loop()
|
next_loop()
|
||||||
run(f"losetup --direct-io=on -f {file}")
|
run(f"losetup --direct-io=on -f {file}")
|
||||||
|
|
||||||
|
|
||||||
|
def list_all_volumes():
|
||||||
|
metas = glob.glob(f"{DATA_DIR}/*/disk.meta")
|
||||||
|
return [basename(dirname(meta)) for meta in metas]
|
||||||
|
@ -4,3 +4,4 @@ click
|
|||||||
pyyaml
|
pyyaml
|
||||||
pykube-ng
|
pykube-ng
|
||||||
munch
|
munch
|
||||||
|
prometheus_client
|
||||||
|
@ -11,6 +11,7 @@ grpcio-tools==1.28.1 # via -r requirements.in
|
|||||||
grpcio==1.28.1 # via -r requirements.in, grpcio-tools
|
grpcio==1.28.1 # via -r requirements.in, grpcio-tools
|
||||||
idna==2.9 # via requests
|
idna==2.9 # via requests
|
||||||
munch==2.5.0 # via -r requirements.in
|
munch==2.5.0 # via -r requirements.in
|
||||||
|
prometheus-client==0.7.1 # via -r requirements.in
|
||||||
protobuf==3.11.3 # via grpcio-tools
|
protobuf==3.11.3 # via grpcio-tools
|
||||||
pykube-ng==20.4.1 # via -r requirements.in
|
pykube-ng==20.4.1 # via -r requirements.in
|
||||||
pyyaml==5.3.1 # via -r requirements.in, pykube-ng
|
pyyaml==5.3.1 # via -r requirements.in, pykube-ng
|
||||||
|
Loading…
Reference in New Issue
Block a user