Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
log.py247 linesDownload Raw Back to mitmproxy
1from __future__ import annotations2 3import logging4import os5import typing6import warnings7from dataclasses import dataclass8 9from mitmproxy import hooks10from mitmproxy.contrib import click as miniclick11from mitmproxy.utils import human12 13if typing.TYPE_CHECKING:14    from mitmproxy import master15 16ALERT = logging.INFO + 117"""18The ALERT logging level has the same urgency as info, but19signals to interactive tools that the user's attention should be20drawn to the output even if they're not currently looking at the21event log.22"""23logging.addLevelName(ALERT, "ALERT")24 25LogLevels = [26    "error",27    "warn",28    "info",29    "alert",30    "debug",31]32 33LOG_COLORS = {logging.ERROR: "red", logging.WARNING: "yellow", ALERT: "magenta"}34 35 36class MitmFormatter(logging.Formatter):37    def __init__(self, colorize: bool):38        super().__init__()39        self.colorize = colorize40        time = "[%s]"41        client = "[%s]"42        if colorize:43            time = miniclick.style(time, fg="cyan", dim=True)44            client = miniclick.style(client, fg="yellow", dim=True)45 46        self.with_client = f"{time}{client} %s"47        self.without_client = f"{time} %s"48 49    default_time_format = "%H:%M:%S"50    default_msec_format = "%s.%03d"51 52    def format(self, record: logging.LogRecord) -> str:53        time = self.formatTime(record)54        message = record.getMessage()55        if record.exc_info:56            message = f"{message}\n{self.formatException(record.exc_info)}"57        if self.colorize:58            message = miniclick.style(59                message,60                fg=LOG_COLORS.get(record.levelno),61                # dim=(record.levelno <= logging.DEBUG)62            )63        if client := getattr(record, "client", None):64            client = human.format_address(client)65            return self.with_client % (time, client, message)66        else:67            return self.without_client % (time, message)68 69 70class MitmLogHandler(logging.Handler):71    def __init__(self, *args, **kwargs):72        super().__init__(*args, **kwargs)73        self._initiated_in_test = os.environ.get("PYTEST_CURRENT_TEST")74 75    def filter(self, record: logging.LogRecord) -> bool:76        # We can't remove stale handlers here because that would modify .handlers during iteration!77        return bool(78            super().filter(record)79            and (80                not self._initiated_in_test81                or self._initiated_in_test == os.environ.get("PYTEST_CURRENT_TEST")82            )83        )84 85    def install(self) -> None:86        if self._initiated_in_test:87            for h in list(logging.getLogger().handlers):88                if (89                    isinstance(h, MitmLogHandler)90                    and h._initiated_in_test != self._initiated_in_test91                ):92                    h.uninstall()93 94        logging.getLogger().addHandler(self)95 96    def uninstall(self) -> None:97        logging.getLogger().removeHandler(self)98 99 100# everything below is deprecated!101 102 103class LogEntry:104    def __init__(self, msg, level):105        # it's important that we serialize to string here already so that we don't pick up changes106        # happening after this log statement.107        self.msg = str(msg)108        self.level = level109 110    def __eq__(self, other):111        if isinstance(other, LogEntry):112            return self.__dict__ == other.__dict__113        return False114 115    def __repr__(self):116        return f"LogEntry({self.msg}, {self.level})"117 118 119class Log:120    """121    The central logger, exposed to scripts as mitmproxy.ctx.log.122 123    Deprecated: Please use the standard Python logging module instead.124    """125 126    def __init__(self, master):127        self.master = master128 129    def debug(self, txt):130        """131        Log with level debug.132        """133        warnings.warn(134            "mitmproxy's ctx.log.debug() is deprecated. Please use the standard Python logging module instead.",135            DeprecationWarning,136            stacklevel=2,137        )138        logging.getLogger().debug(txt)139 140    def info(self, txt):141        """142        Log with level info.143        """144        warnings.warn(145            "mitmproxy's ctx.log.info() is deprecated. Please use the standard Python logging module instead.",146            DeprecationWarning,147            stacklevel=2,148        )149        logging.getLogger().info(txt)150 151    def alert(self, txt):152        """153        Log with level alert. Alerts have the same urgency as info, but154        signals to interactive tools that the user's attention should be155        drawn to the output even if they're not currently looking at the156        event log.157        """158        warnings.warn(159            "mitmproxy's ctx.log.alert() is deprecated. Please use the standard Python logging module instead.",160            DeprecationWarning,161            stacklevel=2,162        )163        logging.getLogger().log(ALERT, txt)164 165    def warn(self, txt):166        """167        Log with level warn.168        """169        warnings.warn(170            "mitmproxy's ctx.log.warn() is deprecated. Please use the standard Python logging module instead.",171            DeprecationWarning,172            stacklevel=2,173        )174        logging.getLogger().warning(txt)175 176    def error(self, txt):177        """178        Log with level error.179        """180        warnings.warn(181            "mitmproxy's ctx.log.error() is deprecated. Please use the standard Python logging module instead.",182            DeprecationWarning,183            stacklevel=2,184        )185        logging.getLogger().error(txt)186 187    def __call__(self, text, level="info"):188        warnings.warn(189            "mitmproxy's ctx.log() is deprecated. Please use the standard Python logging module instead.",190            DeprecationWarning,191            stacklevel=2,192        )193        logging.getLogger().log(level=logging.getLevelName(level.upper()), msg=text)194 195 196LOGGING_LEVELS_TO_LOGENTRY = {197    logging.ERROR: "error",198    logging.WARNING: "warn",199    logging.INFO: "info",200    ALERT: "alert",201    logging.DEBUG: "debug",202}203 204 205class LegacyLogEvents(MitmLogHandler):206    """Emit deprecated `add_log` events from stdlib logging."""207 208    def __init__(209        self,210        master: master.Master,211    ):212        super().__init__()213        self.master = master214        self.formatter = MitmFormatter(colorize=False)215 216    def emit(self, record: logging.LogRecord) -> None:217        entry = LogEntry(218            msg=self.format(record),219            level=LOGGING_LEVELS_TO_LOGENTRY.get(record.levelno, "error"),220        )221        self.master.event_loop.call_soon_threadsafe(222            self.master.addons.trigger,223            AddLogHook(entry),224        )225 226 227@dataclass228class AddLogHook(hooks.Hook):229    """230    **Deprecated:** Starting with mitmproxy 9, users should use the standard Python logging module instead, for example231    by calling `logging.getLogger().addHandler()`.232 233    Called whenever a new log entry is created through the mitmproxy234    context. Be careful not to log from this event, which will cause an235    infinite loop!236    """237 238    entry: LogEntry239 240 241def log_tier(level):242    """243    Comparison method for "old" LogEntry log tiers.244    Ideally you should use the standard Python logging module instead.245    """246    return dict(error=0, warn=1, info=2, alert=2, debug=3).get(level)247 
codekingpro/portable-devtools · Team Ai