diff --git a/concore.py b/concore.py index 4c549e2..924364d 100644 --- a/concore.py +++ b/concore.py @@ -1,10 +1,14 @@ import time +import logging import os from ast import literal_eval import sys import re -import zmq # Added for ZeroMQ -import numpy as np # Added for numpy type conversion +import zmq +logging.basicConfig( + level=logging.INFO, + format='%(levelname)s - %(message)s' +) # Added for ZeroMQ # if windows, create script to kill this process # because batch files don't provide easy way to know pid of last command @@ -37,10 +41,10 @@ def __init__(self, port_type, address, zmq_socket_type): # Bind or connect if self.port_type == "bind": self.socket.bind(address) - print(f"ZMQ Port bound to {address}") + logging.info(f"ZMQ Port bound to {address}") else: self.socket.connect(address) - print(f"ZMQ Port connected to {address}") + logging.info(f"ZMQ Port connected to {address}") def send_json_with_retry(self, message): """Send JSON message with retries if timeout occurs.""" @@ -49,9 +53,9 @@ def send_json_with_retry(self, message): self.socket.send_json(message) return except zmq.Again: - print(f"Send timeout (attempt {attempt + 1}/5)") + logging.warning(f"Send timeout (attempt {attempt + 1}/5)") time.sleep(0.5) - print("Failed to send after retries.") + logging.error("Failed to send after retries.") return def recv_json_with_retry(self): @@ -60,9 +64,9 @@ def recv_json_with_retry(self): try: return self.socket.recv_json() except zmq.Again: - print(f"Receive timeout (attempt {attempt + 1}/5)") + logging.warning(f"Receive timeout (attempt {attempt + 1}/5)") time.sleep(0.5) - print("Failed to receive after retries.") + logging.error("Failed to receive after retries.") return None # Global ZeroMQ ports registry @@ -77,20 +81,20 @@ def init_zmq_port(port_name, port_type, address, socket_type_str): socket_type_str (str): String representation of ZMQ socket type (e.g., "REQ", "REP", "PUB", "SUB"). """ if port_name in zmq_ports: - print(f"ZMQ Port {port_name} already initialized.") + logging.info(f"ZMQ Port {port_name} already initialized.") return # Avoid reinitialization try: # Map socket type string to actual ZMQ constant (e.g., zmq.REQ, zmq.REP) zmq_socket_type = getattr(zmq, socket_type_str.upper()) zmq_ports[port_name] = ZeroMQPort(port_type, address, zmq_socket_type) - print(f"Initialized ZMQ port: {port_name} ({socket_type_str}) on {address}") + logging.info(f"Initialized ZMQ port: {port_name} ({socket_type_str}) on {address}") except AttributeError: - print(f"Error: Invalid ZMQ socket type string '{socket_type_str}'.") + logging.error(f"Error: Invalid ZMQ socket type string '{socket_type_str}'.") except zmq.error.ZMQError as e: - print(f"Error initializing ZMQ port {port_name} on {address}: {e}") + logging.error(f"Error initializing ZMQ port {port_name} on {address}: {e}") except Exception as e: - print(f"An unexpected error occurred during ZMQ port initialization for {port_name}: {e}") + logging.error(f"An unexpected error occurred during ZMQ port initialization for {port_name}: {e}") def terminate_zmq(): for port in zmq_ports.values(): @@ -98,7 +102,7 @@ def terminate_zmq(): port.socket.close() port.context.term() except Exception as e: - print(f"Error while terminating ZMQ port {port.address}: {e}") + logging.error(f"Error while terminating ZMQ port {port.address}: {e}") # --- ZeroMQ Integration End --- @@ -163,13 +167,13 @@ def safe_literal_eval(filename, defaultValue): # Convert key=value;key2=value2 to Python dict format if sparams != '{' and not (sparams.startswith('{') and sparams.endswith('}')): # Check if it needs conversion - print("converting sparams: "+sparams) + logging.debug("converting sparams: "+sparams) sparams = "{'"+re.sub(';',",'",re.sub('=',"':",re.sub(' ','',sparams)))+"}" - print("converted sparams: " + sparams) + logging.debug("converted sparams: " + sparams) try: params = literal_eval(sparams) except Exception as e: - print(f"bad params content: {sparams}, error: {e}") + logging.warning(f"bad params content: {sparams}, error: {e}") params = dict() else: params = dict() @@ -226,17 +230,17 @@ def read(port_identifier, name, initstr_val): message = zmq_p.recv_json_with_retry() return message except zmq.error.ZMQError as e: - print(f"ZMQ read error on port {port_identifier} (name: {name}): {e}. Returning default.") + logging.error(f"ZMQ read error on port {port_identifier} (name: {name}): {e}. Returning default.") return default_return_val except Exception as e: - print(f"Unexpected error during ZMQ read on port {port_identifier} (name: {name}): {e}. Returning default.") + logging.error(f"Unexpected error during ZMQ read on port {port_identifier} (name: {name}): {e}. Returning default.") return default_return_val # Case 2: File-based port try: file_port_num = int(port_identifier) except ValueError: - print(f"Error: Invalid port identifier '{port_identifier}' for file operation. Must be integer or ZMQ name.") + logging.error(f"Error: Invalid port identifier '{port_identifier}' for file operation. Must be integer or ZMQ name.") return default_return_val time.sleep(delay) @@ -250,8 +254,7 @@ def read(port_identifier, name, initstr_val): ins = str(initstr_val) s += ins # Update s to break unchanged() loop except Exception as e: - print(f"Error reading {file_path}: {e}. Using default value.") - s += str(initstr_val) # Update s to break unchanged() loop + logging.error(f"Error reading {file_path}: {e}. Using default value.") return default_return_val # Retry logic if file is empty @@ -263,13 +266,12 @@ def read(port_identifier, name, initstr_val): with open(file_path, "r") as infile: ins = infile.read() except Exception as e: - print(f"Retry {attempts + 1}: Error reading {file_path} - {e}") + logging.warning(f"Retry {attempts + 1}: Error reading {file_path} - {e}") attempts += 1 retrycount += 1 if len(ins) == 0: - print(f"Max retries reached for {file_path}, using default value.") - s += str(initstr_val) # Update s to break unchanged() loop + logging.error(f"Max retries reached for {file_path}, using default value.") return default_return_val s += ins @@ -283,10 +285,10 @@ def read(port_identifier, name, initstr_val): simtime = max(simtime, current_simtime_from_file) return inval[1:] else: - print(f"Warning: Unexpected data format in {file_path}: {ins}. Returning raw content or default.") + logging.warning(f"Warning: Unexpected data format in {file_path}: {ins}. Returning raw content or default.") return inval except Exception as e: - print(f"Error parsing content from {file_path} ('{ins}'): {e}. Returning default.") + logging.error(f"Error parsing content from {file_path} ('{ins}'): {e}. Returning default.") return default_return_val @@ -303,24 +305,23 @@ def write(port_identifier, name, val, delta=0): try: zmq_p.send_json_with_retry(val) except zmq.error.ZMQError as e: - print(f"ZMQ write error on port {port_identifier} (name: {name}): {e}") + logging.error(f"ZMQ write error on port {port_identifier} (name: {name}): {e}") except Exception as e: - print(f"Unexpected error during ZMQ write on port {port_identifier} (name: {name}): {e}") - return + logging.error(f"Unexpected error during ZMQ write on port {port_identifier} (name: {name}): {e}") # Case 2: File-based port try: file_port_num = int(port_identifier) file_path = os.path.join(outpath + str(file_port_num), name) except ValueError: - print(f"Error: Invalid port identifier '{port_identifier}' for file operation. Must be integer or ZMQ name.") + logging.error(f"Error: Invalid port identifier '{port_identifier}' for file operation. Must be integer or ZMQ name.") return # File writing rules if isinstance(val, str): time.sleep(2 * delay) # string writes wait longer elif not isinstance(val, list): - print(f"File write to {file_path} must have list or str value, got {type(val)}") + logging.error(f"File write to {file_path} must have list or str value, got {type(val)}") return try: @@ -334,7 +335,7 @@ def write(port_identifier, name, val, delta=0): else: outfile.write(val) except Exception as e: - print(f"Error writing to {file_path}: {e}") + logging.error(f"Error writing to {file_path}: {e}") def initval(simtime_val_str): """ @@ -350,12 +351,12 @@ def initval(simtime_val_str): simtime = first_element return val[1:] else: - print(f"Error: First element in initval string '{simtime_val_str}' is not a number. Using data part as is or empty.") + logging.error(f"Error: First element in initval string '{simtime_val_str}' is not a number. Using data part as is or empty.") return val[1:] if len(val) > 1 else [] else: - print(f"Error: initval string '{simtime_val_str}' is not a list or is empty. Returning empty list.") + logging.error(f"Error: initval string '{simtime_val_str}' is not a list or is empty. Returning empty list.") return [] except Exception as e: - print(f"Error parsing simtime_val_str '{simtime_val_str}': {e}. Returning empty list.") + logging.error(f"Error parsing simtime_val_str '{simtime_val_str}': {e}. Returning empty list.") return [] \ No newline at end of file diff --git a/mkconcore.py b/mkconcore.py index b243c23..10135dc 100644 --- a/mkconcore.py +++ b/mkconcore.py @@ -413,8 +413,8 @@ fsource = open(CONCOREPATH+"/concoredocker.py") else: fsource = open(CONCOREPATH+"/concore.py") -except: - logging.error(f"{CONCOREPATH} is not correct path to concore") +except (FileNotFoundError, IOError) as e: + logging.error(f"{CONCOREPATH} is not correct path to concore: {e}") quit() with open(outdir+"/src/concore.py","w") as fcopy: fcopy.write(fsource.read()) @@ -426,8 +426,8 @@ fsource = open(CONCOREPATH+"/concoredocker.hpp") else: fsource = open(CONCOREPATH+"/concore.hpp") -except: - logging.error(f"{CONCOREPATH} is not correct path to concore") +except (FileNotFoundError, IOError) as e: + logging.error(f"{CONCOREPATH} is not correct path to concore: {e}") quit() with open(outdir+"/src/concore.hpp","w") as fcopy: fcopy.write(fsource.read()) @@ -439,8 +439,8 @@ fsource = open(CONCOREPATH+"/concoredocker.v") else: fsource = open(CONCOREPATH+"/concore.v") -except: - logging.error(f"{CONCOREPATH} is not correct path to concore") +except (FileNotFoundError, IOError) as e: + logging.error(f"{CONCOREPATH} is not correct path to concore: {e}") quit() with open(outdir+"/src/concore.v","w") as fcopy: fcopy.write(fsource.read()) @@ -449,8 +449,8 @@ #copy mkcompile into /src 5/27/21 try: fsource = open(CONCOREPATH+"/mkcompile") -except: - logging.error(f"{CONCOREPATH} is not correct path to concore") +except (FileNotFoundError, IOError) as e: + logging.error(f"{CONCOREPATH} is not correct path to concore: {e}") quit() with open(outdir+"/src/mkcompile","w") as fcopy: fcopy.write(fsource.read()) @@ -460,56 +460,56 @@ #copy concore*.m into /src 4/2/21 try: #maxtime in matlab 11/22/21 fsource = open(CONCOREPATH+"/concore_default_maxtime.m") -except: - logging.error(f"{CONCOREPATH} is not correct path to concore") +except (FileNotFoundError, IOError) as e: + logging.error(f"{CONCOREPATH} is not correct path to concore: {e}") quit() with open(outdir+"/src/concore_default_maxtime.m","w") as fcopy: fcopy.write(fsource.read()) fsource.close() try: fsource = open(CONCOREPATH+"/concore_unchanged.m") -except: - logging.error(f"{CONCOREPATH} is not correct path to concore") +except (FileNotFoundError, IOError) as e: + logging.error(f"{CONCOREPATH} is not correct path to concore: {e}") quit() with open(outdir+"/src/concore_unchanged.m","w") as fcopy: fcopy.write(fsource.read()) fsource.close() try: fsource = open(CONCOREPATH+"/concore_read.m") -except: - logging.error(f"{CONCOREPATH} is not correct path to concore") +except (FileNotFoundError, IOError) as e: + logging.error(f"{CONCOREPATH} is not correct path to concore: {e}") quit() with open(outdir+"/src/concore_read.m","w") as fcopy: fcopy.write(fsource.read()) fsource.close() try: fsource = open(CONCOREPATH+"/concore_write.m") -except: - logging.error(f"{CONCOREPATH} is not correct path to concore") +except (FileNotFoundError, IOError) as e: + logging.error(f"{CONCOREPATH} is not correct path to concore: {e}") quit() with open(outdir+"/src/concore_write.m","w") as fcopy: fcopy.write(fsource.read()) fsource.close() try: #4/9/21 fsource = open(CONCOREPATH+"/concore_initval.m") -except: - logging.error(f"{CONCOREPATH} is not correct path to concore") +except (FileNotFoundError, IOError) as e: + logging.error(f"{CONCOREPATH} is not correct path to concore: {e}") quit() with open(outdir+"/src/concore_initval.m","w") as fcopy: fcopy.write(fsource.read()) fsource.close() try: #11/19/21 fsource = open(CONCOREPATH+"/concore_iport.m") -except: - logging.error(f"{CONCOREPATH} is not correct path to concore") +except (FileNotFoundError, IOError) as e: + logging.error(f"{CONCOREPATH} is not correct path to concore: {e}") quit() with open(outdir+"/src/concore_iport.m","w") as fcopy: fcopy.write(fsource.read()) fsource.close() try: #11/19/21 fsource = open(CONCOREPATH+"/concore_oport.m") -except: - logging.error(f"{CONCOREPATH} is not correct path to concore") +except (FileNotFoundError, IOError) as e: + logging.error(f"{CONCOREPATH} is not correct path to concore: {e}") quit() with open(outdir+"/src/concore_oport.m","w") as fcopy: fcopy.write(fsource.read()) @@ -519,8 +519,8 @@ fsource = open(CONCOREPATH+"/import_concoredocker.m") else: fsource = open(CONCOREPATH+"/import_concore.m") -except: - logging.error(f"{CONCOREPATH} is not correct path to concore") +except (FileNotFoundError, IOError) as e: + logging.error(f"{CONCOREPATH} is not correct path to concore: {e}") quit() with open(outdir+"/src/import_concore.m","w") as fcopy: fcopy.write(fsource.read())