gllm-core-binary 0.4.4__py3-none-macosx_13_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. gllm_core/__init__.py +1 -0
  2. gllm_core/__init__.pyi +0 -0
  3. gllm_core/adapters/__init__.py +5 -0
  4. gllm_core/adapters/__init__.pyi +3 -0
  5. gllm_core/adapters/tool/__init__.py +6 -0
  6. gllm_core/adapters/tool/__init__.pyi +4 -0
  7. gllm_core/adapters/tool/google_adk.py +91 -0
  8. gllm_core/adapters/tool/google_adk.pyi +23 -0
  9. gllm_core/adapters/tool/langchain.py +130 -0
  10. gllm_core/adapters/tool/langchain.pyi +31 -0
  11. gllm_core/constants.py +55 -0
  12. gllm_core/constants.pyi +36 -0
  13. gllm_core/event/__init__.py +6 -0
  14. gllm_core/event/__init__.pyi +4 -0
  15. gllm_core/event/event_emitter.py +211 -0
  16. gllm_core/event/event_emitter.pyi +155 -0
  17. gllm_core/event/handler/__init__.py +7 -0
  18. gllm_core/event/handler/__init__.pyi +5 -0
  19. gllm_core/event/handler/console_event_handler.py +48 -0
  20. gllm_core/event/handler/console_event_handler.pyi +32 -0
  21. gllm_core/event/handler/event_handler.py +89 -0
  22. gllm_core/event/handler/event_handler.pyi +51 -0
  23. gllm_core/event/handler/print_event_handler.py +130 -0
  24. gllm_core/event/handler/print_event_handler.pyi +33 -0
  25. gllm_core/event/handler/stream_event_handler.py +85 -0
  26. gllm_core/event/handler/stream_event_handler.pyi +62 -0
  27. gllm_core/event/hook/__init__.py +5 -0
  28. gllm_core/event/hook/__init__.pyi +3 -0
  29. gllm_core/event/hook/event_hook.py +30 -0
  30. gllm_core/event/hook/event_hook.pyi +18 -0
  31. gllm_core/event/hook/json_stringify_event_hook.py +32 -0
  32. gllm_core/event/hook/json_stringify_event_hook.pyi +16 -0
  33. gllm_core/event/messenger.py +133 -0
  34. gllm_core/event/messenger.pyi +66 -0
  35. gllm_core/schema/__init__.py +8 -0
  36. gllm_core/schema/__init__.pyi +6 -0
  37. gllm_core/schema/chunk.py +148 -0
  38. gllm_core/schema/chunk.pyi +66 -0
  39. gllm_core/schema/component.py +546 -0
  40. gllm_core/schema/component.pyi +205 -0
  41. gllm_core/schema/event.py +50 -0
  42. gllm_core/schema/event.pyi +33 -0
  43. gllm_core/schema/schema_generator.py +150 -0
  44. gllm_core/schema/schema_generator.pyi +35 -0
  45. gllm_core/schema/tool.py +418 -0
  46. gllm_core/schema/tool.pyi +198 -0
  47. gllm_core/utils/__init__.py +32 -0
  48. gllm_core/utils/__init__.pyi +13 -0
  49. gllm_core/utils/analyzer.py +256 -0
  50. gllm_core/utils/analyzer.pyi +123 -0
  51. gllm_core/utils/binary_handler_factory.py +99 -0
  52. gllm_core/utils/binary_handler_factory.pyi +62 -0
  53. gllm_core/utils/chunk_metadata_merger.py +102 -0
  54. gllm_core/utils/chunk_metadata_merger.pyi +41 -0
  55. gllm_core/utils/concurrency.py +184 -0
  56. gllm_core/utils/concurrency.pyi +94 -0
  57. gllm_core/utils/event_formatter.py +69 -0
  58. gllm_core/utils/event_formatter.pyi +30 -0
  59. gllm_core/utils/google_sheets.py +115 -0
  60. gllm_core/utils/google_sheets.pyi +18 -0
  61. gllm_core/utils/imports.py +91 -0
  62. gllm_core/utils/imports.pyi +42 -0
  63. gllm_core/utils/logger_manager.py +339 -0
  64. gllm_core/utils/logger_manager.pyi +176 -0
  65. gllm_core/utils/main_method_resolver.py +185 -0
  66. gllm_core/utils/main_method_resolver.pyi +54 -0
  67. gllm_core/utils/merger_method.py +130 -0
  68. gllm_core/utils/merger_method.pyi +49 -0
  69. gllm_core/utils/retry.py +258 -0
  70. gllm_core/utils/retry.pyi +41 -0
  71. gllm_core/utils/similarity.py +29 -0
  72. gllm_core/utils/similarity.pyi +10 -0
  73. gllm_core/utils/validation.py +26 -0
  74. gllm_core/utils/validation.pyi +12 -0
  75. gllm_core_binary-0.4.4.dist-info/METADATA +177 -0
  76. gllm_core_binary-0.4.4.dist-info/RECORD +78 -0
  77. gllm_core_binary-0.4.4.dist-info/WHEEL +5 -0
  78. gllm_core_binary-0.4.4.dist-info/top_level.txt +1 -0
