Skip to content

Commit 6569748

Browse files
committed
Refactor logging mechanism to encapsulate console logging behavior and improve logger initialization
1 parent fc5de9a commit 6569748

File tree

3 files changed

+63
-32
lines changed

3 files changed

+63
-32
lines changed

src/iop/_common.py

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,19 @@ class _Common(metaclass=abc.ABCMeta):
1717
INFO_URL: ClassVar[str]
1818
ICON_URL: ClassVar[str]
1919
iris_handle: Any = None
20-
log_to_console: bool = False
20+
_log_to_console: bool = False
21+
22+
@property
23+
def log_to_console(self) -> bool:
24+
return self._log_to_console
25+
26+
@log_to_console.setter
27+
def log_to_console(self, value: bool) -> None:
28+
self._log_to_console = value
29+
self.logger = LogManager.get_logger(self.__class__.__name__,value)
30+
31+
def __init__(self):
32+
self.logger = LogManager.get_logger(self.__class__.__name__)
2133

2234
# Lifecycle methods
2335
def on_init(self) -> None:
@@ -172,7 +184,7 @@ def _get_properties(cls) -> List[List[Any]]:
172184
except:
173185
pass
174186
return ret
175-
187+
176188
# Logging methods
177189
def _log(self) -> Tuple[str, Optional[str]]:
178190
"""Get class and method name for logging.
@@ -189,15 +201,27 @@ def _log(self) -> Tuple[str, Optional[str]]:
189201
pass
190202
return current_class, current_method
191203

192-
@property
193-
def logger(self) -> logging.Logger:
194-
"""Get a logger instance for this component.
204+
def _logging(self, message: str, level: int, to_console: Optional[bool] = None) -> None:
205+
"""Write log entry.
195206
196-
Returns:
197-
Logger configured for IRIS integration
207+
Args:
208+
message: Message to log
209+
level: Log level
210+
to_console: If True, log to console instead of IRIS
198211
"""
199-
class_name, method_name = self._log()
200-
return LogManager.get_logger(class_name, method_name, self.log_to_console)
212+
current_class, current_method = self._log()
213+
if to_console is None:
214+
to_console = self.log_to_console
215+
if level == logging.DEBUG:
216+
self.logger.debug(message, extra={'to_console': to_console, 'class_name': current_class, 'method_name': current_method})
217+
elif level == logging.INFO:
218+
self.logger.info(message, extra={'to_console': to_console, 'class_name': current_class, 'method_name': current_method})
219+
elif level == logging.CRITICAL:
220+
self.logger.critical(message, extra={'to_console': to_console, 'class_name': current_class, 'method_name': current_method})
221+
elif level == logging.WARNING:
222+
self.logger.warning(message, extra={'to_console': to_console, 'class_name': current_class, 'method_name': current_method})
223+
elif level == logging.ERROR:
224+
self.logger.error(message, extra={'to_console': to_console, 'class_name': current_class, 'method_name': current_method})
201225

202226
def trace(self, message: str, to_console: Optional[bool] = None) -> None:
203227
"""Write trace log entry.
@@ -206,8 +230,7 @@ def trace(self, message: str, to_console: Optional[bool] = None) -> None:
206230
message: Message to log
207231
to_console: If True, log to console instead of IRIS
208232
"""
209-
self.logger.debug(message, extra={'to_console': to_console})
210-
233+
self._logging(message, logging.DEBUG, to_console)
211234

212235
def log_info(self, message: str, to_console: Optional[bool] = None) -> None:
213236
"""Write info log entry.
@@ -216,7 +239,7 @@ def log_info(self, message: str, to_console: Optional[bool] = None) -> None:
216239
message: Message to log
217240
to_console: If True, log to console instead of IRIS
218241
"""
219-
self.logger.info(message, extra={'to_console': to_console})
242+
self._logging(message, logging.INFO, to_console)
220243

221244
def log_alert(self, message: str, to_console: Optional[bool] = None) -> None:
222245
"""Write alert log entry.
@@ -225,7 +248,7 @@ def log_alert(self, message: str, to_console: Optional[bool] = None) -> None:
225248
message: Message to log
226249
to_console: If True, log to console instead of IRIS
227250
"""
228-
self.logger.critical(message, extra={'to_console': to_console})
251+
self._logging(message, logging.CRITICAL, to_console)
229252

230253
def log_warning(self, message: str, to_console: Optional[bool] = None) -> None:
231254
"""Write warning log entry.
@@ -234,7 +257,7 @@ def log_warning(self, message: str, to_console: Optional[bool] = None) -> None:
234257
message: Message to log
235258
to_console: If True, log to console instead of IRIS
236259
"""
237-
self.logger.warning(message, extra={'to_console': to_console})
260+
self._logging(message, logging.WARNING, to_console)
238261

