1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
|
#
# This file is part of pysnmp software.
#
# Copyright (c) 2005-2020, Ilya Etingof <etingof@gmail.com>
# License: https://www.pysnmp.com/pysnmp/license.html
#
"""
This module provides debugging and logging utilities for the pysnmp library.
Classes:
Printer: A class for controlling logging output.
Debug: A helper class for managing debug flags and logging messages.
Functions:
__getattr__(attr: str): Handles deprecated attribute access and raises AttributeError for unknown attributes.
setLogger(value): Sets the global logger.
hexdump(octets): Returns a hexdump of the given octets.
Constants:
FLAG_NONE: No flags set.
FLAG_IO: Input/Output flag.
FLAG_DSP: Dispatcher flag.
FLAG_MP: Message Processing flag.
FLAG_SM: Security Model flag.
FLAG_BLD: MIB Builder flag.
FLAG_MIB: MIB flag.
FLAG_INS: Instrumentation flag.
FLAG_ACL: Access Control List flag.
FLAG_PRX: Proxy flag.
FLAG_APP: Application flag.
FLAG_ALL: All flags set.
FLAG_MAP: A dictionary mapping flag names to their corresponding constants.
Attributes:
NullHandler: A logging handler that does nothing.
logger: A global logger variable.
"""
import logging
import warnings
from pysnmp import __version__, error
# Compatibility API
deprecated_attributes = {
"flagMap": "FLAG_MAP",
"flagNone": "FLAG_NONE",
"flagIO": "FLAG_IO",
"flagDSP": "FLAG_DSP",
"flagMP": "FLAG_MP",
"flagSM": "FLAG_SM",
"flagBLD": "FLAG_BLD",
"flagMIB": "FLAG_MIB",
"flagINS": "FLAG_INS",
"flagACL": "FLAG_ACL",
"flagPRX": "FLAG_PRX",
"flagAPP": "FLAG_APP",
"flagALL": "FLAG_ALL",
}
def __getattr__(attr: str):
"""Handle deprecated attributes."""
if newAttr := deprecated_attributes.get(attr):
warnings.warn(
f"{attr} is deprecated. Please use {newAttr} instead.", DeprecationWarning
)
return globals()[newAttr]
raise AttributeError(f"module {__name__} has no attribute {attr}")
FLAG_NONE = 0x0000
FLAG_IO = 0x0001
FLAG_DSP = 0x0002
FLAG_MP = 0x0004
FLAG_SM = 0x0008
FLAG_BLD = 0x0010
FLAG_MIB = 0x0020
FLAG_INS = 0x0040
FLAG_ACL = 0x0080
FLAG_PRX = 0x0100
FLAG_APP = 0x0200
FLAG_ALL = 0xFFFF
FLAG_MAP = {
"io": FLAG_IO,
"dsp": FLAG_DSP,
"msgproc": FLAG_MP,
"secmod": FLAG_SM,
"mibbuild": FLAG_BLD,
"mibview": FLAG_MIB,
"mibinstrum": FLAG_INS,
"acl": FLAG_ACL,
"proxy": FLAG_PRX,
"app": FLAG_APP,
"all": FLAG_ALL,
}
class Printer:
"""Logging control."""
def __init__(self, logger=None, handler=None, formatter=None):
"""Logging control."""
if logger is None:
logger = logging.getLogger("pysnmp")
logger.setLevel(logging.DEBUG)
if handler is None:
handler = logging.StreamHandler()
if formatter is None:
formatter = logging.Formatter("%(asctime)s %(name)s: %(message)s")
handler.setFormatter(formatter)
handler.setLevel(logging.DEBUG)
logger.addHandler(handler)
self.__logger = logger
def __call__(self, msg):
"""Log a message."""
self.__logger.debug(msg)
def __str__(self):
"""Return a string representation of the object."""
return "<python built-in logging>"
NullHandler = logging.NullHandler
class Debug:
"""Logging control."""
DEFAULT_PRINTER = None
def __init__(self, *flags, **options):
"""Helper class for logging control."""
self._flags = FLAG_NONE
if options.get("printer") is not None:
self._printer = options.get("printer")
elif self.DEFAULT_PRINTER is not None:
self._printer = self.DEFAULT_PRINTER
else:
if "loggerName" in options:
# route our logs to parent logger
self._printer = Printer(
logger=logging.getLogger(options["loggerName"]),
handler=NullHandler(),
)
else:
self._printer = Printer()
self("running pysnmp version %s" % __version__)
for f in flags:
inverse = f and f[0] in ("!", "~")
if inverse:
f = f[1:]
try:
if inverse:
self._flags &= ~FLAG_MAP[f]
else:
self._flags |= FLAG_MAP[f]
except KeyError:
raise error.PySnmpError("bad debug flag %s" % f)
self(
"debug category '{}' {}".format(f, inverse and "disabled" or "enabled")
)
def __str__(self):
"""Return a string representation of the object."""
return f"logger {self._printer}, flags {self._flags:x}"
def __call__(self, msg):
"""Log a message."""
self._printer(msg)
def __and__(self, flag):
"""Return a boolean value of the flag."""
return self._flags & flag
def __rand__(self, flag):
"""Return a boolean value of the flag."""
return flag & self._flags
# This will yield false from bitwise and with a flag, and save
# on unnecessary calls
logger = 0
def set_logger(value):
"""Set the global logger."""
global logger
logger = value
def hexdump(octets):
"""Return a hexdump of the given octets."""
return " ".join(
[
"{}{:02X}".format(n % 16 == 0 and ("\n%.5d: " % n) or "", x)
for n, x in zip(range(len(octets)), octets)
]
)
|