1 import logging
2 import sys
3
4
5 VERBOSITY = 3
6
7
8 # The root logger for the whole top-level package:
9 _logger = logging.getLogger(__name__.rpartition('.')[0])
10
11
12 def configure_logger(logger, verbosity=VERBOSITY, *,
13 logfile=None,
14 maxlevel=logging.CRITICAL,
15 ):
16 level = max(1, # 0 disables it, so we use the next lowest.
17 min(maxlevel,
18 maxlevel - verbosity * 10))
19 logger.setLevel(level)
20 #logger.propagate = False
21
22 if not logger.handlers:
23 if logfile:
24 handler = logging.FileHandler(logfile)
25 else:
26 handler = logging.StreamHandler(sys.stdout)
27 handler.setLevel(level)
28 #handler.setFormatter(logging.Formatter())
29 logger.addHandler(handler)
30
31 # In case the provided logger is in a sub-package...
32 if logger is not _logger:
33 configure_logger(
34 _logger,
35 verbosity,
36 logfile=logfile,
37 maxlevel=maxlevel,
38 )
39
40
41 def hide_emit_errors():
42 """Ignore errors while emitting log entries.
43
44 Rather than printing a message describing the error, we show nothing.
45 """
46 # For now we simply ignore all exceptions. If we wanted to ignore
47 # specific ones (e.g. BrokenPipeError) then we would need to use
48 # a Handler subclass with a custom handleError() method.
49 orig = logging.raiseExceptions
50 logging.raiseExceptions = False
51 def restore():
52 logging.raiseExceptions = orig
53 return restore
54
55
56 class ESC[4;38;5;81mPrinter:
57 def __init__(self, verbosity=VERBOSITY):
58 self.verbosity = verbosity
59
60 def info(self, *args, **kwargs):
61 if self.verbosity < 3:
62 return
63 print(*args, **kwargs)