from . import Version
Version.append ('$Revision: 95162 $')
del Version
import ktl
import os
import platform
import resource
import time
try:
import DFW
except ImportError:
DFW = None
# The stdiosvc configuration file is common to all keygrabber KTL services.
try:
reldir = os.environ['RELDIR']
except KeyError:
stdiosvc = None
else:
stdiosvc = os.path.join (reldir, 'data', 'keygrabber', 'stdiosvc.conf')
[docs]def startService (main):
''' If the configuration specifies a KTL service, start a DFW
backend instance to run the service.
'''
if DFW == None:
raise ImportError ('DFW module is not available')
service = main.config.get ('main', 'service')
if service == '':
return None
if stdiosvc == None:
raise RuntimeError ('$RELDIR is not set, cannot locate stdiosvc.conf')
setupKeywords.main = main
service = DFW.Service (service, stdiosvc, setupKeywords)
service['DISPSTA'].set ('ready')
return service
def setupKeywords (service):
main = setupKeywords.main
# The DFW.Keyword subclasses are created here so that they are only
# established when DFW is available.
class Disconnected (DFW.Keyword.String):
def read (self):
try:
services = ktl.cache ()
except TypeError:
# Not supported in this version of KTL Python.
self.period (None)
return ''
disconnected = []
names = services.keys ()
names = list (names)
names.sort ()
for name in names:
service = services[name]
if len (service.descriptors) == 0:
disconnected.append (name)
disconnected = ' '.join (disconnected)
return disconnected
class MemoryUsage (DFW.Keyword.Integer):
def read (self):
resources = resource.getrusage (resource.RUSAGE_SELF)
max_usage = resources.ru_maxrss
max_usage = str (max_usage)
return str (max_usage)
class ProcessorUsage (DFW.Keyword.Integer):
def __init__ (self, *args, **kwargs):
resources = resource.getrusage (resource.RUSAGE_SELF)
self.previous_usage = resources.ru_utime + resources.ru_stime
self.previous_time = time.time ()
DFW.Keyword.Integer.__init__ (self, *args, **kwargs)
def read (self):
resources = resource.getrusage (resource.RUSAGE_SELF)
current_usage = resources.ru_utime + resources.ru_stime
current_time = time.time ()
consumed = current_usage - self.previous_usage
elapsed = current_time - self.previous_time
self.previous_usage = current_usage
self.previous_time = current_time
if elapsed > 0:
usage_percent = 100 * consumed / elapsed
usage_percent = int (round (usage_percent))
elif consumed > 0:
usage_percent = 100
else:
usage_percent = 0
usage_percent = str (usage_percent)
return usage_percent
class RestartKeyword (DFW.Keyword.Boolean):
def __init__ (self, name, service, main):
self.main = main
DFW.Keyword.Boolean.__init__ (self, name, service)
def write (self, value):
if value == '1':
self.main.start.set ()
self.main.shutdown.set ()
class StopKeyword (DFW.Keyword.Boolean):
def __init__ (self, name, service, main):
self.main = main
DFW.Keyword.Boolean.__init__ (self, name, service)
def write (self, value):
if value == '1':
self.main.shutdown.set ()
class DistributorFunction (DFW.Keyword.Integer):
def __init__ (self, name, service, function):
self.function = function
DFW.Keyword.Integer.__init__ (self, name, service,
initial=0, period=1)
def read (self):
return str (self.function ())
class DistributorValue (DFW.Keyword.Integer):
def __init__ (self, name, service, main, attribute):
self.distributor = main.distributor
self.attribute = attribute
DFW.Keyword.Integer.__init__ (self, name, service,
initial=0, period=1)
def read (self):
return str (getattr (self.distributor, self.attribute))
class PendingDBWrites (DistributorFunction):
def __init__ (self, service, main):
name = 'PENDING_DB'
function = main.distributor.database.qsize
DistributorFunction.__init__ (self, name, service, function)
class PendingLogWrites (DistributorFunction):
def __init__ (self, service, main):
name = 'PENDING_LOG'
function = main.distributor.archive.qsize
DistributorFunction.__init__ (self, name, service, function)
class TotalInserts (DistributorValue):
def __init__ (self, service, main):
name = 'INSERTS'
attribute = 'insert_count'
DistributorValue.__init__ (self, name, service, main, attribute)
class TotalUpdates (DistributorValue):
def __init__ (self, service, main):
name = 'UPDATES'
attribute = 'update_count'
DistributorValue.__init__ (self, name, service, main, attribute)
# Administrivia keywords.
DFW.Keyword.Enumerated ('DISPSTA', service, 'initializing')
RestartKeyword ('DISPHUP', service, main)
StopKeyword ('DISPSTOP', service, main)
DFW.Keyword.Integer ('VERSION', service, main.version)
# The following keywords will remain static for the duration of
# this keygrabber's runtime.
hostname = main.config.get ('database', 'hostname')
database = main.config.get ('database', 'database')
DFW.Keyword.String ('DB_HOST', service, hostname)
DFW.Keyword.String ('DB_NAME', service, database)
DFW.Keyword.String ('RUNHOST', service, platform.node ())
keyword_count = 0
services = []
for name in main.services:
services.append (name)
excluded = main.exclude[name]
included = main.include[name]
if len (included) == 0:
keywords = main.services[name].list ()
else:
keywords = included
for keyword in keywords:
if keyword in excluded:
pass
else:
keyword_count += 1
services.sort ()
DFW.Keyword.Integer ('KEYWORDS', service, keyword_count)
DFW.Keyword.Integer ('SERVICE_COUNT', service, len (services))
DFW.Keyword.String ('SERVICES', service, ' '.join (services))
# This next body of keywords will update periodically with new
# values polled from keygrabber itself.
Disconnected ('DISCONNECTED', service, initial='', period=1)
MemoryUsage ('MEMORY', service, period=1)
ProcessorUsage ('PROCESSOR', service, period=1)
PendingDBWrites (service, main)
PendingLogWrites (service, main)
TotalInserts (service, main)
TotalUpdates (service, main)
# vim: set expandtab tabstop=8 softtabstop=4 shiftwidth=4 autoindent: