Merged PR 244: Make pcap and sys logging optional (beta 4)

## Summary
Very straightforward change. Just added some config parameters to make pcap and sys logs optional. These options default to false.

## Test process
Verified that both options produce the desired result by running a primaite session with logs enabled and disabled in the config. Unit tests still pass.

## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [x] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code

Related work items: #2143, #2154
This commit is contained in:
Marek Wolan
2024-01-05 12:40:13 +00:00
7 changed files with 34 additions and 13 deletions

View File

@@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased] ## [Unreleased]
- Made packet capture and system logging optional
### Added ### Added

View File

@@ -14,6 +14,8 @@ io_settings:
save_checkpoints: true save_checkpoints: true
checkpoint_interval: 5 checkpoint_interval: 5
save_step_metadata: false save_step_metadata: false
save_pcap_logs: true
save_sys_logs: true
game: game:

View File

@@ -24,9 +24,13 @@ class SessionIOSettings(BaseModel):
save_transactions: bool = True save_transactions: bool = True
"""Whether to save transactions, If true, the session path will have a transactions folder.""" """Whether to save transactions, If true, the session path will have a transactions folder."""
save_tensorboard_logs: bool = False save_tensorboard_logs: bool = False
"""Whether to save tensorboard logs. If true, the session path will have a tenorboard_logs folder.""" """Whether to save tensorboard logs. If true, the session path will have a tensorboard_logs folder."""
save_step_metadata: bool = False save_step_metadata: bool = False
"""Whether to save the RL agents' action, environment state, and other data at every single step.""" """Whether to save the RL agents' action, environment state, and other data at every single step."""
save_pcap_logs: bool = False
"""Whether to save PCAP logs."""
save_sys_logs: bool = False
"""Whether to save system logs."""
class SessionIO: class SessionIO:
@@ -39,9 +43,10 @@ class SessionIO:
def __init__(self, settings: SessionIOSettings = SessionIOSettings()) -> None: def __init__(self, settings: SessionIOSettings = SessionIOSettings()) -> None:
self.settings: SessionIOSettings = settings self.settings: SessionIOSettings = settings
self.session_path: Path = self.generate_session_path() self.session_path: Path = self.generate_session_path()
# set global SIM_OUTPUT path # set global SIM_OUTPUT path
SIM_OUTPUT.path = self.session_path / "simulation_output" SIM_OUTPUT.path = self.session_path / "simulation_output"
SIM_OUTPUT.save_pcap_logs = self.settings.save_pcap_logs
SIM_OUTPUT.save_sys_logs = self.settings.save_sys_logs
# warning TODO: must be careful not to re-initialise sessionIO because it will create a new path each time it's # warning TODO: must be careful not to re-initialise sessionIO because it will create a new path each time it's
# possible refactor needed # possible refactor needed

View File

@@ -54,7 +54,7 @@ class PrimaiteSession:
self.policy: PolicyABC self.policy: PolicyABC
"""The reinforcement learning policy.""" """The reinforcement learning policy."""
self.io_manager = SessionIO() self.io_manager: Optional["SessionIO"] = None
"""IO manager for the session.""" """IO manager for the session."""
self.game: PrimaiteGame = game self.game: PrimaiteGame = game

View File

@@ -7,11 +7,13 @@ from primaite import _PRIMAITE_ROOT
__all__ = ["SIM_OUTPUT"] __all__ = ["SIM_OUTPUT"]
class __SimOutput: class _SimOutput:
def __init__(self): def __init__(self):
self._path: Path = ( self._path: Path = (
_PRIMAITE_ROOT.parent.parent / "simulation_output" / datetime.now().strftime("%Y-%m-%d_%H-%M-%S") _PRIMAITE_ROOT.parent.parent / "simulation_output" / datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
) )
self.save_pcap_logs: bool = False
self.save_sys_logs: bool = False
@property @property
def path(self) -> Path: def path(self) -> Path:
@@ -23,4 +25,4 @@ class __SimOutput:
self._path.mkdir(exist_ok=True, parents=True) self._path.mkdir(exist_ok=True, parents=True)
SIM_OUTPUT = __SimOutput() SIM_OUTPUT = _SimOutput()

View File

@@ -41,6 +41,9 @@ class PacketCapture:
def setup_logger(self): def setup_logger(self):
"""Set up the logger configuration.""" """Set up the logger configuration."""
if not SIM_OUTPUT.save_pcap_logs:
return
log_path = self._get_log_path() log_path = self._get_log_path()
file_handler = logging.FileHandler(filename=log_path) file_handler = logging.FileHandler(filename=log_path)
@@ -88,5 +91,6 @@ class PacketCapture:
:param frame: The PCAP frame to capture. :param frame: The PCAP frame to capture.
""" """
msg = frame.model_dump_json() if SIM_OUTPUT.save_pcap_logs:
self.logger.log(level=60, msg=msg) # Log at custom log level > CRITICAL msg = frame.model_dump_json()
self.logger.log(level=60, msg=msg) # Log at custom log level > CRITICAL

View File

@@ -41,6 +41,9 @@ class SysLog:
The logger is set to the DEBUG level, and is equipped with a handler that writes to a file and filters out The logger is set to the DEBUG level, and is equipped with a handler that writes to a file and filters out
JSON-like messages. JSON-like messages.
""" """
if not SIM_OUTPUT.save_sys_logs:
return
log_path = self._get_log_path() log_path = self._get_log_path()
file_handler = logging.FileHandler(filename=log_path) file_handler = logging.FileHandler(filename=log_path)
file_handler.setLevel(logging.DEBUG) file_handler.setLevel(logging.DEBUG)
@@ -91,7 +94,8 @@ class SysLog:
:param msg: The message to be logged. :param msg: The message to be logged.
""" """
self.logger.debug(msg) if SIM_OUTPUT.save_sys_logs:
self.logger.debug(msg)
def info(self, msg: str): def info(self, msg: str):
""" """
@@ -99,7 +103,8 @@ class SysLog:
:param msg: The message to be logged. :param msg: The message to be logged.
""" """
self.logger.info(msg) if SIM_OUTPUT.save_sys_logs:
self.logger.info(msg)
def warning(self, msg: str): def warning(self, msg: str):
""" """
@@ -107,7 +112,8 @@ class SysLog:
:param msg: The message to be logged. :param msg: The message to be logged.
""" """
self.logger.warning(msg) if SIM_OUTPUT.save_sys_logs:
self.logger.warning(msg)
def error(self, msg: str): def error(self, msg: str):
""" """
@@ -115,7 +121,8 @@ class SysLog:
:param msg: The message to be logged. :param msg: The message to be logged.
""" """
self.logger.error(msg) if SIM_OUTPUT.save_sys_logs:
self.logger.error(msg)
def critical(self, msg: str): def critical(self, msg: str):
""" """
@@ -123,4 +130,5 @@ class SysLog:
:param msg: The message to be logged. :param msg: The message to be logged.
""" """
self.logger.critical(msg) if SIM_OUTPUT.save_sys_logs:
self.logger.critical(msg)