def getLogs(cls, appname, count, hostname=None, db=None): db = DBCache(db) if hostname is None: hostname = db.gethostname() with db as cursor: cursor.execute( """SELECT DISTINCT pid FROM logging WHERE application=? AND host=? ORDER BY id DESC;""", (appname, hostname)) try: instances = zip(*cursor.fetchall())[0] except IndexError: print "No logs found on system profile." sys.exit(1) if count == -1: count = len(instances) else: count = min(count, len(instances)) for pid in instances[0:count]: yield list( cls._fromQuery( """WHERE application=? AND host=? AND pid=? ORDER BY id;""", (appname, hostname, pid)))
def getLogs(cls, appname, count, hostname=None, db=None): db = DBCache(db) if hostname is None: hostname = db.gethostname() with db as cursor: cursor.execute("""SELECT DISTINCT pid FROM logging WHERE application=? AND host=? ORDER BY id DESC;""", (appname, hostname)) try: instances = zip(*cursor.fetchall())[0] except IndexError: print "No logs found on system profile." sys.exit(1) if count == -1: count = len(instances) else: count = min(count, len(instances)) for pid in instances[0:count]: yield list(cls._fromQuery("""WHERE application=? AND host=? AND pid=? ORDER BY id;""", (appname, hostname, pid)))
def getAppNames(cls, hostname=None, db=None): app = namedtuple('Application', ['name', 'count']) db = DBCache(db) if hostname is None: hostname = db.gethostname() with db as cursor: cursor.execute("""SELECT application, count(1) FROM (SELECT DISTINCT application, pid FROM logging WHERE host=?) AS `pids` GROUP BY application;""", (hostname,)) for row in cursor: yield app(*row)
def getAppNames(cls, hostname=None, db=None): app = namedtuple('Application', ['name', 'count']) db = DBCache(db) if hostname is None: hostname = db.gethostname() with db as cursor: cursor.execute( """SELECT application, count(1) FROM (SELECT DISTINCT application, pid FROM logging WHERE host=?) AS `pids` GROUP BY application;""", (hostname, )) for row in cursor: yield app(*row)
class BECache(object): """ BECache(backend=None, noshutdown=False, db=None) -> MythBackend connection object Basic class for mythbackend socket connections. Offers connection caching to prevent multiple connections. 'backend' allows a hostname or IP address to connect to. If not provided, connect will be made to the master backend. Port is always taken from the database. 'db' allows an existing database object to be supplied. 'noshutdown' specified whether the backend will be allowed to go into automatic shutdown while the connection is alive. Available methods: backendCommand() - Sends a formatted command to the backend and returns the response. """ class _ConnHolder(object): blockshutdown = 0 command = None event = None logmodule = 'Python Backend Connection' _shared = weakref.WeakValueDictionary() _reip = re.compile('(?:\d{1,3}\.){3}\d{1,3}') def __repr__(self): return "<%s 'myth://%s:%d/' at %s>" % \ (str(self.__class__).split("'")[1].split(".")[-1], self.hostname, self.port, hex(id(self))) def __init__(self, backend=None, blockshutdown=False, events=False, db=None): self.db = DBCache(db) self.log = MythLog(self.logmodule, db=self.db) self.hostname = None self.sendcommands = True self.blockshutdown = blockshutdown self.receiveevents = events if backend is None: # no backend given, use master self.host = self.db.settings.NULL.MasterServerIP self.hostname = self.db._gethostfromaddr(self.host) else: backend = backend.strip('[]') query = "SELECT hostname FROM settings WHERE value=? AND data=?" if self._reip.match(backend): # given backend is IP address self.host = backend self.hostname = self.db._gethostfromaddr( backend, 'BackendServerIP') elif check_ipv6(backend): # given backend is IPv6 address self.host = backend self.hostname = self.db._gethostfromaddr( backend, 'BackendServerIP6') else: # given backend is hostname, pull address from database self.hostname = backend self.host = self.db._getpreferredaddr(backend) # lookup port from database self.port = int(self.db.settings[self.hostname].BackendServerPort) if not self.port: raise MythDBError(MythError.DB_SETTING, 'BackendServerPort', self.port) self._ident = '%s:%d' % (self.host, self.port) if self._ident in self._shared: # existing connection found self._conn = self._shared[self._ident] if self.sendcommands: if self._conn.command is None: self._conn.command = self._newcmdconn() elif self.blockshutdown: # upref block of shutdown # issue command to backend if needed self._conn.blockshutdown += 1 if self._conn.blockshutdown == 1: self._conn.command.blockShutdown() if self.receiveevents: if self._conn.event is None: self._conn.event = self._neweventconn() else: # no existing connection, create new self._conn = self._ConnHolder() if self.sendcommands: self._conn.command = self._newcmdconn() if self.blockshutdown: self._conn.blockshutdown = 1 if self.receiveevents: self._conn.event = self._neweventconn() self._shared[self._ident] = self._conn self._events = self._listhandlers() for func in self._events: self.registerevent(func) def __del__(self): # downref block of shutdown # issue command to backend if needed #print 'destructing BECache' if self.blockshutdown: self._conn.blockshutdown -= 1 if not self._conn.blockshutdown: self._conn.command.unblockShutdown() def _newcmdconn(self): return BEConnection(self.host, self.port, self.db.gethostname(), self.blockshutdown) def _neweventconn(self): return BEEventConnection(self.host, self.port, self.db.gethostname()) def backendCommand(self, data): """ obj.backendCommand(data) -> response string Sends a formatted command via a socket to the mythbackend. """ if self._conn.command is None: return "" return self._conn.command.backendCommand(data) def _listhandlers(self): return [] def registerevent(self, func, regex=None): if self._conn.event is None: return if regex is None: regex = func() self._conn.event.registerevent(regex, func) def clearevents(self): self._events = []
class BECache( object ): """ BECache(backend=None, noshutdown=False, db=None) -> MythBackend connection object Basic class for mythbackend socket connections. Offers connection caching to prevent multiple connections. 'backend' allows a hostname or IP address to connect to. If not provided, connect will be made to the master backend. Port is always taken from the database. 'db' allows an existing database object to be supplied. 'noshutdown' specified whether the backend will be allowed to go into automatic shutdown while the connection is alive. Available methods: backendCommand() - Sends a formatted command to the backend and returns the response. """ class _ConnHolder( object ): blockshutdown = 0 command = None event = None logmodule = 'Python Backend Connection' _shared = weakref.WeakValueDictionary() _reip = re.compile('(?:\d{1,3}\.){3}\d{1,3}') def __repr__(self): return "<%s 'myth://%s:%d/' at %s>" % \ (str(self.__class__).split("'")[1].split(".")[-1], self.hostname, self.port, hex(id(self))) def __init__(self, backend=None, blockshutdown=False, events=False, db=None): self.db = DBCache(db) self.log = MythLog(self.logmodule, db=self.db) self.hostname = None self.sendcommands = True self.blockshutdown = blockshutdown self.receiveevents = events if backend is None: # no backend given, use master self.host = self.db.settings.NULL.MasterServerIP self.hostname = self.db._gethostfromaddr(self.host) else: backend = backend.strip('[]') query = "SELECT hostname FROM settings WHERE value=? AND data=?" if self._reip.match(backend): # given backend is IP address self.host = backend self.hostname = self.db._gethostfromaddr( backend, 'BackendServerIP') elif check_ipv6(backend): # given backend is IPv6 address self.host = backend self.hostname = self.db._gethostfromaddr( backend, 'BackendServerIP6') else: # given backend is hostname, pull address from database self.hostname = backend self.host = self.db._getpreferredaddr(backend) # lookup port from database self.port = int(self.db.settings[self.hostname].BackendServerPort) if not self.port: raise MythDBError(MythError.DB_SETTING, 'BackendServerPort', self.port) self._ident = '%s:%d' % (self.host, self.port) if self._ident in self._shared: # existing connection found self._conn = self._shared[self._ident] if self.sendcommands: if self._conn.command is None: self._conn.command = self._newcmdconn() elif self.blockshutdown: # upref block of shutdown # issue command to backend if needed self._conn.blockshutdown += 1 if self._conn.blockshutdown == 1: self._conn.command.blockShutdown() if self.receiveevents: if self._conn.event is None: self._conn.event = self._neweventconn() else: # no existing connection, create new self._conn = self._ConnHolder() if self.sendcommands: self._conn.command = self._newcmdconn() if self.blockshutdown: self._conn.blockshutdown = 1 if self.receiveevents: self._conn.event = self._neweventconn() self._shared[self._ident] = self._conn self._events = self._listhandlers() for func in self._events: self.registerevent(func) def __del__(self): # downref block of shutdown # issue command to backend if needed #print 'destructing BECache' if self.blockshutdown: self._conn.blockshutdown -= 1 if not self._conn.blockshutdown: self._conn.command.unblockShutdown() def _newcmdconn(self): return BEConnection(self.host, self.port, self.db.gethostname(), self.blockshutdown) def _neweventconn(self): return BEEventConnection(self.host, self.port, self.db.gethostname()) def backendCommand(self, data): """ obj.backendCommand(data) -> response string Sends a formatted command via a socket to the mythbackend. """ if self._conn.command is None: return "" return self._conn.command.backendCommand(data) def _listhandlers(self): return [] def registerevent(self, func, regex=None): if self._conn.event is None: return if regex is None: regex = func() self._conn.event.registerevent(regex, func) def clearevents(self): self._events = []