Skip to content

Commit 39c9445

Browse files
authored
Merge pull request #4 from ansys-internal/pyedb_grpc
edb_data_refactored_pass1
2 parents a0a7a1c + c2746e0 commit 39c9445

20 files changed

+4849
-1313
lines changed

src/pyedb/edb.py

Lines changed: 3545 additions & 0 deletions
Large diffs are not rendered by default.

src/pyedb/edb_logger.py

Lines changed: 361 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,361 @@
1+
# -*- coding: utf-8 -*-
2+
import logging
3+
from logging.handlers import RotatingFileHandler
4+
import os
5+
import shutil
6+
import sys
7+
import tempfile
8+
import time
9+
10+
from generic.settings import settings
11+
12+
13+
class Msg:
14+
(INFO, WARNING, ERROR, FATAL) = range(4)
15+
16+
17+
class EdbLogger(object):
18+
"""
19+
Specifies the logger to use for EDB logger.
20+
21+
This class allows you to add a handler to write messages to a file and to indicate
22+
whether to write messages to the standard output (stdout).
23+
24+
Parameters
25+
----------
26+
level : int, optional
27+
Logging level to filter the message severity allowed in the logger.
28+
The default is ``logging.DEBUG``.
29+
filename : str, optional
30+
Name of the file to write messages to. The default is ``None``.
31+
to_stdout : bool, optional
32+
Whether to write log messages to stdout. The default is ``False``.
33+
"""
34+
35+
def __init__(self, level=logging.DEBUG, filename=None, to_stdout=False):
36+
self._std_out_handler = None
37+
self._files_handlers = []
38+
self.level = level
39+
self.filename = filename or settings.logger_file_path
40+
settings.logger_file_path = self.filename
41+
42+
self._global = logging.getLogger("Global")
43+
if not settings.enable_logger:
44+
self._global.addHandler(logging.NullHandler())
45+
return
46+
47+
if settings.formatter:
48+
self.formatter = settings.formatter
49+
else:
50+
self.formatter = logging.Formatter(settings.logger_formatter, datefmt=settings.logger_datefmt)
51+
global_handler = False
52+
if settings.enable_global_log_file:
53+
for handler in self._global.handlers:
54+
if settings.global_log_file_name in str(handler):
55+
global_handler = True
56+
break
57+
log_file = os.path.join(tempfile.gettempdir(), settings.global_log_file_name)
58+
my_handler = RotatingFileHandler(
59+
log_file,
60+
mode="a",
61+
maxBytes=float(settings.global_log_file_size) * 1024 * 1024,
62+
backupCount=2,
63+
encoding=None,
64+
delay=0,
65+
)
66+
my_handler.setFormatter(self.formatter)
67+
my_handler.setLevel(self.level)
68+
if not global_handler and settings.global_log_file_name:
69+
self._global.addHandler(my_handler)
70+
self._files_handlers.append(my_handler)
71+
if self.filename and os.path.exists(self.filename):
72+
shutil.rmtree(self.filename, ignore_errors=True)
73+
if self.filename and settings.enable_local_log_file:
74+
self.add_file_logger(self.filename)
75+
76+
if to_stdout:
77+
settings.enable_screen_logs = True
78+
self._std_out_handler = logging.StreamHandler(sys.stdout)
79+
self._std_out_handler.setLevel(level)
80+
_logger_stdout_formatter = logging.Formatter("PyANSYS-edb %(levelname)s: %(message)s")
81+
82+
self._std_out_handler.setFormatter(_logger_stdout_formatter)
83+
self._global.addHandler(self._std_out_handler)
84+
self._timer = time.time()
85+
86+
def add_file_logger(self, filename):
87+
"""Add a new file to the logger handlers list."""
88+
_file_handler = logging.FileHandler(filename)
89+
_file_handler.setFormatter(self.formatter)
90+
self.info("New logger file {} added to handlers.".format(filename))
91+
self._files_handlers.append(_file_handler)
92+
return True
93+
94+
def remove_file_logger(self, project_name):
95+
"""Remove a file from the logger handlers list."""
96+
handlers = [i for i in self._global.handlers]
97+
for handler in self._files_handlers:
98+
if "pyaedt_{}.log".format(project_name) in str(handler):
99+
handler.close()
100+
if handler in handlers:
101+
self._global.removeHandler(handler)
102+
self.info("logger file pyaedt_{}.log removed from handlers.".format(project_name))
103+
104+
@property
105+
def _log_on_file(self):
106+
return settings.enable_file_logs
107+
108+
@_log_on_file.setter
109+
def _log_on_file(self, val):
110+
settings.enable_file_logs = val
111+
112+
@property
113+
def logger(self):
114+
"""EDB logger object."""
115+
if self._log_on_file:
116+
return logging.getLogger("Global")
117+
else:
118+
return None # pragma: no cover
119+
120+
def reset_timer(self, time_val=None):
121+
""" "Reset actual timer to actual time or specified time.
122+
123+
Parameters
124+
----------
125+
time_val : float, optional
126+
Value time to apply.
127+
128+
Returns
129+
-------
130+
131+
"""
132+
if time_val:
133+
self._timer = time_val
134+
else:
135+
self._timer = time.time()
136+
return self._timer
137+
138+
def add_error_message(self, message_text):
139+
"""
140+
Add a type 2 "Error" message to the message manager tree.
141+
142+
Also add an error message to the logger if the handler is present.
143+
144+
Parameters
145+
----------
146+
message_text : str
147+
Text to display as the error message.
148+
149+
Examples
150+
--------
151+
Add an error message to the AEDT message manager.
152+
153+
>>> hfss.logger.project.error("Project Error Message", "Project")
154+
155+
"""
156+
self.add_message(2, message_text)
157+
158+
def add_warning_message(self, message_text):
159+
"""
160+
Add a type 1 "Warning" message to the message manager tree.
161+
162+
Also add a warning message to the logger if the handler is present.
163+
164+
Parameters
165+
----------
166+
message_text : str
167+
Text to display as the warning message.
168+
169+
Examples
170+
--------
171+
Add a warning message to the EDB message manager.
172+
173+
>>> edb.logger.warning("Global warning message")
174+
175+
"""
176+
self.add_message(1, message_text)
177+
178+
def add_info_message(self, message_text):
179+
"""Add a type 0 "Info" message to the active design level of the message manager tree.
180+
181+
Also add an info message to the logger if the handler is present.
182+
183+
Parameters
184+
----------
185+
message_text : str
186+
Text to display as the info message.
187+
188+
Examples
189+
--------
190+
Add an info message at the global level.
191+
192+
>>> edb.logger.info("Global warning message")
193+
194+
"""
195+
self.add_message(0, message_text)
196+
197+
def add_debug_message(self, message_text):
198+
"""
199+
Parameterized message to the message manager to specify the type and project or design level.
200+
201+
Parameters
202+
----------
203+
message_text : str
204+
Text to display as the message.
205+
level : str, optional
206+
Level to add the info message to. Options are ``"Global"``,
207+
``"Project"``, and ``"Design"``. The default value is ``None``,
208+
in which case the info message gets added to the ``"Design"``
209+
level.
210+
"""
211+
212+
return self.add_message(3, message_text)
213+
214+
def add_message(self, message_type, message_text):
215+
"""Add a message to the message manager to specify the type and project or design level.
216+
217+
Parameters
218+
----------
219+
message_type : int
220+
Type of the message. Options are:
221+
* ``0`` : Info
222+
* ``1`` : Warning
223+
* ``2`` : Error
224+
* ``3`` : Debug
225+
message_text : str
226+
Text to display as the message.
227+
"""
228+
self._log_on_handler(message_type, message_text)
229+
230+
def _log_on_handler(self, message_type, message_text, *args, **kwargs):
231+
if not (self._log_on_file or self._log_on_screen) or not self._global:
232+
return
233+
if len(message_text) > 250:
234+
message_text = message_text[:250] + "..."
235+
if message_type == 0:
236+
self._global.info(message_text, *args, **kwargs)
237+
elif message_type == 1:
238+
self._global.warning(message_text, *args, **kwargs)
239+
elif message_type == 2:
240+
self._global.error(message_text, *args, **kwargs)
241+
elif message_type == 3:
242+
self._global.debug(message_text, *args, **kwargs)
243+
244+
def disable_stdout_log(self):
245+
"""Disable printing log messages to stdout."""
246+
self._log_on_screen = False
247+
self._global.removeHandler(self._std_out_handler)
248+
self.info("StdOut is disabled")
249+
250+
def enable_stdout_log(self):
251+
"""Enable printing log messages to stdout."""
252+
self._log_on_screen = True
253+
if not self._std_out_handler:
254+
self._std_out_handler = logging.StreamHandler(sys.stdout)
255+
self._std_out_handler.setLevel(self.level)
256+
_logger_stdout_formatter = logging.Formatter("pyaedt %(levelname)s: %(message)s")
257+
258+
self._std_out_handler.setFormatter(_logger_stdout_formatter)
259+
self._global.addHandler(self._std_out_handler)
260+
self._global.addHandler(self._std_out_handler)
261+
self.info("StdOut is enabled")
262+
263+
def disable_log_on_file(self):
264+
"""Disable writing log messages to an output file."""
265+
self._log_on_file = False
266+
for _file_handler in self._files_handlers:
267+
_file_handler.close()
268+
self._global.removeHandler(_file_handler)
269+
self.info("Log on file is disabled")
270+
271+
def enable_log_on_file(self):
272+
"""Enable writing log messages to an output file."""
273+
self._log_on_file = True
274+
for _file_handler in self._files_handlers:
275+
self._global.addHandler(_file_handler)
276+
self.info("Log on file is enabled")
277+
278+
def info(self, msg, *args, **kwargs):
279+
"""Write an info message to the global logger."""
280+
if not settings.enable_logger:
281+
return
282+
if args:
283+
try:
284+
msg1 = msg % tuple(str(i) for i in args)
285+
except TypeError:
286+
msg1 = msg
287+
else:
288+
msg1 = msg
289+
return self._log_on_handler(0, msg, *args, **kwargs)
290+
291+
def info_timer(self, msg, start_time=None, *args, **kwargs):
292+
"""Write an info message to the global logger with elapsed time.
293+
Message will have an appendix of type Elapsed time: time."""
294+
if not settings.enable_logger:
295+
return
296+
if not start_time:
297+
start_time = self._timer
298+
td = time.time() - start_time
299+
m, s = divmod(td, 60)
300+
h, m = divmod(m, 60)
301+
d, h = divmod(h, 24)
302+
if d > 0:
303+
msg += " Elapsed time: {}days {}h {}m {}sec".format(round(d), round(h), round(m), round(s))
304+
elif h > 0:
305+
msg += " Elapsed time: {}h {}m {}sec".format(round(h), round(m), round(s))
306+
else:
307+
msg += " Elapsed time: {}m {}sec".format(round(m), round(s))
308+
if args:
309+
try:
310+
msg1 = msg % tuple(str(i) for i in args)
311+
except TypeError:
312+
msg1 = msg
313+
else:
314+
msg1 = msg
315+
return self._log_on_handler(0, msg, *args, **kwargs)
316+
317+
def warning(self, msg, *args, **kwargs):
318+
"""Write a warning message to the global logger."""
319+
if not settings.enable_logger:
320+
return
321+
if args:
322+
try:
323+
msg1 = msg % tuple(str(i) for i in args)
324+
except TypeError:
325+
msg1 = msg
326+
else:
327+
msg1 = msg
328+
return self._log_on_handler(1, msg, *args, **kwargs)
329+
330+
def error(self, msg, *args, **kwargs):
331+
"""Write an error message to the global logger."""
332+
if args:
333+
try:
334+
msg1 = msg % tuple(str(i) for i in args)
335+
except TypeError:
336+
msg1 = msg
337+
else:
338+
msg1 = msg
339+
return self._log_on_handler(2, msg, *args, **kwargs)
340+
341+
def debug(self, msg, *args, **kwargs):
342+
"""Write a debug message to the global logger."""
343+
if not settings.enable_debug_logger or not settings.enable_logger:
344+
return
345+
if args:
346+
try:
347+
msg1 = msg % tuple(str(i) for i in args)
348+
except TypeError:
349+
msg1 = msg
350+
else:
351+
msg1 = msg
352+
return self._log_on_handler(3, msg, *args, **kwargs)
353+
354+
@property
355+
def glb(self):
356+
"""Global logger."""
357+
self._global = logging.getLogger("Global")
358+
return self._global
359+
360+
361+
pyedb_logger = EdbLogger(to_stdout=settings.enable_screen_logs)

0 commit comments

Comments
 (0)