Skip to content

Commit c55a690

Browse files
authored
Merge pull request nunobrum#103 from TSprech/PrintLoggingReplacement
Replacing Print Statements with Logging Module
2 parents cc0f951 + 2db30c1 commit c55a690

18 files changed

+194
-120
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.vscode/
2+
.idea/
23
__pycache__/
34
PyLTSpice.egg-info
45
venv

PyLTSpice/LTSteps.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -88,22 +88,22 @@
8888
import sys
8989

9090
from PyLTSpice.log.ltsteps import *
91-
91+
import logging
92+
_logger = logging.getLogger("PyLTSpice.LTSteps")
9293

9394
def main():
9495
"""
9596
Main function for the LTSteps.py script
9697
"""
97-
9898
def valid_extension(filename):
9999
"""A simple function to check if the filename has a valid extension"""
100100
return filename.endswith('.txt') or filename.endswith('.log') or filename.endswith('.mout')
101101

102102
if len(sys.argv) > 1:
103103
filename = sys.argv[1]
104104
if not valid_extension(filename):
105-
print("Invalid extension in filename '%s'" % filename)
106-
print("This tool only supports the following extensions :'.txt','.log','.mout'")
105+
_logger.error("Invalid extension in filename '%s'" % filename)
106+
_logger.error("This tool only supports the following extensions :'.txt','.log','.mout'")
107107
exit(-1)
108108
else:
109109
filename = None
@@ -114,8 +114,8 @@ def valid_extension(filename):
114114
newer_date = date
115115
filename = f
116116
if filename is None:
117-
print("File not found")
118-
print("This tool only supports the following extensions :'.txt','.log','.mout'")
117+
_logger.error("File not found")
118+
_logger.error("This tool only supports the following extensions :'.txt','.log','.mout'")
119119
exit(-1)
120120

121121
fname_out = None
@@ -126,15 +126,15 @@ def valid_extension(filename):
126126
elif filename.endswith('.mout'):
127127
fname_out = filename[:-len('mout')] + 'tmout'
128128
else:
129-
print("Error in file type")
130-
print("This tool only supports the following extensions :'.txt','.log','.mout'")
129+
_logger.error("Error in file type")
130+
_logger.error("This tool only supports the following extensions :'.txt','.log','.mout'")
131131
exit(-1)
132132

133133
if fname_out is not None:
134-
print("Processing File %s" % filename)
135-
print("Creating File %s" % fname_out)
134+
_logger.debug("Processing File %s" % filename)
135+
_logger.debug("Creating File %s" % fname_out)
136136
if filename.endswith('txt'):
137-
print("Processing Data File")
137+
_logger.debug("Processing Data File")
138138
reformat_LTSpice_export(filename, fname_out)
139139
elif filename.endswith("log"):
140140
data = LTSpiceLogReader(filename)

PyLTSpice/__init__.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,52 @@
66
from .sim.spice_editor import SpiceEditor, SpiceCircuit
77
from .sim.sim_runner import SimRunner
88
from .sim.sim_batch import SimCommander
9+
10+
11+
def all_loggers():
12+
"""
13+
Returns all the name strings used as logger identifiers.
14+
15+
:return: A List of strings which contains all the logger's names used in this library.
16+
:rtype: list[str]
17+
"""
18+
return [
19+
"PyLTSpice.RunTask",
20+
"PyLTSpice.LTSteps",
21+
"PyLTSpice.SimClient",
22+
"PyLTSpice.SimServer",
23+
"PyLTSpice.ServerSimRunner",
24+
"PyLTSpice.LTSteps",
25+
"PyLTSpice.RawRead",
26+
"PyLTSpice.LTSpiceSimulator",
27+
"PyLTSpice.NGSpiceSimulator",
28+
"PyLTSpice.SimBatch",
29+
"PyLTSpice.SimRunner",
30+
"PyLTSpice.SimStepper",
31+
"PyLTSpice.SpiceEditor",
32+
"PyLTSpice.XYCESimulator",
33+
"PyLTSpice.SimBatch"]
34+
35+
36+
def set_log_level(level):
37+
"""
38+
Sets the logging level for all loggers used in the library.
39+
40+
:param level: The logging level to be used, eg. logging.ERROR, logging.DEBUG, etc.
41+
:type level: int
42+
"""
43+
import logging
44+
for logger in all_loggers():
45+
logging.getLogger(logger).setLevel(level)
46+
47+
48+
def add_log_handler(handler):
49+
"""
50+
Sets the logging handler for all loggers used in the library.
51+
52+
:param handler: The logging handler to be used, eg. logging.NullHandler
53+
:type handler: Handler
54+
"""
55+
import logging
56+
for logger in all_loggers():
57+
logging.getLogger(logger).addHandler(handler)

PyLTSpice/client_server/sim_client.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
import time
2626
from collections import OrderedDict
2727
from dataclasses import dataclass
28-
28+
import logging
29+
_logger = logging.getLogger("PyLTSpice.SimClient")
2930

3031
class SimClientInvalidRunId(LookupError):
3132
"""Raised when asking for a run_no that doesn't exist"""
@@ -104,15 +105,15 @@ def __init__(self, host_address, port):
104105
self.server = xmlrpc.client.ServerProxy(f'{host_address}:{port}')
105106
# print(self.server.system.listMethods())
106107
self.session_id = self.server.start_session()
107-
print("started ", self.session_id)
108+
_logger.info("started ", self.session_id)
108109
self.started_jobs = OrderedDict() # This list keeps track of started jobs on the server
109110
self.stored_jobs = OrderedDict() # This list keeps track of finished simulations that haven't yet been transferred.
110111
self.completed_jobs = 0
111112
self.minimum_time_between_server_calls = 0.2 # Minimum time between server calls
112113
self._last_server_call = time.clock()
113114

114115
def __del__(self):
115-
print("closing session ", self.session_id)
116+
_logger.info("closing session ", self.session_id)
116117
self.server.close_session(self.session_id)
117118

118119
def run(self, circuit):
@@ -147,7 +148,7 @@ def run(self, circuit):
147148
self.started_jobs[job_info] = job_info
148149
return run_id
149150
else:
150-
print(f"Circuit {circuit} doesn't exit")
151+
_logger.error(f"Circuit {circuit} doesn't exit")
151152
return -1
152153

153154
def get_runno_data(self, runno) -> str:

PyLTSpice/client_server/sim_server.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
from typing import Tuple
2121
from xmlrpc.client import Binary
2222
from xmlrpc.server import SimpleXMLRPCServer
23+
import logging
24+
_logger = logging.getLogger("PyLTSpice.SimServer")
2325

2426
import threading
2527
import zipfile
@@ -46,18 +48,18 @@ def __init__(self, simulator, parallel_sims=4, output_folder='./temp1', port=900
4648
self.server_thread.start()
4749

4850
def run(self, session_id, circuit_name, zip_data):
49-
print("Run ", session_id, circuit_name)
51+
_logger.info("Run ", session_id, circuit_name)
5052
if session_id not in self.sessions:
5153
return -1 # This indicates that no job is started
5254
# Create a buffer from the zip data
5355
zip_buffer = io.BytesIO(zip_data.data)
54-
print("Created the buffer")
56+
_logger.debug("Created the buffer")
5557
# Extract the contents of the zip file
5658
with zipfile.ZipFile(zip_buffer, 'r') as zip_file:
57-
print(zip_file.namelist())
59+
_logger.debug(zip_file.namelist())
5860
zip_file.extract(circuit_name, self.output_folder)
5961

60-
print(f"Running simulation of {circuit_name}")
62+
_logger.info(f"Running simulation of {circuit_name}")
6163
runno = self.simulation_manager.add_simulation(circuit_name)
6264
if runno != -1:
6365
self.sessions[session_id].append(runno)
@@ -67,7 +69,7 @@ def start_session(self):
6769
"""Returns an unique key that represents the session. It will be later used to sort the sim_tasks belonging
6870
to the session."""
6971
session_id = str(uuid.uuid4()) # Needs to be a string, otherwise the rpc client can't handle it
70-
print("Starting session ", session_id)
72+
_logger.info("Starting session ", session_id)
7173
self.sessions[session_id] = []
7274
return session_id
7375

@@ -83,15 +85,15 @@ def status(self, session_id):
8385
8486
* 'stop' - server time
8587
"""
86-
print("collecting status for ", session_id)
88+
_logger.debug("collecting status for ", session_id)
8789
ret = []
8890
for task_info in self.simulation_manager.completed_tasks:
89-
print(task_info)
91+
_logger.debug(task_info)
9092
runno = task_info['runno']
9193
if runno in self.sessions[session_id]:
9294
ret.append(runno) # transfers the dictionary from the simulation_manager completed task
9395
# to the return dictionary
94-
print("returning status", ret)
96+
_logger.debug("returning status", ret)
9597
return ret
9698

9799
def get_files(self, session_id, runno) -> Tuple[str, Binary]:
@@ -117,10 +119,10 @@ def close_session(self, session_id):
117119
return True # Needs to return always something. None is not supported
118120

119121
def stop_server(self):
120-
print("stopping...ServerInterface")
122+
_logger.info("stopping...ServerInterface")
121123
self.simulation_manager.stop()
122124
self.server.shutdown()
123-
print("stopped...ServerInterface")
125+
_logger.info("stopped...ServerInterface")
124126
return True # Needs to return always something. None is not supported
125127

126128
def running(self):

PyLTSpice/client_server/srv_sim_runner.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
from typing import Any, Callable, Union
2323
from pathlib import Path
2424
import zipfile
25+
import logging
26+
_logger = logging.getLogger("PyLTSpice.ServerSimRunner")
2527

2628
from PyLTSpice.sim.sim_runner import SimRunner
2729
from PyLTSpice.sim.spice_editor import SpiceEditor
@@ -71,10 +73,10 @@ def run(self) -> None:
7173
'start': task.start_time,
7274
'stop': task.stop_time,
7375
})
74-
print(task, "is finished")
76+
_logger.debug(task, "is finished")
7577
del self.runner.sim_tasks[i]
76-
print(self.completed_tasks[-1])
77-
print(len(self.completed_tasks))
78+
_logger.debug(self.completed_tasks[-1])
79+
_logger.debug(len(self.completed_tasks))
7880

7981
time.sleep(0.2)
8082
if self._stop is True:
@@ -84,13 +86,13 @@ def run(self) -> None:
8486

8587
def add_simulation(self, netlist: Union[str, Path, SpiceEditor], *, timeout: float = 600) -> int:
8688
""""""
87-
print("starting ", netlist)
89+
_logger.debug("starting ", netlist)
8890
task = self.runner.run(netlist, wait_resource=True, timeout=timeout, callback=zip_files)
8991
if task is None:
90-
print("Failed to start task ", netlist)
92+
_logger.error("Failed to start task ", netlist)
9193
return -1
9294
else:
93-
print("Started task ", netlist, " with job_id", task.runno)
95+
_logger.info("Started task ", netlist, " with job_id", task.runno)
9496
return task.runno
9597

9698
def _erase_files_and_info(self, pos):
@@ -114,7 +116,7 @@ def cleanup_completed(self):
114116
self._erase_files_and_info(0)
115117

116118
def stop(self):
117-
print("stopping...ServerSimRunner")
119+
_logger.info("stopping...ServerSimRunner")
118120
self._stop = True
119121

120122
def running(self):

PyLTSpice/log/ltsteps.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@
8383
from collections import OrderedDict
8484
from typing import Union, Iterable, List
8585
from ..utils.detect_encoding import detect_encoding
86-
86+
import logging
87+
_logger = logging.getLogger("PyLTSpice.LTSteps")
8788

8889
class LTComplex(object):
8990
"""
@@ -207,7 +208,7 @@ def reformat_LTSpice_export(export_file: str, tabular_file: str):
207208
header_keys.append(param.split('=')[0])
208209
param_header = "\t".join(header_keys)
209210
fout.write("Run\t%s\t%s" % (param_header, headers))
210-
print("Run\t%s\t%s" % (param_header, headers))
211+
_logger.debug("Run\t%s\t%s" % (param_header, headers))
211212
go_header = False
212213
# print("%s\t%s"% (run_no, param_values))
213214
else:
@@ -336,7 +337,7 @@ def __init__(self, log_filename: str, read_measures=True, step_set={}, encoding=
336337
r"^(?P<name>\w+)(:\s+.*)?=(?P<value>[\d\.E+\-\(\)dB,°]+)(( FROM (?P<from>[\d\.E+-]*) TO (?P<to>[\d\.E+-]*))|( at (?P<at>[\d\.E+-]*)))?",
337338
re.IGNORECASE)
338339

339-
print("Processing LOG file", log_filename)
340+
_logger.debug("Processing LOG file", log_filename)
340341
with open(log_filename, 'r', encoding=self.encoding) as fin:
341342
line = fin.readline()
342343

@@ -470,14 +471,14 @@ def __init__(self, log_filename: str, read_measures=True, step_set={}, encoding=
470471
if dataname: # If previous measurement was saved
471472
# store the info
472473
if len(measurements):
473-
print("Storing Measurement %s (count %d)" % (dataname, len(measurements)))
474+
_logger.debug("Storing Measurement %s (count %d)" % (dataname, len(measurements)))
474475
self.measure_count += len(measurements)
475476
for k, title in enumerate(headers):
476477
self.dataset[title] = [line[k] for line in measurements]
477478
headers = []
478479
measurements = []
479480
dataname = line[13:] # text which is after "Measurement: ". len("Measurement: ") -> 13
480-
print("Reading Measurement %s" % line[13:])
481+
_logger.debug("Reading Measurement %s" % line[13:])
481482
else:
482483
tokens = line.split("\t")
483484
if len(tokens) >= 2:
@@ -494,20 +495,20 @@ def __init__(self, log_filename: str, read_measures=True, step_set={}, encoding=
494495
headers = [dataname] + tokens[2:]
495496
measurements = []
496497
else:
497-
print("->", line)
498+
_logger.debug("->", line)
498499

499500
line = fin.readline() # advance to the next line
500501

501502
# storing the last data into the dataset
502503
if dataname:
503-
print("Storing Measurement %s (count %d)" % (dataname, len(measurements)))
504+
_logger.debug("Storing Measurement %s (count %d)" % (dataname, len(measurements)))
504505
if len(measurements):
505506
self.measure_count += len(measurements)
506507
for k, title in enumerate(headers):
507508
self.dataset[title] = [line[k] for line in measurements]
508509

509-
print("%d measurements" % len(self.dataset))
510-
print("Identified %d steps, read %d measurements" % (self.step_count, self.measure_count))
510+
_logger.debug("%d measurements" % len(self.dataset))
511+
_logger.info("Identified %d steps, read %d measurements" % (self.step_count, self.measure_count))
511512

512513
def __getitem__(self, key):
513514
"""
@@ -643,7 +644,7 @@ def export_data(self, export_file: str, append_with_line_prefix=None):
643644
mode = 'a' # Appends an existing file
644645

645646
if len(self.dataset) == 0:
646-
print("Empty data set. Exiting without writing file.")
647+
_logger.warning("Empty data set. Exiting without writing file.")
647648
return
648649

649650
fout = open(export_file, mode, encoding=self.encoding)

0 commit comments

Comments
 (0)