@@ -0,0 +1,339 @@
1
+ """Defines a logger manager to manage logging configuration across the Gen AI application components.
2
+
3
+ Authors:
4
+ Dimitrij Ray (dimitrij.ray@gdplabs.id)
5
+ Henry Wicaksono (henry.wicaksono@gdplabs.id)
6
+ Hermes Vincentius Gani (hermes.v.gani@gdplabs.id)
7
+
8
+ References:
9
+ NONE
10
+ """
11
+
12
+ import logging
13
+ import os
14
+ import threading
15
+
16
+ from pythonjsonlogger.core import LogRecord
17
+ from pythonjsonlogger.json import JsonFormatter
18
+ from rich.console import Console
19
+ from rich.highlighter import NullHighlighter
20
+ from rich.logging import RichHandler
21
+
22
+ from gllm_core.constants import LogMode
23
+
24
+ DEFAULT_DATE_FORMAT = "%Y-%m-%dT%H:%M:%S%z"
25
+ TEXT_COLOR_MAP = {
26
+ logging.DEBUG: "green",
27
+ logging.INFO: "blue",
28
+ logging.WARNING: "yellow",
29
+ logging.ERROR: "red",
30
+ logging.CRITICAL: "bold black on red",
31
+ }
32
+ LOG_FORMAT_KEY = "LOG_FORMAT"
33
+ RICH_CLOSE_TAG = "[/"
34
+ JSON_LOG_FIELDS = ["timestamp", "name", "level", "message"]
35
+ JSON_ERROR_FIELDS_MAP = {
36
+ "exc_info": "message",
37
+ "stack_info": "stacktrace",
38
+ "error_code": "code",
39
+ }
40
+
41
+
42
+ class TextRichHandler(RichHandler):
43
+ """Custom RichHandler that applies specific colors and log format."""
44
+
45
+ def emit(self, record: logging.LogRecord) -> None:
46
+ """Emits a log record with custom coloring.
47
+
48
+ Args:
49
+ record (logging.LogRecord): The log record to emit.
50
+ """
51
+ color = TEXT_COLOR_MAP.get(record.levelno, "white")
52
+
53
+ name, msg = record.name, record.getMessage()
54
+ msg = msg.replace(RICH_CLOSE_TAG, rf"\{RICH_CLOSE_TAG}")
55
+
56
+ record.msg = f"[{color}][{name}] {msg}[/]"
57
+ record.args = None
58
+
59
+ super().emit(record)
60
+
61
+
62
+ class SimpleRichHandler(logging.StreamHandler):
63
+ """Custom StreamHandler that utilizes Rich only to apply colors, without columns or Rich formatting.
64
+
65
+ Attributes:
66
+ console (Console): The Rich Console object to use for printing.
67
+ """
68
+
69
+ def __init__(self, *args, **kwargs) -> None:
70
+ """Initializes a new instance of the SimpleRichHandler class."""
71
+ super().__init__(*args, **kwargs)
72
+ self.console = Console(file=self.stream)
73
+
74
+ def emit(self, record: logging.LogRecord) -> None:
75
+ """Emits a log record with simple Rich coloring.
76
+
77
+ Args:
78
+ record (logging.LogRecord): The log record to emit.
79
+ """
80
+ color = TEXT_COLOR_MAP.get(record.levelno, "white")
81
+ msg = self.format(record)
82
+ msg = msg.replace(RICH_CLOSE_TAG, rf"\{RICH_CLOSE_TAG}")
83
+
84
+ self.console.print(f"[{color}]{msg}[/]", markup=True, highlight=False)
85
+
86
+
87
+ class AppJSONFormatter(JsonFormatter):
88
+ """JSON formatter that groups error-related fields under an 'error' key.
89
+
90
+ This formatter renames the following fields when present:
91
+ 1. exc_info -> error.message
92
+ 2. stack_info -> error.stacktrace
93
+ 3. error_code -> error.code
94
+ """
95
+
96
+ def process_log_record(self, log_record: LogRecord) -> LogRecord:
97
+ """Process log record to group and rename error-related fields.
98
+
99
+ Args:
100
+ log_record (LogRecord): The original log record.
101
+
102
+ Returns:
103
+ LogRecord: The processed log record.
104
+ """
105
+ record = super().process_log_record(log_record)
106
+ logged_record = {key: value for key, value in record.items() if key in JSON_LOG_FIELDS}
107
+ error_payload: dict[str, str] = dict.fromkeys(JSON_ERROR_FIELDS_MAP.values(), "")
108
+
109
+ for key, new_key in JSON_ERROR_FIELDS_MAP.items():
110
+ if value := record.get(key):
111
+ error_payload[new_key] = value
112
+
113
+ if any(error_payload.values()):
114
+ logged_record["error"] = error_payload
115
+
116
+ return logged_record
117
+
118
+
119
+ LOG_FORMAT_HANDLER_MAP = {
120
+ LogMode.TEXT: TextRichHandler(
121
+ markup=True,
122
+ omit_repeated_times=False,
123
+ highlighter=NullHighlighter(),
124
+ ),
125
+ LogMode.SIMPLE: SimpleRichHandler(),
126
+ LogMode.JSON: logging.StreamHandler(),
127
+ }
128
+
129
+ LOG_FORMAT_MAP = {
130
+ LogMode.TEXT: "%(message)s",
131
+ LogMode.SIMPLE: "[%(asctime)s.%(msecs)03d %(name)s %(levelname)s] %(message)s",
132
+ LogMode.JSON: "{asctime} {name} {levelname} {message}",
133
+ }
134
+
135
+
136
+ class LoggerManager:
137
+ """A singleton class to manage logging configuration.
138
+
139
+ This class ensures that the root logger is initialized only once and is used across the application.
140
+
141
+ Basic usage:
142
+ The `LoggerManager` can be used to get a logger instance as follows:
143
+ ```python
144
+ logger = LoggerManager().get_logger()
145
+ logger.info("This is an info message")
146
+ ```
147
+
148
+ Set logging configuration:
149
+ The `LoggerManager` also provides capabilities to set the logging configuration:
150
+ ```python
151
+ manager = LoggerManager()
152
+ manager.set_level(logging.DEBUG)
153
+ manager.set_log_format(custom_log_format)
154
+ manager.set_date_format(custom_date_format)
155
+ ```
156
+
157
+ Add custom handlers:
158
+ The `LoggerManager` also provides capabilities to add custom handlers to the root logger:
159
+ ```python
160
+ manager = LoggerManager()
161
+ handler = logging.FileHandler("app.log")
162
+ manager.add_handler(handler)
163
+ ```
164
+
165
+ Extra error information:
166
+ When logging errors, extra error information can be added as follows:
167
+ ```python
168
+ logger.error("I am dead!", extra={"error_code": "ERR_CONN_REFUSED"})
169
+ ```
170
+
171
+ Logging modes:
172
+ The `LoggerManager` supports three logging modes:
173
+
174
+ 1. Text: Logs in a human-readable format with RichHandler column-based formatting.
175
+ Used when the `LOG_FORMAT` environment variable is set to "text".
176
+ Output example:
177
+ ```log
178
+ 2025-10-08T09:26:16 DEBUG [LoggerName] This is a debug message.
179
+ 2025-10-08T09:26:17 INFO [LoggerName] This is an info message.
180
+ 2025-10-08T09:26:18 WARNING [LoggerName] This is a warning message.
181
+ 2025-10-08T09:26:19 ERROR [LoggerName] This is an error message.
182
+ 2025-10-08T09:26:20 CRITICAL [LoggerName] This is a critical message.
183
+ ```
184
+
185
+ 2. Simple: Logs in a human-readable format with Rich colors but without columns-based formatting.
186
+ Used when the `LOG_FORMAT` environment variable is set to "simple".
187
+ Output example:
188
+ ```log
189
+ [2025-10-08T09:26:16.123 LoggerName DEBUG] This is a debug message.
190
+ [2025-10-08T09:26:17.456 LoggerName INFO] This is an info message.
191
+ [2025-10-08T09:26:18.789 LoggerName WARNING] This is a warning message.
192
+ [2025-10-08T09:26:19.012 LoggerName ERROR] This is an error message.
193
+ [2025-10-08T09:26:20.345 LoggerName CRITICAL] This is a critical message.
194
+ ```
195
+
196
+ 3. JSON: Logs in a JSON format, recommended for easy parsing due to the structured nature of the log records.
197
+ Used when the `LOG_FORMAT` environment variable is set to "json".
198
+ Output example:
199
+ ```log
200
+ {"timestamp": "2025-10-08T11:23:43+0700", "name": "LoggerName", "level": "DEBUG", "message": "..."}
201
+ {"timestamp": "2025-10-08T11:23:44+0700", "name": "LoggerName", "level": "INFO", "message": "..."}
202
+ {"timestamp": "2025-10-08T11:23:45+0700", "name": "LoggerName", "level": "WARNING", "message": "..."}
203
+ {"timestamp": "2025-10-08T11:23:46+0700", "name": "LoggerName", "level": "ERROR", "message": "..."}
204
+ {"timestamp": "2025-10-08T11:23:47+0700", "name": "LoggerName", "level": "CRITICAL", "message": "..."}
205
+ ```
206
+
207
+ When the `LOG_FORMAT` environment is not set, the `LoggerManager` defaults to "text" mode.
208
+ """
209
+
210
+ _instance = None
211
+ _root_logger = None
212
+ _handlers = None
213
+ _formatter = None
214
+ _lock = threading.Lock()
215
+
216
+ def __new__(cls) -> "LoggerManager":
217
+ """Initialize the singleton instance.
218
+
219
+ Returns:
220
+ LoggerManager: The singleton instance.
221
+ """
222
+ with cls._lock:
223
+ if cls._instance is None:
224
+ cls._instance = super().__new__(cls)
225
+ cls._initialize_root_logger()
226
+ return cls._instance
227
+
228
+ # TODO: Refactor determining log mode via parameter instead of environment variable
229
+ @classmethod
230
+ def _initialize_root_logger(cls) -> None:
231
+ """Initialize the root logger with default configuration."""
232
+ log_mode = os.getenv(LOG_FORMAT_KEY, LogMode.TEXT).lower()
233
+
234
+ cls._log_mode = log_mode if log_mode in LOG_FORMAT_HANDLER_MAP else LogMode.TEXT
235
+ cls._root_logger = logging.getLogger()
236
+ cls._root_logger.handlers.clear()
237
+ cls._formatter = cls._build_formatter()
238
+
239
+ default_handler = LOG_FORMAT_HANDLER_MAP[cls._log_mode]
240
+ default_handler.setFormatter(cls._formatter)
241
+ cls._handlers = [default_handler]
242
+ cls._root_logger.addHandler(default_handler)
243
+ cls._root_logger.setLevel(logging.INFO)
244
+ cls._root_logger.propagate = False
245
+
246
+ @classmethod
247
+ def _build_formatter(cls, fmt: str | None = None, datefmt: str = DEFAULT_DATE_FORMAT) -> logging.Formatter:
248
+ """Create a formatter based on current mode (JSON, TEXT, or SIMPLE).
249
+
250
+ Args:
251
+ fmt (str | None, optional): The format string. Defaults to None,
252
+ in which case the default log format is used.
253
+ datefmt (str, optional): The date format string. Defaults to DEFAULT_DATE_FORMAT.
254
+
255
+ Returns:
256
+ logging.Formatter: The formatter.
257
+ """
258
+ fmt = fmt or LOG_FORMAT_MAP[cls._log_mode]
259
+
260
+ if not cls._log_mode == LogMode.JSON:
261
+ return logging.Formatter(fmt, datefmt)
262
+
263
+ return AppJSONFormatter(
264
+ fmt=fmt,
265
+ datefmt=datefmt,
266
+ style="{",
267
+ rename_fields={"asctime": "timestamp", "levelname": "level"},
268
+ )
269
+
270
+ def get_logger(self, name: str | None = None) -> logging.Logger:
271
+ """Get a logger instance.
272
+
273
+ This method returns a logger instance that is a child of the root logger. If name is not provided,
274
+ the root logger will be returned instead.
275
+
276
+ Args:
277
+ name (str | None, optional): The name of the child logger. If None, the root logger will be returned.
278
+ Defaults to None.
279
+
280
+ Returns:
281
+ logging.Logger: Configured logger instance.
282
+ """
283
+ if name:
284
+ child = self._root_logger.getChild(name)
285
+ child.propagate = False
286
+ if not child.handlers:
287
+ for handler in self._handlers:
288
+ child.addHandler(handler)
289
+ return child
290
+ return self._root_logger
291
+
292
+ def set_level(self, level: int) -> None:
293
+ """Set logging level for all loggers in the hierarchy.
294
+
295
+ Args:
296
+ level (int): The logging level to set (e.g., logging.INFO, logging.DEBUG).
297
+ """
298
+ self._root_logger.setLevel(level)
299
+
300
+ def set_log_format(self, log_format: str) -> None:
301
+ """Set logging format for all loggers in the hierarchy.
302
+
303
+ Args:
304
+ log_format (str): The log format to set.
305
+ """
306
+ self._update_formatter(fmt=log_format)
307
+
308
+ def set_date_format(self, date_format: str) -> None:
309
+ """Set date format for all loggers in the hierarchy.
310
+
311
+ Args:
312
+ date_format (str): The date format to set.
313
+ """
314
+ self._update_formatter(datefmt=date_format)
315
+
316
+ def add_handler(self, handler: logging.Handler) -> None:
317
+ """Add a custom handler to the root logger.
318
+
319
+ Args:
320
+ handler (logging.Handler): The handler to add to the root logger.
321
+ """
322
+ handler.setFormatter(self._formatter)
323
+ self._root_logger.addHandler(handler)
324
+ self._handlers.append(handler)
325
+
326
+ def _update_formatter(self, fmt: str | None = None, datefmt: str | None = None) -> None:
327
+ """Update formatter and apply to all handlers.
328
+
329
+ Args:
330
+ fmt (str | None, optional): The format string. Defaults to None.
331
+ datefmt (str | None, optional): The date format string. Defaults to None.
332
+ """
333
+ current_fmt_default = LOG_FORMAT_MAP[self._log_mode]
334
+ current_fmt = fmt if fmt is not None else getattr(self._formatter, "_fmt", current_fmt_default)
335
+ current_datefmt = datefmt if datefmt is not None else getattr(self._formatter, "datefmt", DEFAULT_DATE_FORMAT)
336
+
337
+ self._formatter = self._build_formatter(current_fmt, current_datefmt)
338
+ for handler in self._handlers:
339
+ handler.setFormatter(self._formatter)
@@ -0,0 +1,176 @@
1
+ import logging
2
+ from _typeshed import Incomplete
3
+ from gllm_core.constants import LogMode as LogMode
4
+ from pythonjsonlogger.core import LogRecord
5
+ from pythonjsonlogger.json import JsonFormatter
6
+ from rich.logging import RichHandler
7
+
8
+ DEFAULT_DATE_FORMAT: str
9
+ TEXT_COLOR_MAP: Incomplete
10
+ LOG_FORMAT_KEY: str
11
+ RICH_CLOSE_TAG: str
12
+ JSON_LOG_FIELDS: Incomplete
13
+ JSON_ERROR_FIELDS_MAP: Incomplete
14
+
15
+ class TextRichHandler(RichHandler):
16
+ """Custom RichHandler that applies specific colors and log format."""
17
+ def emit(self, record: logging.LogRecord) -> None:
18
+ """Emits a log record with custom coloring.
19
+
20
+ Args:
21
+ record (logging.LogRecord): The log record to emit.
22
+ """
23
+
24
+ class SimpleRichHandler(logging.StreamHandler):
25
+ """Custom StreamHandler that utilizes Rich only to apply colors, without columns or Rich formatting.
26
+
27
+ Attributes:
28
+ console (Console): The Rich Console object to use for printing.
29
+ """
30
+ console: Incomplete
31
+ def __init__(self, *args, **kwargs) -> None:
32
+ """Initializes a new instance of the SimpleRichHandler class."""
33
+ def emit(self, record: logging.LogRecord) -> None:
34
+ """Emits a log record with simple Rich coloring.
35
+
36
+ Args:
37
+ record (logging.LogRecord): The log record to emit.
38
+ """
39
+
40
+ class AppJSONFormatter(JsonFormatter):
41
+ """JSON formatter that groups error-related fields under an 'error' key.
42
+
43
+ This formatter renames the following fields when present:
44
+ 1. exc_info -> error.message
45
+ 2. stack_info -> error.stacktrace
46
+ 3. error_code -> error.code
47
+ """
48
+ def process_log_record(self, log_record: LogRecord) -> LogRecord:
49
+ """Process log record to group and rename error-related fields.
50
+
51
+ Args:
52
+ log_record (LogRecord): The original log record.
53
+
54
+ Returns:
55
+ LogRecord: The processed log record.
56
+ """
57
+
58
+ LOG_FORMAT_HANDLER_MAP: Incomplete
59
+ LOG_FORMAT_MAP: Incomplete
60
+
61
+ class LoggerManager:
62
+ '''A singleton class to manage logging configuration.
63
+
64
+ This class ensures that the root logger is initialized only once and is used across the application.
65
+
66
+ Basic usage:
67
+ The `LoggerManager` can be used to get a logger instance as follows:
68
+ ```python
69
+ logger = LoggerManager().get_logger()
70
+ logger.info("This is an info message")
71
+ ```
72
+
73
+ Set logging configuration:
74
+ The `LoggerManager` also provides capabilities to set the logging configuration:
75
+ ```python
76
+ manager = LoggerManager()
77
+ manager.set_level(logging.DEBUG)
78
+ manager.set_log_format(custom_log_format)
79
+ manager.set_date_format(custom_date_format)
80
+ ```
81
+
82
+ Add custom handlers:
83
+ The `LoggerManager` also provides capabilities to add custom handlers to the root logger:
84
+ ```python
85
+ manager = LoggerManager()
86
+ handler = logging.FileHandler("app.log")
87
+ manager.add_handler(handler)
88
+ ```
89
+
90
+ Extra error information:
91
+ When logging errors, extra error information can be added as follows:
92
+ ```python
93
+ logger.error("I am dead!", extra={"error_code": "ERR_CONN_REFUSED"})
94
+ ```
95
+
96
+ Logging modes:
97
+ The `LoggerManager` supports three logging modes:
98
+
99
+ 1. Text: Logs in a human-readable format with RichHandler column-based formatting.
100
+ Used when the `LOG_FORMAT` environment variable is set to "text".
101
+ Output example:
102
+ ```log
103
+ 2025-10-08T09:26:16 DEBUG [LoggerName] This is a debug message.
104
+ 2025-10-08T09:26:17 INFO [LoggerName] This is an info message.
105
+ 2025-10-08T09:26:18 WARNING [LoggerName] This is a warning message.
106
+ 2025-10-08T09:26:19 ERROR [LoggerName] This is an error message.
107
+ 2025-10-08T09:26:20 CRITICAL [LoggerName] This is a critical message.
108
+ ```
109
+
110
+ 2. Simple: Logs in a human-readable format with Rich colors but without columns-based formatting.
111
+ Used when the `LOG_FORMAT` environment variable is set to "simple".
112
+ Output example:
113
+ ```log
114
+ [2025-10-08T09:26:16.123 LoggerName DEBUG] This is a debug message.
115
+ [2025-10-08T09:26:17.456 LoggerName INFO] This is an info message.
116
+ [2025-10-08T09:26:18.789 LoggerName WARNING] This is a warning message.
117
+ [2025-10-08T09:26:19.012 LoggerName ERROR] This is an error message.
118
+ [2025-10-08T09:26:20.345 LoggerName CRITICAL] This is a critical message.
119
+ ```
120
+
121
+ 3. JSON: Logs in a JSON format, recommended for easy parsing due to the structured nature of the log records.
122
+ Used when the `LOG_FORMAT` environment variable is set to "json".
123
+ Output example:
124
+ ```log
125
+ {"timestamp": "2025-10-08T11:23:43+0700", "name": "LoggerName", "level": "DEBUG", "message": "..."}
126
+ {"timestamp": "2025-10-08T11:23:44+0700", "name": "LoggerName", "level": "INFO", "message": "..."}
127
+ {"timestamp": "2025-10-08T11:23:45+0700", "name": "LoggerName", "level": "WARNING", "message": "..."}
128
+ {"timestamp": "2025-10-08T11:23:46+0700", "name": "LoggerName", "level": "ERROR", "message": "..."}
129
+ {"timestamp": "2025-10-08T11:23:47+0700", "name": "LoggerName", "level": "CRITICAL", "message": "..."}
130
+ ```
131
+
132
+ When the `LOG_FORMAT` environment is not set, the `LoggerManager` defaults to "text" mode.
133
+ '''
134
+ def __new__(cls) -> LoggerManager:
135
+ """Initialize the singleton instance.
136
+
137
+ Returns:
138
+ LoggerManager: The singleton instance.
139
+ """
140
+ def get_logger(self, name: str | None = None) -> logging.Logger:
141
+ """Get a logger instance.
142
+
143
+ This method returns a logger instance that is a child of the root logger. If name is not provided,
144
+ the root logger will be returned instead.
145
+
146
+ Args:
147
+ name (str | None, optional): The name of the child logger. If None, the root logger will be returned.
148
+ Defaults to None.
149
+
150
+ Returns:
151
+ logging.Logger: Configured logger instance.
152
+ """
153
+ def set_level(self, level: int) -> None:
154
+ """Set logging level for all loggers in the hierarchy.
155
+
156
+ Args:
157
+ level (int): The logging level to set (e.g., logging.INFO, logging.DEBUG).
158
+ """
159
+ def set_log_format(self, log_format: str) -> None:
160
+ """Set logging format for all loggers in the hierarchy.
161
+
162
+ Args:
163
+ log_format (str): The log format to set.
164
+ """
165
+ def set_date_format(self, date_format: str) -> None:
166
+ """Set date format for all loggers in the hierarchy.
167
+
168
+ Args:
169
+ date_format (str): The date format to set.
170
+ """
171
+ def add_handler(self, handler: logging.Handler) -> None:
172
+ """Add a custom handler to the root logger.
173
+
174
+ Args:
175
+ handler (logging.Handler): The handler to add to the root logger.
176
+ """