From 50fc15246be1721d91c5161b5d9731e7f31ed859 Mon Sep 17 00:00:00 2001 From: Robert Sachunsky Date: Wed, 9 Oct 2024 16:34:39 +0000 Subject: [PATCH 1/8] ocrd_utils.initLogging: also add handler to root logger (to be consistent with file config and prevent imported libraries from initing logging first), but disable propagation for ocrd loggers (to avoid duplication) --- src/ocrd_utils/logging.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/ocrd_utils/logging.py b/src/ocrd_utils/logging.py index ac2b3416a..9c9ea73e0 100644 --- a/src/ocrd_utils/logging.py +++ b/src/ocrd_utils/logging.py @@ -50,6 +50,7 @@ # These are the loggers we add handlers to ROOT_OCRD_LOGGERS = [ + '', 'ocrd', 'ocrd_network' ] @@ -193,7 +194,10 @@ def initLogging(builtin_only=False, force_reinit=False, silent=not config.OCRD_L ocrd_handler.setFormatter(logging.Formatter(fmt=LOG_FORMAT, datefmt=LOG_TIMEFMT)) ocrd_handler.setLevel(logging.DEBUG) for logger_name in ROOT_OCRD_LOGGERS: - logging.getLogger(logger_name).addHandler(ocrd_handler) + logger = logging.getLogger(logger_name) + logger.addHandler(ocrd_handler) + if logger_name: + logger.propagate = False # avoid duplication (from root handler) for logger_name, logger_level in LOGGING_DEFAULTS.items(): logging.getLogger(logger_name).setLevel(logger_level) _initialized_flag = True @@ -211,8 +215,8 @@ def disableLogging(silent=not config.OCRD_LOGGING_DEBUG): _initialized_flag = False # logging.basicConfig(level=logging.CRITICAL) # logging.disable(logging.ERROR) - # remove all handlers for the 'ocrd.' and root logger - for logger_name in ROOT_OCRD_LOGGERS + ['']: + # remove all handlers for the ocrd logger + for logger_name in ROOT_OCRD_LOGGERS: for handler in logging.getLogger(logger_name).handlers[:]: logging.getLogger(logger_name).removeHandler(handler) for logger_name in LOGGING_DEFAULTS: From f17d5880c7dbd82e81389b5de39a705cabb5e0ee Mon Sep 17 00:00:00 2001 From: Robert Sachunsky Date: Thu, 7 Nov 2024 18:36:17 +0000 Subject: [PATCH 2/8] initLogging: do not remove any previous handlers/levels --- src/ocrd_utils/logging.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/ocrd_utils/logging.py b/src/ocrd_utils/logging.py index 9c9ea73e0..f88d09803 100644 --- a/src/ocrd_utils/logging.py +++ b/src/ocrd_utils/logging.py @@ -163,18 +163,6 @@ def initLogging(builtin_only=False, force_reinit=False, silent=not config.OCRD_L global _initialized_flag if _initialized_flag and not force_reinit: return - # disableLogging() - - # https://docs.python.org/3/library/logging.html#logging.disable - # If logging.disable(logging.NOTSET) is called, it effectively removes this - # overriding level, so that logging output again depends on the effective - # levels of individual loggers. - logging.disable(logging.NOTSET) - - # remove all handlers for the ocrd root loggers - for logger_name in ROOT_OCRD_LOGGERS: - for handler in logging.getLogger(logger_name).handlers[:]: - logging.getLogger(logger_name).removeHandler(handler) config_file = None if not builtin_only: From d6c551ec0f55cf9211ef7a71c901d9ad616b090e Mon Sep 17 00:00:00 2001 From: Robert Sachunsky Date: Thu, 7 Nov 2024 18:38:44 +0000 Subject: [PATCH 3/8] initLogging: only add root handler instead of multiple redundant handlers with propagate=false --- src/ocrd_utils/logging.py | 7 ++----- src/ocrd_utils/ocrd_logging.conf | 28 +++++++++++++--------------- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/ocrd_utils/logging.py b/src/ocrd_utils/logging.py index f88d09803..f01855aa0 100644 --- a/src/ocrd_utils/logging.py +++ b/src/ocrd_utils/logging.py @@ -181,11 +181,8 @@ def initLogging(builtin_only=False, force_reinit=False, silent=not config.OCRD_L ocrd_handler = logging.StreamHandler(stream=sys.stderr) ocrd_handler.setFormatter(logging.Formatter(fmt=LOG_FORMAT, datefmt=LOG_TIMEFMT)) ocrd_handler.setLevel(logging.DEBUG) - for logger_name in ROOT_OCRD_LOGGERS: - logger = logging.getLogger(logger_name) - logger.addHandler(ocrd_handler) - if logger_name: - logger.propagate = False # avoid duplication (from root handler) + root_logger = logging.getLogger('') + root_logger.addHandler(ocrd_handler) for logger_name, logger_level in LOGGING_DEFAULTS.items(): logging.getLogger(logger_name).setLevel(logger_level) _initialized_flag = True diff --git a/src/ocrd_utils/ocrd_logging.conf b/src/ocrd_utils/ocrd_logging.conf index 5cf161398..0af039b2a 100644 --- a/src/ocrd_utils/ocrd_logging.conf +++ b/src/ocrd_utils/ocrd_logging.conf @@ -56,22 +56,22 @@ handlers=consoleHandler,fileHandler # ocrd loggers [logger_ocrd] level=INFO -handlers=consoleHandler,fileHandler +handlers= qualname=ocrd -propagate=0 [logger_ocrd_network] level=INFO -handlers=consoleHandler,processingServerHandler +#handlers=consoleHandler,processingServerHandler +handlers=processingServerHandler qualname=ocrd_network -propagate=0 +#propagate=0 # # logger tensorflow # [logger_ocrd_tensorflow] level=ERROR -handlers=consoleHandler +handlers= qualname=tensorflow # @@ -79,7 +79,7 @@ qualname=tensorflow # [logger_ocrd_shapely_geos] level=ERROR -handlers=consoleHandler +handlers= qualname=shapely.geos @@ -88,7 +88,7 @@ qualname=shapely.geos # [logger_ocrd_PIL] level=INFO -handlers=consoleHandler +handlers= qualname=PIL # @@ -96,34 +96,32 @@ qualname=PIL # [logger_paramiko] level=INFO -handlers=consoleHandler +handlers= qualname=paramiko -propagate=0 [logger_paramiko_transport] level=INFO -handlers=consoleHandler +handlers= qualname=paramiko.transport -propagate=0 # # uvicorn loggers # [logger_uvicorn] level=INFO -handlers=consoleHandler +handlers= qualname=uvicorn [logger_uvicorn_access] level=WARN -handlers=consoleHandler +handlers= qualname=uvicorn.access [logger_uvicorn_error] level=INFO -handlers=consoleHandler +handlers= qualname=uvicorn.error [logger_multipart] level=INFO -handlers=consoleHandler +handlers= qualname=multipart From 8e87023adaec951e299ea141c63d253dffe707a6 Mon Sep 17 00:00:00 2001 From: Robert Sachunsky Date: Thu, 7 Nov 2024 18:41:20 +0000 Subject: [PATCH 4/8] disableLogging: remove all handlers, reset all levels --- src/ocrd_utils/logging.py | 35 ++++++++++------------------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/src/ocrd_utils/logging.py b/src/ocrd_utils/logging.py index f01855aa0..80d98eb2d 100644 --- a/src/ocrd_utils/logging.py +++ b/src/ocrd_utils/logging.py @@ -48,13 +48,6 @@ 'setOverrideLogLevel', ] -# These are the loggers we add handlers to -ROOT_OCRD_LOGGERS = [ - '', - 'ocrd', - 'ocrd_network' -] - LOGGING_DEFAULTS = { 'ocrd': logging.INFO, 'ocrd_network': logging.INFO, @@ -198,24 +191,16 @@ def disableLogging(silent=not config.OCRD_LOGGING_DEBUG): if _initialized_flag and not silent: print("[LOGGING] Disabling logging", file=sys.stderr) _initialized_flag = False - # logging.basicConfig(level=logging.CRITICAL) - # logging.disable(logging.ERROR) - # remove all handlers for the ocrd logger - for logger_name in ROOT_OCRD_LOGGERS: - for handler in logging.getLogger(logger_name).handlers[:]: - logging.getLogger(logger_name).removeHandler(handler) - for logger_name in LOGGING_DEFAULTS: - logging.getLogger(logger_name).setLevel(logging.NOTSET) + # remove all handlers we might have added (via initLogging on builtin or file config) + for logger_name in logging.root.manager.loggerDict: + if not silent: + print(f'[LOGGING] Resetting {logger_name} log level and handlers') + logger = logging.getLogger(logger_name) + logger.setLevel(logging.NOTSET) + for handler in logger.handlers[:]: + logger.removeHandler(handler) + for handler in logging.root.handlers[:]: + logging.root.removeHandler(handler) # Python default log level is WARNING logging.root.setLevel(logging.WARNING) -# Initializing stream handlers at module level -# would cause message output in all runtime contexts, -# including those which are already run for std output -# (--dump-json, --version, ocrd-tool, bashlib etc). -# So this needs to be an opt-in from the CLIs/decorators: -#initLogging() -# Also, we even have to block log output for libraries -# (like matplotlib/tensorflow) which set up logging -# themselves already: -disableLogging() From 4a2a0906a47a672184aefb7f46e9bbc45b177201 Mon Sep 17 00:00:00 2001 From: Robert Sachunsky Date: Thu, 7 Nov 2024 18:42:52 +0000 Subject: [PATCH 5/8] setOverrideLogLevel: override all currently active loggers' level --- src/ocrd_utils/logging.py | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/ocrd_utils/logging.py b/src/ocrd_utils/logging.py index 80d98eb2d..a209a1b4a 100644 --- a/src/ocrd_utils/logging.py +++ b/src/ocrd_utils/logging.py @@ -109,18 +109,15 @@ def setOverrideLogLevel(lvl, silent=not config.OCRD_LOGGING_DEBUG): lvl (string): Log level name. silent (boolean): Whether to log the override call """ - if not _initialized_flag: - initLogging(silent=silent) - ocrd_logger = logging.getLogger('ocrd') - - if lvl is None: - if not silent: - print('[LOGGING] Reset log level override', file=sys.stderr) - ocrd_logger.setLevel(logging.NOTSET) - else: - if not silent: - print(f'[LOGGING] Overriding ocrd log level to {lvl}', file=sys.stderr) - ocrd_logger.setLevel(lvl) + if lvl is not None: + lvl = getLevelName(lvl) + if not _initialized_flag: + initLogging(silent=silent) + # affect all configured loggers + for logger_name in logging.root.manager.loggerDict: + if not silent: + print(f'[LOGGING] Overriding {logger_name} log level to {lvl}', file=sys.stderr) + logging.getLogger(logger_name).setLevel(lvl) def get_logging_config_files(): """ From 7e8705e30ad8ad364e08cb5b8847103adc2a4fbc Mon Sep 17 00:00:00 2001 From: Robert Sachunsky Date: Thu, 7 Nov 2024 18:43:40 +0000 Subject: [PATCH 6/8] logging: increase default root (not ocrd) level from INFO to WARNING --- src/ocrd_utils/logging.py | 1 + src/ocrd_utils/ocrd_logging.conf | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ocrd_utils/logging.py b/src/ocrd_utils/logging.py index a209a1b4a..c56c1401f 100644 --- a/src/ocrd_utils/logging.py +++ b/src/ocrd_utils/logging.py @@ -49,6 +49,7 @@ ] LOGGING_DEFAULTS = { + '': logging.WARNING, 'ocrd': logging.INFO, 'ocrd_network': logging.INFO, # 'ocrd.resolver': logging.INFO, diff --git a/src/ocrd_utils/ocrd_logging.conf b/src/ocrd_utils/ocrd_logging.conf index 0af039b2a..41e6d5af7 100644 --- a/src/ocrd_utils/ocrd_logging.conf +++ b/src/ocrd_utils/ocrd_logging.conf @@ -34,7 +34,7 @@ keys=defaultFormatter,detailedFormatter # default logger "root" using consoleHandler # [logger_root] -level=INFO +level=WARNING handlers=consoleHandler,fileHandler From edaab4e4483c32381231893a148e2186b8585332 Mon Sep 17 00:00:00 2001 From: Robert Sachunsky Date: Thu, 7 Nov 2024 18:27:25 +0000 Subject: [PATCH 7/8] tests: prevent side effects from ocrd_logging --- tests/base.py | 2 -- tests/cli/test_log.py | 11 +++++-- tests/processor/test_processor.py | 21 ++++++------- tests/test_decorators.py | 17 +++++------ tests/test_logging.py | 6 ++++ tests/test_logging_conf.py | 49 +++++++++++++------------------ tests/test_mets_server.py | 28 ++++++++++++------ 7 files changed, 72 insertions(+), 62 deletions(-) diff --git a/tests/base.py b/tests/base.py index 53f393e08..9eb1f20db 100644 --- a/tests/base.py +++ b/tests/base.py @@ -26,8 +26,6 @@ class TestCase(VanillaTestCase): def setUp(self): chdir(dirname(realpath(__file__)) + '/..') - disableLogging() - initLogging(builtin_only=True) class CapturingTestCase(TestCase): """ diff --git a/tests/cli/test_log.py b/tests/cli/test_log.py index c63d78c31..3d81e8266 100644 --- a/tests/cli/test_log.py +++ b/tests/cli/test_log.py @@ -6,8 +6,8 @@ from tests.base import CapturingTestCase as TestCase, main, assets, copy_of_directory from ocrd.decorators import ocrd_loglevel -from ocrd_utils import setOverrideLogLevel, logging, disableLogging -import logging as python_logging +from ocrd_utils import disableLogging, initLogging +import logging @click.group() @ocrd_loglevel @@ -18,14 +18,19 @@ def mock_ocrd_cli(log_level): class TestLogCli(TestCase): def _get_log_output(self, *args): - disableLogging() code, out, err = self.invoke_cli(mock_ocrd_cli, args) print({'code': code, 'out': out, 'err': err}) return err + def setUp(self): + super().setUp() + initLogging() + def tearDown(self): if 'OCRD_TOOL_NAME' in ENV: del(ENV['OCRD_TOOL_NAME']) + super().tearDown() + disableLogging() def test_loglevel(self): assert 'DEBUG ocrd.log_cli - foo' not in self._get_log_output('log', 'debug', 'foo') diff --git a/tests/processor/test_processor.py b/tests/processor/test_processor.py index f2261d0ff..8fed91480 100644 --- a/tests/processor/test_processor.py +++ b/tests/processor/test_processor.py @@ -17,21 +17,21 @@ class TestProcessor(TestCase): + def run(self, result=None): + with copy_of_directory(assets.path_to('SBB0000F29300010000/data')) as workdir: + with pushd_popd(workdir): + self.resolver = Resolver() + self.workspace = self.resolver.workspace_from_url('mets.xml') + super().run(result=result) + def setUp(self): super().setUp() - # make sure we get an isolated temporary copy of the testdata each time - # as long as we are not using pytest but unittest, we need to manage contexts - # (enterContext is only supported starting with py311) - with ExitStack() as stack: - self.resolver = Resolver() - self.workdir = stack.enter_context(copy_of_directory(assets.path_to('SBB0000F29300010000/data'))) - stack.enter_context(pushd_popd(self.workdir)) - self.workspace = self.resolver.workspace_from_url('mets.xml') - self.addCleanup(stack.pop_all().close) + initLogging() def tearDown(self): super().tearDown() config.reset_defaults() + disableLogging() def test_incomplete_processor(self): proc = IncompleteProcessor(None) @@ -251,6 +251,7 @@ class ZipTestProcessor(Processor): pass def test_run_output_metsserver(start_mets_server): mets_server_url, ws = start_mets_server + assert len(ws.mets.find_all_files(fileGrp="OCR-D-OUT")) == 0 run_processor(DummyProcessorWithOutput, workspace=ws, input_file_grp="OCR-D-IMG", output_file_grp="OCR-D-OUT", @@ -269,7 +270,7 @@ def test_run_output_metsserver(start_mets_server): output_file_grp="OCR-D-OUT", mets_server_url=mets_server_url) assert "already exists" in str(exc.value) - + config.reset_defaults() if __name__ == "__main__": main(__file__) diff --git a/tests/test_decorators.py b/tests/test_decorators.py index c36577020..561fdc762 100644 --- a/tests/test_decorators.py +++ b/tests/test_decorators.py @@ -41,22 +41,20 @@ def cli_dummy_processor(*args, **kwargs): class TestDecorators(TestCase): - def setUp(self): - super().setUp() - disableLogging() - def tearDown(self): super().tearDown() config.reset_defaults() + disableLogging() def test_minimal(self): - exit_code, out, err = self.invoke_cli(cli_with_ocrd_cli_options, ['-l', 'DEBUG']) - print(out, err) - assert not exit_code + initLogging() + code, out, err = self.invoke_cli(cli_with_ocrd_cli_options, ['-l', 'DEBUG']) + assert not code, (out, err) def test_loglevel_invalid(self): - code, _, err = self.invoke_cli(cli_with_ocrd_loglevel, ['--log-level', 'foo']) - assert code + initLogging() + code, out, err = self.invoke_cli(cli_with_ocrd_loglevel, ['--log-level', 'foo']) + assert code, (out, err) import click if int(click.__version__[0]) < 8: assert 'invalid choice: foo' in err @@ -67,7 +65,6 @@ def test_loglevel_override(self): if get_logging_config_files(): pytest.skip(f"ocrd_logging.conf found at {get_logging_config_files()}, skipping logging test") import logging - disableLogging() assert logging.getLogger('').getEffectiveLevel() == logging.WARNING assert logging.getLogger('ocrd').getEffectiveLevel() == logging.WARNING initLogging() diff --git a/tests/test_logging.py b/tests/test_logging.py index 2e4e0861b..bd6aa7e7b 100644 --- a/tests/test_logging.py +++ b/tests/test_logging.py @@ -26,16 +26,22 @@ class TestLogging(TestCase): def setUp(self): pass # do not chdir + def tearDown(self): + super().tearDown() + disableLogging() + def test_loglevel_inheritance(self): initLogging(builtin_only=True) ocrd_logger = logging.getLogger('ocrd') assert ocrd_logger.getEffectiveLevel() == logging.INFO some_logger = getLogger('ocrd.foo') + assert some_logger.level == logging.NOTSET assert some_logger.getEffectiveLevel() == logging.INFO setOverrideLogLevel('ERROR') assert ocrd_logger.getEffectiveLevel() == logging.ERROR assert some_logger.getEffectiveLevel() == logging.ERROR another_logger = getLogger('ocrd.bar') + assert another_logger.level == logging.NOTSET assert another_logger.getEffectiveLevel() == logging.ERROR def test_getLevelName(self): diff --git a/tests/test_logging_conf.py b/tests/test_logging_conf.py index f8e0e9e89..071767410 100644 --- a/tests/test_logging_conf.py +++ b/tests/test_logging_conf.py @@ -21,74 +21,67 @@ # sys.path.append(os.path.dirname(os.path.realpath(__file__)) + '/../ocrd') TEST_ROOT = pathlib.Path(os.path.dirname(os.path.abspath(__file__))).parent -def resetLogging(): - disableLogging() - initLogging() - - @pytest.fixture(name="logging_conf") -def _fixture_logging_conf(tmpdir): +def _fixture_logging_conf(tmpdir, capfd): path_logging_conf_orig = os.path.join( str(TEST_ROOT), 'src', 'ocrd_utils', 'ocrd_logging.conf') path_logging_conf_dest = os.path.join(str(tmpdir), 'ocrd_logging.conf') shutil.copy(path_logging_conf_orig, path_logging_conf_dest) - return str(tmpdir) + with pushd_popd(tmpdir): + with capfd.disabled(): + initLogging() + yield str(tmpdir) + disableLogging() -def test_configured_dateformat(logging_conf, capsys): +def test_configured_dateformat(logging_conf, capfd): """Ensure example ocrd_logging.conf is valid and produces desired record format""" # arrange - with pushd_popd(logging_conf): - resetLogging() - test_logger = getLogger('') + test_logger = getLogger('ocrd') - # act - test_logger.info("test logger initialized") + # act + test_logger.info("test logger initialized") - log_info_output = capsys.readouterr().err - must_not_match = r"^\d{4}-\d{2}-\d{2}.*" - assert not re.match(must_not_match, log_info_output) - match_pattern = r"^\d{2}:\d{2}:\d{2}.*" - assert re.match(match_pattern, log_info_output) + log_info_output = capfd.readouterr().err + must_not_match = r"^\d{4}-\d{2}-\d{2}.*" + assert not re.match(must_not_match, log_info_output) + match_pattern = r"^\d{2}:\d{2}:\d{2}.*" + assert re.match(match_pattern, log_info_output), log_info_output -def test_configured_tensorflow_logger_present(logging_conf, capsys): +def test_configured_tensorflow_logger_present(logging_conf, capfd): """Ensure example ocrd_logging.conf is valid and contains logger tensorflow""" # arrange - os.chdir(logging_conf) - resetLogging() logger_under_test = getLogger('tensorflow') # act info logger_under_test.info("tensorflow logger initialized") - log_info_output = capsys.readouterr().err + log_info_output = capfd.readouterr().err assert not log_info_output # act error logger_under_test.error("tensorflow has error") - log_error_output = capsys.readouterr().err + log_error_output = capfd.readouterr().err assert log_error_output -def test_configured_shapely_logger_present(logging_conf, capsys): +def test_configured_shapely_logger_present(logging_conf, capfd): """Ensure example ocrd_logging.conf is valid and contains logger shapely.geos""" # arrange - os.chdir(logging_conf) - resetLogging() logger_under_test = getLogger('shapely.geos') # act info logger_under_test.info("shapely.geos logger initialized") - log_info_output = capsys.readouterr().err + log_info_output = capfd.readouterr().err assert not log_info_output # act error logger_under_test.error("shapely alert") - log_error_output = capsys.readouterr().err + log_error_output = capfd.readouterr().err assert log_error_output if __name__ == '__main__': diff --git a/tests/test_mets_server.py b/tests/test_mets_server.py index dc94d6c56..3bb96535c 100644 --- a/tests/test_mets_server.py +++ b/tests/test_mets_server.py @@ -22,20 +22,17 @@ from requests.exceptions import ConnectionError from ocrd import Resolver, OcrdMetsServer, Workspace -from ocrd_utils import pushd_popd, MIMETYPE_PAGE, initLogging, setOverrideLogLevel +from ocrd_utils import pushd_popd, MIMETYPE_PAGE, initLogging, setOverrideLogLevel, disableLogging, getLogger TRANSPORTS = ['/tmp/ocrd-mets-server.sock', 'http://127.0.0.1:12345'] -initLogging() -setOverrideLogLevel(10) - @fixture(scope='function', name='start_mets_server', params=TRANSPORTS) def fixture_start_mets_server(request, tmpdir) -> Iterable[Tuple[str, Workspace]]: - tmpdir = str(tmpdir) - def _start_mets_server(*args, **kwargs): - mets_server = OcrdMetsServer(*args, **kwargs) - mets_server.startup() + initLogging() + #setOverrideLogLevel(10) + logger = getLogger('ocrd') + tmpdir = str(tmpdir) mets_server_url = request.param if mets_server_url == TRANSPORTS[0]: @@ -47,13 +44,26 @@ def _start_mets_server(*args, **kwargs): copytree(assets.path_to('SBB0000F29300010000/data'), tmpdir) workspace = Workspace(Resolver(), tmpdir) - p = Process(target=_start_mets_server, kwargs={'workspace': workspace, 'url': request.param}) + class MetsServerProcess(Process): + def __init__(self, *args, **kwargs): + self.server = OcrdMetsServer(*args, **kwargs) + super().__init__() + def run(self): + self.server.startup() + def terminate(self): + self.server.workspace.save_mets() + super().terminate() + p = MetsServerProcess(workspace=workspace, url=request.param) p.start() + logger.info("started METS Server") sleep(1) # sleep to start up server workspace_server = Workspace(Resolver(), tmpdir, mets_server_url=mets_server_url) yield mets_server_url, workspace_server p.terminate() + p.join() + logger.info("terminated METS Server") rmtree(tmpdir, ignore_errors=True) + disableLogging() def add_file_server(x, force=False): mets_server_url, directory, i = x From 192895afd5c38314e9a7de59b866b8bfedf1f523 Mon Sep 17 00:00:00 2001 From: Robert Sachunsky Date: Mon, 11 Nov 2024 13:34:10 +0000 Subject: [PATCH 8/8] initLogging: call disableLogging if already initialized and force_reinit --- src/ocrd_utils/logging.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ocrd_utils/logging.py b/src/ocrd_utils/logging.py index c56c1401f..addd1cfca 100644 --- a/src/ocrd_utils/logging.py +++ b/src/ocrd_utils/logging.py @@ -152,8 +152,11 @@ def initLogging(builtin_only=False, force_reinit=False, silent=not config.OCRD_L - silent (bool, True): Whether to log logging behavior by printing to stderr """ global _initialized_flag - if _initialized_flag and not force_reinit: - return + if _initialized_flag: + if force_reinit: + disableLogging(silent=silent) + else: + return config_file = None if not builtin_only: