#!/usr/bin/env python3 import argparse import logging import os import sqlite3 from datetime import datetime from datetime import timedelta from pathlib import Path import pandas as pd import plotly.express as px log = logging.getLogger(__name__) HERE = Path(os.path.dirname(os.path.realpath(__file__))) TABLE_NAME = "dc_stats" INTERVALS = [1] # on cron interval is 10min def parse_args(): parser = argparse.ArgumentParser(description="Extract docker stats in a sqlite db") parser.add_argument( "sqlite", nargs="?", type=Path, help="Path to sqlite file", default=HERE / "stats.sqlite", ) parser.add_argument( "html", nargs="?", type=Path, help="Path to html output report", default=HERE / "stats.html", ) parser.add_argument("--debug", "-d", action="store_true", help="Run in debug mode") parser.add_argument("-n", "--n-days-histo", dest="n_days_histo", type=int, default=30, help="Number of day to show") args = parser.parse_args() return args.sqlite, args.html, args.debug, args.n_days_histo def generate_html_report(sqlite_fn: Path, html_fn: Path, n_days_histo): # Create your connection. log.info(f"Read sqlite {sqlite_fn}") cnx = sqlite3.connect(sqlite_fn) first_date = datetime.today() - timedelta(days = n_days_histo) log.debug(f"First date : {first_date}") df = pd.read_sql_query(f"SELECT * FROM {TABLE_NAME} WHERE date > '{first_date}'", cnx) df = df.set_index("date") log.info(f"Find {len(df)} items") # df["granu"] = 1 dfs = pd.DataFrame() for i in INTERVALS: dfi = df[::i].copy() # dfi["granu"] = i dfs = dfs.append(dfi) #breakpoint() # Remove empty conlumn dfs = dfs.dropna(axis=1, how='all') #breakpoint() log.info(f"Get {len(dfs)} items after sub-sampling") fig = px.area(dfs) fig.for_each_trace(lambda trace: trace.update(fillcolor=trace.line.color)) fig["layout"].pop("updatemenus") # optional, drop animation buttons fig.update_layout(transition={"duration": 1e12}) now = datetime.now() fig.update_layout( title="Utilisation de RAM pour les docker-compose de l'eunuque (pour voir une stat, mettre la sourie sur " f"le haut des courbes, vers les points), généré le {now.strftime('%d/%m/%Y %H:%M:%S')}", xaxis_title="Temps", yaxis_title="RAM (MiB)", legend={"traceorder":"reversed"} ) fig.write_html(html_fn, include_plotlyjs="cdn") log.info(f"Report generate in {html_fn}") def main(): sqlite_fn, html_fn, debug, n_days_histo = parse_args() if debug: logging.basicConfig(level=logging.DEBUG) else: logging.basicConfig(level=logging.INFO) generate_html_report(sqlite_fn, html_fn, n_days_histo) if __name__ == "__main__": main()