1## This file is part of Scapy
2## See http://www.secdev.org/projects/scapy for more informations
3## Copyright (C) Philippe Biondi <phil@secdev.org>
4## This program is published under a GPLv2 license
5
6"""
7Logging subsystem and basic exception class.
8"""
9
10#############################
11##### Logging subsystem #####
12#############################
13
14class Scapy_Exception(Exception):
15    pass
16
17import logging, traceback, time
18
19class ScapyFreqFilter(logging.Filter):
20    def __init__(self):
21        logging.Filter.__init__(self)
22        self.warning_table = {}
23    def filter(self, record):
24        from scapy.config import conf
25        wt = conf.warning_threshold
26        if wt > 0:
27            stk = traceback.extract_stack()
28            caller=None
29            for f,l,n,c in stk:
30                if n == 'warning':
31                    break
32                caller = l
33            tm,nb = self.warning_table.get(caller, (0,0))
34            ltm = time.time()
35            if ltm-tm > wt:
36                tm = ltm
37                nb = 0
38            else:
39                if conf.warning_next_only_once:
40                    conf.warning_next_only_once = False
41                    return 0
42                if nb < 2:
43                    nb += 1
44                    if nb == 2:
45                        record.msg = "more "+record.msg
46                else:
47                    return 0
48            self.warning_table[caller] = (tm,nb)
49        return 1
50
51try:
52    from logging import NullHandler
53except ImportError:
54    # compat for python 2.6
55    from logging import Handler
56    class NullHandler(Handler):
57        def emit(self, record):
58            pass
59log_scapy = logging.getLogger("scapy")
60log_scapy.addHandler(NullHandler())
61log_runtime = logging.getLogger("scapy.runtime")          # logs at runtime
62log_runtime.addFilter(ScapyFreqFilter())
63log_interactive = logging.getLogger("scapy.interactive")  # logs in interactive functions
64log_loading = logging.getLogger("scapy.loading")          # logs when loading Scapy
65
66
67def warning(x, *args, **kargs):
68    """
69    Prints a warning during runtime.
70
71    onlyOnce - if True, the warning will never be printed again.
72    """
73    if kargs.pop("onlyOnce", False):
74        from scapy.config import conf
75        conf.warning_next_only_once = True
76    log_runtime.warning(x, *args, **kargs)
77