bitbake: bitbake: Add ui event handlers filtering

Add functionality to allow UIs to update and change the types of events they
recieve. To do this we need to add a new command and also need to be able
to obtain the current event hander ID. In the case of xmlrpc, this is
straightforward, in the case of the process server we need to save the result
in a multiprocessing.Value() so we can retrive it. An excplit command
was added to the server API to facilitate this.

The same function can also be used to mask or unmask specific log messages,
allowing the UI to optionally differ from the standard set of message
filtering.

Based upon work by Cristiana Voicu <cristiana.voicu@intel.com>

(Bitbake rev: ba5a6c88785d9889d4172ec79937ac2a5555327e)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Richard Purdie 2013-08-23 16:16:50 +00:00
parent bfab986ccd
commit 69aab78dd8
5 changed files with 46 additions and 8 deletions

View File

@ -240,6 +240,13 @@ class CommandsSync:
name = params[0] name = params[0]
command.cooker.createConfigFile(name) command.cooker.createConfigFile(name)
def setEventMask(self, command, params):
handlerNum = params[0]
llevel = params[1]
debug_domains = params[2]
mask = params[3]
return bb.event.set_UIHmask(handlerNum, llevel, debug_domains, mask)
class CommandsAsync: class CommandsAsync:
""" """
A class of asynchronous commands A class of asynchronous commands

View File

@ -193,7 +193,7 @@ def register(name, handler, mask=[]):
else: else:
_handlers[name] = handler _handlers[name] = handler
if not mask: if not mask or '*' in mask:
_catchall_handlers[name] = True _catchall_handlers[name] = True
else: else:
for m in mask: for m in mask:
@ -225,7 +225,7 @@ class UIEventFilter(object):
self.update(None, level, debug_domains) self.update(None, level, debug_domains)
def update(self, eventmask, level, debug_domains): def update(self, eventmask, level, debug_domains):
self.eventmask = None self.eventmask = eventmask
self.stdlevel = level self.stdlevel = level
self.debug_domains = debug_domains self.debug_domains = debug_domains
@ -236,9 +236,20 @@ class UIEventFilter(object):
if event.name in self.debug_domains and event.levelno >= self.debug_domains[event.name]: if event.name in self.debug_domains and event.levelno >= self.debug_domains[event.name]:
return True return True
return False return False
# Implement other event masking here on self.eventmask eid = str(event.__class__)[8:-2]
if eid not in self.eventmask:
return False
return True return True
def set_UIHmask(handlerNum, level, debug_domains, mask):
if not handlerNum in _ui_handlers:
return False
if '*' in mask:
_ui_logfilters[handlerNum].update(None, level, debug_domains)
else:
_ui_logfilters[handlerNum].update(mask, level, debug_domains)
return True
def getName(e): def getName(e):
"""Returns the name of a class or class instance""" """Returns the name of a class or class instance"""
if getattr(e, "__name__", None) == None: if getattr(e, "__name__", None) == None:

View File

@ -37,8 +37,9 @@ from . import BitBakeBaseServer, BitBakeBaseServerConnection, BaseImplServer
logger = logging.getLogger('BitBake') logger = logging.getLogger('BitBake')
class ServerCommunicator(): class ServerCommunicator():
def __init__(self, connection): def __init__(self, connection, event_handle):
self.connection = connection self.connection = connection
self.event_handle = event_handle
def runCommand(self, command): def runCommand(self, command):
# @todo try/except # @todo try/except
@ -54,6 +55,8 @@ class ServerCommunicator():
except KeyboardInterrupt: except KeyboardInterrupt:
pass pass
def getEventHandle(self):
return self.event_handle.value
class EventAdapter(): class EventAdapter():
""" """
@ -84,11 +87,12 @@ class ProcessServer(Process, BaseImplServer):
self.keep_running = Event() self.keep_running = Event()
self.keep_running.set() self.keep_running.set()
self.event_handle = multiprocessing.Value("i")
def run(self): def run(self):
for event in bb.event.ui_queue: for event in bb.event.ui_queue:
self.event_queue.put(event) self.event_queue.put(event)
self.event_handle = bb.event.register_UIHhandler(self) self.event_handle.value = bb.event.register_UIHhandler(self)
bb.cooker.server_main(self.cooker, self.main) bb.cooker.server_main(self.cooker, self.main)
def main(self): def main(self):
@ -106,7 +110,7 @@ class ProcessServer(Process, BaseImplServer):
logger.exception('Running command %s', command) logger.exception('Running command %s', command)
self.event_queue.close() self.event_queue.close()
bb.event.unregister_UIHhandler(self.event_handle) bb.event.unregister_UIHhandler(self.event_handle.value)
self.command_channel.close() self.command_channel.close()
self.cooker.stop() self.cooker.stop()
self.idle_commands(.1) self.idle_commands(.1)
@ -147,7 +151,7 @@ class BitBakeProcessServerConnection(BitBakeBaseServerConnection):
self.procserver = serverImpl self.procserver = serverImpl
self.ui_channel = ui_channel self.ui_channel = ui_channel
self.event_queue = event_queue self.event_queue = event_queue
self.connection = ServerCommunicator(self.ui_channel) self.connection = ServerCommunicator(self.ui_channel, self.procserver.event_handle)
self.events = self.event_queue self.events = self.event_queue
def terminate(self): def terminate(self):

View File

@ -95,7 +95,8 @@ class BitBakeServerCommands():
""" """
s, t = _create_server(host, port) s, t = _create_server(host, port)
return bb.event.register_UIHhandler(s) self.event_handle = bb.event.register_UIHhandler(s)
return self.event_handle
def unregisterEventHandler(self, handlerNum): def unregisterEventHandler(self, handlerNum):
""" """
@ -109,6 +110,9 @@ class BitBakeServerCommands():
""" """
return self.cooker.command.runCommand(command, self.server.readonly) return self.cooker.command.runCommand(command, self.server.readonly)
def getEventHandle(self):
return self.event_handle
def terminateServer(self): def terminateServer(self):
""" """
Trigger the server to quit Trigger the server to quit

View File

@ -232,6 +232,15 @@ def _log_settings_from_server(server):
raise BaseException(error) raise BaseException(error)
return includelogs, loglines, consolelogfile return includelogs, loglines, consolelogfile
_evt_list = [ "bb.runqueue.runQueueExitWait", "bb.event.LogExecTTY", "logging.LogRecord",
"bb.build.TaskFailed", "bb.build.TaskBase", "bb.event.ParseStarted",
"bb.event.ParseProgress", "bb.event.ParseCompleted", "bb.event.CacheLoadStarted",
"bb.event.CacheLoadProgress", "bb.event.CacheLoadCompleted", "bb.command.CommandFailed",
"bb.command.CommandExit", "bb.command.CommandCompleted", "bb.cooker.CookerExit",
"bb.event.MultipleProviders", "bb.event.NoProvider", "bb.runqueue.sceneQueueTaskStarted",
"bb.runqueue.runQueueTaskStarted", "bb.runqueue.runQueueTaskFailed", "bb.runqueue.sceneQueueTaskFailed",
"bb.event.BuildBase", "bb.build.TaskStarted", "bb.build.TaskSucceeded", "bb.build.TaskFailedSilent"]
def main(server, eventHandler, params, tf = TerminalFilter): def main(server, eventHandler, params, tf = TerminalFilter):
includelogs, loglines, consolelogfile = _log_settings_from_server(server) includelogs, loglines, consolelogfile = _log_settings_from_server(server)
@ -262,6 +271,9 @@ def main(server, eventHandler, params, tf = TerminalFilter):
consolelog.setFormatter(conlogformat) consolelog.setFormatter(conlogformat)
logger.addHandler(consolelog) logger.addHandler(consolelog)
llevel, debug_domains = bb.msg.constructLogOptions()
server.runCommand(["setEventMask", server.getEventHandle(), llevel, debug_domains, _evt_list])
if not params.observe_only: if not params.observe_only:
params.updateFromServer(server) params.updateFromServer(server)
cmdline = params.parseActions() cmdline = params.parseActions()