Skip to content

Commit

Permalink
Streamline logging architecture
Browse files Browse the repository at this point in the history
  • Loading branch information
bruno-f-cruz committed Oct 29, 2024
1 parent 83b9f6a commit 00e19c0
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 45 deletions.
7 changes: 6 additions & 1 deletion src/aind_behavior_experiment_launcher/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
__version__ = "0.2.0-rc3"
__version__ = "0.2.0-rc4"

import logging
import logging.config

logger = logging.getLogger(__name__)

fmt = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"

logging.basicConfig(level=logging.INFO, format=fmt, datefmt="%Y-%m-%dT%H%M%S%z")
13 changes: 6 additions & 7 deletions src/aind_behavior_experiment_launcher/launcher/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@
AindBehaviorTaskLogicModel,
)

import aind_behavior_experiment_launcher
from aind_behavior_experiment_launcher import ui_helper
from aind_behavior_experiment_launcher.logging import logging_helper
from aind_behavior_experiment_launcher import logging_helper, ui_helper
from aind_behavior_experiment_launcher.services import ServicesFactoryManager

TRig = TypeVar("TRig", bound=AindBehaviorRigModel) # pylint: disable=invalid-name
Expand Down Expand Up @@ -58,11 +56,12 @@ def __init__(
self.temp_dir.mkdir(parents=True, exist_ok=True)

if attached_logger:
logging_helper.default_logger_builder(attached_logger, self.temp_dir / "launcher.log")
_logger = logging_helper.add_file_logger(attached_logger, self.temp_dir / "launcher.log")
else:
logging_helper.default_logger_builder(
aind_behavior_experiment_launcher.logger, self.temp_dir / "launcher.log"
)
_logger = logging_helper.add_file_logger(logger, self.temp_dir / "launcher.log")

if debug_mode:
_logger.setLevel(logging.DEBUG)

self._ui_helper = ui_helper.UIHelper()
self._cli_args = self._cli_wrapper()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@
from aind_behavior_services.utils import model_from_json_file, utcnow
from typing_extensions import override

from aind_behavior_experiment_launcher import logging_helper
from aind_behavior_experiment_launcher.apps.app_service import BonsaiApp
from aind_behavior_experiment_launcher.data_mappers.aind_data_schema import AindDataSchemaSessionDataMapper
from aind_behavior_experiment_launcher.data_mappers.data_mapper_service import DataMapperService
from aind_behavior_experiment_launcher.data_transfer.data_transfer_service import DataTransferService
from aind_behavior_experiment_launcher.data_transfer.robocopy_service import RobocopyService
from aind_behavior_experiment_launcher.data_transfer.watchdog_service import WatchdogDataTransferService
from aind_behavior_experiment_launcher.launcher import BaseLauncher, TRig, TSession, TTaskLogic
from aind_behavior_experiment_launcher.logging import logging_helper
from aind_behavior_experiment_launcher.resource_monitor.resource_monitor_service import ResourceMonitor
from aind_behavior_experiment_launcher.services import IService, ServiceFactory, ServicesFactoryManager

Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
import datetime
import logging
import os
import sys
from pathlib import Path
from typing import Optional, TypeVar
from typing import TypeVar

import aind_behavior_services.utils as utils

from aind_behavior_experiment_launcher import fmt

TLogger = TypeVar("TLogger", bound=logging.Logger)


def default_logger_builder(logger: TLogger, output_path: Optional[os.PathLike]) -> logging.Logger:
logger.setLevel(logging.INFO)
fmt = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
utc_formatter = _TzFormatter(fmt, tz=datetime.timezone.utc)
tz_formatter = _TzFormatter(fmt)
class _TzFormatter(logging.Formatter):
def __init__(self, *args, **kwargs):
self._tz = kwargs.pop("tz", None)
super().__init__(*args, **kwargs)

def formatTime(self, record, datefmt=None) -> str:
record_time = datetime.datetime.fromtimestamp(record.created, tz=self._tz)
return utils.format_datetime(record_time)


utc_formatter = _TzFormatter(fmt, tz=datetime.timezone.utc)

console_handler = logging.StreamHandler(sys.stdout)
console_handler.setFormatter(tz_formatter)
logger.addHandler(console_handler)

if output_path is not None:
file_handler = logging.FileHandler(Path(output_path), encoding="utf-8", mode="w")
file_handler.setFormatter(utc_formatter)
logger.addHandler(file_handler)
def add_file_logger(logger: TLogger, output_path: os.PathLike) -> TLogger:
file_handler = logging.FileHandler(Path(output_path), encoding="utf-8", mode="w")
file_handler.setFormatter(utc_formatter)
logger.addHandler(file_handler)
return logger


Expand All @@ -37,13 +41,3 @@ def close_file_handlers(logger: TLogger) -> TLogger:
if isinstance(handler, logging.FileHandler):
handler.close()
return logger


class _TzFormatter(logging.Formatter):
def __init__(self, *args, **kwargs):
self._tz = kwargs.pop("tz", None)
super().__init__(*args, **kwargs)

def formatTime(self, record, datefmt=None) -> str:
record_time = datetime.datetime.fromtimestamp(record.created, tz=self._tz)
return utils.format_datetime(record_time)
16 changes: 4 additions & 12 deletions tests/test_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,24 @@
from pathlib import Path
from unittest.mock import MagicMock, patch

from aind_behavior_experiment_launcher.logging.logging_helper import default_logger_builder
from aind_behavior_experiment_launcher.logging_helper import add_file_logger


class TestLoggingHelper(unittest.TestCase):
def setUp(self):
self.logger = logging.getLogger("test_logger")
self.logger.handlers = [] # Clear existing handlers

def test_default_logger_builder_no_output_path(self):
logger = default_logger_builder(self.logger, None)
self.assertEqual(logger.level, logging.INFO)
self.assertEqual(len(logger.handlers), 1)
self.assertIsInstance(logger.handlers[0], logging.StreamHandler)

@patch("logging.FileHandler")
def test_default_logger_builder_with_output_path(self, mock_file_handler):
mock_file_handler_instance = MagicMock()
mock_file_handler.return_value = mock_file_handler_instance

output_path = Path("/fake/path/to/logfile.log")
logger = default_logger_builder(self.logger, output_path)
logger = add_file_logger(self.logger, output_path)

self.assertEqual(logger.level, logging.INFO)
self.assertEqual(len(logger.handlers), 2)
self.assertIsInstance(logger.handlers[0], logging.StreamHandler)
self.assertEqual(logger.handlers[1], mock_file_handler_instance)
self.assertEqual(len(logger.handlers), 1)
self.assertEqual(logger.handlers[0], mock_file_handler_instance)
mock_file_handler.assert_called_once_with(output_path, encoding="utf-8", mode="w")


Expand Down

0 comments on commit 00e19c0

Please sign in to comment.