Skip to content

Commit

Permalink
Major bug fix to logger class. CSV files and log paths are respected …
Browse files Browse the repository at this point in the history
…now.
  • Loading branch information
senthurayyappan committed Nov 21, 2024
1 parent 554e09c commit ba56f3f
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 26 deletions.
2 changes: 1 addition & 1 deletion opensourceleg/logging/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def decorator(func: Callable) -> Callable:
@wraps(func)
def wrapper(*args: Any, **kwargs: Any) -> Any:
LOGGER.warning(
f"Function `{func.__name__}` is deprecated. Please use `{alternative_func.__name__}` instead,"
f"Function `{func.__name__}` is deprecated. Please use `{alternative_func.__name__}` instead, "
"which will be called automatically now."
)
return alternative_func(*args, **kwargs)
Expand Down
4 changes: 2 additions & 2 deletions opensourceleg/logging/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class ActuatorIsNoneException(Exception):

def __init__(self, mode: str) -> None:
super().__init__(
f"Actuator is None in {mode} mode, please pass the actuator instance to the mode during"
f"Actuator is None in {mode} mode, please pass the actuator instance to the mode during "
"initialization or set the actuator instance using set_actuator method."
)

Expand Down Expand Up @@ -89,6 +89,6 @@ class ActuatorKeyException(Exception):

def __init__(self, tag: str, key: str) -> None:
super().__init__(
f"{tag} does not have {key} key in the actuators dictionary."
f"{tag} does not have {key} key in the actuators dictionary. "
f"Please check the actuators dictionary for the `{key}` key."
)
45 changes: 26 additions & 19 deletions opensourceleg/logging/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
from typing import Any, Callable, Optional, Union


