2# +==== BEGIN rotary_logger =================+
4# ..........####...####..........
5# ......###.....#.#########......
6# ....##........#.###########....
7# ...#..........#.############...
8# ...#..........#.#####.######...
9# ..#.....##....#.###..#...####..
10# .#.....#.##...#.##..##########.
11# #.....##########....##...######
12# #.....#...##..#.##..####.######
13# .#...##....##.#.##..###..#####.
14# ..#.##......#.#.####...######..
15# ..#...........#.#############..
16# ..#...........#.#############..
17# ...##.........#.############...
18# ......#.......#.#########......
19# .......#......#.########.......
20# .........#####...#####.........
22# PROJECT: rotary_logger
24# CREATION DATE: 18-03-2026
25# LAST Modified: 9:20:42 27-03-2026
27# A module that provides a universal python light on iops way of logging to files your program execution.
29# COPYRIGHT: (c) Asperguide
30# PURPOSE: A class that is tailored to the module to allow it to log without fering of breaking structure.
32# +==== END rotary_logger =================+
37from threading
import RLock
38from datetime
import datetime
39from io
import TextIOWrapper
40from typing
import Optional, TextIO, Union, TYPE_CHECKING
41from .constants
import MODULE_NAME, LogToggle, RAW_STDOUT, RAW_STDERR
44 from .tee_stream
import TeeStream
49 This is a custom made class that aims to work seamlessly with the library so that it doesn't break streams.
52 _class_lock: RLock = RLock()
53 _function_lock: RLock = RLock()
54 _instance: Optional[
"Rogger"] =
None
64 program_log: bool =
False,
65 program_debug_log: bool =
False,
66 suppress_program_warning_logs: bool =
False,
67 suppress_program_error_logs: bool =
False
73 suppress_program_warning_logs,
74 suppress_program_error_logs
87 program_log: bool =
False,
88 program_debug_log: bool =
False,
89 suppress_program_warning_logs: bool =
False,
90 suppress_program_error_logs: bool =
False
92 """Re-create the toggle settings after the class has already been initialised.
95 program_log (bool, optional): Wether to log to the terminal. Defaults to False.
96 program_debug_log (bool, optional): Wether to log debug. Defaults to False.
97 suppress_program_warning_logs (bool, optional): Wether to display warnings or not. Defaults to False.
98 suppress_program_error_logs (bool, optional): Wether to display errors or not. Defaults to False.
103 suppress_program_warning_logs,
104 suppress_program_error_logs
111 program_log: bool =
False,
112 program_debug_log: bool =
False,
113 suppress_program_warning_logs: bool =
False,
114 suppress_program_error_logs: bool =
False
116 """Define which log modes can be used.
119 LogToggle: The dataclass to follow.
121 _success: bool =
True
123 _warning: bool =
True
125 _critical: bool =
True
127 if program_debug_log
is False:
129 if program_log
is False:
132 if suppress_program_warning_logs
is True:
136 if suppress_program_error_logs
is True:
143 program_log=program_log,
154 The function in charge of returning the date string for the line.
157 str: the string ready to be embedded.
160 final = now.strftime(
163 final += f
",{now.microsecond // 1000:03d}"
167 """Determine the name of the class that called the log
170 depth (int, optional): The upstream depth to look into. Defaults to 2.
173 Optional[str]: The name of the class (if any)
175 if self.
toggles.program_log
is False:
179 frame = inspect.currentframe()
188 while current_depth < depth:
189 if frame
and frame.f_back
is not None:
202 locals_ = frame.f_locals
208 if "self" in locals_:
210 return type(locals_[
"self"]).__name__
218 return locals_[
"cls"].__name__
226 """Determine the name of the function that called the log
229 depth (int, optional): The upstream depth to look into. Defaults to 2.
232 Optional[str]: The name of the function (if any)
234 if self.
toggles.program_log
is False:
237 _func_name = inspect.currentframe()
241 if _func_name
is None:
245 while current_depth < depth:
246 if _func_name
and _func_name.f_back
is not None:
247 _func_name = _func_name.f_back
255 if _func_name
is None:
258 return _func_name.f_code.co_name
263 def _log_if_possible(self, log_type: str, message: str, function_name: Optional[str], class_name: Optional[str], stream: Union[Optional[TextIOWrapper], TextIO,
"TeeStream"]) ->
None:
264 """The generic function to log the message to the provided stream
267 log_type (str): The type of log message (Info, Warning, Error, etc)
268 message (str): The message provided by the user
269 function_name (Optional[str]): The name of the function
270 stream (Union[TextIO, TeeStream]): The stream to write to
272 if function_name
is None:
274 if class_name
is None:
277 final_msg = f
"[{date}] {self.program_name} {log_type} ({class_name}.{function_name}): {message}\n"
281 stream.write(final_msg)
283 def log_success(self, message: str, *, function_name: Optional[str] =
None, class_name: Optional[str] =
None, stream: Union[Optional[TextIOWrapper], TextIO,
"TeeStream"] = RAW_STDOUT) ->
None:
284 """Log a success message to the stream (if logging conditions are met)
287 message (str): The message to display
288 function_name (Optional[str], optional): The name of the function calling it. Defaults to None.
289 class_name (Optional[str], optional): The name of the class calling it. Defaults to None.
290 stream (Union[TextIO, TeeStream], optional): The stream to write to. Defaults to RAW_STDOUT.
292 if self.
toggles.success
is False:
294 if function_name
is None:
296 if class_name
is None:
301 function_name=function_name,
302 class_name=class_name,
306 def log_info(self, message: str, *, function_name: Optional[str] =
None, class_name: Optional[str] =
None, stream: Union[Optional[TextIOWrapper], TextIO,
"TeeStream"] = RAW_STDOUT) ->
None:
307 """Log a info message to the stream (if logging conditions are met)
310 message (str): The message to display
311 function_name (Optional[str], optional): The name of the function calling it. Defaults to None.
312 class_name (Optional[str], optional): The name of the class calling it. Defaults to None.
313 stream (Union[TextIO, TeeStream], optional): The stream to write to. Defaults to RAW_STDOUT.
317 if function_name
is None:
319 if class_name
is None:
324 function_name=function_name,
325 class_name=class_name,
329 def log_warning(self, message: str, *, function_name: Optional[str] =
None, class_name: Optional[str] =
None, stream: Union[Optional[TextIOWrapper], TextIO,
"TeeStream"] = RAW_STDERR) ->
None:
330 """Log a warning message to the stream (if logging conditions are met)
333 message (str): The message to display
334 function_name (Optional[str], optional): The name of the function calling it. Defaults to None.
335 class_name (Optional[str], optional): The name of the class calling it. Defaults to None.
336 stream (Union[TextIO, TeeStream], optional): The stream to write to. Defaults to RAW_STDERR.
338 if self.
toggles.warning
is False:
340 if function_name
is None:
342 if class_name
is None:
347 function_name=function_name,
348 class_name=class_name,
352 def log_error(self, message: str, *, function_name: Optional[str] =
None, class_name: Optional[str] =
None, stream: Union[Optional[TextIOWrapper], TextIO,
"TeeStream"] = RAW_STDERR) ->
None:
353 """Log an error message to the stream (if logging conditions are met)
356 message (str): The message to display
357 function_name (Optional[str], optional): The name of the function calling it. Defaults to None.
358 class_name (Optional[str], optional): The name of the class calling it. Defaults to None.
359 stream (Union[TextIO, TeeStream], optional): The stream to write to. Defaults to RAW_STDERR.
361 if self.
toggles.error
is False:
363 if function_name
is None:
365 if class_name
is None:
370 function_name=function_name,
371 class_name=class_name,
375 def log_critical(self, message: str, *, function_name: Optional[str] =
None, class_name: Optional[str] =
None, stream: Union[Optional[TextIOWrapper], TextIO,
"TeeStream"] = RAW_STDERR) ->
None:
376 """Log a critical message to the stream (if logging conditions are met)
379 message (str): The message to display
380 function_name (Optional[str], optional): The name of the function calling it. Defaults to None.
381 class_name (Optional[str], optional): The name of the class calling it. Defaults to None.
382 stream (Union[TextIO, TeeStream], optional): The stream to write to. Defaults to RAW_STDERR.
384 if self.
toggles.critical
is False:
386 if function_name
is None:
388 if class_name
is None:
393 function_name=function_name,
394 class_name=class_name,
398 def log_debug(self, message: str, *, function_name: Optional[str] =
None, class_name: Optional[str] =
None, stream: Union[Optional[TextIOWrapper], TextIO,
"TeeStream"] = RAW_STDOUT) ->
None:
399 """Log a debug message to the stream (if logging conditions are met)
402 message (str): The message to display
403 function_name (Optional[str], optional): The name of the function calling it. Defaults to None.
404 class_name (Optional[str], optional): The name of the class calling it. Defaults to None.
405 stream (Union[TextIO, TeeStream], optional): The stream to write to. Defaults to RAW_STDOUT.
407 if self.
toggles.debug
is False:
409 if function_name
is None:
411 if class_name
is None:
416 function_name=function_name,
417 class_name=class_name,
None log_info(self, str message, *, Optional[str] function_name=None, Optional[str] class_name=None, Union[Optional[TextIOWrapper], TextIO, "TeeStream"] stream=RAW_STDOUT)
None log_error(self, str message, *, Optional[str] function_name=None, Optional[str] class_name=None, Union[Optional[TextIOWrapper], TextIO, "TeeStream"] stream=RAW_STDERR)
None re_toggle(self, bool program_log=False, bool program_debug_log=False, bool suppress_program_warning_logs=False, bool suppress_program_error_logs=False)
None log_warning(self, str message, *, Optional[str] function_name=None, Optional[str] class_name=None, Union[Optional[TextIOWrapper], TextIO, "TeeStream"] stream=RAW_STDERR)
None log_critical(self, str message, *, Optional[str] function_name=None, Optional[str] class_name=None, Union[Optional[TextIOWrapper], TextIO, "TeeStream"] stream=RAW_STDERR)
None _log_if_possible(self, str log_type, str message, Optional[str] function_name, Optional[str] class_name, Union[Optional[TextIOWrapper], TextIO, "TeeStream"] stream)
None log_debug(self, str message, *, Optional[str] function_name=None, Optional[str] class_name=None, Union[Optional[TextIOWrapper], TextIO, "TeeStream"] stream=RAW_STDOUT)
LogToggle _create_log_toggle(self, bool program_log=False, bool program_debug_log=False, bool suppress_program_warning_logs=False, bool suppress_program_error_logs=False)
Optional[str] _get_class_name(self, int depth=1)
None __init__(self, bool program_log=False, bool program_debug_log=False, bool suppress_program_warning_logs=False, bool suppress_program_error_logs=False)
None log_success(self, str message, *, Optional[str] function_name=None, Optional[str] class_name=None, Union[Optional[TextIOWrapper], TextIO, "TeeStream"] stream=RAW_STDOUT)
Optional[str] _get_function_name(self, int depth=2)