Logging System¶
pcapkit.utilities.logging integrates pcapkit with the standard
logging system. It owns the package-wide logger hierarchy rooted at
logger and the configuration API through
which an application decides what, if anything, pcapkit emits.
- pcapkit.utilities.logging.logger¶
Loggerinstance named afterpcapkit, at the root of the package’s logger hierarchy. Per-module loggers are its children, so configuring this one configures all ofpcapkit.- Type:
The Logger Hierarchy¶
pcapkit is the root. Every module inside the package logs through its own
child logger, named after the module and obtained from
get_logger(), so a record carries the name of
the code that emitted it and any subtree can be addressed on its own:
import logging
# quieten the registry's bookkeeping, keep everything else
logging.getLogger('pcapkit.foundation.registry').setLevel(logging.WARNING)
# or follow just the extraction path
logging.getLogger('pcapkit.foundation.extraction').setLevel(logging.DEBUG)
The names in use are the module paths themselves, e.g.
pcapkit.foundation.extraction, pcapkit.foundation.registry.protocols,
pcapkit.foundation.engines.pcap, pcapkit.foundation.reassembly.reassembly,
pcapkit.foundation.traceflow.tcp, pcapkit.utilities.warnings.
- pcapkit.utilities.logging.get_logger(name=None)[source]¶
Retrieve a logger inside
pcapkit’s hierarchy.This is the accessor every module in
pcapkituses, aslogger = get_logger(__name__), so that records carry the emitting module’s name and an application can address one subtree at a time.- Parameters:
name (
str|None) – Dotted logger name, normally the caller’s__name__.Noneor'pcapkit'yields the rootlogger. A name outside thepcapkithierarchy – notably'__main__', which is what__name__reports for a module run as a script – is placed under the root rather than beside it, since a sibling ofpcapkitwould escape everypcapkit-level configuration.- Return type:
- Returns:
The requested logger.
What DEBUG Will Tell You¶
At logging.DEBUG the library explains what it did with a file, without
descending to per-field parsing: which input was opened, which engine was
requested and which was actually used (including a fallback when an optional
dependency is missing), the file format identified from the magic number, the
output format and dumper, whether reassembly and flow tracing were enabled and
with which flags, how many frames were read, and when cleanup ran. Reassembly
reports datagram counts on flush and flow tracing reports flows opening and
closing.
Note
Nothing is logged from inside per-frame or per-field parsing loops, so
enabling DEBUG does not turn a capture with a million
packets into a million records. Registration bookkeeping across
pcapkit.foundation.registry is also at DEBUG rather
than INFO, since a library announcing its own registry
entries is not news to its consumer.
Configuring the Output¶
Importing pcapkit configures no logging output: the only handler
attached to logger is a
logging.NullHandler, and no level is set. This is the behaviour
recommended for libraries – the application keeps control of its own logging,
and pcapkit’s records simply propagate into whatever it has configured,
typically via logging.basicConfig() or logging.config.
For an application that would rather let pcapkit set up its own output,
configure() does so at runtime:
import logging
import sys
from pcapkit.utilities.logging import configure, reset
# everything pcapkit does, on stderr
configure(logging.DEBUG, stream=sys.stderr)
# to a file, with a format of your own
configure(logging.INFO, handler=logging.FileHandler('pcapkit.log'),
fmt='%(asctime)s %(name)s %(levelname)s %(message)s')
# loud in general, quiet about the registry
configure(logging.DEBUG, stream=sys.stderr)
configure(logging.WARNING, name='pcapkit.foundation.registry')
# and back to the pristine, library-neutral state
reset()
- pcapkit.utilities.logging.configure(level=None, *, name=None, stream=None, handler=None, fmt=None, datefmt=None, propagate=None, replace=True)[source]¶
Configure
pcapkit’s logging at runtime.Every argument is optional and only the ones supplied take effect, so this is usable both as a one-shot setup call and as a targeted adjustment.
- Parameters:
level (
int|str|None) – Level for the logger, as either astrname ('DEBUG') or anint(logging.DEBUG). Left untouched whenNone, which for a freshly importedpcapkitmeans the level is inherited from the application.name (
str|None) – Logger to configure, as accepted byget_logger(). Defaults to the rootlogger; pass e.g.'pcapkit.foundation.registry'to configure one subtree.stream (
IO[str] |None) – Writable text stream to log to, e.g.sys.stderr. Alogging.StreamHandleris created for it and given alogging.Formatterbuilt fromfmtanddatefmt.handler (
Handler|None) – An already-built handler to attach instead, for anything a plain stream cannot express – aRotatingFileHandler, a queue handler, a test double. Mutually exclusive withstream. Its formatter is only replaced iffmtordatefmtis given.fmt (
str|None) – Format string for the handler this call creates. Defaults toDEFAULT_FORMAT.datefmt (
str|None) – Date format string for the handler this call creates. Defaults toDEFAULT_DATE_FORMAT.propagate (
bool|None) – Whether records should reach ancestor loggers. Setting this toFalseon the rootloggerkeepspcapkit’s records out of the application’s own handlers.replace (
bool) – Whether to detach the logger’s existing handlers first, so that repeated calls replace rather than accumulate output. PassFalseto add a second destination. Unlikereset(), this only touches handlers – the level and propagation are left alone unless the corresponding arguments are given.
- Return type:
- Returns:
The logger that was configured, for chaining or inspection.
- Raises:
ValueError – If both
streamandhandlerare given, since which one is meant to receivefmtwould be ambiguous.
Example
Restore the pre-1.4 default of
sys.stderratlogging.INFO:configure(logging.INFO, stream=sys.stderr)
Send everything to a file, but keep the registry’s bookkeeping out:
configure(logging.DEBUG, handler=logging.FileHandler('pcapkit.log')) configure(logging.INFO, name='pcapkit.foundation.registry')
- pcapkit.utilities.logging.reset(name=None)[source]¶
Restore a
pcapkitlogger to its pristine, library-neutral state.That is: no handlers other than the
logging.NullHandleron the root, no level of its own (logging.NOTSET, so the level is inherited from the application’s configuration), and propagation enabled.- Parameters:
name (
str|None) – Logger to reset, as accepted byget_logger(). Defaults to the rootlogger, which also resets nothing else – children keep any level explicitly set on them.- Return type:
- Returns:
The logger that was reset.
Note
This discards the
PCAPKIT_DEVMODEbootstrap along with everything else. To reinstate it, callconfigure(logging.DEBUG, stream=sys.stderr).
- pcapkit.utilities.logging.ensure_output(level=10, *, stream=None)[source]¶
Guarantee that
pcapkit’s records have somewhere to go.This is for a caller that has switched something on precisely because it wants to see the output, and for which staying silent merely because the application never configured
loggingwould be unhelpful.Note that
Extractor(verbose=True)and the CLI’s-vdo not go through here: their frame chains are user-facing output and are written tosys.stdoutwithprint(), so they are visible with no logging configuration at all. Nothing inpcapkitcalls this function itself; it exists for consumers.An application that has configured its own handlers has already answered the question, so nothing is changed in that case.
Formatting¶
- pcapkit.utilities.logging.DEFAULT_FORMAT = '[%(levelname)s] %(asctime)s - %(message)s'¶
Default
logging.Formatterformat string.- Type:
- pcapkit.utilities.logging.DEFAULT_DATE_FORMAT = '%m/%d/%Y %I:%M:%S %p'¶
Default
logging.Formatterdate format string.- Type:
- pcapkit.utilities.logging.formatter¶
Default formatter, used by any handler that
configure()creates and by thePCAPKIT_DEVMODEbootstrap.- Type:
- pcapkit.utilities.logging.handler¶
The historical
sys.stderrhandler. It is only attached underPCAPKIT_DEVMODE; it is constructed unconditionally so thatlogger.addHandler(handler)remains a one-line way back to the pre-1.4 default output.- Type:
Environment Variables¶
- pcapkit.utilities.logging.DEVMODE¶
Development mode flag.
- Type:
See also
This variable can be configured through the environment variable
PCAPKIT_DEVMODE.
- pcapkit.utilities.logging.VERBOSE¶
Verbose output flag.
- Type:
See also
This variable can be configured through the environment variable
PCAPKIT_VERBOSE.
- pcapkit.utilities.logging.SPHINX_TYPE_CHECKING¶
This is a workaround for
typing.TYPE_CHECKINGin Sphinx.- Type:
See also
This variable can be configured through the environment variable
PCAPKIT_SPHINX.
Compatibility Note¶
Warning
pcapkit used to attach a logging.StreamHandler on
sys.stderr and force the level to logging.INFO (or
logging.DEBUG under PCAPKIT_DEVMODE) at import time.
That is no longer done, because it hijacked the logging configuration of
every application that imported pcapkit.
Two consequences are visible to existing code:
Messages that used to appear on stderr no longer do. In particular the
registered ...bookkeeping is now atlogging.DEBUGrather thanlogging.INFO. Restore the old output in one line:import logging, sys from pcapkit.utilities.logging import configure configure(logging.INFO, stream=sys.stderr)
Equivalently, re-attach the module’s own handler, which is still built and still carries the historical format:
from pcapkit.utilities.logging import handler, logger logger.setLevel(logging.INFO) logger.addHandler(handler)
The handler is no longer at
logger.handlers[0]. Code that reached into that list to remove or reconfigure the handler should callreset()orconfigure()instead.
Unaffected: logger remains public,
importable from both pcapkit.utilities.logging and
pcapkit.utilities, and named pcapkit;
PCAPKIT_DEVMODE still produces the stderr handler at
logging.DEBUG; and Extractor(verbose=True) – like the CLI’s
-v – still prints a line per frame to sys.stdout. That output is
a feature of the tool rather than diagnostics, so it deliberately stays on
print(): routing it through logging would have moved it to
another stream and made it invisible until the consumer configured a handler.
Note
The warning channel is documented separately, in
User Defined Warnings. In short:
pcapkit.utilities.warnings.warn() reports each warning exactly once per
channel – one logging.WARNING record and one warnings.warn()
– and constructing a warning no longer mutates the process-wide warning
filters, so suppression is the application’s to configure.