* [PATCH 0/5] Fix writing events to file
@ 2016-06-20 11:00 Ed Bartosh
2016-06-20 11:00 ` [PATCH 1/5] cooker: move EventLogWriteHandler to the top module level Ed Bartosh
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Ed Bartosh @ 2016-06-20 11:00 UTC (permalink / raw)
To: bitbake-devel
Hi,
This patchset fixes "object is not JSON serializable" error caused by attempt
to convert binary pickled event object to JSON when bitbake is called with
-w command line option.
It also fixes error caused writing the same event to the file multiple times and
refactoring of event writing functionality.
The following changes since commit 09d08340fe0fca6f551c33d2fdcafb72f52812d2:
Revert "cmake.bbclass: set the modules directory correctly" (2016-06-20 08:40:21 +0100)
are available in the git repository at:
git://git.yoctoproject.org/poky-contrib ed/bitbake/cooker-event-pickling-9803
http://git.yoctoproject.org/cgit.cgi/poky-contrib/log/?h=ed/bitbake/cooker-event-pickling-9803
Ed Bartosh (5):
cooker: move EventLogWriteHandler to the top module level
cooker: encode event objects to base64
cooker: don't remove event file
cooker: replace EventLogWriteHandler with namedtuple
cooker: clean up EvertWriter
bitbake/lib/bb/cooker.py | 114 +++++++++++++++++++++--------------------------
1 file changed, 51 insertions(+), 63 deletions(-)
--
Regards,
Ed
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/5] cooker: move EventLogWriteHandler to the top module level
2016-06-20 11:00 [PATCH 0/5] Fix writing events to file Ed Bartosh
@ 2016-06-20 11:00 ` Ed Bartosh
2016-06-20 11:00 ` [PATCH 2/5] cooker: encode event objects to base64 Ed Bartosh
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Ed Bartosh @ 2016-06-20 11:00 UTC (permalink / raw)
To: bitbake-devel
EventLogWriteHandler object was created and used in
BBCooker.initConfigurationData.
This causes creation of multiple EventLogWriteHandler objects
and results in duplicated entries in the output event file
as BBCooker.initConfigurationData is called multiple times.
Added eventlogfile parameter to EventLogWriteHandler to avoid using
global variable DEFAULT_EVENTFILE.
Moved EventLogWriteHandler to the module level.
Created EventLogWriteHandler object in BBCooker.__init__ to ensure that only
one handler object is created.
Signed-off-by: Ed Bartosh <ed.bartosh@linux.intel.com>
---
bitbake/lib/bb/cooker.py | 126 ++++++++++++++++++++++++-----------------------
1 file changed, 64 insertions(+), 62 deletions(-)
diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py
index 60ee5d7..b2cf0cd 100644
--- a/bitbake/lib/bb/cooker.py
+++ b/bitbake/lib/bb/cooker.py
@@ -42,6 +42,8 @@ import subprocess
import errno
import prserv.serv
import pyinotify
+import json
+import pickle
logger = logging.getLogger("BitBake")
collectlog = logging.getLogger("BitBake.Collection")
@@ -114,6 +116,63 @@ class CookerFeatures(object):
return next(self._features)
+class EventLogWriteHandler:
+
+ def __init__(self, cooker, eventfile):
+ # set our handler's event processor
+ self.event = self.EventWriter(cooker, eventfile)
+
+ class EventWriter:
+ def __init__(self, cooker, eventfile):
+ self.file_inited = None
+ self.cooker = cooker
+ self.eventfile = eventfile
+ self.event_queue = []
+
+ def init_file(self):
+ try:
+ # delete the old log
+ os.remove(self.eventfile)
+ except:
+ pass
+
+ # write current configuration data
+ with open(eventfile, "w") as f:
+ f.write("%s\n" % json.dumps({ "allvariables" : self.cooker.getAllKeysWithFlags(["doc", "func"])}))
+
+ def write_event(self, event):
+ with open(self.eventfile, "a") as f:
+ try:
+ f.write("%s\n" % json.dumps({"class":event.__module__ + "." + event.__class__.__name__, "vars":json.dumps(pickle.dumps(event)) }))
+ except Exception as e:
+ import traceback
+ print(e, traceback.format_exc())
+
+
+ def send(self, event):
+ event_class = event.__module__ + "." + event.__class__.__name__
+
+ # init on bb.event.BuildStarted
+ if self.file_inited is None:
+ if event_class == "bb.event.BuildStarted":
+ self.init_file()
+ self.file_inited = True
+
+ # write pending events
+ for e in self.event_queue:
+ self.write_event(e)
+
+ # also write the current event
+ self.write_event(event)
+
+ else:
+ # queue all events until the file is inited
+ self.event_queue.append(event)
+
+ else:
+ # we have the file, just write the event
+ self.write_event(event)
+
#============================================================================#
# BBCooker
#============================================================================#
@@ -151,6 +210,11 @@ class BBCooker:
self.initConfigurationData()
+ # we log all events to a file if so directed
+ if self.configuration.writeeventlog:
+ # register the log file writer as UI Handler
+ bb.event.register_UIHhandler(EventLogWriteHandler(self, self.configuration.writeeventlog))
+
self.inotify_modified_files = []
def _process_inotify_updates(server, notifier_list, abort):
@@ -301,68 +365,6 @@ class BBCooker:
if consolelog:
self.data.setVar("BB_CONSOLELOG", consolelog)
- # we log all events to a file if so directed
- if self.configuration.writeeventlog:
- import json, pickle
- DEFAULT_EVENTFILE = self.configuration.writeeventlog
- class EventLogWriteHandler():
-
- class EventWriter():
- def __init__(self, cooker):
- self.file_inited = None
- self.cooker = cooker
- self.event_queue = []
-
- def init_file(self):
- try:
- # delete the old log
- os.remove(DEFAULT_EVENTFILE)
- except:
- pass
-
- # write current configuration data
- with open(DEFAULT_EVENTFILE, "w") as f:
- f.write("%s\n" % json.dumps({ "allvariables" : self.cooker.getAllKeysWithFlags(["doc", "func"])}))
-
- def write_event(self, event):
- with open(DEFAULT_EVENTFILE, "a") as f:
- try:
- f.write("%s\n" % json.dumps({"class":event.__module__ + "." + event.__class__.__name__, "vars":json.dumps(pickle.dumps(event)) }))
- except Exception as e:
- import traceback
- print(e, traceback.format_exc())
-
-
- def send(self, event):
- event_class = event.__module__ + "." + event.__class__.__name__
-
- # init on bb.event.BuildStarted
- if self.file_inited is None:
- if event_class == "bb.event.BuildStarted":
- self.init_file()
- self.file_inited = True
-
- # write pending events
- for e in self.event_queue:
- self.write_event(e)
-
- # also write the current event
- self.write_event(event)
-
- else:
- # queue all events until the file is inited
- self.event_queue.append(event)
-
- else:
- # we have the file, just write the event
- self.write_event(event)
-
- # set our handler's event processor
- event = EventWriter(self) # self is the cooker here
-
- # register the log file writer as UI Handler
- bb.event.register_UIHhandler(EventLogWriteHandler())
-
#
# Copy of the data store which has been expanded.
# Used for firing events and accessing variables where expansion needs to be accounted for
--
2.1.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/5] cooker: encode event objects to base64
2016-06-20 11:00 [PATCH 0/5] Fix writing events to file Ed Bartosh
2016-06-20 11:00 ` [PATCH 1/5] cooker: move EventLogWriteHandler to the top module level Ed Bartosh
@ 2016-06-20 11:00 ` Ed Bartosh
2016-06-20 11:00 ` [PATCH 3/5] cooker: don't remove event file Ed Bartosh
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Ed Bartosh @ 2016-06-20 11:00 UTC (permalink / raw)
To: bitbake-devel
pickle converts python objects into the binary form that can't be
decoded to text and therefore can't be converted to JSON format.
Attempt to convert event objects raises this error:
TypeError:
b'\x80\x03cbb.runqueue\nrunQueueTaskSkipped\nq\x00)...
is not JSON serializable
Encoded pickled event objects to base64 to be able to convert data
structure to JSON.
[YOCTO #9803]
Signed-off-by: Ed Bartosh <ed.bartosh@linux.intel.com>
---
bitbake/lib/bb/cooker.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py
index b2cf0cd..2de6b3e 100644
--- a/bitbake/lib/bb/cooker.py
+++ b/bitbake/lib/bb/cooker.py
@@ -44,6 +44,7 @@ import prserv.serv
import pyinotify
import json
import pickle
+import codecs
logger = logging.getLogger("BitBake")
collectlog = logging.getLogger("BitBake.Collection")
@@ -143,7 +144,9 @@ class EventLogWriteHandler:
def write_event(self, event):
with open(self.eventfile, "a") as f:
try:
- f.write("%s\n" % json.dumps({"class":event.__module__ + "." + event.__class__.__name__, "vars":json.dumps(pickle.dumps(event)) }))
+ str_event = codecs.encode(pickle.dumps(event), 'base64').decode('utf-8')
+ f.write("%s\n" % json.dumps({"class": event.__module__ + "." + event.__class__.__name__,
+ "vars": str_event}))
except Exception as e:
import traceback
print(e, traceback.format_exc())
--
2.1.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/5] cooker: don't remove event file
2016-06-20 11:00 [PATCH 0/5] Fix writing events to file Ed Bartosh
2016-06-20 11:00 ` [PATCH 1/5] cooker: move EventLogWriteHandler to the top module level Ed Bartosh
2016-06-20 11:00 ` [PATCH 2/5] cooker: encode event objects to base64 Ed Bartosh
@ 2016-06-20 11:00 ` Ed Bartosh
2016-06-20 11:00 ` [PATCH 4/5] cooker: replace EventLogWriteHandler with namedtuple Ed Bartosh
2016-06-20 11:00 ` [PATCH 5/5] cooker: clean up EvertWriter Ed Bartosh
4 siblings, 0 replies; 6+ messages in thread
From: Ed Bartosh @ 2016-06-20 11:00 UTC (permalink / raw)
To: bitbake-devel
There is no need to remove output file as it gets rewritten by
open(self.eventfile, 'w') anyway.
Signed-off-by: Ed Bartosh <ed.bartosh@linux.intel.com>
---
bitbake/lib/bb/cooker.py | 6 ------
1 file changed, 6 deletions(-)
diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py
index 2de6b3e..ca53ff4 100644
--- a/bitbake/lib/bb/cooker.py
+++ b/bitbake/lib/bb/cooker.py
@@ -131,12 +131,6 @@ class EventLogWriteHandler:
self.event_queue = []
def init_file(self):
- try:
- # delete the old log
- os.remove(self.eventfile)
- except:
- pass
-
# write current configuration data
with open(eventfile, "w") as f:
f.write("%s\n" % json.dumps({ "allvariables" : self.cooker.getAllKeysWithFlags(["doc", "func"])}))
--
2.1.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/5] cooker: replace EventLogWriteHandler with namedtuple
2016-06-20 11:00 [PATCH 0/5] Fix writing events to file Ed Bartosh
` (2 preceding siblings ...)
2016-06-20 11:00 ` [PATCH 3/5] cooker: don't remove event file Ed Bartosh
@ 2016-06-20 11:00 ` Ed Bartosh
2016-06-20 11:00 ` [PATCH 5/5] cooker: clean up EvertWriter Ed Bartosh
4 siblings, 0 replies; 6+ messages in thread
From: Ed Bartosh @ 2016-06-20 11:00 UTC (permalink / raw)
To: bitbake-devel
class EventLogWriteHandler is a simple wrapper class with only one
class member. Replacing it with namedtuple makes code less nested and more
readable.
Signed-off-by: Ed Bartosh <ed.bartosh@linux.intel.com>
---
bitbake/lib/bb/cooker.py | 86 +++++++++++++++++++++++-------------------------
1 file changed, 41 insertions(+), 45 deletions(-)
diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py
index ca53ff4..3e4f8d8 100644
--- a/bitbake/lib/bb/cooker.py
+++ b/bitbake/lib/bb/cooker.py
@@ -33,7 +33,7 @@ import threading
from io import StringIO
from contextlib import closing
from functools import wraps
-from collections import defaultdict
+from collections import defaultdict, namedtuple
import bb, bb.exceptions, bb.command
from bb import utils, data, parse, event, cache, providers, taskdata, runqueue, build
import queue
@@ -117,58 +117,52 @@ class CookerFeatures(object):
return next(self._features)
-class EventLogWriteHandler:
-
+class EventWriter:
def __init__(self, cooker, eventfile):
- # set our handler's event processor
- self.event = self.EventWriter(cooker, eventfile)
-
- class EventWriter:
- def __init__(self, cooker, eventfile):
- self.file_inited = None
- self.cooker = cooker
- self.eventfile = eventfile
- self.event_queue = []
-
- def init_file(self):
- # write current configuration data
- with open(eventfile, "w") as f:
- f.write("%s\n" % json.dumps({ "allvariables" : self.cooker.getAllKeysWithFlags(["doc", "func"])}))
-
- def write_event(self, event):
- with open(self.eventfile, "a") as f:
- try:
- str_event = codecs.encode(pickle.dumps(event), 'base64').decode('utf-8')
- f.write("%s\n" % json.dumps({"class": event.__module__ + "." + event.__class__.__name__,
- "vars": str_event}))
- except Exception as e:
- import traceback
- print(e, traceback.format_exc())
+ self.file_inited = None
+ self.cooker = cooker
+ self.eventfile = eventfile
+ self.event_queue = []
+ def init_file(self):
+ # write current configuration data
+ with open(eventfile, "w") as f:
+ f.write("%s\n" % json.dumps({ "allvariables" : self.cooker.getAllKeysWithFlags(["doc", "func"])}))
+
+ def write_event(self, event):
+ with open(self.eventfile, "a") as f:
+ try:
+ str_event = codecs.encode(pickle.dumps(event), 'base64').decode('utf-8')
+ f.write("%s\n" % json.dumps({"class": event.__module__ + "." + event.__class__.__name__,
+ "vars": str_event}))
+ except Exception as e:
+ import traceback
+ print(e, traceback.format_exc())
- def send(self, event):
- event_class = event.__module__ + "." + event.__class__.__name__
- # init on bb.event.BuildStarted
- if self.file_inited is None:
- if event_class == "bb.event.BuildStarted":
- self.init_file()
- self.file_inited = True
+ def send(self, event):
+ event_class = event.__module__ + "." + event.__class__.__name__
- # write pending events
- for e in self.event_queue:
- self.write_event(e)
+ # init on bb.event.BuildStarted
+ if self.file_inited is None:
+ if event_class == "bb.event.BuildStarted":
+ self.init_file()
+ self.file_inited = True
- # also write the current event
- self.write_event(event)
+ # write pending events
+ for e in self.event_queue:
+ self.write_event(e)
- else:
- # queue all events until the file is inited
- self.event_queue.append(event)
+ # also write the current event
+ self.write_event(event)
else:
- # we have the file, just write the event
- self.write_event(event)
+ # queue all events until the file is inited
+ self.event_queue.append(event)
+
+ else:
+ # we have the file, just write the event
+ self.write_event(event)
#============================================================================#
# BBCooker
@@ -210,7 +204,9 @@ class BBCooker:
# we log all events to a file if so directed
if self.configuration.writeeventlog:
# register the log file writer as UI Handler
- bb.event.register_UIHhandler(EventLogWriteHandler(self, self.configuration.writeeventlog))
+ writer = EventWriter(self, self.configuration.writeeventlog)
+ EventLogWriteHandler = namedtuple('EventLogWriteHandler', ['event'])
+ bb.event.register_UIHhandler(EventLogWriteHandler(writer))
self.inotify_modified_files = []
--
2.1.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 5/5] cooker: clean up EvertWriter
2016-06-20 11:00 [PATCH 0/5] Fix writing events to file Ed Bartosh
` (3 preceding siblings ...)
2016-06-20 11:00 ` [PATCH 4/5] cooker: replace EventLogWriteHandler with namedtuple Ed Bartosh
@ 2016-06-20 11:00 ` Ed Bartosh
4 siblings, 0 replies; 6+ messages in thread
From: Ed Bartosh @ 2016-06-20 11:00 UTC (permalink / raw)
To: bitbake-devel
Restructured EventWriter code to make it more readable:
- got rid of init_file method as it's called only once
- renamed exception variable e -> err
- renamed event variable e -> evt
- simplified main 'if' structure of send method
Signed-off-by: Ed Bartosh <ed.bartosh@linux.intel.com>
---
bitbake/lib/bb/cooker.py | 33 +++++++++++++--------------------
1 file changed, 13 insertions(+), 20 deletions(-)
diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py
index 3e4f8d8..9bd3460 100644
--- a/bitbake/lib/bb/cooker.py
+++ b/bitbake/lib/bb/cooker.py
@@ -124,46 +124,39 @@ class EventWriter:
self.eventfile = eventfile
self.event_queue = []
- def init_file(self):
- # write current configuration data
- with open(eventfile, "w") as f:
- f.write("%s\n" % json.dumps({ "allvariables" : self.cooker.getAllKeysWithFlags(["doc", "func"])}))
-
def write_event(self, event):
with open(self.eventfile, "a") as f:
try:
str_event = codecs.encode(pickle.dumps(event), 'base64').decode('utf-8')
f.write("%s\n" % json.dumps({"class": event.__module__ + "." + event.__class__.__name__,
"vars": str_event}))
- except Exception as e:
+ except Exception as err:
import traceback
- print(e, traceback.format_exc())
-
+ print(err, traceback.format_exc())
def send(self, event):
- event_class = event.__module__ + "." + event.__class__.__name__
+ if self.file_inited:
+ # we have the file, just write the event
+ self.write_event(event)
+ else:
+ # init on bb.event.BuildStarted
+ name = "%s.%s" % (event.__module__, event.__class__.__name__)
+ if name == "bb.event.BuildStarted":
+ with open(self.eventfile, "w") as f:
+ f.write("%s\n" % json.dumps({ "allvariables" : self.cooker.getAllKeysWithFlags(["doc", "func"])}))
- # init on bb.event.BuildStarted
- if self.file_inited is None:
- if event_class == "bb.event.BuildStarted":
- self.init_file()
self.file_inited = True
# write pending events
- for e in self.event_queue:
- self.write_event(e)
+ for evt in self.event_queue:
+ self.write_event(evt)
# also write the current event
self.write_event(event)
-
else:
# queue all events until the file is inited
self.event_queue.append(event)
- else:
- # we have the file, just write the event
- self.write_event(event)
-
#============================================================================#
# BBCooker
#============================================================================#
--
2.1.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2016-06-20 11:02 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-06-20 11:00 [PATCH 0/5] Fix writing events to file Ed Bartosh
2016-06-20 11:00 ` [PATCH 1/5] cooker: move EventLogWriteHandler to the top module level Ed Bartosh
2016-06-20 11:00 ` [PATCH 2/5] cooker: encode event objects to base64 Ed Bartosh
2016-06-20 11:00 ` [PATCH 3/5] cooker: don't remove event file Ed Bartosh
2016-06-20 11:00 ` [PATCH 4/5] cooker: replace EventLogWriteHandler with namedtuple Ed Bartosh
2016-06-20 11:00 ` [PATCH 5/5] cooker: clean up EvertWriter Ed Bartosh
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.