diff --git a/IPython/config/application.py b/IPython/config/application.py index ba26b57..59a21e5 100644 --- a/IPython/config/application.py +++ b/IPython/config/application.py @@ -132,6 +132,27 @@ class Application(SingletonConfigurable): new = getattr(logging, new) self.log_level = new self.log.setLevel(new) + + log = Instance(logging.Logger) + def _log_default(self): + """Start logging for this application. + + The default is to log to stdout using a StreaHandler. The log level + starts at loggin.WARN, but this can be adjusted by setting the + ``log_level`` attribute. + """ + log = logging.getLogger(self.__class__.__name__) + log.setLevel(self.log_level) + if sys.executable.endswith('pythonw.exe'): + # this should really go to a file, but file-logging is only + # hooked up in parallel applications + _log_handler = logging.StreamHandler(open(os.devnull, 'w')) + else: + _log_handler = logging.StreamHandler() + _log_formatter = logging.Formatter("[%(name)s] %(message)s") + _log_handler.setFormatter(_log_formatter) + log.addHandler(_log_handler) + return log # the alias map for configurables aliases = Dict({'log-level' : 'Application.log_level'}) @@ -169,32 +190,11 @@ class Application(SingletonConfigurable): if self.__class__ not in self.classes: self.classes.insert(0, self.__class__) - self.init_logging() - def _config_changed(self, name, old, new): SingletonConfigurable._config_changed(self, name, old, new) self.log.debug('Config changed:') self.log.debug(repr(new)) - def init_logging(self): - """Start logging for this application. - - The default is to log to stdout using a StreaHandler. The log level - starts at loggin.WARN, but this can be adjusted by setting the - ``log_level`` attribute. - """ - self.log = logging.getLogger(self.__class__.__name__) - self.log.setLevel(self.log_level) - if sys.executable.endswith('pythonw.exe'): - # this should really go to a file, but file-logging is only - # hooked up in parallel applications - self._log_handler = logging.StreamHandler(open(os.devnull, 'w')) - else: - self._log_handler = logging.StreamHandler() - self._log_formatter = logging.Formatter("[%(name)s] %(message)s") - self._log_handler.setFormatter(self._log_formatter) - self.log.addHandler(self._log_handler) - @catch_config_error def initialize(self, argv=None): """Do the basic steps to configure me. diff --git a/IPython/frontend/html/notebook/clustermanager.py b/IPython/frontend/html/notebook/clustermanager.py index 27e1e9b..7e4f428 100644 --- a/IPython/frontend/html/notebook/clustermanager.py +++ b/IPython/frontend/html/notebook/clustermanager.py @@ -45,8 +45,6 @@ class DummyIPClusterStart(IPClusterStart): def init_signal(self): pass - def init_logging(self): - pass def reinit_logging(self): pass diff --git a/IPython/frontend/html/notebook/notebookapp.py b/IPython/frontend/html/notebook/notebookapp.py index b157c97..22dbf20 100644 --- a/IPython/frontend/html/notebook/notebookapp.py +++ b/IPython/frontend/html/notebook/notebookapp.py @@ -390,7 +390,6 @@ class NotebookApp(BaseIPythonApplication): self.cluster_manager.update_profiles() def init_logging(self): - super(NotebookApp, self).init_logging() # This prevents double log messages because tornado use a root logger that # self.log is a child of. The logging module dipatches log messages to a log # and all of its ancenstors until propagate is set to False. @@ -493,6 +492,7 @@ class NotebookApp(BaseIPythonApplication): @catch_config_error def initialize(self, argv=None): + self.init_logging() super(NotebookApp, self).initialize(argv) self.init_configurables() self.init_webapp() diff --git a/IPython/parallel/apps/baseapp.py b/IPython/parallel/apps/baseapp.py index 6d6382a..32b6d98 100644 --- a/IPython/parallel/apps/baseapp.py +++ b/IPython/parallel/apps/baseapp.py @@ -175,9 +175,12 @@ class BaseParallelApplication(BaseIPythonApplication): else: open_log_file = None if open_log_file is not None: - self.log.removeHandler(self._log_handler) + while self.log.handlers: + self.log.removeHandler(self.log.handlers[0]) self._log_handler = logging.StreamHandler(open_log_file) self.log.addHandler(self._log_handler) + else: + self._log_handler = self.log.handlers[0] # Add timestamps to log format: self._log_formatter = logging.Formatter("%(asctime)s.%(msecs).03d [%(name)s] %(message)s", datefmt="%Y-%m-%d %H:%M:%S") diff --git a/IPython/parallel/apps/ipcontrollerapp.py b/IPython/parallel/apps/ipcontrollerapp.py index ead40a7..da9070a 100755 --- a/IPython/parallel/apps/ipcontrollerapp.py +++ b/IPython/parallel/apps/ipcontrollerapp.py @@ -434,11 +434,9 @@ class IPControllerApp(BaseParallelApplication): lsock = context.socket(zmq.PUB) lsock.connect(self.log_url) handler = PUBHandler(lsock) - self.log.removeHandler(self._log_handler) handler.root_topic = 'controller' handler.setLevel(self.log_level) self.log.addHandler(handler) - self._log_handler = handler @catch_config_error def initialize(self, argv=None): diff --git a/IPython/parallel/apps/ipengineapp.py b/IPython/parallel/apps/ipengineapp.py index c901635..f26750b 100755 --- a/IPython/parallel/apps/ipengineapp.py +++ b/IPython/parallel/apps/ipengineapp.py @@ -288,11 +288,9 @@ class IPEngineApp(BaseParallelApplication): context = self.engine.context lsock = context.socket(zmq.PUB) lsock.connect(self.log_url) - self.log.removeHandler(self._log_handler) handler = EnginePUBHandler(self.engine, lsock) handler.setLevel(self.log_level) self.log.addHandler(handler) - self._log_handler = handler def init_mpi(self): global mpi