239262
def log_error(self, message: str, to_console: Optional[bool] = None) -> None:
240263
"""Write error log entry.
@@ -243,7 +266,7 @@ def log_error(self, message: str, to_console: Optional[bool] = None) -> None:
243266
message: Message to log
244267
to_console: If True, log to console instead of IRIS
245268
"""
246-
self.logger.error(message, extra={'to_console': to_console})
269+
self._logging(message, logging.ERROR, to_console)
247270

248271
def log_assert(self, message: str) -> None:
249272
"""Write a log entry of type "assert". Log entries can be viewed in the management portal.

src/iop/_log_manager.py

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import traceback
12
import iris
23
import logging
34
from typing import Optional, Tuple
@@ -6,7 +7,7 @@ class LogManager:
67
"""Manages logging integration between Python's logging module and IRIS."""
78

89
@staticmethod
9-
def get_logger(class_name: str, method_name: Optional[str] = None, to_console: bool = False) -> logging.Logger:
10+
def get_logger(class_name: str, to_console: bool = False) -> logging.Logger:
1011
"""Get a logger instance configured for IRIS integration.
1112
1213
Args:
@@ -17,11 +18,11 @@ def get_logger(class_name: str, method_name: Optional[str] = None, to_console: b
1718
Returns:
1819
Logger instance configured for IRIS integration
1920
"""
20-
logger = logging.getLogger(f"{class_name}.{method_name}" if method_name else class_name)
21+
logger = logging.Logger(f"{class_name}")
2122

2223
# Only add handler if none exists
2324
if not logger.handlers:
24-
handler = IRISLogHandler(class_name, method_name, to_console)
25+
handler = IRISLogHandler(to_console=to_console)
2526
formatter = logging.Formatter('%(message)s')
2627
handler.setFormatter(formatter)
2728
logger.addHandler(handler)
@@ -33,17 +34,9 @@ def get_logger(class_name: str, method_name: Optional[str] = None, to_console: b
3334
class IRISLogHandler(logging.Handler):
3435
"""Custom logging handler that routes Python logs to IRIS logging system."""
3536

36-
def __init__(self, class_name: str, method_name: Optional[str] = None, to_console: bool = False):
37-
"""Initialize the handler with context information.
38-
39-
Args:
40-
class_name: Name of the class logging the message
41-
method_name: Optional name of the method logging the message
42-
console: If True, log to the console instead of IRIS
43-
"""
37+
def __init__(self, to_console: bool = False):
38+
"""Initialize the IRIS logging handler."""
4439
super().__init__()
45-
self.class_name = class_name
46-
self.method_name = method_name
4740
self.to_console = to_console
4841

4942
# Map Python logging levels to IRIS logging methods
@@ -80,10 +73,11 @@ def emit(self, record: logging.LogRecord) -> None:
8073
Args:
8174
record: The logging record to emit
8275
"""
83-
84-
log_func = self.level_map.get(record.levelno, iris.cls("Ens.Util.Log").LogInfo)
76+
class_name = record.class_name if hasattr(record, "class_name") else record.name
77+
method_name = record.method_name if hasattr(record, "method_name") else record.funcName
8578
if self.to_console or (hasattr(record, "to_console") and record.to_console):
8679
iris.cls("%SYS.System").WriteToConsoleLog(self.format(record),
87-
0,self.level_map_console.get(record.levelno, 0),record.name)
80+
0,self.level_map_console.get(record.levelno, 0),class_name+"."+method_name)
8881
else:
89-
log_func(self.class_name, self.method_name, self.format(record))
82+
log_func = self.level_map.get(record.levelno, iris.cls("Ens.Util.Log").LogInfo)
83+
log_func(class_name, method_name, self.format(record))

src/tests/test_commun.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,20 @@ def test_is_iris_object_instance(self):
4545
assert is_iris_object_instance(msg_job) == False
4646

4747
class TestLogging:
48+
49+
def test_log_info_loggger(self, common, random_string):
50+
common.logger.info(random_string)
51+
rs = self._check_log_entry(random_string, 'test_log_info_loggger')
52+
assert len(rs) == 1
53+
54+
def test_log_info_loggger_to_console(self, common, random_string):
55+
common.log_to_console = True
56+
common.logger.info(random_string)
57+
58+
with open(MESSAGE_LOG_PATH, 'r') as file:
59+
last_line = file.readlines()[-1]
60+
assert random_string in last_line
61+
4862
def test_log_info_to_console(self, common, random_string):
4963
common.log_to_console = True
5064
common.log_info(random_string)

0 commit comments

Comments
 (0)