Add render

This commit is contained in:
Alban Bronisz 2021-02-13 20:15:17 +01:00
parent 15d979e9c6
commit ff76f43e14
5 changed files with 158 additions and 1 deletions

2
.gitignore vendored
View File

@ -1 +1,3 @@
stats.json stats.json
venv
mem_usage.png

View File

@ -31,4 +31,26 @@ the crontab line redirect the outputs into `/dev/null`. Can also be a path to a
Display stats Display stats
------------- -------------
To be done... This steps permit to generate a render from a stats file (generated by the script
called by the crontab, see stats export section).
### Install
Need python3 with venv module
sudo apt install python3 python3-venv
### Run
Go in [display](display) folder
cd display
Then to generate a png, just run (install is automatically done if needed)
./render_stats.sh stats.json
It is also possible to see a web version fo the render :
./render_stats.sh stats.json -w
**Note:** if the stats file is in a remote server, one can use `scp` to get it:
scp alban@eunuque.caracals.org:/path/to/docker-stats-histo/stats.json .

72
display/render.py Normal file
View File

@ -0,0 +1,72 @@
import argparse
import json
from datetime import datetime
import pygal
PNG_OUTPUT = 'mem_usage.png'
def parse_args():
parser = argparse.ArgumentParser(
description=("Render for docker stats memory usage")
)
parser.add_argument('stats', type=str, help="Path to stats file")
parser.add_argument('--web', '-w', action='store_true',
help="Render in web browser instead of svg")
args = parser.parse_args()
return args.stats, args.web
def name_from_field(field: str) -> str :
if field.startswith("onlyoffice-"):
return "onlyoffice"
return field.split("_")[0]
def main():
stats_fn, web_render = parse_args()
data = load_data(stats_fn)
render(data, web_render)
def load_data(stats_fn: str):
with open(stats_fn) as stats_f:
data = json.load(stats_f)
data_dict = {name_from_field(field): [0]*len(data) for field in data[0]}
print("Found", len(data), "points")
for t_i, stat in enumerate(data):
for field in stat:
if field == "date": # date
data_dict[field][t_i] = datetime.strptime(stat[field], "%Y-%m-%dT%H:%M:%S%z")
else: # float
value = stat[field].split(" ")[0]
value = value.replace("MiB", "e3")
data_dict[name_from_field(field)][t_i] += float(value) / 1000 # values are in MiB
return data_dict
def render(data: dict, web_render:bool=False):
bar_chart = pygal.StackedBar(height=400)
bar_chart.x_labels = data["date"]
for k in data:
if k == "date":
continue
#if "db" in k or "database" in k or "mysql" in k or "mongo" in k or "postgre" in k:
# continue
bar_chart.add(k, data[k])
if web_render:
bar_chart.render_in_browser()
else:
bar_chart.render_to_png(PNG_OUTPUT)
print("Image generated in:", PNG_OUTPUT)
if __name__ == "__main__":
main()

51
display/render_stats.sh Executable file
View File

@ -0,0 +1,51 @@
#!/usr/bin/env bash
set -eu
# Need to replace last line of file from "}," to "}]"
# To avoid modify original file, use temporary file
TMP_FILE=stats_tmp.json
VENV=venv
if [[ $# -ne 1 ]] && [[ $# -ne 2 ]]; then
echo "Usage:"
echo " $0 STATS_FILE [-w] "
echo ""
echo "Params:"
echo " - stats_file: path to stats file"
echo ""
echo "Options:"
echo " - w: do rende1r using web browser"
exit 1
fi
STATS_FILE=$1
OPT=""
if [[ $# -eq 2 ]]; then
OPT=${OPT}" -w"
fi
# Pip install -----------------------------------------------------------------
if [ ! -d ${VENV} ]; then
echo "Installing python environment in ${VENV}..."
python3 -m venv ${VENV}
. ${VENV}/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
echo "Python environment installed..."
echo ""
else
. ${VENV}/bin/activate
fi
# Render ----------------------------------------------------------------------
sed -e '$s/},/}]/' ${STATS_FILE} > ${TMP_FILE}
# Update last line
# Generate render
python render.py ${TMP_FILE} ${OPT}
rm ${TMP_FILE}
deactivate

10
display/requirements.txt Normal file
View File

@ -0,0 +1,10 @@
pygal
# For pygal web render
lxml
tinycss
cssselect
cairosvg