Coverage for src / prepare_times_nz / utilities / logger_setup.py: 53%
30 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-01 22:14 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-01 22:14 +0000
1"""
2Logger Configuration and Utilities Module
4This module configures and defines logging behavior for the entire application.
5It provides a custom logging formatter that adds colored output to console logs,
6making different log levels visually distinct.
8Main Features:
9- **CustomFormatter**: A logging formatter that applies ANSI color codes to log messages
10 based on their severity (DEBUG, INFO, WARNING, ERROR, CRITICAL).
11 This improves readability when scanning logs in the console.
12- **HTML-like Color Markup**: Supports limited markup parsing for inline coloring
13 within messages. For example, wrapping text in `<red>` or `<blue>` tags dynamically
14 highlights parts of a log entry.
15- **Convenience Functions**:
16 - `h1(text)`: Emits a prominent heading in the logs to delineate sections.
17 - `h2(text)`: Emits a secondary heading with less emphasis.
18 - `red_text(text)`: Wraps a string with `<red>` tags for red highlighting.
19 Good for drawing attention to key issues
20 - `blue_text(text)`: Wraps a string with `<blue>` tags for blue highlighting.
21 Good for highlighting field/address components of a message
23Usage:
24- Call `setup_logging()` once at application startup to initialize the logger.
25- Use the `h1()` and `h2()` functions to visually separate major log sections.
26- Use `red_text()` and `blue_text()` to inject colored text inline within log messages.
28Color References:
29- Debug: Blue
30- Info: Green
31- Warning: Yellow
32- Error: Red
33- Critical: Bright Red
35Example:
36 logger.info("This is an info message.")
37 logger.warning(red_text"This warning contains red_text(red text!)")
38 h1("Major Section Start")
39 h2("Secondary section start)
41Note:
42The color codes rely on ANSI escape sequences and will work in most modern terminals.
43Logs redirected to files will contain the raw escape codes unless handled separately.
46"""
48import logging
50logger = logging.getLogger()
53def setup_logging():
54 """
55 Runs all required commands to setup the logger handlers and set to
56 required level (currently INFO)
57 """
58 handler = logging.StreamHandler()
59 handler.setFormatter(CustomFormatter())
60 logger.handlers = [handler]
61 logger.setLevel(logging.INFO)
64class CustomFormatter(logging.Formatter):
65 """
66 A custom logging formatter that adds ANSI color codes to log messages.
68 This formatter applies color highlighting to log output based on the
69 log level (DEBUG, INFO, WARNING, ERROR, CRITICAL), making logs easier
70 to read in the console. In addition to coloring the entire message,
71 it supports limited inline markup for selectively highlighting text
72 within messages.
73 """
75 # Define colors for each log level
76 COLORS = {
77 logging.DEBUG: "\033[94m", # Blue
78 logging.INFO: "\033[92m", # Green
79 logging.WARNING: "\033[93m", # Yellow
80 logging.ERROR: "\033[91m", # Red
81 logging.CRITICAL: "\033[1;91m", # Bright Red
82 }
84 RESET = "\033[0m"
86 def format(self, record):
87 """
88 Format the specified log record as a string with color highlighting.
90 This method applies ANSI color codes to the entire log message based
91 on the record's log level (DEBUG, INFO, WARNING, ERROR, CRITICAL).
92 It also parses and replaces custom HTML-like tags (`<red>...</red>`,
93 `<blue>...</blue>`) within the log message to allow inline color highlighting.
95 Args:
96 record (logging.LogRecord): The log record to be formatted.
98 Returns:
99 str: The formatted log message string with ANSI color codes applied.
101 Notes:
102 - If no matching color is found for a log level, the default terminal
103 reset code is used.
104 - Inline color tags are replaced only if they exactly match the predefined
105 patterns (e.g., "<red>", "</red>").
106 - The reset code applied to closing tags ensures that the inline color
107 correctly blends with the outer log level color.
109 Colour reference:
111 black \033[30m
112 red \033[91m
113 green \033[92m
114 yellow \033[93m
115 blue \033[94m
116 magenta \033[95m
117 cyan \033[96m
118 white \033[97m
119 reset \033[0m
122 Extra Extra
123 bold \033[1m
124 dim \033[2m
125 underline \033[4m
126 blink \033[5m
128 """
130 color = self.COLORS.get(record.levelno, self.RESET)
131 msg = f"{color} {record.getMessage()}{self.RESET}"
133 # We add limited parsing support for html colour tags
135 # red
136 msg = msg.replace("<red>", "\033[91m")
137 msg = msg.replace("</red>", color)
139 # blue
140 msg = msg.replace("<blue>", "\033[94m")
141 msg = msg.replace("</blue>", color)
143 return msg
146# Headers
147def h1(text: str):
148 """
149 takes the string input and returns a logging info formatted to make headings
150 Allowing consistent log heading methods (h1)
151 """
152 line = "-" * (len(text) + 12)
153 # logger.info("")
154 logger.info(line)
155 logger.info("---- {%s} ----", text)
156 logger.info(line)
159def h2(text: str):
160 """
161 takes the string input and returns a log info formatted to make headings
162 Allowing consistent log heading methods (h2)
163 Less grandiose than h1
164 """
165 logger.info("---- {%s} ----", text)
168# Specific colours
169def red_text(text):
170 """
171 Returns input text string with html tags for red
172 """
173 return f"<red>{text}</red>"
176def blue_text(text):
177 """
178 Returns input text string with html tags for blue.
179 """
180 return f"<blue>{text}</blue>"
183setup_logging()