diff --git a/esds/__init__.py b/esds/__init__.py index 10c6881..2ffc1cf 100644 --- a/esds/__init__.py +++ b/esds/__init__.py @@ -1,4 +1,4 @@ -__all__ = ["simulator", "node", "plugins", "helpers", "rcode"] +__all__ = ["simulator", "node", "plugins", "helpers", "rcode", "debug"] from esds.simulator import Simulator from esds.rcode import RCode diff --git a/esds/debug.py b/esds/debug.py new file mode 100644 index 0000000..168033a --- /dev/null +++ b/esds/debug.py @@ -0,0 +1,100 @@ +import sys,time,json +import numpy as np + +def serialize_int64(obj): + if isinstance(obj, np.int64): + return int(obj) + raise TypeError ("Type %s is not serializable" % type(obj)) + +class Debug: + def __init__(self, simulator, file_path, breakpoints,breakpoints_every,interferences): + self.simulator=simulator + self.file_path=file_path + self.loop_count=0 + header={ + "python_version" : sys.version, + "simulation_started_at": simulator.startat, + "number_of_nodes": len(simulator.nodes), + "manual_breakpoints": breakpoints, + "auto_breakpoint": breakpoints_every + } + self.write(header,append=False) + + def write(self,data, append=True): + mode="a" if append else "w" + with open(self.file_path, mode) as f: + f.write(json.dumps(data,default=serialize_int64)) + f.write("\n") + + def get_network_interfaces(self): + data=dict() + for interface in self.simulator.netmat: + data[interface]={ + "is_wired":self.simulator.netmat[interface]["is_wired"], + "bandwidth": self.simulator.netmat[interface]["bandwidth"].tolist(), + "latency": self.simulator.netmat[interface]["latency"].tolist(), + } + if self.simulator.netmat[interface]["is_wired"]: + data[interface]["sharing"]=self.simulator.sharing[interface].tolist() + + return(data) + + def get_events_list(self): + events=list() + for event_numpy in self.simulator.events: + event_id=event_numpy[0] + content=event_numpy[2].tolist() + final_content=dict() + if event_id == 0: + final_content={ + "src": content[0], + "dst": content[1], + "interface": content[2], + "datasize":content[4], + "duration":content[5], + "datasize_remaining": content[6], + "start_timestamp":content[7], + "perform_delivery":content[8], + "receiver_required":content[9] + } + elif event_id == 1: + final_content={ + "node": content + } + elif event_id == 4: + final_content={ + "node": content + } + event={ + "id": event_id, + "ts": event_numpy[1], + "priority": event_numpy[3], + "content": final_content, + } + events.append(event) + return(events) + + def get_nodes_infos(self): + nodes_infos=list() + for node in self.simulator.nodes: + node_info = { + "turned_on": node["turned_on"] + } + nodes_infos.append(node_info) + return(nodes_infos) + + def debug(self): + """ + Log all the informations for debugging + """ + self.loop_count+=1 + loop_data={ + "loop_count": self.loop_count, + "started_since": round(time.time()-self.simulator.startat,2), + "simulated_time": float(self.simulator.time_truncated), + "simulated_time_accurate": self.simulator.time, + "network_interfaces": self.get_network_interfaces(), + "events_list": self.get_events_list(), + "nodes_infos": self.get_nodes_infos() + } + self.write(loop_data) diff --git a/esds/simulator.py b/esds/simulator.py index 44c45c4..2ea77b9 100644 --- a/esds/simulator.py +++ b/esds/simulator.py @@ -2,6 +2,7 @@ import numpy as np import threading,sys,time from esds.node import Node from esds.rcode import RCode +from esds.debug import Debug class Simulator: """ @@ -72,38 +73,6 @@ class Simulator: event[2][6]=new_datasize_remaining event[2][5]=new_duration self.netmat=netmat - - def debug(self): - """ - Log all the informations for debugging - """ - with open(self.debug_file_path, "a") as debug_file: - debug_file.write("-----------------------------------------------\n") - debug_file.write("Started since {}s\n".format(round(time.time()-self.startat,2))) - debug_file.write("Simulated time {}s (or more precisely {}s)\n".format(self.time_truncated,self.time)) - states=dict() - timeout_mode=list() - sharing=dict() - for node in self.nodes: - s=node["state"] - states[s]=states[s]+1 if s in states else 1 - node_key="n"+str(node.node_id) - for interface in self.sharing.keys(): - if self.sharing[interface][node.node_id] > 0: - if node_key not in sharing: - sharing[node_key] = "" - sharing[node_key]+=str(int(self.sharing[interface][node.node_id])) - debug_file.write("Node number per state: ") - for key in states: - debug_file.write(key+"="+str(states[key])) - debug_file.write("\nNode sharing: ") - for node_id in sharing: - debug_file.write(node_id+"="+sharing[node_id]) - debug_file.write("\nIds of node in timeout mode: ") - for n in timeout_mode: - debug_file.write(n) - debug_file.write("\nSorted events list:\n") - debug_file.write(np.array_str(self.events)+"\n") def create_node(self, src, args=None): """ @@ -393,12 +362,7 @@ class Simulator: if breakpoints_every != None: self.add_event(3,breakpoints_every,0,1) if debug: - with open(self.debug_file_path, "w") as f: - f.write("Python version {}\n".format(sys.version)) - f.write("Simulation started at {}\n".format(self.startat)) - f.write("Number of nodes is "+str(len(self.nodes))+"\n") - f.write("Manual breakpoints list: "+str(breakpoints)+"\n") - f.write("Breakpoints every "+str(breakpoints_every)+"s\n") + self.debug=Debug(self,self.debug_file_path, breakpoints,breakpoints_every,interferences) ##### Simulation loop while True: # Synchronize non-blocking api calls @@ -409,7 +373,7 @@ class Simulator: self.sync_node_blocking(node) # Generate debug logs if debug: - self.debug() + self.debug.debug() # Simulation end if len(self.events) <= 0 or len(self.events) == 1 and self.events[0,0] == 3: # Notify nodes that wait for the end of the simulation