Coverage for src/irorun/logger_setup.py: 66%
32 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-02 16:59 -0500
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-02 16:59 -0500
1# Copyright 2025 Faith O. Oyedemi
2# SPDX-License-Identifier: Apache-2.0
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16# For more details, see the full text of the Apache License at:
17# http://www.apache.org/licenses/LICENSE-2.0
19import logging
20import logging.config
21import os
23import typer
26class TyperLoggerHandler(logging.Handler):
27 """
28 A custom logging handler that uses Typer's secho to produce elegant, color-coded log messages.
29 """
31 def emit(self, record: logging.LogRecord) -> None:
32 fg = None
33 bg = None
35 # Map log levels to Typer colors.
36 match record.levelno:
37 case logging.DEBUG:
38 fg = typer.colors.BLACK
39 case logging.INFO:
40 fg = typer.colors.BRIGHT_BLUE
41 case logging.WARNING:
42 fg = typer.colors.BRIGHT_MAGENTA
43 case logging.ERROR:
44 fg = typer.colors.BRIGHT_WHITE
45 bg = typer.colors.RED
46 case logging.CRITICAL:
47 fg = typer.colors.BRIGHT_RED
49 message = self.format(record)
50 typer.secho(message, fg=fg, bg=bg)
53def setup_logging(config_path: str = 'logging.conf') -> logging.Logger:
54 """
55 Loads logging configuration from the specified configuration file.
56 Falls back to a basic configuration using TyperLoggerHandler if the config file is not found.
57 """
58 if os.path.exists(config_path):
59 logging.config.fileConfig(config_path, disable_existing_loggers=False)
60 else:
61 # Fallback configuration: use TyperLoggerHandler directly.
62 handler = TyperLoggerHandler()
63 formatter = logging.Formatter(
64 '[%(asctime)s] %(levelname)s in %(module)s: %(message)s',
65 datefmt='%Y-%m-%d %H:%M:%S',
66 )
67 handler.setFormatter(formatter)
68 logging.basicConfig(level=logging.INFO, handlers=[handler])
69 return logging.getLogger('irorun')
72# Initialize and export the logger.
73def get_logger() -> logging.Logger:
74 """
75 Returns the configured logger.
76 """
77 return setup_logging()