def my_function(logfilename): # Since a fork() has been made, the logging module must be initialized bxilog.basicConfig(filename=logfilename, filemode='w') # Using the bxilog.multiprocessing_target decorator guarantees that # uncaught exception will be reported by the logging system # and that the logging system will be cleanup properly (and therefore # flushed). bxilog.out("In subprocess") bxilog.flush() # Test 1 : simple trace message bxilog.trace("A simple trace message") # Test 2 : simple error message bxilog.error("A simple error message") # Test 3 : catch warning error try: raise ValueError("An expected exception in first subprocess") except: bxilog.exception("Handling an exception in subprocess", level=bxilog.WARNING) # Test 4 : # This will be catched thanks to the bxilog.multiprocessing_target() decorator # Otherwise, the exception will appear on the standard error as usual raise ValueError("An unexpected exception in second subprocess")
def test_remote_logging_bind_simple(self): """ Process Parent receives logs from child process """ # Configure the log in the parent so that all logs received from the child # goes to a dedicated file from which we can count the number of messages # produced by the child tmpdir = tempfile.mkdtemp(suffix="tmp", prefix=BXIRemoteLoggerTest.__name__) all = os.path.join(tmpdir, 'all.bxilog') child = os.path.join(tmpdir, 'child.bxilog') parent_config = { 'handlers': ['all', 'child'], 'all': { 'module': 'bxi.base.log.file_handler', 'filters': ':lowest', 'path': all, 'append': True, }, 'child': { 'module': 'bxi.base.log.file_handler', 'filters': ':off,%s:lowest' % LOGGER_CMD, 'path': child, 'append': True, } } bxilog.set_config(configobj.ConfigObj(parent_config)) print("Logging output: all: %s, child: %s" % (all, child)) url = 'ipc://%s/rh-cfg.zock' % tmpdir logs_nb = 25 full_cmd_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), LOGGER_CMD) logger_output_file = os.path.join( tmpdir, os.path.splitext(LOGGER_CMD)[0] + '.bxilog') args = [ full_cmd_path, logger_output_file, url, 'False', '1', str(logs_nb) ] bxilog.out("Executing '%s': it must produce %d logs", ' '.join(args), logs_nb) popen = subprocess.Popen(args) bxilog.out("Starting logs reception thread on %s", url) receiver = remote_receiver.RemoteReceiver([url], bind=True) receiver.start() bxilog.out("Waiting for the child termination") popen.wait() rc = popen.returncode bxilog.out("Child exited with return code %s", rc) self.assertEquals(rc, logs_nb) # Wait a bit for the logs to be processed time.sleep(1) bxilog.out("Stopping the receiver") receiver.stop(True) bxilog.out("Flushing bxilog") bxilog.flush() with open(child) as file_: lines = file_.readlines() self.assertEquals(len(lines), logs_nb)
def _check_log_produced(self, file, log_f, *args, **kwargs): old_size = os.stat(file).st_size if os.path.exists(file) else 0 log_f(*args, **kwargs) bxilog.flush() new_size = os.stat(file).st_size self.assertTrue( new_size > old_size, "%s: new_size=%d > %d=old_size: " % (file, new_size, old_size))
def test_config_file(self): """Test logging with configuration items""" orig_size = os.stat(FILENAME).st_size if os.path.exists( FILENAME) else 0 conf = { 'handlers': ['out', 'null'], 'setsighandler': True, 'out': { 'module': 'bxi.base.log.file_handler', 'filters': ':output,foo:debug,foo.bar:trace', 'path': FILENAME, 'append': True }, 'null': { 'module': 'bxi.base.log.null_handler', 'filters': ':off,foo:fine,foo.bar:debug', }, } bxilog.set_config(configobj.ConfigObj(conf)) # It is required to initialize the library for the configuration to be used bxilog.init() foo = bxilog.getLogger('foo') self.assertEqual(foo.level, bxilog.FINE) bar = bxilog.getLogger('foo.bar') self.assertEqual(bar.level, bxilog.TRACE) any = bxilog.getLogger('bebopalula') self.assertEqual(any.level, bxilog.OUTPUT) any.info('This message must not appear in file %s', FILENAME) bxilog.flush() newsize = os.stat(FILENAME).st_size self.assertEquals(newsize, orig_size) bar.lowest('This message must also not appear in file %s', FILENAME) bxilog.flush() newsize = os.stat(FILENAME).st_size self.assertEquals(newsize, orig_size) foo.fine('This message must not appear in file %s', FILENAME) bxilog.flush() newsize = os.stat(FILENAME).st_size self.assertEquals(newsize, orig_size) self._check_log_produced(FILENAME, any.output, 'This message must appear in file %s', FILENAME) self._check_log_produced(FILENAME, bar.trace, 'This message must also appear in file %s', FILENAME) self._check_log_produced(FILENAME, foo.debug, 'This message must also appear in file %s', FILENAME) self._check_log_produced(FILENAME, bxilog.output, "This message must also appear in file %s", FILENAME)
def flush(): """Convenience method for flushing all logs @return """ bxilog.flush()