From b8d4a8cc8dbd4f81cf13b78489faddfdafa1ab1b Mon Sep 17 00:00:00 2001 From: Czar Echavez Date: Fri, 19 Apr 2024 11:37:52 +0100 Subject: [PATCH] #2470: changed default log level to warning + changed sys logging in code to be more aligned with severity of messages --- .../config/_package_data/data_manipulation.yaml | 1 + src/primaite/simulator/__init__.py | 2 +- src/primaite/simulator/file_system/file.py | 2 +- .../simulator/file_system/file_system.py | 13 +++++-------- src/primaite/simulator/file_system/folder.py | 5 +---- src/primaite/simulator/network/airspace.py | 2 +- src/primaite/simulator/network/hardware/base.py | 8 ++++---- .../network/hardware/nodes/host/host_node.py | 2 +- .../network/hardware/nodes/network/router.py | 4 ++-- .../network/hardware/nodes/network/switch.py | 2 +- .../hardware/nodes/network/wireless_router.py | 2 +- .../simulator/system/applications/application.py | 5 +---- .../system/applications/database_client.py | 15 ++++++--------- .../red_applications/data_manipulation_bot.py | 16 +++++++++------- .../applications/red_applications/dos_bot.py | 4 ++-- .../red_applications/ransomware_script.py | 11 ++++------- .../simulator/system/applications/web_browser.py | 10 ++++++---- .../simulator/system/core/software_manager.py | 6 +++--- .../simulator/system/services/arp/arp.py | 4 ++-- .../system/services/database/database_service.py | 12 ++++++------ .../simulator/system/services/dns/dns_client.py | 9 +++++---- .../simulator/system/services/dns/dns_server.py | 3 ++- .../simulator/system/services/ftp/ftp_client.py | 9 +++++---- .../simulator/system/services/ftp/ftp_server.py | 3 ++- .../simulator/system/services/icmp/icmp.py | 4 ++-- .../simulator/system/services/ntp/ntp_client.py | 3 +-- .../simulator/system/services/ntp/ntp_server.py | 3 ++- .../simulator/system/services/service.py | 4 ++-- .../system/services/web_server/web_server.py | 3 ++- src/primaite/simulator/system/software.py | 10 ++++++---- 30 files changed, 87 insertions(+), 90 deletions(-) diff --git a/src/primaite/config/_package_data/data_manipulation.yaml b/src/primaite/config/_package_data/data_manipulation.yaml index 8c365320..9dea1b14 100644 --- a/src/primaite/config/_package_data/data_manipulation.yaml +++ b/src/primaite/config/_package_data/data_manipulation.yaml @@ -3,6 +3,7 @@ io_settings: save_step_metadata: false save_pcap_logs: false save_sys_logs: false + sys_log_level: WARNING game: diff --git a/src/primaite/simulator/__init__.py b/src/primaite/simulator/__init__.py index ddb098c6..3f371ee5 100644 --- a/src/primaite/simulator/__init__.py +++ b/src/primaite/simulator/__init__.py @@ -31,7 +31,7 @@ class _SimOutput: self.save_pcap_logs: bool = False self.save_sys_logs: bool = False self.write_sys_log_to_terminal: bool = False - self.sys_log_level: LogLevel = LogLevel.INFO # default log level is at INFO + self.sys_log_level: LogLevel = LogLevel.WARNING # default log level is at WARNING @property def path(self) -> Path: diff --git a/src/primaite/simulator/file_system/file.py b/src/primaite/simulator/file_system/file.py index 3a1c24df..7e2847a5 100644 --- a/src/primaite/simulator/file_system/file.py +++ b/src/primaite/simulator/file_system/file.py @@ -223,5 +223,5 @@ class File(FileSystemItemABC): self.num_access += 1 # file was accessed self.deleted = True - self.sys_log.info(f"File deleted {self.folder_name}/{self.name}") + self.sys_log.warning(f"File deleted {self.folder_name}/{self.name}") return True diff --git a/src/primaite/simulator/file_system/file_system.py b/src/primaite/simulator/file_system/file_system.py index aacb7d01..0eae6009 100644 --- a/src/primaite/simulator/file_system/file_system.py +++ b/src/primaite/simulator/file_system/file_system.py @@ -6,7 +6,6 @@ from typing import Dict, Optional from prettytable import MARKDOWN, PrettyTable -from primaite import getLogger from primaite.interface.request import RequestResponse from primaite.simulator.core import RequestManager, RequestType, SimComponent from primaite.simulator.file_system.file import File @@ -14,8 +13,6 @@ from primaite.simulator.file_system.file_type import FileType from primaite.simulator.file_system.folder import Folder from primaite.simulator.system.core.sys_log import SysLog -_LOGGER = getLogger(__name__) - class FileSystem(SimComponent): """Class that contains all the simulation File System.""" @@ -163,11 +160,11 @@ class FileSystem(SimComponent): :param folder_name: The name of the folder. """ if folder_name == "root": - self.sys_log.warning("Cannot delete the root folder.") + self.sys_log.error("Cannot delete the root folder.") return False folder = self.get_folder(folder_name) if not folder: - _LOGGER.debug(f"Cannot delete folder as it does not exist: {folder_name}") + self.sys_log.error(f"Cannot delete folder as it does not exist: {folder_name}") return False # set folder to deleted state @@ -180,7 +177,7 @@ class FileSystem(SimComponent): folder.remove_all_files() self.deleted_folders[folder.uuid] = folder - self.sys_log.info(f"Deleted folder /{folder.name} and its contents") + self.sys_log.warning(f"Deleted folder /{folder.name} and its contents") return True def delete_folder_by_id(self, folder_uuid: str) -> None: @@ -283,7 +280,7 @@ class FileSystem(SimComponent): folder = self.get_folder(folder_name, include_deleted=include_deleted) if folder: return folder.get_file(file_name, include_deleted=include_deleted) - self.sys_log.info(f"File not found /{folder_name}/{file_name}") + self.sys_log.warning(f"File not found /{folder_name}/{file_name}") def get_file_by_id( self, file_uuid: str, folder_uuid: Optional[str] = None, include_deleted: Optional[bool] = False @@ -499,7 +496,7 @@ class FileSystem(SimComponent): """ folder = self.get_folder(folder_name=folder_name) if not folder: - _LOGGER.debug(f"Cannot restore file {file_name} in folder {folder_name} as the folder does not exist.") + self.sys_log.error(f"Cannot restore file {file_name} in folder {folder_name} as the folder does not exist.") return False file = folder.get_file(file_name=file_name, include_deleted=True) diff --git a/src/primaite/simulator/file_system/folder.py b/src/primaite/simulator/file_system/folder.py index 9f176660..51b7a819 100644 --- a/src/primaite/simulator/file_system/folder.py +++ b/src/primaite/simulator/file_system/folder.py @@ -4,14 +4,11 @@ from typing import Dict, Optional from prettytable import MARKDOWN, PrettyTable -from primaite import getLogger from primaite.interface.request import RequestResponse from primaite.simulator.core import RequestManager, RequestType from primaite.simulator.file_system.file import File from primaite.simulator.file_system.file_system_item_abc import FileSystemItemABC, FileSystemItemHealthStatus -_LOGGER = getLogger(__name__) - class Folder(FileSystemItemABC): """Simulation Folder.""" @@ -254,7 +251,7 @@ class Folder(FileSystemItemABC): file.delete() self.sys_log.info(f"Removed file {file.name} (id: {file.uuid})") else: - _LOGGER.debug(f"File with UUID {file.uuid} was not found.") + self.sys_log.error(f"File with UUID {file.uuid} was not found.") def remove_file_by_id(self, file_uuid: str): """ diff --git a/src/primaite/simulator/network/airspace.py b/src/primaite/simulator/network/airspace.py index abda587e..3c5c048c 100644 --- a/src/primaite/simulator/network/airspace.py +++ b/src/primaite/simulator/network/airspace.py @@ -161,7 +161,7 @@ class WirelessNetworkInterface(NetworkInterface, ABC): return if self._connected_node.operating_state != NodeOperatingState.ON: - self._connected_node.sys_log.info( + self._connected_node.sys_log.error( f"Interface {self} cannot be enabled as the connected Node is not powered on" ) return diff --git a/src/primaite/simulator/network/hardware/base.py b/src/primaite/simulator/network/hardware/base.py index 55636356..ac78ce62 100644 --- a/src/primaite/simulator/network/hardware/base.py +++ b/src/primaite/simulator/network/hardware/base.py @@ -307,13 +307,13 @@ class WiredNetworkInterface(NetworkInterface, ABC): return False if self._connected_node.operating_state != NodeOperatingState.ON: - self._connected_node.sys_log.info( + self._connected_node.sys_log.error( f"Interface {self} cannot be enabled as the connected Node is not powered on" ) return False if not self._connected_link: - self._connected_node.sys_log.info(f"Interface {self} cannot be enabled as there is no Link connected.") + self._connected_node.sys_log.warning(f"Interface {self} cannot be enabled as there is no Link connected.") return False self.enabled = True @@ -1201,7 +1201,7 @@ class Node(SimComponent): self._nic_request_manager.add_request(new_nic_num, RequestType(func=network_interface._request_manager)) else: msg = f"Cannot connect NIC {network_interface} as it is already connected" - self.sys_log.logger.error(msg) + self.sys_log.logger.warning(msg) raise NetworkError(msg) def disconnect_nic(self, network_interface: Union[NetworkInterface, str]): @@ -1228,7 +1228,7 @@ class Node(SimComponent): self._nic_request_manager.remove_request(network_interface_num) else: msg = f"Cannot disconnect Network Interface {network_interface} as it is not connected" - self.sys_log.logger.error(msg) + self.sys_log.logger.warning(msg) raise NetworkError(msg) def ping(self, target_ip_address: Union[IPv4Address, str], pings: int = 4) -> bool: diff --git a/src/primaite/simulator/network/hardware/nodes/host/host_node.py b/src/primaite/simulator/network/hardware/nodes/host/host_node.py index 31378689..517b16e9 100644 --- a/src/primaite/simulator/network/hardware/nodes/host/host_node.py +++ b/src/primaite/simulator/network/hardware/nodes/host/host_node.py @@ -147,7 +147,7 @@ class HostARP(ARP): super()._process_arp_request(arp_packet, from_network_interface) # Unmatched ARP Request if arp_packet.target_ip_address != from_network_interface.ip_address: - self.sys_log.info( + self.sys_log.warning( f"Ignoring ARP request for {arp_packet.target_ip_address}. Current IP address is " f"{from_network_interface.ip_address}" ) diff --git a/src/primaite/simulator/network/hardware/nodes/network/router.py b/src/primaite/simulator/network/hardware/nodes/network/router.py index 5d041fd1..0e5e1bfc 100644 --- a/src/primaite/simulator/network/hardware/nodes/network/router.py +++ b/src/primaite/simulator/network/hardware/nodes/network/router.py @@ -933,7 +933,7 @@ class RouterICMP(ICMP): ) if not network_interface: - self.sys_log.error( + self.sys_log.warning( "Cannot send ICMP echo reply as there is no outbound Network Interface to use. Try configuring the " "default gateway." ) @@ -1483,7 +1483,7 @@ class Router(NetworkNode): frame.ethernet.dst_mac_addr = target_mac network_interface.send_frame(frame) else: - self.sys_log.error(f"Frame dropped as there is no route to {frame.ip.dst_ip_address}") + self.sys_log.warning(f"Frame dropped as there is no route to {frame.ip.dst_ip_address}") def configure_port(self, port: int, ip_address: Union[IPv4Address, str], subnet_mask: Union[IPv4Address, str]): """ diff --git a/src/primaite/simulator/network/hardware/nodes/network/switch.py b/src/primaite/simulator/network/hardware/nodes/network/switch.py index aa405e14..db1863e0 100644 --- a/src/primaite/simulator/network/hardware/nodes/network/switch.py +++ b/src/primaite/simulator/network/hardware/nodes/network/switch.py @@ -74,7 +74,7 @@ class SwitchPort(WiredNetworkInterface): if self.enabled: frame.decrement_ttl() if frame.ip and frame.ip.ttl < 1: - self._connected_node.sys_log.info("Frame discarded as TTL limit reached") + self._connected_node.sys_log.warning("Frame discarded as TTL limit reached") return False self.pcap.capture_inbound(frame) self._connected_node.receive_frame(frame=frame, from_network_interface=self) diff --git a/src/primaite/simulator/network/hardware/nodes/network/wireless_router.py b/src/primaite/simulator/network/hardware/nodes/network/wireless_router.py index 62332269..f66ebd27 100644 --- a/src/primaite/simulator/network/hardware/nodes/network/wireless_router.py +++ b/src/primaite/simulator/network/hardware/nodes/network/wireless_router.py @@ -68,7 +68,7 @@ class WirelessAccessPoint(IPWirelessNetworkInterface): if self.enabled: frame.decrement_ttl() if frame.ip and frame.ip.ttl < 1: - self._connected_node.sys_log.info("Frame discarded as TTL limit reached") + self._connected_node.sys_log.warning("Frame discarded as TTL limit reached") return False frame.set_received_timestamp() self.pcap.capture_inbound(frame) diff --git a/src/primaite/simulator/system/applications/application.py b/src/primaite/simulator/system/applications/application.py index ff71b51a..7ba3f8cf 100644 --- a/src/primaite/simulator/system/applications/application.py +++ b/src/primaite/simulator/system/applications/application.py @@ -2,13 +2,10 @@ from abc import abstractmethod from enum import Enum from typing import Any, Dict, Set -from primaite import getLogger from primaite.interface.request import RequestResponse from primaite.simulator.core import RequestManager, RequestType from primaite.simulator.system.software import IOSoftware, SoftwareHealthState -_LOGGER = getLogger(__name__) - class ApplicationOperatingState(Enum): """Enumeration of Application Operating States.""" @@ -99,7 +96,7 @@ class Application(IOSoftware): if self.operating_state is not self.operating_state.RUNNING: # service is not running - _LOGGER.debug(f"Cannot perform action: {self.name} is {self.operating_state.name}") + self.sys_log.error(f"Cannot perform action: {self.name} is {self.operating_state.name}") return False return True diff --git a/src/primaite/simulator/system/applications/database_client.py b/src/primaite/simulator/system/applications/database_client.py index d304c200..675ff817 100644 --- a/src/primaite/simulator/system/applications/database_client.py +++ b/src/primaite/simulator/system/applications/database_client.py @@ -2,7 +2,6 @@ from ipaddress import IPv4Address from typing import Any, Dict, Optional from uuid import uuid4 -from primaite import getLogger from primaite.interface.request import RequestResponse from primaite.simulator.core import RequestManager, RequestType from primaite.simulator.network.transmission.network_layer import IPProtocol @@ -10,8 +9,6 @@ from primaite.simulator.network.transmission.transport_layer import Port from primaite.simulator.system.applications.application import Application from primaite.simulator.system.core.software_manager import SoftwareManager -_LOGGER = getLogger(__name__) - class DatabaseClient(Application): """ @@ -136,7 +133,7 @@ class DatabaseClient(Application): self.server_ip_address = server_ip_address return True else: - self.sys_log.info( + self.sys_log.warning( f"{self.name} {connection_id=}: DatabaseClient connection to {server_ip_address} declined" ) return False @@ -156,12 +153,12 @@ class DatabaseClient(Application): def disconnect(self) -> bool: """Disconnect from the Database Service.""" if not self._can_perform_action(): - self.sys_log.error(f"Unable to disconnect - {self.name} is {self.operating_state.name}") + self.sys_log.warning(f"Unable to disconnect - {self.name} is {self.operating_state.name}") return False # if there are no connections - nothing to disconnect if not self._server_connection_id: - self.sys_log.error(f"Unable to disconnect - {self.name} has no active connections.") + self.sys_log.warning(f"Unable to disconnect - {self.name} has no active connections.") return False # if no connection provided, disconnect the first connection @@ -196,7 +193,7 @@ class DatabaseClient(Application): if success: self.sys_log.info(f"{self.name}: Query successful {sql}") return True - self.sys_log.info(f"{self.name}: Unable to run query {sql}") + self.sys_log.error(f"{self.name}: Unable to run query {sql}") return False else: software_manager: SoftwareManager = self.software_manager @@ -236,7 +233,7 @@ class DatabaseClient(Application): if not connection_id: msg = "Cannot run sql query, could not establish connection with the server." - self.parent.sys_log(msg) + self.sys_log.warning(msg) return False uuid = str(uuid4()) @@ -265,5 +262,5 @@ class DatabaseClient(Application): status_code = payload.get("status_code") self._query_success_tracker[query_id] = status_code == 200 if self._query_success_tracker[query_id]: - _LOGGER.debug(f"Received payload {payload}") + self.sys_log.debug(f"Received {payload=}") return True diff --git a/src/primaite/simulator/system/applications/red_applications/data_manipulation_bot.py b/src/primaite/simulator/system/applications/red_applications/data_manipulation_bot.py index ee276971..abb564dd 100644 --- a/src/primaite/simulator/system/applications/red_applications/data_manipulation_bot.py +++ b/src/primaite/simulator/system/applications/red_applications/data_manipulation_bot.py @@ -71,7 +71,7 @@ class DataManipulationBot(Application): """Return the database client that is installed on the same machine as the DataManipulationBot.""" db_client = self.software_manager.software.get("DatabaseClient") if db_client is None: - _LOGGER.info(f"{self.__class__.__name__} cannot find a database client on its host.") + self.sys_log.warning(f"{self.__class__.__name__} cannot find a database client on its host.") return db_client def _init_request_manager(self) -> RequestManager: @@ -127,7 +127,7 @@ class DataManipulationBot(Application): """ if self.attack_stage == DataManipulationAttackStage.NOT_STARTED: # Bypass this stage as we're not dealing with logon for now - self.sys_log.info(f"{self.name}: ") + self.sys_log.debug(f"{self.name}: ") self.attack_stage = DataManipulationAttackStage.LOGON def _perform_port_scan(self, p_of_success: Optional[float] = 0.1): @@ -145,7 +145,7 @@ class DataManipulationBot(Application): # perform the port scan port_is_open = True # Temporary; later we can implement NMAP port scan. if port_is_open: - self.sys_log.info(f"{self.name}: ") + self.sys_log.debug(f"{self.name}: ") self.attack_stage = DataManipulationAttackStage.PORT_SCAN def _perform_data_manipulation(self, p_of_success: Optional[float] = 0.1): @@ -177,7 +177,7 @@ class DataManipulationBot(Application): self.sys_log.info(f"{self.name}: Data manipulation successful") self.attack_stage = DataManipulationAttackStage.SUCCEEDED else: - self.sys_log.info(f"{self.name}: Data manipulation failed") + self.sys_log.error(f"{self.name}: Data manipulation failed") self.attack_stage = DataManipulationAttackStage.FAILED def run(self): @@ -191,7 +191,9 @@ class DataManipulationBot(Application): def attack(self) -> bool: """Perform the attack steps after opening the application.""" if not self._can_perform_action(): - _LOGGER.debug("Data manipulation application attempted to execute but it cannot perform actions right now.") + self.sys_log.warning( + "Data manipulation application attempted to execute but it cannot perform actions right now." + ) self.run() self.num_executions += 1 @@ -206,7 +208,7 @@ class DataManipulationBot(Application): if not self._can_perform_action(): return False if self.server_ip_address and self.payload: - self.sys_log.info(f"{self.name}: Running") + self.sys_log.debug(f"{self.name}: Running") self._logon() self._perform_port_scan(p_of_success=self.port_scan_p_of_success) self._perform_data_manipulation(p_of_success=self.data_manipulation_p_of_success) @@ -220,7 +222,7 @@ class DataManipulationBot(Application): return True else: - self.sys_log.error(f"{self.name}: Failed to start as it requires both a target_ip_address and payload.") + self.sys_log.warning(f"{self.name}: Failed to start as it requires both a target_ip_address and payload.") return False def apply_timestep(self, timestep: int) -> None: diff --git a/src/primaite/simulator/system/applications/red_applications/dos_bot.py b/src/primaite/simulator/system/applications/red_applications/dos_bot.py index 27a4da05..53fc9740 100644 --- a/src/primaite/simulator/system/applications/red_applications/dos_bot.py +++ b/src/primaite/simulator/system/applications/red_applications/dos_bot.py @@ -122,7 +122,7 @@ class DoSBot(DatabaseClient): # DoS bot cannot do anything without a target if not self.target_ip_address or not self.target_port: - self.sys_log.error( + self.sys_log.warning( f"{self.name} is not properly configured. {self.target_ip_address=}, {self.target_port=}" ) return True @@ -152,7 +152,7 @@ class DoSBot(DatabaseClient): # perform the port scan port_is_open = True # Temporary; later we can implement NMAP port scan. if port_is_open: - self.sys_log.info(f"{self.name}: ") + self.sys_log.debug(f"{self.name}: ") self.attack_stage = DoSAttackStage.PORT_SCAN def _perform_dos(self): diff --git a/src/primaite/simulator/system/applications/red_applications/ransomware_script.py b/src/primaite/simulator/system/applications/red_applications/ransomware_script.py index 54880271..74d8a196 100644 --- a/src/primaite/simulator/system/applications/red_applications/ransomware_script.py +++ b/src/primaite/simulator/system/applications/red_applications/ransomware_script.py @@ -2,7 +2,6 @@ from enum import IntEnum from ipaddress import IPv4Address from typing import Dict, Optional -from primaite import getLogger from primaite.game.science import simulate_trial from primaite.interface.request import RequestResponse from primaite.simulator.core import RequestManager, RequestType @@ -11,8 +10,6 @@ from primaite.simulator.network.transmission.transport_layer import Port from primaite.simulator.system.applications.application import Application from primaite.simulator.system.applications.database_client import DatabaseClient -_LOGGER = getLogger(__name__) - class RansomwareAttackStage(IntEnum): """ @@ -94,7 +91,7 @@ class RansomwareScript(Application): """Return the database client that is installed on the same machine as the Ransomware Script.""" db_client = self.software_manager.software.get("DatabaseClient") if db_client is None: - _LOGGER.info(f"{self.__class__.__name__} cannot find a database client on its host.") + self.sys_log.warning(f"{self.__class__.__name__} cannot find a database client on its host.") return db_client def _init_request_manager(self) -> RequestManager: @@ -158,7 +155,7 @@ class RansomwareScript(Application): self.attack_stage = RansomwareAttackStage.NOT_STARTED return True else: - self.sys_log.error(f"{self.name}: Failed to start as it requires both a target_ip_address and payload.") + self.sys_log.warning(f"{self.name}: Failed to start as it requires both a target_ip_address and payload.") return False def configure( @@ -254,7 +251,7 @@ class RansomwareScript(Application): def attack(self) -> bool: """Perform the attack steps after opening the application.""" if not self._can_perform_action(): - _LOGGER.debug("Ransomware application is unable to perform it's actions.") + self.sys_log.warning("Ransomware application is unable to perform it's actions.") self.run() self.num_executions += 1 return self._application_loop() @@ -289,7 +286,7 @@ class RansomwareScript(Application): self.sys_log.info(f"{self.name}: Payload failed") self.attack_stage = RansomwareAttackStage.FAILED else: - self.sys_log.error("Attack Attempted to launch too quickly") + self.sys_log.warning("Attack Attempted to launch too quickly") self.attack_stage = RansomwareAttackStage.FAILED def _local_download(self): diff --git a/src/primaite/simulator/system/applications/web_browser.py b/src/primaite/simulator/system/applications/web_browser.py index e669ca32..0e6fec00 100644 --- a/src/primaite/simulator/system/applications/web_browser.py +++ b/src/primaite/simulator/system/applications/web_browser.py @@ -97,7 +97,7 @@ class WebBrowser(Application): try: parsed_url = urlparse(url) except Exception: - self.sys_log.error(f"{url} is not a valid URL") + self.sys_log.warning(f"{url} is not a valid URL") return False # get the IP address of the domain name via DNS @@ -114,7 +114,7 @@ class WebBrowser(Application): self.domain_name_ip_address = IPv4Address(parsed_url.hostname) except Exception: # unable to deal with this request - self.sys_log.error(f"{self.name}: Unable to resolve URL {url}") + self.sys_log.warning(f"{self.name}: Unable to resolve URL {url}") return False # create HTTPRequest payload @@ -140,7 +140,8 @@ class WebBrowser(Application): ) return self.latest_response.status_code is HttpStatusCode.OK else: - self.sys_log.error(f"Error sending Http Packet {str(payload)}") + self.sys_log.warning(f"{self.name}: Error sending Http Packet") + self.sys_log.debug(f"{self.name}: {payload=}") self.history.append( WebBrowser.BrowserHistoryItem( url=url, status=self.BrowserHistoryItem._HistoryItemStatus.SERVER_UNREACHABLE @@ -181,7 +182,8 @@ class WebBrowser(Application): :return: True if successful, False otherwise. """ if not isinstance(payload, HttpResponsePacket): - self.sys_log.error(f"{self.name} received a packet that is not an HttpResponsePacket") + self.sys_log.warning(f"{self.name} received a packet that is not an HttpResponsePacket") + self.sys_log.debug(f"{self.name}: {payload=}") return False self.sys_log.info(f"{self.name}: Received HTTP {payload.status_code.value}") self.latest_response = payload diff --git a/src/primaite/simulator/system/core/software_manager.py b/src/primaite/simulator/system/core/software_manager.py index e6fe7b23..ff7f8502 100644 --- a/src/primaite/simulator/system/core/software_manager.py +++ b/src/primaite/simulator/system/core/software_manager.py @@ -87,7 +87,7 @@ class SoftwareManager: # TODO: Software manager and node itself both have an install method. Need to refactor to have more logical # separation of concerns. if software_class in self._software_class_to_name_map: - self.sys_log.info(f"Cannot install {software_class} as it is already installed") + self.sys_log.warning(f"Cannot install {software_class} as it is already installed") return software = software_class( software_manager=self, sys_log=self.sys_log, file_system=self.file_system, dns_server=self.dns_server @@ -144,7 +144,7 @@ class SoftwareManager: if receiver: receiver.receive_payload(payload) else: - self.sys_log.error(f"No Service of Application found with the name {target_software}") + self.sys_log.warning(f"No Service of Application found with the name {target_software}") def send_payload_to_session_manager( self, @@ -196,7 +196,7 @@ class SoftwareManager: payload=payload, session_id=session_id, from_network_interface=from_network_interface, frame=frame ) else: - self.sys_log.error(f"No service or application found for port {port} and protocol {protocol}") + self.sys_log.warning(f"No service or application found for port {port} and protocol {protocol}") pass def show(self, markdown: bool = False): diff --git a/src/primaite/simulator/system/services/arp/arp.py b/src/primaite/simulator/system/services/arp/arp.py index 75bb03ae..bfbc8c9c 100644 --- a/src/primaite/simulator/system/services/arp/arp.py +++ b/src/primaite/simulator/system/services/arp/arp.py @@ -147,7 +147,7 @@ class ARP(Service): payload=arp_packet, dst_ip_address=target_ip_address, dst_port=self.port, ip_protocol=self.protocol ) else: - self.sys_log.error( + self.sys_log.warning( "Cannot send ARP request as there is no outbound Network Interface to use. Try configuring the default " "gateway." ) @@ -173,7 +173,7 @@ class ARP(Service): ip_protocol=self.protocol, ) else: - self.sys_log.error( + self.sys_log.warning( "Cannot send ARP reply as there is no outbound Network Interface to use. Try configuring the default " "gateway." ) diff --git a/src/primaite/simulator/system/services/database/database_service.py b/src/primaite/simulator/system/services/database/database_service.py index 833b1fa5..9fdd0cdd 100644 --- a/src/primaite/simulator/system/services/database/database_service.py +++ b/src/primaite/simulator/system/services/database/database_service.py @@ -57,7 +57,7 @@ class DatabaseService(Service): # check if the backup server was configured if self.backup_server_ip is None: - self.sys_log.error(f"{self.name} - {self.sys_log.hostname}: not configured.") + self.sys_log.warning(f"{self.name} - {self.sys_log.hostname}: not configured.") return False software_manager: SoftwareManager = self.software_manager @@ -110,7 +110,7 @@ class DatabaseService(Service): db_file = self.file_system.get_file(folder_name="database", file_name="database.db", include_deleted=True) if db_file is None: - self.sys_log.error("Database file not initialised.") + self.sys_log.warning("Database file not initialised.") return False # if the file was deleted, get the old visible health state @@ -170,12 +170,12 @@ class DatabaseService(Service): # try to create connection if not self.add_connection(connection_id=connection_id): status_code = 500 - self.sys_log.info(f"{self.name}: Connect request for {connection_id=} declined") + self.sys_log.warning(f"{self.name}: Connect request for {connection_id=} declined") else: self.sys_log.info(f"{self.name}: Connect request for {connection_id=} authorised") else: status_code = 401 # Unauthorised - self.sys_log.info(f"{self.name}: Connect request for {connection_id=} declined") + self.sys_log.warning(f"{self.name}: Connect request for {connection_id=} declined") else: status_code = 404 # service not found return { @@ -206,7 +206,7 @@ class DatabaseService(Service): self.sys_log.info(f"{self.name}: Running {query}") if not self.db_file: - self.sys_log.info(f"{self.name}: Failed to run {query} because the database file is missing.") + self.sys_log.error(f"{self.name}: Failed to run {query} because the database file is missing.") return {"status_code": 404, "type": "sql", "data": False} if query == "SELECT": @@ -276,7 +276,7 @@ class DatabaseService(Service): return {"status_code": 401, "data": False} else: # Invalid query - self.sys_log.info(f"{self.name}: Invalid {query}") + self.sys_log.warning(f"{self.name}: Invalid {query}") return {"status_code": 500, "data": False} def describe_state(self) -> Dict: diff --git a/src/primaite/simulator/system/services/dns/dns_client.py b/src/primaite/simulator/system/services/dns/dns_client.py index 967af6b2..063ff74f 100644 --- a/src/primaite/simulator/system/services/dns/dns_client.py +++ b/src/primaite/simulator/system/services/dns/dns_client.py @@ -72,7 +72,7 @@ class DNSClient(Service): # check if DNS server is configured if self.dns_server is None: - self.sys_log.error(f"{self.name}: DNS Server is not configured") + self.sys_log.warning(f"{self.name}: DNS Server is not configured") return False # check if the target domain is in the client's DNS cache @@ -88,7 +88,7 @@ class DNSClient(Service): else: # return False if already reattempted if is_reattempt: - self.sys_log.info(f"{self.name}: Domain lookup for {target_domain} failed") + self.sys_log.warning(f"{self.name}: Domain lookup for {target_domain} failed") return False else: # send a request to check if domain name exists in the DNS Server @@ -143,7 +143,8 @@ class DNSClient(Service): """ # The payload should be a DNS packet if not isinstance(payload, DNSPacket): - _LOGGER.debug(f"{payload} is not a DNSPacket") + self.sys_log.warning(f"{self.name}: Payload is not a DNSPacket") + self.sys_log.debug(f"{self.name}: {payload}") return False if payload.dns_reply is not None: @@ -156,5 +157,5 @@ class DNSClient(Service): self.dns_cache[payload.dns_request.domain_name_request] = payload.dns_reply.domain_name_ip_address return True - self.sys_log.error(f"Failed to resolve domain name {payload.dns_request.domain_name_request}") + self.sys_log.warning(f"Failed to resolve domain name {payload.dns_request.domain_name_request}") return False diff --git a/src/primaite/simulator/system/services/dns/dns_server.py b/src/primaite/simulator/system/services/dns/dns_server.py index 4d0ebbb8..7dbc5d60 100644 --- a/src/primaite/simulator/system/services/dns/dns_server.py +++ b/src/primaite/simulator/system/services/dns/dns_server.py @@ -90,7 +90,8 @@ class DNSServer(Service): # The payload should be a DNS packet if not isinstance(payload, DNSPacket): - _LOGGER.debug(f"{payload} is not a DNSPacket") + self.sys_log.warning(f"{payload} is not a DNSPacket") + self.sys_log.debug(f"{payload} is not a DNSPacket") return False # cast payload into a DNS packet diff --git a/src/primaite/simulator/system/services/ftp/ftp_client.py b/src/primaite/simulator/system/services/ftp/ftp_client.py index 7c334ced..f2b78d52 100644 --- a/src/primaite/simulator/system/services/ftp/ftp_client.py +++ b/src/primaite/simulator/system/services/ftp/ftp_client.py @@ -82,7 +82,7 @@ class FTPClient(FTPServiceABC): else: if is_reattempt: # reattempt failed - self.sys_log.info( + self.sys_log.warning( f"{self.name}: Unable to connect to FTP Server " f"{dest_ip_address} via port {payload.ftp_command_args.value}" ) @@ -93,7 +93,7 @@ class FTPClient(FTPServiceABC): dest_ip_address=dest_ip_address, dest_port=dest_port, session_id=session_id, is_reattempt=True ) else: - self.sys_log.error(f"{self.name}: Unable to send FTPPacket") + self.sys_log.warning(f"{self.name}: Unable to send FTPPacket") return False def _disconnect_from_server( @@ -158,7 +158,7 @@ class FTPClient(FTPServiceABC): # check if the file to transfer exists on the client file_to_transfer: File = self.file_system.get_file(folder_name=src_folder_name, file_name=src_file_name) if not file_to_transfer: - self.sys_log.error(f"Unable to send file that does not exist: {src_folder_name}/{src_file_name}") + self.sys_log.warning(f"Unable to send file that does not exist: {src_folder_name}/{src_file_name}") return False # check if FTP is currently connected to IP @@ -253,7 +253,8 @@ class FTPClient(FTPServiceABC): :type: session_id: Optional[str] """ if not isinstance(payload, FTPPacket): - self.sys_log.error(f"{payload} is not an FTP packet") + self.sys_log.warning(f"{self.name}: Payload is not an FTP packet") + self.sys_log.debug(f"{self.name}: {payload}") return False """ diff --git a/src/primaite/simulator/system/services/ftp/ftp_server.py b/src/primaite/simulator/system/services/ftp/ftp_server.py index c5330de2..de714a10 100644 --- a/src/primaite/simulator/system/services/ftp/ftp_server.py +++ b/src/primaite/simulator/system/services/ftp/ftp_server.py @@ -70,7 +70,8 @@ class FTPServer(FTPServiceABC): def receive(self, payload: Any, session_id: Optional[str] = None, **kwargs) -> bool: """Receives a payload from the SessionManager.""" if not isinstance(payload, FTPPacket): - self.sys_log.error(f"{payload} is not an FTP packet") + self.sys_log.warning(f"{self.name}: Payload is not an FTP packet") + self.sys_log.debug(f"{self.name}: {payload}") return False if not super().receive(payload=payload, session_id=session_id, **kwargs): diff --git a/src/primaite/simulator/system/services/icmp/icmp.py b/src/primaite/simulator/system/services/icmp/icmp.py index 103d1c60..c4b4173f 100644 --- a/src/primaite/simulator/system/services/icmp/icmp.py +++ b/src/primaite/simulator/system/services/icmp/icmp.py @@ -95,7 +95,7 @@ class ICMP(Service): network_interface = self.software_manager.session_manager.resolve_outbound_network_interface(target_ip_address) if not network_interface: - self.sys_log.error( + self.sys_log.warning( "Cannot send ICMP echo request as there is no outbound Network Interface to use. Try configuring the " "default gateway." ) @@ -130,7 +130,7 @@ class ICMP(Service): ) if not network_interface: - self.sys_log.error( + self.sys_log.warning( "Cannot send ICMP echo reply as there is no outbound Network Interface to use. Try configuring the " "default gateway." ) diff --git a/src/primaite/simulator/system/services/ntp/ntp_client.py b/src/primaite/simulator/system/services/ntp/ntp_client.py index fe351dba..dcc502c7 100644 --- a/src/primaite/simulator/system/services/ntp/ntp_client.py +++ b/src/primaite/simulator/system/services/ntp/ntp_client.py @@ -87,7 +87,7 @@ class NTPClient(Service): :return: True if successful, False otherwise. """ if not isinstance(payload, NTPPacket): - _LOGGER.debug(f"{self.name}: Failed to parse NTP update") + self.sys_log.warning(f"{self.name}: Failed to parse NTP update") return False if payload.ntp_reply.ntp_datetime: self.time = payload.ntp_reply.ntp_datetime @@ -115,7 +115,6 @@ class NTPClient(Service): :param timestep: The current timestep number. (Amount of time since simulation episode began) :type timestep: int """ - self.sys_log.info(f"{self.name} apply_timestep") super().apply_timestep(timestep) if self.operating_state == ServiceOperatingState.RUNNING: # request time from server diff --git a/src/primaite/simulator/system/services/ntp/ntp_server.py b/src/primaite/simulator/system/services/ntp/ntp_server.py index f9d9ee7c..01d10b84 100644 --- a/src/primaite/simulator/system/services/ntp/ntp_server.py +++ b/src/primaite/simulator/system/services/ntp/ntp_server.py @@ -51,7 +51,8 @@ class NTPServer(Service): :return: True if valid NTP request else False. """ if not (isinstance(payload, NTPPacket)): - _LOGGER.debug(f"{payload} is not a NTPPacket") + self.sys_log.warning(f"{self.name}: Payload is not a NTPPacket") + self.sys_log.debug(f"{self.name}: {payload}") return False payload: NTPPacket = payload diff --git a/src/primaite/simulator/system/services/service.py b/src/primaite/simulator/system/services/service.py index b2a6f685..caaefc06 100644 --- a/src/primaite/simulator/system/services/service.py +++ b/src/primaite/simulator/system/services/service.py @@ -59,7 +59,7 @@ class Service(IOSoftware): if self.operating_state is not ServiceOperatingState.RUNNING: # service is not running - _LOGGER.debug(f"Cannot perform action: {self.name} is {self.operating_state.name}") + self.sys_log.debug(f"Cannot perform action: {self.name} is {self.operating_state.name}") return False return True @@ -187,6 +187,6 @@ class Service(IOSoftware): super().apply_timestep(timestep) if self.operating_state == ServiceOperatingState.RESTARTING: if self.restart_countdown <= 0: - _LOGGER.debug(f"Restarting finished for service {self.name}") + self.sys_log.debug(f"Restarting finished for service {self.name}") self.operating_state = ServiceOperatingState.RUNNING self.restart_countdown -= 1 diff --git a/src/primaite/simulator/system/services/web_server/web_server.py b/src/primaite/simulator/system/services/web_server/web_server.py index 5e7591e9..c0eb0632 100644 --- a/src/primaite/simulator/system/services/web_server/web_server.py +++ b/src/primaite/simulator/system/services/web_server/web_server.py @@ -167,7 +167,8 @@ class WebServer(Service): # check if the payload is an HTTPPacket if not isinstance(payload, HttpRequestPacket): - self.sys_log.error("Payload is not an HTTPPacket") + self.sys_log.warning(f"{self.name}: Payload is not an HTTPPacket") + self.sys_log.debug(f"{self.name}: {payload}") return False return self._process_http_request(payload=payload, session_id=session_id) diff --git a/src/primaite/simulator/system/software.py b/src/primaite/simulator/system/software.py index 50c96c17..b609b0b2 100644 --- a/src/primaite/simulator/system/software.py +++ b/src/primaite/simulator/system/software.py @@ -6,7 +6,7 @@ from ipaddress import IPv4Address, IPv4Network from typing import Any, Dict, Optional, TYPE_CHECKING, Union from primaite.interface.request import RequestResponse -from primaite.simulator.core import _LOGGER, RequestManager, RequestType, SimComponent +from primaite.simulator.core import RequestManager, RequestType, SimComponent from primaite.simulator.file_system.file_system import FileSystem, Folder from primaite.simulator.network.hardware.node_operating_state import NodeOperatingState from primaite.simulator.network.transmission.network_layer import IPProtocol @@ -287,7 +287,9 @@ class IOSoftware(Software): Returns true if the software can perform actions. """ if self.software_manager and self.software_manager.node.operating_state != NodeOperatingState.ON: - _LOGGER.debug(f"{self.name} Error: {self.software_manager.node.hostname} is not online.") + self.software_manager.node.sys_log.error( + f"{self.name} Error: {self.software_manager.node.hostname} is not online." + ) return False return True @@ -308,7 +310,7 @@ class IOSoftware(Software): # if over or at capacity, set to overwhelmed if len(self._connections) >= self.max_sessions: self.set_health_state(SoftwareHealthState.OVERWHELMED) - self.sys_log.error(f"{self.name}: Connect request for {connection_id=} declined. Service is at capacity.") + self.sys_log.warning(f"{self.name}: Connect request for {connection_id=} declined. Service is at capacity.") return False else: # if service was previously overwhelmed, set to good because there is enough space for connections @@ -327,7 +329,7 @@ class IOSoftware(Software): self.sys_log.info(f"{self.name}: Connect request for {connection_id=} authorised") return True # connection with given id already exists - self.sys_log.error( + self.sys_log.warning( f"{self.name}: Connect request for {connection_id=} declined. Connection already exists." ) return False