Skip to content
Snippets Groups Projects
Commit 68bb94d1 authored by David Huss's avatar David Huss :speech_balloon:
Browse files

Add --read-load-from option to meetings

parent bcdba8a5
Branches
No related tags found
No related merge requests found
__version__ = '0.1.31' __version__ = '0.1.32'
...@@ -13,6 +13,7 @@ from bbbmon.xmldict import XmlListConfig, XmlDictConfig ...@@ -13,6 +13,7 @@ from bbbmon.xmldict import XmlListConfig, XmlDictConfig
from bbbmon.configuration import Config, Endpoint, SERVER_PROPERTIES_FILE, Url, Secret, get_user_config_path, init_config, new_config from bbbmon.configuration import Config, Endpoint, SERVER_PROPERTIES_FILE, Url, Secret, get_user_config_path, init_config, new_config
from bbbmon.meetings import * from bbbmon.meetings import *
from bbbmon.printing import * from bbbmon.printing import *
from bbbmon.load import *
...@@ -53,7 +54,7 @@ def main(userconfig, watch, version): ...@@ -53,7 +54,7 @@ def main(userconfig, watch, version):
Internally bbbmon relies on the offical bbb-API, which means you need to have the server's secret in order to create a valid request. Create a new configuration with: bbbmon config --new Internally bbbmon relies on the offical bbb-API, which means you need to have the server's secret in order to create a valid request. Create a new configuration with: bbbmon config --new
""" """
__version__ = "0.1.31" __version__ = "0.1.32"
if version: if version:
print(__version__) print(__version__)
...@@ -68,6 +69,7 @@ def main(userconfig, watch, version): ...@@ -68,6 +69,7 @@ def main(userconfig, watch, version):
@click.option('--endpoint', '-e', multiple=True, help="Filter by one or more endpoints as named in the user configuration (e.g. [servername]). Order is respected.") @click.option('--endpoint', '-e', multiple=True, help="Filter by one or more endpoints as named in the user configuration (e.g. [servername]). Order is respected.")
@click.option('--watch', '-w', help="Run repeatedly with the given interval in seconds", type=click.IntRange(2, 2147483647, clamp=True)) @click.option('--watch', '-w', help="Run repeatedly with the given interval in seconds", type=click.IntRange(2, 2147483647, clamp=True))
@click.option('-n', help="The number of meetings to show in the leaderboards (Default: 5)", type=int) @click.option('-n', help="The number of meetings to show in the leaderboards (Default: 5)", type=int)
@click.option('--read-load-from', help="Read the load from file/https (if starts with http(s) request, else read from path). Looks for floats and calculates the average.", type=str)
@click.option('--leaderboards/--no-leaderboards', default=True, show_default=True, help="Hide or show the meeting leaderboards") @click.option('--leaderboards/--no-leaderboards', default=True, show_default=True, help="Hide or show the meeting leaderboards")
@click.option('--participants/--no-participants', default=True, show_default=True, help="Hide or show the participants") @click.option('--participants/--no-participants', default=True, show_default=True, help="Hide or show the participants")
@click.option('--meetings/--no-meetings', default=True, show_default=True, help="Hide or show the meetings") @click.option('--meetings/--no-meetings', default=True, show_default=True, help="Hide or show the meetings")
...@@ -79,7 +81,7 @@ def main(userconfig, watch, version): ...@@ -79,7 +81,7 @@ def main(userconfig, watch, version):
@click.option('--all', '-a', 'all_', is_flag=True, help="Print all") @click.option('--all', '-a', 'all_', is_flag=True, help="Print all")
@click.option('--fancy/--no-fancy', default=False, show_default=True, help="Use fancy headers") @click.option('--fancy/--no-fancy', default=False, show_default=True, help="Use fancy headers")
@click.option('--sum','sum_', is_flag=True, help="Print all") @click.option('--sum','sum_', is_flag=True, help="Print all")
def meetings(ctx, userconfig, watch, short, compact, n, all_, twolines, leaderboards, participants, presenter, presenter_id, meetings, endpoint, fancy, sum_): def meetings(ctx, userconfig, watch, short, compact, n, all_, twolines, read_load_from, leaderboards, participants, presenter, presenter_id, meetings, endpoint, fancy, sum_):
"""View currently active meetings""" """View currently active meetings"""
if short: if short:
leaderboards = False leaderboards = False
...@@ -99,21 +101,25 @@ def meetings(ctx, userconfig, watch, short, compact, n, all_, twolines, leaderbo ...@@ -99,21 +101,25 @@ def meetings(ctx, userconfig, watch, short, compact, n, all_, twolines, leaderbo
config = init_config(userconfig) config = init_config(userconfig)
config.filter_endpoints(endpoint) config.filter_endpoints(endpoint)
# Load is none if it doesn't work
load = read_load(read_load_from)
if watch is not None: if watch is not None:
while watch is not None: while watch is not None:
try: try:
if twolines: if twolines:
meetings_twolines(config, watch, fancy, sum_) meetings_twolines(config, watch, fancy, sum_, load)
else: else:
list_meetings(config, leaderboards, n, participants, presenter, presenter_id, meetings, watch, fancy, compact, sum_) list_meetings(config, leaderboards, n, participants, presenter, presenter_id, meetings, watch, fancy, compact, sum_, load)
time.sleep(watch) time.sleep(watch)
except KeyboardInterrupt: except KeyboardInterrupt:
sys.exit() sys.exit()
else: else:
if twolines: if twolines:
meetings_twolines(config, watch, fancy, sum_) meetings_twolines(config, watch, fancy, sum_, load)
else: else:
list_meetings(config, leaderboards, n, participants, presenter, presenter_id, meetings, watch, fancy, compact, sum_) list_meetings(config, leaderboards, n, participants, presenter, presenter_id, meetings, watch, fancy, compact, sum_, load)
......
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import sys
import re
import requests
from typing import Optional
from bbbmon.printing import eprint
LOAD_PATTERN = re.compile(r"(?!\d+\.\d+[\./])\d+\.\d+")
def read_load(read_load_from: Optional[str]) -> Optional[float]:
"""
Read the load either from a file or a url depending on the input. Return None if anything fails.
This matches all floats in the given file/url and returns the average
"""
if read_load_from is None:
return None
text = ""
if read_load_from.lower().startswith(("http")):
try:
r = requests.get(read_load_from, timeout=3)
text = r.text
except:
eprint("Error: Ignored load - Couldn't read load from {}: Response was: {}".format(read_load_from, r))
return None
else:
if os.path.isfile(read_load_from):
with open(read_load_from, "r", encoding="utf-8") as f:
text = f.read()
else:
eprint("Error: Ignored load - Couldn't read load from {}: Not a file or not readable".format(read_load_from))
return None
text = text.strip()
if text == "":
eprint("Error: Ignored load - Couldn't read load from {}: The file was empty".format(read_load_from))
return None
matches = re.findall(LOAD_PATTERN, text)
if matches is None:
eprint("Error: Ignored load - Couldn't read load from {}: No float values found".format(read_load_from))
return None
elif len(matches) == 0:
eprint("Error: Ignored load - Couldn't read load from {}: No float values found".format(read_load_from))
return None
else:
return sum([float(m) for m in matches]) / float(len(matches))
\ No newline at end of file
...@@ -143,7 +143,7 @@ def get_duration(meeting: XmlDictConfig) -> timedelta: ...@@ -143,7 +143,7 @@ def get_duration(meeting: XmlDictConfig) -> timedelta:
return duration return duration
def list_meetings(config: Config, leaderboards: bool, n: int, participants: bool, presenter: bool, presenter_id: bool, show_meetings: bool, watch: int, fancy: bool, compact: bool, sum_:bool): def list_meetings(config: Config, leaderboards: bool, n: int, participants: bool, presenter: bool, presenter_id: bool, show_meetings: bool, watch: int, fancy: bool, compact: bool, sum_:bool, load: Optional[float]):
""" """
For each endpoint in the configuration get the active meetings and print For each endpoint in the configuration get the active meetings and print
out an overview of the current bbb-usage out an overview of the current bbb-usage
...@@ -163,6 +163,10 @@ def list_meetings(config: Config, leaderboards: bool, n: int, participants: bool ...@@ -163,6 +163,10 @@ def list_meetings(config: Config, leaderboards: bool, n: int, participants: bool
if watch is not None: if watch is not None:
click.clear() click.clear()
# Average load
if load is not None:
print("Average load is: {:04.2f}".format(load))
for i, endpoint in enumerate(config_override.endpoints): for i, endpoint in enumerate(config_override.endpoints):
# Print divider if there is more than one endpoint # Print divider if there is more than one endpoint
...@@ -270,7 +274,7 @@ def sum_meetings(config: Config, meetings: Optional[XmlDictConfig]) -> Optiona ...@@ -270,7 +274,7 @@ def sum_meetings(config: Config, meetings: Optional[XmlDictConfig]) -> Optiona
def meetings_twolines(config: Config, watch: int, fancy: bool, sum_:bool): def meetings_twolines(config: Config, watch: int, fancy: bool, sum_:bool, load: Optional[float]):
""" """
For each endpoint in the configuration get the active meetings and print For each endpoint in the configuration get the active meetings and print
out an overview of the current bbb-usage. This is guaranteed to fit within out an overview of the current bbb-usage. This is guaranteed to fit within
...@@ -349,7 +353,7 @@ def meetings_twolines(config: Config, watch: int, fancy: bool, sum_:bool): ...@@ -349,7 +353,7 @@ def meetings_twolines(config: Config, watch: int, fancy: bool, sum_:bool):
avg_s = avg_s/60./60. avg_s = avg_s/60./60.
if not fancy: if not fancy:
if config_override.on_server: if config_override.on_server and load is None:
# If on server get load # If on server get load
w = subprocess.run(["w | head -1"], shell=True, stdout=subprocess.PIPE) w = subprocess.run(["w | head -1"], shell=True, stdout=subprocess.PIPE)
w = w.stdout.decode('utf-8').strip().split("load average:") w = w.stdout.decode('utf-8').strip().split("load average:")
...@@ -366,6 +370,12 @@ def meetings_twolines(config: Config, watch: int, fancy: bool, sum_:bool): ...@@ -366,6 +370,12 @@ def meetings_twolines(config: Config, watch: int, fancy: bool, sum_:bool):
"stats {:>2} / {:<2} {:>3} {:>3} {:>3} {:>3} {:>3} {:.1f}"\ "stats {:>2} / {:<2} {:>3} {:>3} {:>3} {:>3} {:>3} {:.1f}"\
.format(n_recording, n_running, n_participants, n_moderator, n_video, n_voice, n_listeners, w) .format(n_recording, n_running, n_participants, n_moderator, n_video, n_voice, n_listeners, w)
] ]
elif load is not None:
lines = [
"{} rec / ses ppl mod vid mic ear lod".format(endpoint.name[:3]),
"stats {:>2} / {:<2} {:>3} {:>3} {:>3} {:>3} {:>3} {:.1f}"\
.format(n_recording, n_running, n_participants, n_moderator, n_video, n_voice, n_listeners, load)
]
else: else:
lines = [ lines = [
"{} rec / ses ppl mod vid mic ear".format(endpoint.name[:3]), "{} rec / ses ppl mod vid mic ear".format(endpoint.name[:3]),
......
[tool.poetry] [tool.poetry]
name = "bbbmon" name = "bbbmon"
version = "0.1.31" version = "0.1.32"
description = "A small CLI utility to monitor bbb usage" description = "A small CLI utility to monitor bbb usage"
authors = ["David Huss <david.huss@hfbk-hamburg.de>"] authors = ["David Huss <david.huss@hfbk-hamburg.de>"]
maintainers = ["David Huss <david.huss@hfbk-hamburg.de>"] maintainers = ["David Huss <david.huss@hfbk-hamburg.de>"]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment