mirror of
https://codeberg.org/langfingaz/bbb-status
synced 2024-11-23 20:39:33 +01:00
override logging interval with secret/minutes.txt
This commit is contained in:
parent
ac28f77543
commit
724a9c1d1d
@ -5,7 +5,7 @@
|
|||||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="jdk" jdkName="Python 3.9 (venv-39)" jdkType="Python SDK" />
|
<orderEntry type="jdk" jdkName="Python 3.10 (venv-310)" jdkType="Python SDK" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
</component>
|
</component>
|
||||||
<component name="PackageRequirementsSettings">
|
<component name="PackageRequirementsSettings">
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9 (venv-39)" project-jdk-type="Python SDK" />
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (venv-310)" project-jdk-type="Python SDK" />
|
||||||
</project>
|
</project>
|
18
README.md
18
README.md
@ -1,13 +1,15 @@
|
|||||||
# README
|
# bbb-status
|
||||||
|
|
||||||
|
Python3 script to log and plot BigBlueButton usage statistics.
|
||||||
|
|
||||||
Thanks to Bernd Wurst who inspired this project with his gist on github:
|
Thanks to Bernd Wurst who inspired this project with his gist on github:
|
||||||
* https://gist.github.com/bwurst/7f94e0392c75d273a08d1e686182fc5e
|
* [https://gist.github.com/bwurst/7f94e0392c75d273a08d1e686182fc5e]()
|
||||||
|
|
||||||
## setup
|
## Setup
|
||||||
|
|
||||||
Execute `bbb-conf --secret` on your server.
|
Execute `bbb-conf --secret` on your server.
|
||||||
|
|
||||||
This gives you your **API-secret**, the **URL** at which BigBlueButton is running at.
|
This gives you your **API-secret** and the **URL** at which BigBlueButton is running at.
|
||||||
|
|
||||||
Save these two values in the first line of the following files:
|
Save these two values in the first line of the following files:
|
||||||
|
|
||||||
@ -16,7 +18,9 @@ Save these two values in the first line of the following files:
|
|||||||
|
|
||||||
Note: You may `chmod 600` on the two above files.
|
Note: You may `chmod 600` on the two above files.
|
||||||
|
|
||||||
## run
|
Optionally: Set the log interval to something different from 5 minutes by creating `secret/minutes.txt` with an integer in the first line.
|
||||||
|
|
||||||
|
## Run
|
||||||
|
|
||||||
Start logging in the background:
|
Start logging in the background:
|
||||||
|
|
||||||
@ -30,7 +34,7 @@ Generate a new plot based on saved meeting data:
|
|||||||
sudo docker-compose run bbb-status plot
|
sudo docker-compose run bbb-status plot
|
||||||
```
|
```
|
||||||
|
|
||||||
## example logging
|
## Example - log meeting statistics
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
sudo docker-compose up -d # start logging in the background
|
sudo docker-compose up -d # start logging in the background
|
||||||
@ -53,6 +57,6 @@ bbb-status_1 | moderatorCount: 1
|
|||||||
bbb-status_1 | >> Sleeping for five minutes <<
|
bbb-status_1 | >> Sleeping for five minutes <<
|
||||||
```
|
```
|
||||||
|
|
||||||
## example plot
|
## Example - create a plot from saved statistics
|
||||||
|
|
||||||
![plot of one month BBB usage](plot-last-month.png)
|
![plot of one month BBB usage](plot-last-month.png)
|
||||||
|
@ -73,7 +73,7 @@ def getRequestUrl(api_method: str = 'getMeetings', query_string: str = '') -> st
|
|||||||
|
|
||||||
|
|
||||||
def getUrl() -> str:
|
def getUrl() -> str:
|
||||||
filepath = fileUtil.getProjectBaseDir().joinpath("secret").joinpath("url.txt")
|
filepath = fileUtil.getProjectBaseDir() / "secret" / "url.txt"
|
||||||
url = fileUtil.readFirstLine(filepath).strip()
|
url = fileUtil.readFirstLine(filepath).strip()
|
||||||
if not url.endswith("/"):
|
if not url.endswith("/"):
|
||||||
raise ValueError("url should end with '/'")
|
raise ValueError("url should end with '/'")
|
||||||
@ -81,9 +81,16 @@ def getUrl() -> str:
|
|||||||
|
|
||||||
|
|
||||||
def getSecret() -> str:
|
def getSecret() -> str:
|
||||||
filepath = fileUtil.getProjectBaseDir().joinpath("secret").joinpath("secret.txt")
|
filepath = fileUtil.getProjectBaseDir() / "secret" / "secret.txt"
|
||||||
secret = fileUtil.readFirstLine(filepath).strip()
|
secret = fileUtil.readFirstLine(filepath).strip()
|
||||||
min_length = 12
|
min_length = 12
|
||||||
if len(secret) <= min_length:
|
if len(secret) <= min_length:
|
||||||
raise ValueError("secret should be longer than {} characters!".format(min_length))
|
raise ValueError(f"secret should be longer than {min_length} characters!")
|
||||||
return secret
|
return secret
|
||||||
|
|
||||||
|
|
||||||
|
def getSleepMinutes() -> int:
|
||||||
|
filepath = fileUtil.getProjectBaseDir() / "secret" / "minutes.txt"
|
||||||
|
if not filepath.exists():
|
||||||
|
return 5
|
||||||
|
return int(fileUtil.readFirstLine(filepath).strip())
|
||||||
|
@ -1,21 +1,19 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
|
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from langfingaz import parseMeetings, bbbRequest, saveData
|
from langfingaz import parseMeetings, bbbRequest, saveData
|
||||||
|
from langfingaz.bbbRequest import getSleepMinutes
|
||||||
from langfingaz.util import util as util
|
from langfingaz.util import util as util
|
||||||
import langfingaz.util.fileUtil as fileUtil
|
import langfingaz.util.fileUtil as fileUtil
|
||||||
|
|
||||||
|
|
||||||
def sleepFiveMin(verbose=False):
|
def sleepMinutes(verbose=False):
|
||||||
minute = 60
|
minutes = getSleepMinutes()
|
||||||
fiveMinutes = 5 * minute
|
seconds = minutes * 60
|
||||||
|
|
||||||
if verbose:
|
if verbose:
|
||||||
print(">> Sleeping for five minutes <<")
|
print(f">> Sleeping for {minutes} minutes <<")
|
||||||
util.sleep(fiveMinutes)
|
util.sleep(seconds)
|
||||||
|
|
||||||
|
|
||||||
def v2(folder: Path = fileUtil.getDataDir()):
|
def v2(folder: Path = fileUtil.getDataDir()):
|
||||||
@ -24,21 +22,21 @@ def v2(folder: Path = fileUtil.getDataDir()):
|
|||||||
while True:
|
while True:
|
||||||
meetingsStr = bbbRequest.requestMeetingData()
|
meetingsStr = bbbRequest.requestMeetingData()
|
||||||
savedFile = saveData.saveMeetingsData(meetingsStr, folder)
|
savedFile = saveData.saveMeetingsData(meetingsStr, folder)
|
||||||
print("Saved meetings at {}".format(savedFile))
|
print(f"Saved meetings at {savedFile}")
|
||||||
|
|
||||||
meetings = parseMeetings.parseMeetingsData(meetingsStr)
|
meetings = parseMeetings.parseMeetingsData(meetingsStr)
|
||||||
bbbStatus = parseMeetings.BbbStatus(meetings)
|
bbbStatus = parseMeetings.BbbStatus(meetings)
|
||||||
bbbStatusStr = str(bbbStatus)
|
bbbStatusStr = str(bbbStatus)
|
||||||
print(util.indentMultilineStr(bbbStatusStr))
|
print(util.indentMultilineStr(bbbStatusStr))
|
||||||
|
|
||||||
sleepFiveMin(verbose=True)
|
sleepMinutes(verbose=True)
|
||||||
|
|
||||||
|
|
||||||
def v1(folder: Path = fileUtil.getDataDir()):
|
def v1(folder: Path = fileUtil.getDataDir()):
|
||||||
while True:
|
while True:
|
||||||
saveData.requestAndSaveMeetingData(folder)
|
saveData.requestAndSaveMeetingData(folder)
|
||||||
print('.')
|
print('.')
|
||||||
sleepFiveMin()
|
sleepMinutes()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
@ -14,7 +14,7 @@ from langfingaz.util import util
|
|||||||
|
|
||||||
|
|
||||||
def getDefaultPlotFolder() -> Path:
|
def getDefaultPlotFolder() -> Path:
|
||||||
return fileUtil.getProjectBaseDir().joinpath("plot")
|
return fileUtil.getProjectBaseDir() / "plot"
|
||||||
|
|
||||||
|
|
||||||
def plotMeetings(dataDir: Path = fileUtil.getDataDir()):
|
def plotMeetings(dataDir: Path = fileUtil.getDataDir()):
|
||||||
@ -81,7 +81,7 @@ def doPlotMeetings(bbbStati: List[BbbStatus]) -> Path:
|
|||||||
fig.autofmt_xdate()
|
fig.autofmt_xdate()
|
||||||
|
|
||||||
imgFormat = 'png'
|
imgFormat = 'png'
|
||||||
image: Path = getDefaultPlotFolder().joinpath(
|
image: Path = getDefaultPlotFolder() / (
|
||||||
"{}_until_{}.{}".format(
|
"{}_until_{}.{}".format(
|
||||||
fileUtil.asString(time[0]),
|
fileUtil.asString(time[0]),
|
||||||
fileUtil.asString(time[-1]),
|
fileUtil.asString(time[-1]),
|
||||||
|
@ -39,7 +39,7 @@ def doSaveData(dataStr: str, folder: Path, dataType: str) -> Path:
|
|||||||
:return: Path to created file
|
:return: Path to created file
|
||||||
"""
|
"""
|
||||||
|
|
||||||
fileWithoutDate = folder.joinpath(dataType + '.xml')
|
fileWithoutDate = folder / f"{dataType}.xml"
|
||||||
prefixedFile = fileUtil.setDatetimePrefix(fileWithoutDate, datetime.now())
|
prefixedFile = fileUtil.setDatetimePrefix(fileWithoutDate, datetime.now())
|
||||||
|
|
||||||
with open(prefixedFile, "w") as xml_file:
|
with open(prefixedFile, "w") as xml_file:
|
||||||
|
@ -15,7 +15,7 @@ def getDataDir() -> Path:
|
|||||||
"""
|
"""
|
||||||
:return: The default data directory
|
:return: The default data directory
|
||||||
"""
|
"""
|
||||||
return getProjectBaseDir().joinpath("data")
|
return getProjectBaseDir() / "data"
|
||||||
|
|
||||||
|
|
||||||
def readFirstLine(file: Path) -> str:
|
def readFirstLine(file: Path) -> str:
|
||||||
@ -39,14 +39,14 @@ def setDatetimePrefix(file: Path, t: datetime) -> Path:
|
|||||||
# filename = file.name
|
# filename = file.name
|
||||||
prefix = asString(t)
|
prefix = asString(t)
|
||||||
filename = prefix + "_" + file.name
|
filename = prefix + "_" + file.name
|
||||||
return file.parent.joinpath(filename)
|
return file.parent / filename
|
||||||
|
|
||||||
|
|
||||||
def removeDatetimePrefix(file: Path) -> Path:
|
def removeDatetimePrefix(file: Path) -> Path:
|
||||||
prefixLen = __getDatetimePrefixLength()
|
prefixLen = __getDatetimePrefixLength()
|
||||||
|
|
||||||
# prefixlen + 1 to remove the underline!
|
# prefixlen + 1 to remove the underline!
|
||||||
return file.parent.joinpath(file.name[prefixLen + 1:])
|
return file.parent / file.name[prefixLen + 1:]
|
||||||
|
|
||||||
|
|
||||||
def getDatetimePrefix(file: Path) -> datetime:
|
def getDatetimePrefix(file: Path) -> datetime:
|
||||||
|
Loading…
Reference in New Issue
Block a user