Coverage for functions \ flipdare \ util \ app_log_formatter.py: 100%
0 statements
« prev ^ index » next coverage.py v7.13.0, created at 2026-05-08 12:22 +1000
« prev ^ index » next coverage.py v7.13.0, created at 2026-05-08 12:22 +1000
1#!/usr/bin/env python
2# Copyright (c) 2026 Flipdare Pty Ltd. All rights reserved.
3#
4# This file is part of Flipdare's proprietary software and contains
5# confidential and copyrighted material. Unauthorised copying,
6# modification, distribution, or use of this file is strictly
7# prohibited without prior written permission from Flipdare Pty Ltd.
8#
9# This software includes third-party components licensed under MIT,
10# BSD, and Apache 2.0 licences. See THIRD_PARTY_NOTICES for details.
11#
14import logging
15from typing import override
16from pathlib import Path
17from flipdare.util.ansi_codes import AnsiCodes
19_LOG_FORMAT = "[%(levelname)5s %(asctime)s] %(relpath)s:%(lineno)d:%(funcName)s - %(message)s"
21_DATE_FORMAT = "%M:%S"
23_C = AnsiCodes
25# 5 - TRACE, 10 - DEBUG, 20 - INFO, 30 - WARNING, 40 - ERROR, 50 - CRITICAL
26TRACE_LEVEL = 5 # Custom log level for trace, below DEBUG (10)
27PERFORMANCE_LEVEL = 60 # Custom log level for performance (60), since important...
30class AppLogFormatter(logging.Formatter): # pragma: no cover
32 def __init__(self) -> None:
34 super().__init__(fmt=_LOG_FORMAT, datefmt=_DATE_FORMAT)
35 # Pre-create formatters for each level to ensure thread safety
36 self.project_root = Path.cwd()
37 self.formatters = {
38 logging.DEBUG: logging.Formatter(
39 _C.LIGHT_BLUE + _LOG_FORMAT + _C.RESET_COLOR,
40 _DATE_FORMAT,
41 ),
42 logging.INFO: logging.Formatter(
43 _C.LIGHT_GREEN + _LOG_FORMAT + _C.RESET_COLOR,
44 _DATE_FORMAT,
45 ),
46 logging.WARNING: logging.Formatter(
47 _C.ORANGE + _LOG_FORMAT + _C.RESET_COLOR,
48 _DATE_FORMAT,
49 ),
50 logging.ERROR: logging.Formatter(_C.RED + _LOG_FORMAT + _C.RESET_COLOR, _DATE_FORMAT),
51 logging.CRITICAL: logging.Formatter(
52 _C.LIGHT_PURPLE + _LOG_FORMAT + _C.RESET_COLOR,
53 _DATE_FORMAT,
54 ),
55 TRACE_LEVEL: logging.Formatter(
56 _C.GRAY + _LOG_FORMAT + _C.RESET_COLOR,
57 _DATE_FORMAT,
58 ),
59 PERFORMANCE_LEVEL: logging.Formatter(
60 _C.YELLOW + _LOG_FORMAT + _C.RESET_COLOR,
61 _DATE_FORMAT,
62 ),
63 }
65 # @override
66 # def formatException(self, ei: Any) -> str:
67 # # Get the standard formatted traceback string
68 # result = super().formatException(ei)
69 # # Wrap it in your custom markers
70 # return f"\n---Begin Stack Trace---\n{result}\n---End Stack Trace ---\n\n"
72 @override
73 def format(self, record: logging.LogRecord) -> str:
74 # 1. Tweak level names directly on the record before formatting
75 # This is safer than string replacement on the final message
76 if record.levelname == "WARNING":
77 record.levelname = " WARN"
79 rel_path = Path(record.pathname).relative_to(self.project_root)
80 # record.relpath = f"./{rel_path}" if not str(rel_path).startswith(".") else str(rel_path)
81 record.relpath = rel_path
82 # 2. Select the pre-configured formatter
83 formatter = self.formatters.get(record.levelno, self)
85 # 3. Use the selected formatter to get the final string
86 return formatter.format(record)