diff --git a/force_bdss/bdss_application.py b/force_bdss/bdss_application.py index 2cc751620af346bcad03a6db223f75ec4faaa29c..4f498eb497a6206b8a3cebf37658083336381ba8 100644 --- a/force_bdss/bdss_application.py +++ b/force_bdss/bdss_application.py @@ -12,6 +12,8 @@ from .factory_registry_plugin import FactoryRegistryPlugin from .core_evaluation_driver import CoreEvaluationDriver from .core_mco_driver import CoreMCODriver +log = logging.getLogger(__name__) + class BDSSApplication(Application): """Main application for the BDSS. @@ -47,7 +49,7 @@ class BDSSApplication(Application): try: mgr.map(functools.partial(_import_extensions, plugins)) except NoMatches: - logging.info("No extensions found") + log.info("No extensions found") super(BDSSApplication, self).__init__(plugins=plugins) @@ -56,7 +58,7 @@ def _import_extensions(plugins, ext): """Service routine extracted for testing. Imports the extension in the plugins argument. """ - logging.info("Found extension {}".format(ext.obj)) + log.info("Found extension {}".format(ext.obj)) plugins.append(ext.obj) @@ -65,7 +67,8 @@ def _load_failure_callback(plugins, manager, entry_point, exception): Reports failure to load a module through stevedore, using the on_load_failure_callback option. """ - logging.error( + log.error( "Unable to load plugin {}. Exception: {}. Message: {}".format( entry_point, exception.__class__.__name__, exception) ) + log.exception(exception) diff --git a/force_bdss/cli/force_bdss.py b/force_bdss/cli/force_bdss.py index 48ce95353a49a5531c68bd09d4e441c7151179d7..40503ce5116ce15db3d00e9f85d726b10d028c3b 100644 --- a/force_bdss/cli/force_bdss.py +++ b/force_bdss/cli/force_bdss.py @@ -1,3 +1,4 @@ +import logging import click from ..bdss_application import BDSSApplication @@ -10,12 +11,26 @@ push_exception_handler(reraise_exceptions=True) @click.command() @click.option("--evaluate", is_flag=True) +@click.option("--logfile", + type=click.Path(exists=False), + help="If specified, the log filename. " + " If unspecified, the log will be written to stdout.") @click.argument('workflow_filepath', type=click.Path(exists=True)) -def run(evaluate, workflow_filepath): +def run(evaluate, logfile, workflow_filepath): - application = BDSSApplication( - evaluate=evaluate, - workflow_filepath=workflow_filepath - ) + logging_config = {} + if logfile is not None: + logging_config["filename"] = logfile - application.run() + logging.basicConfig(**logging_config) + log = logging.getLogger(__name__) + + try: + application = BDSSApplication( + evaluate=evaluate, + workflow_filepath=workflow_filepath + ) + + application.run() + except Exception as e: + log.exception(e) diff --git a/force_bdss/core_evaluation_driver.py b/force_bdss/core_evaluation_driver.py index 33fc4755a456ad4c0609b0365c643e8f844641a5..1f4b9dc42b10b5d10d9e3719246628cd5ed1f88f 100644 --- a/force_bdss/core_evaluation_driver.py +++ b/force_bdss/core_evaluation_driver.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import sys import logging @@ -14,6 +12,8 @@ from .io.workflow_reader import ( CORE_EVALUATION_DRIVER_ID = plugin_id("core", "CoreEvaluationDriver") +log = logging.getLogger(__name__) + class CoreEvaluationDriver(BaseCoreDriver): """Main plugin that handles the execution of the MCO @@ -26,12 +26,12 @@ class CoreEvaluationDriver(BaseCoreDriver): try: workflow = self.workflow except (InvalidVersionException, InvalidFileException) as e: - print(str(e), file=sys.stderr) + log.exception(e) sys.exit(1) mco_model = workflow.mco if mco_model is None: - print("No MCO defined. Nothing to do. Exiting.") + log.info("No MCO defined. Nothing to do. Exiting.") sys.exit(0) mco_factory = mco_model.factory @@ -105,7 +105,7 @@ def _compute_layer_results(environment_data_values, in_slots) # execute data source, passing only relevant data values. - logging.info("Evaluating for Data Source {}".format( + log.info("Evaluating for Data Source {}".format( factory.name)) res = evaluator.run(model, passed_data_values) @@ -118,7 +118,7 @@ def _compute_layer_results(environment_data_values, len(res), factory.name, len(out_slots) ) - logging.error(error_txt) + log.error(error_txt) raise RuntimeError(error_txt) if len(res) != len(model.output_slot_names): @@ -133,7 +133,7 @@ def _compute_layer_results(environment_data_values, len(model.output_slot_names) ) - logging.error(error_txt) + log.error(error_txt) raise RuntimeError(error_txt) # At this point, the returned data values are unnamed. @@ -173,7 +173,7 @@ def _get_data_values_from_mco(model, communicator): " file is corrupted.").format( len(mco_data_values), len(model.parameters) ) - logging.error(error_txt) + log.error(error_txt) raise RuntimeError(error_txt) # The data values obtained by the communicator are unnamed. diff --git a/force_bdss/core_mco_driver.py b/force_bdss/core_mco_driver.py index 478499af138b50ee6ecdd1abe0ca95e583d37e85..ea2cbfafbec5683480450ec2854d402137d2b717 100644 --- a/force_bdss/core_mco_driver.py +++ b/force_bdss/core_mco_driver.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import sys import logging @@ -44,12 +42,12 @@ class CoreMCODriver(BaseCoreDriver): try: workflow = self.workflow except (InvalidVersionException, InvalidFileException) as e: - print(str(e), file=sys.stderr) + log.exception(e) sys.exit(1) mco_model = workflow.mco if mco_model is None: - print("No MCO defined. Nothing to do. Exiting.") + log.info("No MCO defined. Nothing to do. Exiting.") sys.exit(0) mco_factory = mco_model.factory diff --git a/force_bdss/io/tests/test_workflow_writer.py b/force_bdss/io/tests/test_workflow_writer.py index 7d649c067abf006eb9e71dd36feea441610fe1dd..74a8dbf90ff1b776f1bccbc9f40a73462a1d16cf 100644 --- a/force_bdss/io/tests/test_workflow_writer.py +++ b/force_bdss/io/tests/test_workflow_writer.py @@ -53,7 +53,6 @@ class TestWorkflowWriter(unittest.TestCase): fp = StringIO() wf = self._create_mock_workflow() wfwriter.write(wf, fp) - print(fp.getvalue()) fp.seek(0) wfreader = WorkflowReader(self.mock_registry) wf_result = wfreader.read(fp) diff --git a/force_bdss/io/workflow_reader.py b/force_bdss/io/workflow_reader.py index 19d4ecbb9b06309cc1169d7cd465da32558543f2..748479e2ecc1ef31d48c5036fbd705a1021c04f3 100644 --- a/force_bdss/io/workflow_reader.py +++ b/force_bdss/io/workflow_reader.py @@ -7,6 +7,8 @@ from force_bdss.core.input_slot_map import InputSlotMap from force_bdss.core.workflow import Workflow from ..factory_registry_plugin import IFactoryRegistryPlugin +log = logging.getLogger(__name__) + SUPPORTED_FILE_VERSIONS = ["1"] @@ -69,12 +71,12 @@ class WorkflowReader(HasStrictTraits): try: version = json_data["version"] except KeyError: - logging.error("File missing version information") + log.error("File missing version information") raise InvalidFileException("Corrupted input file, no version" " specified") if version not in SUPPORTED_FILE_VERSIONS: - logging.error( + log.error( "File contains version {} that is not in the " "list of supported versions {}".format( version, SUPPORTED_FILE_VERSIONS) @@ -92,7 +94,7 @@ class WorkflowReader(HasStrictTraits): wf.notification_listeners[:] = \ self._extract_notification_listeners(wf_data) except KeyError as e: - logging.exception("Could not read file {}".format(file)) + log.exception("Could not read file {}".format(file)) raise InvalidFileException("Could not read file {}. " "Unable to find key {}".format(file, e)) return wf