diff --git a/examples/timeseries.py b/examples/timeseries.py new file mode 100644 index 0000000000000000000000000000000000000000..2f7c92166c1983261f99e274bb50ada1acd9cd04 --- /dev/null +++ b/examples/timeseries.py @@ -0,0 +1,51 @@ +import logging +import os + +from grid5000 import Grid5000 + +import pandas as pd +import matplotlib.pyplot as plt +import seaborn as sns +import time + +logging.basicConfig(level=logging.DEBUG) + +conf_file = os.path.join(os.environ.get("HOME"), ".python-grid5000.yaml") +gk = Grid5000.from_yaml(conf_file) + +metrics = gk.sites["lyon"].metrics +print("--- available metrics") +print(metrics.list()) + +print("---- power metric") +print(metrics["power"]) + +print("----- a timeserie") +now = time.time() +kwargs = { + "only": "nova-1,nova-2,nova-3", + "resolution": 1, + "from": int(now - 600), + "to": int(now) +} + +# let's visualize this +timeseries = metrics["power"].timeseries.list(**kwargs) +df = pd.DataFrame() +for timeserie in timeseries: + print(timeserie) + timestamp = timeserie.timestamps + value = timeserie.values + measurement = timeserie.uid + df = pd.concat([df, pd.DataFrame({ + "timestamp": timestamp, + "value": value, + "measurement": [measurement]*len(timestamp) + })]) + +sns.relplot(data=df, + x="timestamp", + y="value", + hue="measurement", + kind="line") +plt.show() \ No newline at end of file diff --git a/grid5000/cli.py b/grid5000/cli.py index 0d6131560b02fa825392cc72838cf614edc230e2..4a58df9daaaaf874a85eb0b5c9bdffb4b12073c5 100644 --- a/grid5000/cli.py +++ b/grid5000/cli.py @@ -37,6 +37,6 @@ def main(): if not path.exists(): print("Configuratio file %s is missing" % CONF_PATH) return - gk = Grid5000.from_yaml(CONF_PATH) + _ = Grid5000.from_yaml(CONF_PATH) IPython.embed(header=motd) diff --git a/grid5000/objects.py b/grid5000/objects.py index dc9f1208d637dc1cb0242ea48754ee752565fe7b..6103598a1ca9e0585db92da836c99aeb6a845d28 100644 --- a/grid5000/objects.py +++ b/grid5000/objects.py @@ -2,6 +2,14 @@ from .base import * # noqa from .mixins import * # noqa +class Timeserie(RESTObject): + pass + + +class Metric(RESTObject): + _managers = (("timeseries", "TimeserieManager"),) + + class Server(RESTObject): pass @@ -63,7 +71,7 @@ class Job(RESTObject, RefreshMixin, ObjectDeleteMixin): try: _repr = ["%s:%s" % (k, getattr(self, k)) for k in keys] return "<%s %s>" % (self.__class__.__name__, " ".join(_repr)) - except: + except Exception: return super().__repr__() @@ -72,6 +80,7 @@ class Site(RESTObject): ("clusters", "ClusterManager"), ("deployments", "DeploymentManager"), ("jobs", "JobManager"), + ("metrics", "SiteMetricManager"), ("servers", "ServerManager"), ("status", "SiteStatusManager"), ("storage", "StorageHomeManager"), @@ -302,3 +311,15 @@ class ServerManager(RESTManager, BracketMixin, RetrieveMixin): _path = "/sites/%(site)s/servers" _obj_cls = Server _from_parent_attrs = {"site": "uid"} + + +class SiteMetricManager(RESTManager, BracketMixin, RetrieveMixin): + _path = "/sites/%(site)s/metrics" + _obj_cls = Metric + _from_parent_attrs = {"site": "uid"} + + +class TimeserieManager(RESTManager, ListMixin): + _path = "/sites/%(site)s/metrics/%(metric)s/timeseries" + _obj_cls = Timeserie + _from_parent_attrs = {"site": "site", "metric": "uid"}