aboutsummaryrefslogtreecommitdiffstats
path: root/pydis_core/utils/logging.py
blob: c8eb5b199ec474db213a24b9ed996f5dbce763ed (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
"""Common logging related functions."""

import logging
import typing

if typing.TYPE_CHECKING:
    LoggerClass = logging.Logger
else:
    LoggerClass = logging.getLoggerClass()

TRACE_LEVEL = 5
log_format = logging.Formatter("%(asctime)s | %(levelname)s | %(name)s | %(message)s")
"""
A :obj:`logging.Formatter` that can be used to standardise logging across all projects using pydis_core.

:meta hide-value:
"""


class CustomLogger(LoggerClass):
    """Custom implementation of the :obj:`logging.Logger` class with an added :obj:`trace` method."""

    def trace(self, msg: str, *args, **kwargs) -> None:
        """
        Log the given message with the severity ``"TRACE"``.

        To pass exception information, use the keyword argument exc_info with a true value:

        .. code-block:: py

            logger.trace("Houston, we have an %s", "interesting problem", exc_info=1)

        Args:
            msg: The message to be logged.
            args, kwargs: Passed to the base log function as is.
        """
        if self.isEnabledFor(TRACE_LEVEL):
            self.log(TRACE_LEVEL, msg, *args, **kwargs)


def get_logger(name: str | None = None) -> CustomLogger:
    """
    Utility to make mypy recognise that logger is of type :obj:`CustomLogger`.

    Args:
        name: The name given to the logger.

    Returns:
        An instance of the :obj:`CustomLogger` class.
    """
    return typing.cast(CustomLogger, logging.getLogger(name))


# Setup trace level logging so that we can use it within pydis_core.
logging.TRACE = TRACE_LEVEL
logging.setLoggerClass(CustomLogger)
logging.addLevelName(TRACE_LEVEL, "TRACE")