Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/scapy/error.py: 90%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# SPDX-License-Identifier: GPL-2.0-only
2# This file is part of Scapy
3# See https://scapy.net/ for more information
4# Copyright (C) Philippe Biondi <phil@secdev.org>
6"""
7Logging subsystem and basic exception class.
8"""
10#############################
11# Logging subsystem #
12#############################
15import logging
16import traceback
17import time
19from scapy.consts import WINDOWS
21# Typing imports
22from logging import LogRecord
23from typing import (
24 Any,
25 Dict,
26 Tuple,
27)
30class Scapy_Exception(Exception):
31 pass
34class ScapyInvalidPlatformException(Scapy_Exception):
35 pass
38class ScapyNoDstMacException(Scapy_Exception):
39 pass
42class ScapyFreqFilter(logging.Filter):
43 def __init__(self):
44 # type: () -> None
45 logging.Filter.__init__(self)
46 self.warning_table = {} # type: Dict[int, Tuple[float, int]] # noqa: E501
48 def filter(self, record):
49 # type: (LogRecord) -> bool
50 from scapy.config import conf
51 # Levels below INFO are not covered
52 if record.levelno <= logging.INFO:
53 return True
54 wt = conf.warning_threshold
55 if wt > 0:
56 stk = traceback.extract_stack()
57 caller = 0 # type: int
58 for _, l, n, _ in stk:
59 if n == 'warning':
60 break
61 caller = l
62 tm, nb = self.warning_table.get(caller, (0, 0))
63 ltm = time.time()
64 if ltm - tm > wt:
65 tm = ltm
66 nb = 0
67 else:
68 if nb < 2:
69 nb += 1
70 if nb == 2:
71 record.msg = "more " + str(record.msg)
72 else:
73 return False
74 self.warning_table[caller] = (tm, nb)
75 return True
78class ScapyColoredFormatter(logging.Formatter):
79 """A subclass of logging.Formatter that handles colors."""
80 levels_colored = {
81 'DEBUG': 'reset',
82 'INFO': 'reset',
83 'WARNING': 'bold+yellow',
84 'ERROR': 'bold+red',
85 'CRITICAL': 'bold+white+bg_red'
86 }
88 def format(self, record):
89 # type: (LogRecord) -> str
90 message = super(ScapyColoredFormatter, self).format(record)
91 from scapy.config import conf
92 message = conf.color_theme.format(
93 message,
94 self.levels_colored[record.levelname]
95 )
96 return message
99if WINDOWS:
100 # colorama is bundled within IPython, but
101 # logging.StreamHandler will be overwritten when called,
102 # so we can't wait for IPython to call it
103 try:
104 import colorama
105 colorama.init()
106 except ImportError:
107 pass
109# get Scapy's master logger
110log_scapy = logging.getLogger("scapy")
111log_scapy.propagate = False
112# override the level if not already set
113if log_scapy.level == logging.NOTSET:
114 log_scapy.setLevel(logging.WARNING)
115# add a custom handler controlled by Scapy's config
116_handler = logging.StreamHandler()
117_handler.setFormatter(
118 ScapyColoredFormatter(
119 "%(levelname)s: %(message)s",
120 )
121)
122log_scapy.addHandler(_handler)
123# logs at runtime
124log_runtime = logging.getLogger("scapy.runtime")
125log_runtime.addFilter(ScapyFreqFilter())
126# logs in interactive functions
127log_interactive = logging.getLogger("scapy.interactive")
128log_interactive.setLevel(logging.DEBUG)
129# logs when loading Scapy
130log_loading = logging.getLogger("scapy.loading")
133def warning(x, *args, **kargs):
134 # type: (str, *Any, **Any) -> None
135 """
136 Prints a warning during runtime.
137 """
138 log_runtime.warning(x, *args, **kargs)