Fixed-width grid formatter with semantic highlighting and burst suppression. Format: TIME | LVL | SOURCE | ID | MESSAGE Example output: 22:47:51.690 INF API y74ebn9 Received /v1/chat/completions request 22:47:51.692 INF WORKR y74ebn9 Processing request logic... 22:47:51.
| 266 | |
| 267 | |
| 268 | class GridFormatter(logging.Formatter): |
| 269 | """ |
| 270 | Fixed-width grid formatter with semantic highlighting and burst suppression. |
| 271 | |
| 272 | Format: TIME | LVL | SOURCE | ID | MESSAGE |
| 273 | |
| 274 | Example output: |
| 275 | 22:47:51.690 INF API y74ebn9 Received /v1/chat/completions request |
| 276 | 22:47:51.692 INF WORKR y74ebn9 Processing request logic... |
| 277 | 22:47:51.695 INF PROXY Sniff HTTPS requests (x5) |
| 278 | """ |
| 279 | |
| 280 | def __init__( |
| 281 | self, |
| 282 | colorize: bool = True, |
| 283 | burst_suppression: bool = True, |
| 284 | show_tree: bool = True, # Deprecated, kept for compatibility |
| 285 | ): |
| 286 | super().__init__() |
| 287 | self.colorize = colorize |
| 288 | self.burst_suppression = burst_suppression |
| 289 | |
| 290 | def format(self, record: logging.LogRecord) -> str: |
| 291 | """Format log record into grid layout.""" |
| 292 | # Skip during Python shutdown to avoid ImportError |
| 293 | if sys.meta_path is None: |
| 294 | return record.getMessage() |
| 295 | |
| 296 | # Extract context variables with defaults |
| 297 | try: |
| 298 | req_id = request_id_var.get() |
| 299 | except LookupError: |
| 300 | req_id = " " |
| 301 | |
| 302 | try: |
| 303 | source = source_var.get() |
| 304 | except LookupError: |
| 305 | source = "SYS" |
| 306 | |
| 307 | # Normalize source to 5-letter code |
| 308 | source_normalized = normalize_source(source) |
| 309 | |
| 310 | # Column 1: Time (HH:MM:SS.mmm) - no date |
| 311 | now = datetime.now() |
| 312 | timestamp = now.strftime("%H:%M:%S.") + f"{int(now.microsecond / 1000):03d}" |
| 313 | if self.colorize: |
| 314 | time_col = f"{Colors.TIME}{timestamp}{Colors.RESET}" |
| 315 | else: |
| 316 | time_col = timestamp |
| 317 | |
| 318 | # Column 2: Level (3 chars) |
| 319 | level_abbrev = Colors.LEVEL_ABBREV.get( |
| 320 | record.levelname, record.levelname[:3].upper() |
| 321 | ) |
| 322 | if self.colorize: |
| 323 | level_color = Colors.LEVELS.get(record.levelname, Fore.WHITE) |
| 324 | level_col = f"{level_color}{level_abbrev}{Colors.RESET}" |
| 325 | else: |
no outgoing calls