conference-stats/jitsi-log.py

224 lines
6.6 KiB
Python
Raw Normal View History

2020-06-14 15:52:08 +02:00
#!/bin/env python3
#
import re
import sys
import threading
import time
from time import sleep
from os.path import basename
from datetime import datetime
from argparse import ArgumentParser
from http.server import BaseHTTPRequestHandler, HTTPServer
try:
from pygtail import Pygtail
except ImportError as e:
print('[Error] Please install pygtail via pip! {}'.format(e))
sys.exit(1)
try:
from sh import tail
except ImportError as e:
print('[Error] Please install sh via pip! {}'.format(e))
sys.exit(1)
class MeetingRoom():
"""
represent a Jitsi Meetingroom
jid: eg room@conference.meet.leinelab.org
ctime: eg 2020-06-01 12:32:02 ..
"""
members = []
def __init__(self, jid, ctime):
self.jid = jid
self.ctime = ctime
def setOwner(self, name):
self.owner = name
def getOwner(self):
if hasattr(self, 'owner'):
return self.owner
else:
return None
def addMember(self, name):
self.members.append(name)
def getMembers(self):
return self.members
def __str__(self):
return '{}: {}'.format(self.jid, self.owner)
class logThread(threading.Thread):
def __init__(self, threadID, name, filename):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.filename = filename
def run(self):
while True:
getLogMsg(self.filename)
sleep(5)
class MyServer(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
self.wfile.write(bytes("<html><head><title>Jitsi Stats</title></head>", "utf-8"))
self.wfile.write(bytes("<p>Request: %s</p>" % self.path, "utf-8"))
self.wfile.write(bytes("<body>", "utf-8"))
self.wfile.write(bytes("<p>This is an example web server.</p>", "utf-8"))
if basename(self.path) in roomList:
self.wfile.write(bytes("<p>"+basename(self.path)+": "+str(roomList[basename(self.path)].ctime)+"</p>", "utf-8"))
self.wfile.write(bytes("<p> Participants: "+str(len(roomList[basename(self.path)].members))+"</p>", "utf-8"))
else:
for key, value in roomList.items():
link = '<p><a href="{}">{}</a></p>'.format(value.jid, key)
self.wfile.write(bytes(link, "utf-8"))
self.wfile.write(bytes("</body></html>", "utf-8"))
def getRoomName(jid):
return jid.split("@")[0].strip()
def mkDatetime(str_date, str_time):
return datetime.fromisoformat('{} {}'.format(str_date, str_time))
# active room dictionary
roomList = {}
testList = {
'test': 'Nichts wichtiges',
'lounge': 'lounge@meet.leinelab.de'
}
# @see https://regex101.com/r/R1B1OL/1
regex = r"(Jicofo)\s(\d+-\d+-\d+)\s(\d+\:\d+\:\d+\.\d+)\s(\w+):\s\[(\d+)\]\s(.*)\(\)\s(.*)"
prog = re.compile(regex)
##
# new jitsi room
room_regex = r"(^Joining\sthe\sroom):(.*)"
room = re.compile(room_regex)
# disposed room
disposed_regex = r"^Disposed\sconference\sfor\sroom\:\s(.*)@(.*)\sconference\scount:\s(\d+)"
disposed = re.compile(disposed_regex)
##
# get the room owner
owner_regex = r"Granted\sowner\sto\s([a-z0-9-]+)\@(.*)\/(.*)"
owner = re.compile(owner_regex)
# get member for room
member_regex = r"^Member\s(.*)@(.*)\/(.*)\sjoined."
member = re.compile(member_regex)
def process_line(line):
"""
process a logfile line, using global object and vars
globals: prog, disposed, owner, member, roomList
line: string
"""
erg = prog.match(line)
if erg:
# detect room creation
new_room = room.match(erg.group(7))
if new_room:
room_name = getRoomName(new_room.group(2))
room_date = mkDatetime(erg.group(2), erg.group(3))
print('{} {}'.format(room_date, room_name))
currentRoom = MeetingRoom(room_name, room_date)
if room_name in roomList:
# delete old room and recreate it
del roomList[room_name]
roomList[room_name] = currentRoom
else:
roomList[room_name] = currentRoom
disposed_room = disposed.match(erg.group(7))
if disposed_room:
room_name = disposed_room.group(1)
print('-> room disposed: {}'.format(room_name))
if room_name in roomList:
del roomList[room_name]
owner_match = owner.match(erg.group(7))
if owner_match:
room_name = owner_match.group(1).strip()
room_owner = owner_match.group(3).strip()
# print('{}: {}'.format(room_name, room_owner))
if room_name in roomList:
roomList[room_name].setOwner(room_owner)
member_match = member.match(erg.group(7))
if member_match:
room_name = member_match.group(1).strip()
room_member = member_match.group(3).strip()
print('--> {}: {}'.format(room_name, room_member))
if room_name in roomList:
roomList[room_name].addMember(room_member)
def getLogMsg(logfile):
"""
get log messages and commit it to process_line
used pytail module
"""
# for line in Pygtail(logfile, full_lines=True):
# process_line(line)
for line in tail("-f", logfile, _iter=True):
process_line(line)
if __name__ == '__main__':
# start cmdline processing
parser = ArgumentParser(description='Jitsi Meet Conference Stats')
parser.add_argument('--log', '-l',
help='full path to jicofo logfile eg. /var/log/jitsi/jicofo.log')
parser.add_argument('--verbose', '-v',
help='be verbose eg. for debugging', action='store_true')
parser.add_argument('--logwatch', '-w',
help='run as logwatch module, dont start the webserver and only run once')
args = parser.parse_args()
if args.log:
try:
loggerThread = logThread(1, "Thread-Logger", args.log)
loggerThread.start()
except:
print('Error: unable to start threads')
hostName = 'localhost'
serverPort = 9999
webServer = HTTPServer((hostName, serverPort), MyServer)
try:
print("Server started http://%s:%s" % (hostName, serverPort))
webServer.serve_forever()
except:
pass
# for key in roomList:
# print('Room : {}'.format(roomList[key].jid))
# print(' Created: {}'.format(roomList[key].ctime))
# print(' Owner : {}'.format(roomList[key].getOwner()))
# print(' Members: {}'.format(roomList[key].getMembers()))