[PATCH] [Wok] Bugfix 33: Implement a multiprocess file handler for log system

- This commit adds a new watched file handler, used in Wok, but it uses a recursive lock before emitting the log register to avoid possible concurrency issues since multiple processes will write in the same log file. Signed-off-by: Jose Ricardo Ziviani <joserz@linux.vnet.ibm.com> --- *NOTE*: based on '[PATCH] [Wok] Bugfix 30: Duplicated log messages' src/wok/safewatchedfilehandler.py | 44 +++++++++++++++++++++++++++++++++++++++ src/wok/server.py | 4 ++-- 2 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 src/wok/safewatchedfilehandler.py diff --git a/src/wok/safewatchedfilehandler.py b/src/wok/safewatchedfilehandler.py new file mode 100644 index 0000000..c5fad85 --- /dev/null +++ b/src/wok/safewatchedfilehandler.py @@ -0,0 +1,44 @@ +# +# Project Kimchi +# +# Copyright IBM, Corp. 2016 +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +from logging.handlers import WatchedFileHandler +from multiprocessing import RLock + + +class SafeWatchedFileHandler(WatchedFileHandler): + + def __init__(self, filename, mode='a', encoding=None, delay=0): + WatchedFileHandler.__init__(self, filename, mode, encoding, delay) + self._lock = RLock() + + def close(self): + self._lock.acquire(timeout=2) + try: + WatchedFileHandler.close(self) + + finally: + self._lock.release() + + def emit(self, record): + self._lock.acquire(timeout=2) + try: + WatchedFileHandler.emit(self, record) + + finally: + self._lock.release() diff --git a/src/wok/server.py b/src/wok/server.py index 13851e8..75b41d5 100644 --- a/src/wok/server.py +++ b/src/wok/server.py @@ -35,6 +35,7 @@ from wok.control import sub_nodes from wok.model import model from wok.proxy import start_proxy, terminate_proxy from wok.root import WokRoot +from wok.safewatchedfilehandler import SafeWatchedFileHandler from wok.utils import get_enabled_plugins, import_class LOGGING_LEVEL = {"debug": logging.DEBUG, @@ -122,8 +123,7 @@ class Server(object): cherrypy.log.access_log.addHandler(h) # Create handler to error log file - h = logging.handlers.WatchedFileHandler(options.error_log, 'a', - delay=1) + h = SafeWatchedFileHandler(options.error_log, 'a', delay=1) h.setLevel(logLevel) h.setFormatter(cherrypy._cplogging.logfmt) -- 1.9.1

Reviewed-By: Lucio Correia <luciojhc@linux.vnet.ibm.com> On 15-02-2016 21:45, Jose Ricardo Ziviani wrote:
- This commit adds a new watched file handler, used in Wok, but it uses a recursive lock before emitting the log register to avoid possible concurrency issues since multiple processes will write in the same log file.
Signed-off-by: Jose Ricardo Ziviani <joserz@linux.vnet.ibm.com> --- *NOTE*: based on '[PATCH] [Wok] Bugfix 30: Duplicated log messages'
src/wok/safewatchedfilehandler.py | 44 +++++++++++++++++++++++++++++++++++++++ src/wok/server.py | 4 ++-- 2 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 src/wok/safewatchedfilehandler.py
diff --git a/src/wok/safewatchedfilehandler.py b/src/wok/safewatchedfilehandler.py new file mode 100644 index 0000000..c5fad85 --- /dev/null +++ b/src/wok/safewatchedfilehandler.py @@ -0,0 +1,44 @@ +# +# Project Kimchi +# +# Copyright IBM, Corp. 2016 +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +from logging.handlers import WatchedFileHandler +from multiprocessing import RLock + + +class SafeWatchedFileHandler(WatchedFileHandler): + + def __init__(self, filename, mode='a', encoding=None, delay=0): + WatchedFileHandler.__init__(self, filename, mode, encoding, delay) + self._lock = RLock() + + def close(self): + self._lock.acquire(timeout=2) + try: + WatchedFileHandler.close(self) + + finally: + self._lock.release() + + def emit(self, record): + self._lock.acquire(timeout=2) + try: + WatchedFileHandler.emit(self, record) + + finally: + self._lock.release() diff --git a/src/wok/server.py b/src/wok/server.py index 13851e8..75b41d5 100644 --- a/src/wok/server.py +++ b/src/wok/server.py @@ -35,6 +35,7 @@ from wok.control import sub_nodes from wok.model import model from wok.proxy import start_proxy, terminate_proxy from wok.root import WokRoot +from wok.safewatchedfilehandler import SafeWatchedFileHandler from wok.utils import get_enabled_plugins, import_class
LOGGING_LEVEL = {"debug": logging.DEBUG, @@ -122,8 +123,7 @@ class Server(object): cherrypy.log.access_log.addHandler(h)
# Create handler to error log file - h = logging.handlers.WatchedFileHandler(options.error_log, 'a', - delay=1) + h = SafeWatchedFileHandler(options.error_log, 'a', delay=1) h.setLevel(logLevel) h.setFormatter(cherrypy._cplogging.logfmt)
-- Lucio Correia Software Engineer IBM LTC Brazil
participants (3)
-
Aline Manera
-
Jose Ricardo Ziviani
-
Lucio Correia