Merge pull request #196 from albertosottile/master
Allow collection of server statistical data
This commit is contained in:
commit
b3a7ed836c
@ -53,6 +53,7 @@ DIFFERENT_DURATION_THRESHOLD = 2.5
|
||||
PROTOCOL_TIMEOUT = 12.5
|
||||
RECONNECT_RETRIES = 999
|
||||
SERVER_STATE_INTERVAL = 1
|
||||
SERVER_STATS_SNAPSHOT_INTERVAL = 3600
|
||||
WARNING_OSD_MESSAGES_LOOP_INTERVAL = 1
|
||||
AUTOPLAY_DELAY = 3.0
|
||||
DO_NOT_RESET_POSITION_THRESHOLD = 1.0
|
||||
|
||||
@ -434,7 +434,8 @@ de = {
|
||||
"server-motd-argument": "Pfad zur Datei, von der die Nachricht des Tages geladen wird",
|
||||
"server-chat-argument": "Should chat be disabled?", # TODO: Translate
|
||||
"server-chat-maxchars-argument": "Maximum number of characters in a chat message (default is {})", # TODO: Translate
|
||||
"server-maxusernamelength-argument": "Maximum number of charactrs in a username (default is {})", # TODO: Translate
|
||||
"server-maxusernamelength-argument": "Maximum number of characters in a username (default is {})", # TODO: Translate
|
||||
"server-stats-db-file-argument": "Enable server stats using the SQLite db file provided", # TODO: Translate
|
||||
"server-messed-up-motd-unescaped-placeholders": "Die Nachricht des Tages hat unmaskierte Platzhalter. Alle $-Zeichen sollten verdoppelt werden ($$).",
|
||||
"server-messed-up-motd-too-long": "Die Nachricht des Tages ist zu lang - Maximal {} Zeichen, aktuell {}.",
|
||||
|
||||
|
||||
@ -437,8 +437,9 @@ en = {
|
||||
"server-disable-ready-argument": "disable readiness feature",
|
||||
"server-motd-argument": "path to file from which motd will be fetched",
|
||||
"server-chat-argument": "Should chat be disabled?",
|
||||
"server-chat-maxchars-argument": "Maximum number of characters in a chat message (default is {})", # Default number of characters
|
||||
"server-maxusernamelength-argument": "Maximum number of charactrs in a username (default is {})",
|
||||
"server-chat-maxchars-argument": "Maximum number of characters in a chat message (default is {})", # Default number of characters
|
||||
"server-maxusernamelength-argument": "Maximum number of characters in a username (default is {})",
|
||||
"server-stats-db-file-argument": "Enable server stats using the SQLite db file provided",
|
||||
"server-messed-up-motd-unescaped-placeholders": "Message of the Day has unescaped placeholders. All $ signs should be doubled ($$).",
|
||||
"server-messed-up-motd-too-long": "Message of the Day is too long - maximum of {} chars, {} given.",
|
||||
|
||||
|
||||
@ -437,8 +437,9 @@ it = {
|
||||
"server-disable-ready-argument": "disabilita la funzionalità \"pronto\"",
|
||||
"server-motd-argument": "percorso del file da cui verrà letto il messaggio del giorno",
|
||||
"server-chat-argument": "abilita o disabilita la chat",
|
||||
"server-chat-maxchars-argument": "Numero massimo di caratteri in un messaggio di chat (default è {})", # Default number of characters
|
||||
"server-maxusernamelength-argument": "Maximum number of charactrs in a username (default is {})", # TODO: Translate
|
||||
"server-chat-maxchars-argument": "Numero massimo di caratteri in un messaggio di chat (default è {})", # Default number of characters
|
||||
"server-maxusernamelength-argument": "Numero massimo di caratteri in un nome utente (default è {})",
|
||||
"server-stats-db-file-argument": "Abilita la raccolta dei dati statistici nel file SQLite indicato",
|
||||
"server-messed-up-motd-unescaped-placeholders": "Il messaggio del giorno ha dei caratteri non 'escaped'. Tutti i simboli $ devono essere doppi ($$).",
|
||||
"server-messed-up-motd-too-long": "Il messaggio del giorno è troppo lungo - numero massimo di caratteri è {}, {} trovati.",
|
||||
|
||||
|
||||
@ -440,9 +440,10 @@ ru = {
|
||||
"server-motd-argument": "путь к файлу, из которого будет извлекаться MOTD-сообщение",
|
||||
"server-chat-argument": "Should chat be disabled?", # TODO: Translate
|
||||
"server-chat-maxchars-argument": "Maximum number of characters in a chat message (default is {})", # TODO: Translate
|
||||
"server-maxusernamelength-argument": "Maximum number of charactrs in a username (default is {})", # TODO: Translate
|
||||
"server-messed-up-motd-unescaped-placeholders": "MOTD-сообщение содержит неэкранированные спец.символы. Все знаки $ должны быть продублированы ($$).",
|
||||
"server-messed-up-motd-too-long": "MOTD-сообщение слишком длинное: максимальная длина - {} символ(ов), текущая длина - {} символ(ов).",
|
||||
"server-maxusernamelength-argument": "Maximum number of characters in a username (default is {})", # TODO: Translate
|
||||
"server-stats-db-file-argument": "Enable server stats using the SQLite db file provided", # TODO: Translate
|
||||
"server-messed-up-motd-unescaped-placeholders" : "MOTD-сообщение содержит неэкранированные спец.символы. Все знаки $ должны быть продублированы ($$).",
|
||||
"server-messed-up-motd-too-long" : "MOTD-сообщение слишком длинное: максимальная длина - {} символ(ов), текущая длина - {} символ(ов).",
|
||||
|
||||
# Server errors
|
||||
"unknown-command-server-error": "Неизвестная команда: {}", # message
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
|
||||
import argparse
|
||||
import codecs
|
||||
import hashlib
|
||||
@ -7,6 +6,7 @@ import random
|
||||
import time
|
||||
from string import Template
|
||||
|
||||
from twisted.enterprise import adbapi
|
||||
from twisted.internet import task, reactor
|
||||
from twisted.internet.protocol import Factory
|
||||
|
||||
@ -18,11 +18,12 @@ from syncplay.utils import RoomPasswordProvider, NotControlledRoom, RandomString
|
||||
|
||||
|
||||
class SyncFactory(Factory):
|
||||
def __init__(self, password='', motdFilePath=None, isolateRooms=False, salt=None,
|
||||
def __init__(self, port='', password='', motdFilePath=None, isolateRooms=False, salt=None,
|
||||
disableReady=False, disableChat=False, maxChatMessageLength=constants.MAX_CHAT_MESSAGE_LENGTH,
|
||||
maxUsernameLength=constants.MAX_USERNAME_LENGTH):
|
||||
maxUsernameLength=constants.MAX_USERNAME_LENGTH, statsDbFile=None):
|
||||
self.isolateRooms = isolateRooms
|
||||
print(getMessage("welcome-server-notification").format(syncplay.version))
|
||||
self.port = port
|
||||
if password:
|
||||
password = hashlib.md5(password).hexdigest()
|
||||
self.password = password
|
||||
@ -39,6 +40,13 @@ class SyncFactory(Factory):
|
||||
self._roomManager = RoomManager()
|
||||
else:
|
||||
self._roomManager = PublicRoomManager()
|
||||
if statsDbFile is not None:
|
||||
self._statsDbHandle = DBManager(statsDbFile)
|
||||
self._statsRecorder = StatsRecorder(self._statsDbHandle, self._roomManager)
|
||||
statsDelay = 5*(int(self.port)%10 + 1)
|
||||
self._statsRecorder.startRecorder(statsDelay)
|
||||
else:
|
||||
self._statsDbHandle = None
|
||||
|
||||
def buildProtocol(self, addr):
|
||||
return SyncServerProtocol(self)
|
||||
@ -186,6 +194,55 @@ class SyncFactory(Factory):
|
||||
watcher.setPlaylistIndex(room.getName(), room.getPlaylistIndex())
|
||||
|
||||
|
||||
class StatsRecorder(object):
|
||||
def __init__(self, dbHandle, roomManager):
|
||||
self._dbHandle = dbHandle
|
||||
self._roomManagerHandle = roomManager
|
||||
|
||||
def startRecorder(self, delay):
|
||||
try:
|
||||
self._dbHandle.connect()
|
||||
reactor.callLater(delay, self._scheduleClientSnapshot)
|
||||
except:
|
||||
print("--- Error in initializing the stats database. Server Stats not enabled. ---")
|
||||
|
||||
def _scheduleClientSnapshot(self):
|
||||
self._clientSnapshotTimer = task.LoopingCall(self._runClientSnapshot)
|
||||
self._clientSnapshotTimer.start(constants.SERVER_STATS_SNAPSHOT_INTERVAL)
|
||||
|
||||
def _runClientSnapshot(self):
|
||||
try:
|
||||
snapshotTime = int(time.time())
|
||||
rooms = self._roomManagerHandle.exportRooms()
|
||||
for room in rooms.values():
|
||||
for watcher in room.getWatchers():
|
||||
self._dbHandle.addVersionLog(snapshotTime, watcher.getVersion())
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
class DBManager(object):
|
||||
def __init__(self, dbpath):
|
||||
self._dbPath = dbpath
|
||||
self._connection = None
|
||||
|
||||
def __del__(self):
|
||||
if self._connection is not None:
|
||||
self._connection.close()
|
||||
|
||||
def connect(self):
|
||||
self._connection = adbapi.ConnectionPool("sqlite3", self._dbPath, check_same_thread=False)
|
||||
self._createSchema()
|
||||
|
||||
def _createSchema(self):
|
||||
initQuery = 'create table if not exists clients_snapshots (snapshot_time integer, version string)'
|
||||
self._connection.runQuery(initQuery)
|
||||
|
||||
def addVersionLog(self, timestamp, version):
|
||||
content = (timestamp, version, )
|
||||
self._connection.runQuery("INSERT INTO clients_snapshots VALUES (?, ?)", content)
|
||||
|
||||
|
||||
class RoomManager(object):
|
||||
def __init__(self):
|
||||
self._rooms = {}
|
||||
@ -244,6 +301,9 @@ class RoomManager(object):
|
||||
while username.lower() in allnames:
|
||||
username += '_'
|
||||
return username
|
||||
|
||||
def exportRooms(self):
|
||||
return self._rooms
|
||||
|
||||
|
||||
class PublicRoomManager(RoomManager):
|
||||
@ -562,3 +622,4 @@ class ConfigurationGetter(object):
|
||||
self._argparser.add_argument('--motd-file', metavar='file', type=str, nargs='?', help=getMessage("server-motd-argument"))
|
||||
self._argparser.add_argument('--max-chat-message-length', metavar='maxChatMessageLength', type=int, nargs='?', help=getMessage("server-chat-maxchars-argument").format(constants.MAX_CHAT_MESSAGE_LENGTH))
|
||||
self._argparser.add_argument('--max-username-length', metavar='maxUsernameLength', type=int, nargs='?', help=getMessage("server-maxusernamelength-argument").format(constants.MAX_USERNAME_LENGTH))
|
||||
self._argparser.add_argument('--stats-db-file', metavar='file', type=str, nargs='?', help=getMessage("server-stats-db-file-argument"))
|
||||
|
||||
@ -22,11 +22,14 @@ if __name__ == '__main__':
|
||||
reactor.listenTCP(
|
||||
int(args.port),
|
||||
SyncFactory(
|
||||
args.port,
|
||||
args.password,
|
||||
args.motd_file,
|
||||
args.isolate_rooms,
|
||||
args.salt,
|
||||
args.disable_ready,
|
||||
args.disable_chat,
|
||||
args.max_chat_message_length))
|
||||
args.max_chat_message_length,
|
||||
args.max_username_length,
|
||||
args.stats_db_file))
|
||||
reactor.run()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user