From 8b37126169f292a6d3e7e6e716e3d08192b8e20b Mon Sep 17 00:00:00 2001 From: msimonin <matthieu.simonin@inria.fr> Date: Sun, 20 Mar 2022 21:59:32 +0100 Subject: [PATCH] Update metric endpoint --- README.org | 79 ++++++++------------------------------ examples/job_timeseries.py | 36 ----------------- examples/timeseries.py | 37 ++++++++---------- grid5000/base.py | 4 ++ grid5000/objects.py | 9 +++++ 5 files changed, 46 insertions(+), 119 deletions(-) delete mode 100644 examples/job_timeseries.py diff --git a/README.org b/README.org index 6445c33..726ba72 100644 --- a/README.org +++ b/README.org @@ -594,47 +594,6 @@ In [2]: # gk is your entry point #+END_SRC ** Metrics API -*** Get the timeseries corresponding to a job - Credits to ~lturpin~. - #+BEGIN_SRC python :exports code :tangle examples/job_timeseries.py -import logging -import os - -from grid5000 import Grid5000 - - -logging.basicConfig(level=logging.DEBUG) - - -def get_job_consumption(job_id, gk, site): - metrics = gk.sites[site].metrics - job = gk.sites[site].jobs[job_id] - # nodes as list : "cluster-number.site.grid5000.fr" - nodes_dom = job.assigned_nodes - # nodes as list : "cluster-number" - nodes = map(lambda node_dom: node_dom.split('.')[0], nodes_dom) - # nodes as string : "cluster-number,cluster-number,..." - nodes_str = ','.join(nodes) - - start = job.started_at - end = job.stopped_at - kwargs = { - "only": nodes_str, - "resolution": 1, - "from": start, - "to": end - } - timeseries = metrics["power"].timeseries.list(**kwargs) - return timeseries - - -conf_file = os.path.join(os.environ.get("HOME"), ".python-grid5000.yaml") -gk = Grid5000.from_yaml(conf_file) - -timeseries = get_job_consumption("1092446", gk, "lyon") -print(timeseries) - #+END_SRC - *** Get some timeseries (and plot them) For this example you'll need ~matplotlib~, ~seaborn~ and ~pandas~. @@ -649,47 +608,43 @@ print(timeseries) import seaborn as sns import time - logging.basicConfig(level=logging.DEBUG) + logging.basicConfig(level=logging.INFO) conf_file = os.path.join(os.environ.get("HOME"), ".python-grid5000.yaml") gk = Grid5000.from_yaml(conf_file) - metrics = gk.sites["lyon"].metrics + metrics = gk.sites["lyon"].clusters["nova"].metrics print("--- available metrics") - print(metrics.list()) - - print("---- power metric") - print(metrics["power"]) + print(metrics) print("----- a timeserie") now = time.time() + # NOTE that you can pass a job_id here kwargs = { - "only": "nova-1,nova-2,nova-3", - "resolution": 1, - "from": int(now - 600), - "to": int(now) + "nodes": "nova-1,nova-2,nova-3", + "metrics": "wattmetre_power_watt", + "start_time": int(now - 600), } - timeseries = metrics["power"].timeseries.list(**kwargs) + metrics = gk.sites["lyon"].metrics.list(**kwargs) # let's visualize this df = pd.DataFrame() - for timeserie in timeseries: - print(timeserie) - timestamp = timeserie.timestamps - value = timeserie.values - measurement = timeserie.uid + for metric in metrics: + timestamp = metric.timestamp + value = metric.value + device_id = metric.device_id df = pd.concat([df, pd.DataFrame({ - "timestamp": timestamp, - "value": value, - "measurement": [measurement]*len(timestamp) + "timestamp": [timestamp], + "value": [value], + "device_id": [device_id] })]) - sns.relplot(data=df, x="timestamp", y="value", - hue="measurement", + hue="device_id", kind="line") plt.show() + #+END_SRC diff --git a/examples/job_timeseries.py b/examples/job_timeseries.py deleted file mode 100644 index 492477a..0000000 --- a/examples/job_timeseries.py +++ /dev/null @@ -1,36 +0,0 @@ -import logging -import os - -from grid5000 import Grid5000 - - -logging.basicConfig(level=logging.DEBUG) - - -def get_job_consumption(job_id, gk, site): - metrics = gk.sites[site].metrics - job = gk.sites[site].jobs[job_id] - # nodes as list : "cluster-number.site.grid5000.fr" - nodes_dom = job.assigned_nodes - # nodes as list : "cluster-number" - nodes = map(lambda node_dom: node_dom.split('.')[0], nodes_dom) - # nodes as string : "cluster-number,cluster-number,..." - nodes_str = ','.join(nodes) - - start = job.started_at - end = job.stopped_at - kwargs = { - "only": nodes_str, - "resolution": 1, - "from": start, - "to": end - } - timeseries = metrics["power"].timeseries.list(**kwargs) - return timeseries - - -conf_file = os.path.join(os.environ.get("HOME"), ".python-grid5000.yaml") -gk = Grid5000.from_yaml(conf_file) - -timeseries = get_job_consumption("1092446", gk, "lyon") -print(timeseries) diff --git a/examples/timeseries.py b/examples/timeseries.py index 82a7ba0..af6ce84 100644 --- a/examples/timeseries.py +++ b/examples/timeseries.py @@ -8,44 +8,39 @@ import matplotlib.pyplot as plt import seaborn as sns import time -logging.basicConfig(level=logging.DEBUG) +logging.basicConfig(level=logging.INFO) conf_file = os.path.join(os.environ.get("HOME"), ".python-grid5000.yaml") gk = Grid5000.from_yaml(conf_file) -metrics = gk.sites["lyon"].metrics +metrics = gk.sites["lyon"].clusters["nova"].metrics print("--- available metrics") -print(metrics.list()) - -print("---- power metric") -print(metrics["power"]) +print(metrics) print("----- a timeserie") now = time.time() +# NOTE that you can pass a job_id here kwargs = { - "only": "nova-1,nova-2,nova-3", - "resolution": 1, - "from": int(now - 600), - "to": int(now) + "nodes": "nova-1,nova-2,nova-3", + "metrics": "wattmetre_power_watt", + "start_time": int(now - 600), } -timeseries = metrics["power"].timeseries.list(**kwargs) +metrics = gk.sites["lyon"].metrics.list(**kwargs) # let's visualize this df = pd.DataFrame() -for timeserie in timeseries: - print(timeserie) - timestamp = timeserie.timestamps - value = timeserie.values - measurement = timeserie.uid +for metric in metrics: + timestamp = metric.timestamp + value = metric.value + device_id = metric.device_id df = pd.concat([df, pd.DataFrame({ - "timestamp": timestamp, - "value": value, - "measurement": [measurement]*len(timestamp) + "timestamp": [timestamp], + "value": [value], + "device_id": [device_id] })]) - sns.relplot(data=df, x="timestamp", y="value", - hue="measurement", + hue="device_id", kind="line") plt.show() diff --git a/grid5000/base.py b/grid5000/base.py index fe28466..74044ac 100644 --- a/grid5000/base.py +++ b/grid5000/base.py @@ -1,3 +1,4 @@ +import copy import importlib import json @@ -164,3 +165,6 @@ class RESTObject(object): def __eq__(self, value): return self.get_id() == value.get_id() + + def to_dict(self): + return copy.deepcopy(self._attrs) \ No newline at end of file diff --git a/grid5000/objects.py b/grid5000/objects.py index d3ebca3..73d54e5 100644 --- a/grid5000/objects.py +++ b/grid5000/objects.py @@ -16,6 +16,15 @@ class Timeserie(RESTObject): class Metric(RESTObject): _managers = (("timeseries", "TimeserieManager"),) + _id_attr = None + + def __repr__(self): + keys = ["timestamp", "value", "metric_id", "device_id"] + try: + _repr = ["%s:%s" % (k, getattr(self, k)) for k in keys] + return "<%s %s>" % (self.__class__.__name__, " ".join(_repr)) + except Exception: + return super().__repr__() class Server(RESTObject): -- GitLab