class LogLevel(Enum):
class LogLevel(int, Enum):
DEBUG = logging.DEBUG
INFO = logging.INFO
WARNING = logging.WARNING
Expand Down Expand Up @@ -72,8 +72,8 @@ def __init__(
self._file_backup_count = file_backup_count
self._user_file_name = file_name

self._file_path: str = ""
self._csv_path: str = ""
self._file_path: Optional[str] = None
self._csv_path: Optional[str] = None
self._file: Optional[Any] = None
self._writer: Any = None
self._is_logging = False
Expand All @@ -87,6 +87,7 @@ def __init__(
self._setup_logging()
self._initialized: bool = True
else:
self._log_path = log_path
self.set_file_name(file_name)
self.set_file_level(file_level)
self.set_stream_level(stream_level)
Expand All @@ -95,28 +96,26 @@ def __init__(
self._file_backup_count = file_backup_count
self.set_buffer_size(buffer_size)

self._log_path = log_path

def _setup_logging(self) -> None:
self.setLevel(level=self._file_level.value)
self.setLevel(level=self._file_level)
self._std_formatter = logging.Formatter(self._log_format)

self._stream_handler = logging.StreamHandler()
self._stream_handler.setLevel(level=self._stream_level.value)
self._stream_handler.setLevel(level=self._stream_level)
self._stream_handler.setFormatter(fmt=self._std_formatter)
self.addHandler(hdlr=self._stream_handler)

def _setup_file_handler(self) -> None:
if self._file_path == "":
if not self._file_path:
self._generate_file_paths()

self._file_handler = RotatingFileHandler(
filename=self._file_path,
mode="a",
mode="w",
maxBytes=self._file_max_bytes,
backupCount=self._file_backup_count,
)
self._file_handler.setLevel(level=self._file_level.value)
self._file_handler.setLevel(level=self._file_level)
self._file_handler.setFormatter(fmt=self._std_formatter)
self.addHandler(hdlr=self._file_handler)

Expand All @@ -139,17 +138,16 @@ def __repr__(self) -> str:

def set_file_name(self, file_name: Union[str, None]) -> None:
self._user_file_name = file_name
self._file_path = ""
self._csv_path = ""
self._generate_file_paths()

def set_file_level(self, level: LogLevel) -> None:
self._file_level = level
if hasattr(self, "_file_handler"):
self._file_handler.setLevel(level=level.value)
self._file_handler.setLevel(level=level)

def set_stream_level(self, level: LogLevel) -> None:
self._stream_level = level
self._stream_handler.setLevel(level=level.value)
self._stream_handler.setLevel(level=level)

def set_format(self, log_format: str) -> None:
self._log_format = log_format
Expand Down Expand Up @@ -183,7 +181,7 @@ def flush_buffer(self) -> None:
self._ensure_file_handler()

if self._file is None:
self._file = open(self._csv_path, "a", newline="")
self._file = open(self._csv_path, "w", newline="")
self._writer = csv.writer(self._file)

if not self._header_written:
Expand All @@ -206,15 +204,21 @@ def _generate_file_paths(self) -> None:

base_name = self._user_file_name if self._user_file_name else f"{script_name}_{timestamp}"

if not os.path.exists(self._log_path):
os.makedirs(self._log_path)

file_path = os.path.join(self._log_path, base_name)

self._file_path = file_path + ".log"
self._csv_path = file_path + ".csv"

# Log the generated file paths for debugging
self.debug(f"Generated file paths: log file - {self._file_path}, csv file - {self._csv_path}")

def __enter__(self) -> "Logger":
return self

def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
self.flush_buffer()
self.close()

def reset(self) -> None:
Expand All @@ -227,6 +231,8 @@ def reset(self) -> None:
del self._file_handler

def close(self) -> None:
self.flush_buffer()

if self._file:
self._file.close()
self._file = None
Expand Down Expand Up @@ -258,7 +264,7 @@ def log(self, level: int, msg: object, *args: object, **kwargs: Any) -> None:

@property
def file_path(self) -> str:
if self._file_path == "":
if not self._file_path:
self._generate_file_paths()
return self._file_path

Expand Down Expand Up @@ -295,15 +301,16 @@ def __init__(self) -> None:
def update(self) -> None:
self.a += 0.2

my_logger = Logger(buffer_size=5000, file_name="my_log")
my_logger = Logger(buffer_size=5000, file_name="test_logger", log_path="./logs")
x = 0.0
y = 0.0

test = Test()

my_logger.track_variable(lambda: x, "x")
my_logger.track_variable(lambda: y, "y")
LOGGER.track_variable(lambda: test.a, "A")
my_logger.track_variable(lambda: test.a, "A")
my_logger.info("Starting logging...")

for _i in range(1000):
x += 0.1
Expand Down
2 changes: 1 addition & 1 deletion tests/test_safety/test_safety.py
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,7 @@ def test_start():

test_manager.start()
with pytest.raises(ValueError, match="Value must be negative"):
pass
_ = samp.test


# Test update & safe objects
Expand Down
6 changes: 3 additions & 3 deletions tests/test_time/test_time.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ def test_loopkiller_init():

lk = LoopKiller()
assert lk._fade_time == 0.0
assert lk._soft_kill_time is None
assert lk._soft_kill_time == 0.0
lk1 = LoopKiller(fade_time=1.0)
assert lk1._fade_time == 1.0
assert lk1._soft_kill_time is None
assert lk1._soft_kill_time == 0.0
assert lk1._kill_now is False
assert lk1._kill_soon is False

Expand Down Expand Up @@ -85,7 +85,7 @@ def test_loopkiller_kill_now_setter(patch_time_time2):
lkkns.kill_now = False
assert lkkns._kill_now is False
assert lkkns._kill_soon is False
assert lkkns._soft_kill_time is None
assert lkkns._soft_kill_time == 0.0
lkkns.kill_now = True
assert lkkns._kill_soon is True
assert lkkns._soft_kill_time == 0.0
Expand Down

0 comments on commit ba56f3f

Please sign in to comment.